mirror of
https://invent.kde.org/network/falkon.git
synced 2024-12-20 02:36:34 +01:00
Completely rewritten whole completion for address bar.
- fixed occasional flickering when typing in address bar - support for opening completions with pressing Down key - support for selecting completions with Tab key closes #105
This commit is contained in:
parent
98d51b0661
commit
64bdafde87
@ -50,7 +50,6 @@ SOURCES += \
|
||||
history/historymodel.cpp \
|
||||
history/historymanager.cpp \
|
||||
navigation/websearchbar.cpp \
|
||||
navigation/locationcompleter.cpp \
|
||||
navigation/locationbar.cpp \
|
||||
network/networkmanagerproxy.cpp \
|
||||
network/networkmanager.cpp \
|
||||
@ -170,7 +169,10 @@ SOURCES += \
|
||||
tools/plaineditwithlines.cpp \
|
||||
webview/websettings.cpp \
|
||||
tools/focusselectlineedit.cpp \
|
||||
navigation/locationcompleterdelegate.cpp
|
||||
navigation/completer/locationcompleterdelegate.cpp \
|
||||
navigation/completer/locationcompleter.cpp \
|
||||
navigation/completer/locationcompletermodel.cpp \
|
||||
navigation/completer/locationcompleterview.cpp
|
||||
|
||||
HEADERS += \
|
||||
webview/tabpreview.h \
|
||||
@ -189,7 +191,6 @@ HEADERS += \
|
||||
history/historymodel.h \
|
||||
history/historymanager.h \
|
||||
navigation/websearchbar.h \
|
||||
navigation/locationcompleter.h \
|
||||
navigation/locationbar.h \
|
||||
network/networkmanagerproxy.h \
|
||||
network/networkmanager.h \
|
||||
@ -313,7 +314,10 @@ HEADERS += \
|
||||
sidebar/sidebarinterface.h \
|
||||
webview/websettings.h \
|
||||
tools/focusselectlineedit.h \
|
||||
navigation/locationcompleterdelegate.h
|
||||
navigation/completer/locationcompleterdelegate.h \
|
||||
navigation/completer/locationcompleter.h \
|
||||
navigation/completer/locationcompletermodel.h \
|
||||
navigation/completer/locationcompleterview.h
|
||||
|
||||
FORMS += \
|
||||
preferences/autofillmanager.ui \
|
||||
|
120
src/lib/navigation/completer/locationcompleter.cpp
Normal file
120
src/lib/navigation/completer/locationcompleter.cpp
Normal file
@ -0,0 +1,120 @@
|
||||
/* ============================================================
|
||||
* QupZilla - WebKit based browser
|
||||
* Copyright (C) 2010-2012 David Rosca <nowrep@gmail.com>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
* ============================================================ */
|
||||
#include "locationcompleter.h"
|
||||
#include "locationcompletermodel.h"
|
||||
#include "locationcompleterview.h"
|
||||
#include "locationcompleterdelegate.h"
|
||||
#include "locationbar.h"
|
||||
|
||||
LocationCompleterView* LocationCompleter::s_view = 0;
|
||||
LocationCompleterModel* LocationCompleter::s_model = 0;
|
||||
|
||||
LocationCompleter::LocationCompleter(QObject* parent)
|
||||
: QObject(parent)
|
||||
, m_locationBar(0)
|
||||
{
|
||||
if (!s_view) {
|
||||
s_model = new LocationCompleterModel;
|
||||
s_view = new LocationCompleterView;
|
||||
|
||||
s_view->setModel(s_model);
|
||||
s_view->setItemDelegate(new LocationCompleterDelegate(s_view));
|
||||
}
|
||||
}
|
||||
|
||||
void LocationCompleter::setLocationBar(LocationBar* locationBar)
|
||||
{
|
||||
m_locationBar = locationBar;
|
||||
}
|
||||
|
||||
void LocationCompleter::closePopup()
|
||||
{
|
||||
s_view->close();
|
||||
}
|
||||
|
||||
void LocationCompleter::complete(const QString &string)
|
||||
{
|
||||
s_model->refreshCompletions(string);
|
||||
|
||||
showPopup();
|
||||
}
|
||||
|
||||
void LocationCompleter::showMostVisited()
|
||||
{
|
||||
s_model->refreshCompletions(QString());
|
||||
|
||||
showPopup();
|
||||
}
|
||||
|
||||
void LocationCompleter::currentChanged(const QModelIndex &index)
|
||||
{
|
||||
QString completion = index.data().toString();
|
||||
if (completion.isEmpty()) {
|
||||
completion = m_originalText;
|
||||
}
|
||||
|
||||
emit showCompletion(completion);
|
||||
}
|
||||
|
||||
void LocationCompleter::popupClosed()
|
||||
{
|
||||
disconnect(s_view->selectionModel(), SIGNAL(currentChanged(QModelIndex, QModelIndex)), this, SLOT(currentChanged(QModelIndex)));
|
||||
disconnect(s_view, SIGNAL(clicked(QModelIndex)), this, SIGNAL(completionActivated()));
|
||||
disconnect(s_view, SIGNAL(closed()), this, SLOT(popupClosed()));
|
||||
}
|
||||
|
||||
void LocationCompleter::showPopup()
|
||||
{
|
||||
Q_ASSERT(m_locationBar);
|
||||
|
||||
if (s_model->rowCount() == 0) {
|
||||
s_view->close();
|
||||
return;
|
||||
}
|
||||
|
||||
if (s_view->isVisible()) {
|
||||
adjustPopupSize();
|
||||
return;
|
||||
}
|
||||
|
||||
QRect popupRect(m_locationBar->mapToGlobal(m_locationBar->pos()), m_locationBar->size());
|
||||
popupRect.setY(popupRect.bottom());
|
||||
|
||||
s_view->setFocusProxy(m_locationBar);
|
||||
s_view->setGeometry(popupRect);
|
||||
|
||||
connect(s_view->selectionModel(), SIGNAL(currentChanged(QModelIndex, QModelIndex)), this, SLOT(currentChanged(QModelIndex)));
|
||||
connect(s_view, SIGNAL(clicked(QModelIndex)), this, SIGNAL(completionActivated()));
|
||||
connect(s_view, SIGNAL(closed()), this, SLOT(popupClosed()));
|
||||
|
||||
adjustPopupSize();
|
||||
}
|
||||
|
||||
void LocationCompleter::adjustPopupSize()
|
||||
{
|
||||
const int maxItemsCount = 6;
|
||||
|
||||
int popupHeight = s_view->sizeHintForRow(0) * qMin(maxItemsCount, s_model->rowCount());
|
||||
popupHeight += 2 * s_view->frameWidth();
|
||||
|
||||
s_view->resize(s_view->width(), popupHeight);
|
||||
s_view->setCurrentIndex(QModelIndex());
|
||||
s_view->show();
|
||||
|
||||
m_originalText = m_locationBar->text();
|
||||
}
|
63
src/lib/navigation/completer/locationcompleter.h
Normal file
63
src/lib/navigation/completer/locationcompleter.h
Normal file
@ -0,0 +1,63 @@
|
||||
/* ============================================================
|
||||
* QupZilla - WebKit based browser
|
||||
* Copyright (C) 2010-2012 David Rosca <nowrep@gmail.com>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
* ============================================================ */
|
||||
#ifndef LOCATIONCOMPLETER_H
|
||||
#define LOCATIONCOMPLETER_H
|
||||
|
||||
#include <QObject>
|
||||
|
||||
#include "qz_namespace.h"
|
||||
|
||||
class QModelIndex;
|
||||
|
||||
class LocationCompleterModel;
|
||||
class LocationCompleterView;
|
||||
class LocationBar;
|
||||
|
||||
class QT_QUPZILLA_EXPORT LocationCompleter : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
explicit LocationCompleter(QObject* parent = 0);
|
||||
|
||||
void setLocationBar(LocationBar* locationBar);
|
||||
void closePopup();
|
||||
|
||||
signals:
|
||||
void showCompletion(const QString &);
|
||||
void completionActivated();
|
||||
|
||||
public slots:
|
||||
void complete(const QString &string);
|
||||
void showMostVisited();
|
||||
|
||||
private slots:
|
||||
void currentChanged(const QModelIndex &index);
|
||||
void popupClosed();
|
||||
|
||||
private:
|
||||
void showPopup();
|
||||
void adjustPopupSize();
|
||||
|
||||
LocationBar* m_locationBar;
|
||||
QString m_originalText;
|
||||
|
||||
static LocationCompleterView* s_view;
|
||||
static LocationCompleterModel* s_model;
|
||||
};
|
||||
|
||||
#endif // LOCATIONCOMPLETER_H
|
@ -16,78 +16,17 @@
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
* ============================================================ */
|
||||
#include "locationcompleterdelegate.h"
|
||||
#include "locationcompleterview.h"
|
||||
|
||||
#include <QPainter>
|
||||
#include <QApplication>
|
||||
#include <QMouseEvent>
|
||||
|
||||
#include <QDebug>
|
||||
|
||||
CompleterListView::CompleterListView(QWidget* parent)
|
||||
: QListView(parent)
|
||||
, m_selectedItemByMousePosition(false)
|
||||
, m_rowHeight(0)
|
||||
{
|
||||
setMouseTracking(true);
|
||||
setUniformItemSizes(true);
|
||||
}
|
||||
|
||||
bool CompleterListView::ignoreSelectedFlag() const
|
||||
{
|
||||
return m_selectedItemByMousePosition;
|
||||
}
|
||||
|
||||
int CompleterListView::rowHeight() const
|
||||
{
|
||||
return m_rowHeight;
|
||||
}
|
||||
|
||||
void CompleterListView::setRowHeight(int height)
|
||||
{
|
||||
m_rowHeight = height;
|
||||
}
|
||||
|
||||
void CompleterListView::currentChanged(const QModelIndex ¤t, const QModelIndex &previous)
|
||||
{
|
||||
m_selectedItemByMousePosition = false;
|
||||
m_lastMouseIndex = current;
|
||||
|
||||
QListView::currentChanged(current, previous);
|
||||
|
||||
viewport()->repaint();
|
||||
}
|
||||
|
||||
void CompleterListView::mouseMoveEvent(QMouseEvent* event)
|
||||
{
|
||||
QModelIndex last = m_lastMouseIndex;
|
||||
QModelIndex atCursor = indexAt(mapFromGlobal(QCursor::pos()));
|
||||
|
||||
if (atCursor.isValid()) {
|
||||
m_lastMouseIndex = atCursor;
|
||||
m_selectedItemByMousePosition = true;
|
||||
}
|
||||
|
||||
if (last != atCursor) {
|
||||
viewport()->repaint();
|
||||
}
|
||||
|
||||
QListView::mouseMoveEvent(event);
|
||||
}
|
||||
|
||||
void CompleterListView::keyPressEvent(QKeyEvent* event)
|
||||
{
|
||||
if (currentIndex() != m_lastMouseIndex) {
|
||||
setCurrentIndex(m_lastMouseIndex);
|
||||
}
|
||||
|
||||
QListView::keyPressEvent(event);
|
||||
}
|
||||
|
||||
LocationCompleterDelegate::LocationCompleterDelegate(CompleterListView* parent)
|
||||
LocationCompleterDelegate::LocationCompleterDelegate(LocationCompleterView* parent)
|
||||
: QStyledItemDelegate(parent)
|
||||
, m_rowHeight(0)
|
||||
, m_padding(0)
|
||||
, m_listView(parent)
|
||||
, m_view(parent)
|
||||
{
|
||||
}
|
||||
|
||||
@ -110,14 +49,15 @@ void LocationCompleterDelegate::paint(QPainter* painter, const QStyleOptionViewI
|
||||
int leftPosition = m_padding * 2;
|
||||
int rightPosition = opt.rect.right() - m_padding;
|
||||
|
||||
if (m_listView->ignoreSelectedFlag()) {
|
||||
if (opt.state.testFlag(QStyle::State_MouseOver)) {
|
||||
opt.state |= QStyle::State_Selected;
|
||||
}
|
||||
else {
|
||||
opt.state &= ~QStyle::State_Selected;
|
||||
}
|
||||
// if (m_view->ignoreSelectedFlag()) {
|
||||
// if (opt.state.testFlag(QStyle::State_MouseOver)) {
|
||||
if (m_view->hoveredIndex() == index) {
|
||||
opt.state |= QStyle::State_Selected;
|
||||
}
|
||||
else {
|
||||
opt.state &= ~QStyle::State_Selected;
|
||||
}
|
||||
// }
|
||||
|
||||
const QPalette::ColorRole colorRole = opt.state & QStyle::State_Selected ? QPalette::HighlightedText : QPalette::Text;
|
||||
const QPalette::ColorRole colorLinkRole = opt.state & QStyle::State_Selected ? QPalette::HighlightedText : QPalette::Link;
|
||||
@ -169,11 +109,7 @@ QSize LocationCompleterDelegate::sizeHint(const QStyleOptionViewItem &option, co
|
||||
const QFontMetrics titleMetrics(titleFont);
|
||||
|
||||
m_rowHeight = 2 * m_padding + opt.fontMetrics.leading() + opt.fontMetrics.height() + titleMetrics.height();
|
||||
|
||||
m_listView->setRowHeight(m_rowHeight);
|
||||
m_listView->setMaximumHeight(6 * m_rowHeight);
|
||||
}
|
||||
|
||||
return QSize(200, m_rowHeight);
|
||||
}
|
||||
|
@ -19,38 +19,15 @@
|
||||
#define LOCATIONCOMPLETERDELEGATE_H
|
||||
|
||||
#include <QStyledItemDelegate>
|
||||
#include <QListView>
|
||||
|
||||
#include "qz_namespace.h"
|
||||
|
||||
class QT_QUPZILLA_EXPORT CompleterListView : public QListView
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
explicit CompleterListView(QWidget* parent = 0);
|
||||
|
||||
bool ignoreSelectedFlag() const;
|
||||
|
||||
int rowHeight() const;
|
||||
void setRowHeight(int height);
|
||||
|
||||
private slots:
|
||||
void currentChanged(const QModelIndex ¤t, const QModelIndex &previous);
|
||||
protected:
|
||||
void mouseMoveEvent(QMouseEvent* event);
|
||||
void keyPressEvent(QKeyEvent* event);
|
||||
|
||||
private:
|
||||
bool m_selectedItemByMousePosition;
|
||||
int m_rowHeight;
|
||||
|
||||
QModelIndex m_lastMouseIndex;
|
||||
};
|
||||
class LocationCompleterView;
|
||||
|
||||
class QT_QUPZILLA_EXPORT LocationCompleterDelegate : public QStyledItemDelegate
|
||||
{
|
||||
public:
|
||||
explicit LocationCompleterDelegate(CompleterListView* parent = 0);
|
||||
explicit LocationCompleterDelegate(LocationCompleterView* parent = 0);
|
||||
|
||||
void paint(QPainter* painter, const QStyleOptionViewItem &option, const QModelIndex &index) const;
|
||||
QSize sizeHint(const QStyleOptionViewItem &option, const QModelIndex &index) const;
|
||||
@ -59,7 +36,7 @@ private:
|
||||
mutable int m_rowHeight;
|
||||
mutable int m_padding;
|
||||
|
||||
CompleterListView* m_listView;
|
||||
LocationCompleterView* m_view;
|
||||
};
|
||||
|
||||
#endif // LOCATIONCOMPLETERDELEGATE_H
|
@ -15,65 +15,37 @@
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
* ============================================================ */
|
||||
#include "locationcompleter.h"
|
||||
#include "locationcompleterdelegate.h"
|
||||
#include "locationbar.h"
|
||||
#include "locationcompletermodel.h"
|
||||
#include "iconprovider.h"
|
||||
#include "mainapplication.h"
|
||||
|
||||
#include <QStandardItemModel>
|
||||
#include <QSqlQuery>
|
||||
|
||||
LocationCompleter::LocationCompleter(QObject* parent)
|
||||
: QCompleter(parent)
|
||||
LocationCompleterModel::LocationCompleterModel(QObject* parent)
|
||||
: QStandardItemModel(parent)
|
||||
, m_lastCompletion(QChar(QChar::Nbsp))
|
||||
{
|
||||
m_model = new QStandardItemModel();
|
||||
|
||||
m_listView = new CompleterListView();
|
||||
m_listView->setItemDelegateForColumn(0, new LocationCompleterDelegate(m_listView));
|
||||
|
||||
setModel(m_model);
|
||||
setPopup(m_listView);
|
||||
|
||||
setCompletionMode(QCompleter::PopupCompletion);
|
||||
setMaxVisibleItems(6);
|
||||
}
|
||||
|
||||
QStringList LocationCompleter::splitPath(const QString &path) const
|
||||
void LocationCompleterModel::refreshCompletions(const QString &string)
|
||||
{
|
||||
Q_UNUSED(path);
|
||||
return QStringList();
|
||||
}
|
||||
|
||||
void LocationCompleter::showMostVisited()
|
||||
{
|
||||
m_model->clear();
|
||||
|
||||
QSqlQuery query;
|
||||
query.exec("SELECT url, title FROM history ORDER BY count DESC LIMIT 15");
|
||||
|
||||
while (query.next()) {
|
||||
QStandardItem* item = new QStandardItem();
|
||||
const QUrl &url = query.value(0).toUrl();
|
||||
|
||||
item->setIcon(_iconForUrl(url));
|
||||
item->setText(url.toEncoded());
|
||||
item->setData(query.value(1), Qt::UserRole);
|
||||
|
||||
m_model->appendRow(item);
|
||||
if (m_lastCompletion == string) {
|
||||
return;
|
||||
}
|
||||
|
||||
QCompleter::complete();
|
||||
}
|
||||
m_lastCompletion = string;
|
||||
|
||||
if (string.isEmpty()) {
|
||||
showMostVisited();
|
||||
return;
|
||||
}
|
||||
|
||||
clear();
|
||||
|
||||
void LocationCompleter::refreshCompleter(const QString &string)
|
||||
{
|
||||
int limit = string.size() < 3 ? 25 : 15;
|
||||
QString searchString = QString("%%1%").arg(string);
|
||||
QList<QUrl> urlList;
|
||||
|
||||
m_model->clear();
|
||||
|
||||
QSqlQuery query;
|
||||
query.prepare("SELECT url, title, icon FROM bookmarks WHERE title LIKE ? OR url LIKE ? LIMIT ?");
|
||||
query.addBindValue(searchString);
|
||||
@ -89,7 +61,7 @@ void LocationCompleter::refreshCompleter(const QString &string)
|
||||
item->setData(query.value(1), Qt::UserRole);
|
||||
item->setIcon(IconProvider::iconFromImage(QImage::fromData(query.value(2).toByteArray())));
|
||||
|
||||
m_model->appendRow(item);
|
||||
appendRow(item);
|
||||
urlList.append(url);
|
||||
}
|
||||
|
||||
@ -113,6 +85,25 @@ void LocationCompleter::refreshCompleter(const QString &string)
|
||||
item->setText(url.toEncoded());
|
||||
item->setData(query.value(1), Qt::UserRole);
|
||||
|
||||
m_model->appendRow(item);
|
||||
appendRow(item);
|
||||
}
|
||||
}
|
||||
|
||||
void LocationCompleterModel::showMostVisited()
|
||||
{
|
||||
clear();
|
||||
|
||||
QSqlQuery query;
|
||||
query.exec("SELECT url, title FROM history ORDER BY count DESC LIMIT 15");
|
||||
|
||||
while (query.next()) {
|
||||
QStandardItem* item = new QStandardItem();
|
||||
const QUrl &url = query.value(0).toUrl();
|
||||
|
||||
item->setIcon(_iconForUrl(url));
|
||||
item->setText(url.toEncoded());
|
||||
item->setData(query.value(1), Qt::UserRole);
|
||||
|
||||
appendRow(item);
|
||||
}
|
||||
}
|
@ -15,34 +15,26 @@
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
* ============================================================ */
|
||||
#ifndef LOCATIONCOMPLETER_H
|
||||
#define LOCATIONCOMPLETER_H
|
||||
#ifndef LOCATIONCOMPLETERMODEL_H
|
||||
#define LOCATIONCOMPLETERMODEL_H
|
||||
|
||||
#include <QCompleter>
|
||||
#include <QStandardItemModel>
|
||||
|
||||
#include "qz_namespace.h"
|
||||
|
||||
class QStandardItemModel;
|
||||
|
||||
class CompleterListView;
|
||||
|
||||
class QT_QUPZILLA_EXPORT LocationCompleter : public QCompleter
|
||||
class LocationCompleterModel : public QStandardItemModel
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
explicit LocationCompleter(QObject* parent = 0);
|
||||
explicit LocationCompleterModel(QObject* parent = 0);
|
||||
|
||||
virtual QStringList splitPath(const QString &path) const;
|
||||
void refreshCompletions(const QString &string);
|
||||
void showMostVisited();
|
||||
|
||||
signals:
|
||||
|
||||
public slots:
|
||||
void refreshCompleter(const QString &string);
|
||||
void showMostVisited();
|
||||
|
||||
private:
|
||||
CompleterListView* m_listView;
|
||||
QStandardItemModel* m_model;
|
||||
QString m_lastCompletion;
|
||||
|
||||
};
|
||||
|
||||
#endif // LOCATIONCOMPLETER_H
|
||||
#endif // LOCATIONCOMPLETERMODEL_H
|
188
src/lib/navigation/completer/locationcompleterview.cpp
Normal file
188
src/lib/navigation/completer/locationcompleterview.cpp
Normal file
@ -0,0 +1,188 @@
|
||||
/* ============================================================
|
||||
* QupZilla - WebKit based browser
|
||||
* Copyright (C) 2010-2012 David Rosca <nowrep@gmail.com>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
* ============================================================ */
|
||||
#include "locationcompleterview.h"
|
||||
|
||||
#include <QKeyEvent>
|
||||
#include <QApplication>
|
||||
#include <QStyle>
|
||||
|
||||
LocationCompleterView::LocationCompleterView()
|
||||
: QListView(0)
|
||||
, m_ignoreNextMouseMove(false)
|
||||
{
|
||||
setWindowFlags(Qt::Popup);
|
||||
|
||||
setUniformItemSizes(true);
|
||||
setEditTriggers(QAbstractItemView::NoEditTriggers);
|
||||
setVerticalScrollMode(QAbstractItemView::ScrollPerPixel);
|
||||
setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
|
||||
setSelectionBehavior(QAbstractItemView::SelectRows);
|
||||
setSelectionMode(QAbstractItemView::SingleSelection);
|
||||
|
||||
setMouseTracking(true);
|
||||
installEventFilter(this);
|
||||
}
|
||||
|
||||
QPersistentModelIndex LocationCompleterView::hoveredIndex() const
|
||||
{
|
||||
return m_hoveredIndex;
|
||||
}
|
||||
|
||||
bool LocationCompleterView::eventFilter(QObject* object, QEvent* event)
|
||||
{
|
||||
// Event filter based on QCompleter::eventFilter from qcompleter.cpp
|
||||
|
||||
switch (event->type()) {
|
||||
case QEvent::KeyPress: {
|
||||
QKeyEvent* keyEvent = static_cast<QKeyEvent*>(event);
|
||||
QModelIndex curIndex = m_hoveredIndex;
|
||||
|
||||
if ((keyEvent->key() == Qt::Key_Up || keyEvent->key() == Qt::Key_Down)
|
||||
&& currentIndex() != curIndex) {
|
||||
setCurrentIndex(curIndex);
|
||||
}
|
||||
|
||||
switch (keyEvent->key()) {
|
||||
case Qt::Key_End:
|
||||
case Qt::Key_Home:
|
||||
if (keyEvent->modifiers() & Qt::ControlModifier) {
|
||||
return false;
|
||||
}
|
||||
break;
|
||||
|
||||
case Qt::Key_Left:
|
||||
case Qt::Key_Right:
|
||||
close();
|
||||
break;
|
||||
|
||||
case Qt::Key_Escape:
|
||||
close();
|
||||
return false;
|
||||
|
||||
case Qt::Key_F4:
|
||||
if (keyEvent->modifiers() == Qt::AltModifier) {
|
||||
close();
|
||||
return false;
|
||||
}
|
||||
break;
|
||||
|
||||
case Qt::Key_Tab:
|
||||
case Qt::Key_Backtab: {
|
||||
Qt::Key k = keyEvent->key() == Qt::Key_Tab ? Qt::Key_Down : Qt::Key_Up;
|
||||
QKeyEvent ev(QKeyEvent::KeyPress, k, Qt::NoModifier);
|
||||
QApplication::sendEvent(this, &ev);
|
||||
return false;
|
||||
}
|
||||
|
||||
case Qt::Key_Up:
|
||||
if (!curIndex.isValid()) {
|
||||
int rowCount = model()->rowCount();
|
||||
QModelIndex lastIndex = model()->index(rowCount - 1, 0);
|
||||
setCurrentIndex(lastIndex);
|
||||
return true;
|
||||
}
|
||||
else if (curIndex.row() == 0) {
|
||||
setCurrentIndex(QModelIndex());
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
|
||||
case Qt::Key_Down:
|
||||
if (!curIndex.isValid()) {
|
||||
QModelIndex firstIndex = model()->index(0, 0);
|
||||
setCurrentIndex(firstIndex);
|
||||
return true;
|
||||
}
|
||||
else if (curIndex.row() == model()->rowCount() - 1) {
|
||||
setCurrentIndex(QModelIndex());
|
||||
scrollToTop();
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
|
||||
case Qt::Key_PageUp:
|
||||
case Qt::Key_PageDown:
|
||||
return false;
|
||||
} // switch (keyEvent->key())
|
||||
|
||||
(static_cast<QObject*>(focusProxy()))->event(keyEvent);
|
||||
break;
|
||||
}
|
||||
|
||||
case QEvent::Show:
|
||||
m_ignoreNextMouseMove = true;
|
||||
return false;
|
||||
|
||||
case QEvent::MouseButtonPress:
|
||||
if (!underMouse()) {
|
||||
close();
|
||||
return true;
|
||||
}
|
||||
break;
|
||||
|
||||
case QEvent::InputMethod:
|
||||
case QEvent::ShortcutOverride:
|
||||
QApplication::sendEvent(focusProxy(), event);
|
||||
break;
|
||||
|
||||
default:
|
||||
return QListView::eventFilter(object, event);
|
||||
} // switch (event->type())
|
||||
|
||||
return QListView::eventFilter(object, event);
|
||||
}
|
||||
|
||||
void LocationCompleterView::close()
|
||||
{
|
||||
emit closed();
|
||||
m_hoveredIndex = QPersistentModelIndex();
|
||||
|
||||
QListView::hide();
|
||||
}
|
||||
|
||||
void LocationCompleterView::currentChanged(const QModelIndex ¤t, const QModelIndex &previous)
|
||||
{
|
||||
m_hoveredIndex = current;
|
||||
|
||||
QListView::currentChanged(current, previous);
|
||||
|
||||
viewport()->update();
|
||||
}
|
||||
|
||||
void LocationCompleterView::mouseMoveEvent(QMouseEvent* event)
|
||||
{
|
||||
if (m_ignoreNextMouseMove || !isVisible()) {
|
||||
m_ignoreNextMouseMove = false;
|
||||
|
||||
QListView::mouseMoveEvent(event);
|
||||
return;
|
||||
}
|
||||
|
||||
QModelIndex last = m_hoveredIndex;
|
||||
QModelIndex atCursor = indexAt(mapFromGlobal(QCursor::pos()));
|
||||
|
||||
if (atCursor.isValid()) {
|
||||
m_hoveredIndex = atCursor;
|
||||
}
|
||||
|
||||
if (last != atCursor) {
|
||||
viewport()->update();
|
||||
}
|
||||
|
||||
QListView::mouseMoveEvent(event);
|
||||
}
|
53
src/lib/navigation/completer/locationcompleterview.h
Normal file
53
src/lib/navigation/completer/locationcompleterview.h
Normal file
@ -0,0 +1,53 @@
|
||||
/* ============================================================
|
||||
* QupZilla - WebKit based browser
|
||||
* Copyright (C) 2010-2012 David Rosca <nowrep@gmail.com>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
* ============================================================ */
|
||||
#ifndef LOCATIONCOMPLETERVIEW_H
|
||||
#define LOCATIONCOMPLETERVIEW_H
|
||||
|
||||
#include <QListView>
|
||||
|
||||
#include "qz_namespace.h"
|
||||
|
||||
class QT_QUPZILLA_EXPORT LocationCompleterView : public QListView
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
explicit LocationCompleterView();
|
||||
|
||||
QPersistentModelIndex hoveredIndex() const;
|
||||
|
||||
bool eventFilter(QObject* object, QEvent* event);
|
||||
|
||||
signals:
|
||||
void closed();
|
||||
|
||||
public slots:
|
||||
void close();
|
||||
|
||||
private slots:
|
||||
void currentChanged(const QModelIndex ¤t, const QModelIndex &previous);
|
||||
|
||||
protected:
|
||||
void mouseMoveEvent(QMouseEvent* event);
|
||||
|
||||
private:
|
||||
bool m_ignoreNextMouseMove;
|
||||
|
||||
QPersistentModelIndex m_hoveredIndex;
|
||||
};
|
||||
|
||||
#endif // LOCATIONCOMPLETERVIEW_H
|
@ -20,7 +20,6 @@
|
||||
#include "tabbedwebview.h"
|
||||
#include "rssmanager.h"
|
||||
#include "mainapplication.h"
|
||||
#include "locationcompleter.h"
|
||||
#include "clickablelabel.h"
|
||||
#include "siteinfowidget.h"
|
||||
#include "rsswidget.h"
|
||||
@ -66,12 +65,11 @@ LocationBar::LocationBar(QupZilla* mainClass)
|
||||
|
||||
setWidgetSpacing(0);
|
||||
|
||||
m_locationCompleter = new LocationCompleter();
|
||||
setCompleter(m_locationCompleter);
|
||||
m_completer.setLocationBar(this);
|
||||
connect(&m_completer, SIGNAL(showCompletion(QString)), this, SLOT(showCompletion(QString)));
|
||||
connect(&m_completer, SIGNAL(completionActivated()), this, SLOT(urlEnter()));
|
||||
|
||||
connect(this, SIGNAL(textEdited(QString)), this, SLOT(textEdit()));
|
||||
connect(this, SIGNAL(textEdited(QString)), m_locationCompleter, SLOT(refreshCompleter(QString)));
|
||||
connect(m_locationCompleter->popup(), SIGNAL(clicked(QModelIndex)), this, SLOT(urlEnter()));
|
||||
connect(m_siteIcon, SIGNAL(clicked()), this, SLOT(showSiteInfo()));
|
||||
connect(m_goIcon, SIGNAL(clicked(QPoint)), this, SLOT(urlEnter()));
|
||||
connect(m_rssIcon, SIGNAL(clicked(QPoint)), this, SLOT(rssIconClicked()));
|
||||
@ -93,6 +91,12 @@ void LocationBar::updatePlaceHolderText()
|
||||
setPlaceholderText(tr("Enter URL address or search on %1").arg(mApp->searchEnginesManager()->activeEngine().name));
|
||||
}
|
||||
|
||||
void LocationBar::showCompletion(const QString &newText)
|
||||
{
|
||||
LineEdit::setText(newText);
|
||||
end(false);
|
||||
}
|
||||
|
||||
QUrl LocationBar::createUrl()
|
||||
{
|
||||
QUrl urlToLoad;
|
||||
@ -124,7 +128,7 @@ QUrl LocationBar::createUrl()
|
||||
|
||||
void LocationBar::urlEnter()
|
||||
{
|
||||
m_locationCompleter->popup()->hide();
|
||||
m_completer.closePopup();
|
||||
m_webView->setFocus();
|
||||
|
||||
emit loadUrl(createUrl());
|
||||
@ -132,6 +136,13 @@ void LocationBar::urlEnter()
|
||||
|
||||
void LocationBar::textEdit()
|
||||
{
|
||||
if (!text().isEmpty()) {
|
||||
m_completer.complete(text());
|
||||
}
|
||||
else {
|
||||
m_completer.closePopup();
|
||||
}
|
||||
|
||||
showGoButton();
|
||||
}
|
||||
|
||||
@ -165,15 +176,7 @@ void LocationBar::hideGoButton()
|
||||
|
||||
void LocationBar::showMostVisited()
|
||||
{
|
||||
if (text().isEmpty()) {
|
||||
// Workaround: If we show popup when text in locationbar is empty and then
|
||||
// move up and down in completer and then we leave completer -> completer will
|
||||
// set text in locationbar back to last "real" completion
|
||||
QKeyEvent event(QEvent::KeyPress, Qt::Key_unknown, Qt::NoModifier, QString(" "));
|
||||
keyPressEvent(&event);
|
||||
}
|
||||
|
||||
m_locationCompleter->showMostVisited();
|
||||
m_completer.complete(QString());
|
||||
}
|
||||
|
||||
void LocationBar::showSiteInfo()
|
||||
@ -400,6 +403,10 @@ void LocationBar::keyPressEvent(QKeyEvent* event)
|
||||
}
|
||||
break;
|
||||
|
||||
case Qt::Key_Down:
|
||||
m_completer.complete(text());
|
||||
break;
|
||||
|
||||
case Qt::Key_Escape:
|
||||
m_webView->setFocus();
|
||||
showUrl(m_webView->url());
|
||||
@ -470,5 +477,4 @@ void LocationBar::keyReleaseEvent(QKeyEvent* event)
|
||||
LocationBar::~LocationBar()
|
||||
{
|
||||
delete m_bookmarkIcon;
|
||||
delete m_locationCompleter;
|
||||
}
|
||||
|
@ -22,6 +22,7 @@
|
||||
|
||||
#include "qz_namespace.h"
|
||||
#include "lineedit.h"
|
||||
#include "completer/locationcompleter.h"
|
||||
|
||||
class QupZilla;
|
||||
class LineEdit;
|
||||
@ -52,7 +53,7 @@ signals:
|
||||
|
||||
public slots:
|
||||
void showUrl(const QUrl &url);
|
||||
virtual void setText(const QString &text);
|
||||
void setText(const QString &text);
|
||||
|
||||
private slots:
|
||||
void siteIconChanged();
|
||||
@ -67,6 +68,7 @@ private slots:
|
||||
void pasteAndGo();
|
||||
|
||||
void updatePlaceHolderText();
|
||||
void showCompletion(const QString &newText);
|
||||
|
||||
private:
|
||||
void contextMenuEvent(QContextMenuEvent* event);
|
||||
@ -82,6 +84,8 @@ private:
|
||||
void showGoButton();
|
||||
void hideGoButton();
|
||||
|
||||
LocationCompleter m_completer;
|
||||
|
||||
BookmarkIcon* m_bookmarkIcon;
|
||||
GoIcon* m_goIcon;
|
||||
RssIcon* m_rssIcon;
|
||||
@ -89,7 +93,6 @@ private:
|
||||
|
||||
QupZilla* p_QupZilla;
|
||||
TabbedWebView* m_webView;
|
||||
LocationCompleter* m_locationCompleter;
|
||||
|
||||
QMenu* m_menu;
|
||||
QAction* m_pasteAndGoAction;
|
||||
|
Loading…
Reference in New Issue
Block a user