1
mirror of https://invent.kde.org/network/falkon.git synced 2024-12-20 10:46:35 +01:00

Merge pull request #657 from ff2000/master

"Switch to tab" for completion popup if suggested url is already loaded in another window/tab
This commit is contained in:
David Rosca 2012-12-06 05:26:18 -08:00
commit d6ec6f67ff
14 changed files with 170 additions and 24 deletions

1
.gitignore vendored
View File

@ -26,3 +26,4 @@ Thumbs.db
tests/modeltest
*.pdb
*.ilk
*.kdev4

View File

@ -325,7 +325,6 @@ HEADERS += \
tools/focusselectlineedit.h \
navigation/completer/locationcompleterdelegate.h \
navigation/completer/locationcompleter.h \
navigation/completer/locationcompletermodel.h \
navigation/completer/locationcompleterview.h \
history/history.h \
history/historymodel.h \

View File

@ -77,6 +77,7 @@ 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()));
disconnect(s_view, SIGNAL(aboutToActivateTab(TabPosition)), m_locationBar, SLOT(clear()));
}
void LocationCompleter::showPopup()
@ -102,6 +103,7 @@ void LocationCompleter::showPopup()
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()));
connect(s_view, SIGNAL(aboutToActivateTab(TabPosition)), m_locationBar, SLOT(clear()));
adjustPopupSize();
}

View File

@ -28,6 +28,7 @@ LocationCompleterDelegate::LocationCompleterDelegate(LocationCompleterView* pare
: QStyledItemDelegate(parent)
, m_rowHeight(0)
, m_padding(0)
, m_drawSwitchToTab(true)
, m_view(parent)
{
}
@ -109,8 +110,14 @@ void LocationCompleterDelegate::paint(QPainter* painter, const QStyleOptionViewI
QRect linkRect(titleRect.x(), infoYPos, titleRect.width(), opt.fontMetrics.height());
QString link(opt.fontMetrics.elidedText(index.data(Qt::DisplayRole).toString(), Qt::ElideRight, linkRect.width()));
painter->setFont(opt.font);
TabPosition pos = index.data(LocationCompleterModel::TabPositionRole).value<TabPosition>();
if(m_drawSwitchToTab && pos.windowIndex != -1) {
// TODO: select and paint a nice icon to give better feedback to the user.
drawTextLine(linkRect, tr("Switch to tab"), painter, style, opt, colorLinkRole);
}
else {
drawHighlightedTextLine(linkRect, link, searchText, painter, style, opt, colorLinkRole);
}
// Draw line at the very bottom of item if the item is not highlighted
if (!(opt.state & QStyle::State_Selected)) {
@ -288,3 +295,9 @@ QSize LocationCompleterDelegate::sizeHint(const QStyleOptionViewItem &option, co
return QSize(200, m_rowHeight);
}
void LocationCompleterDelegate::drawSwitchToTab(bool enable)
{
m_drawSwitchToTab = enable;
}

View File

@ -32,6 +32,8 @@ public:
void paint(QPainter* painter, const QStyleOptionViewItem &option, const QModelIndex &index) const;
QSize sizeHint(const QStyleOptionViewItem &option, const QModelIndex &index) const;
void drawSwitchToTab(bool enable);
private:
void drawHighlightedTextLine(const QRect &rect, QString text, const QString &searchText,
QPainter* painter, const QStyle* style, const QStyleOptionViewItemV4 &option,
@ -45,6 +47,7 @@ private:
mutable int m_rowHeight;
mutable int m_padding;
bool m_drawSwitchToTab;
LocationCompleterView* m_view;
};

View File

@ -19,6 +19,8 @@
#include "iconprovider.h"
#include "qzsettings.h"
#include "mainapplication.h"
#include "qupzilla.h"
#include "tabwidget.h"
#include <QSqlQuery>
@ -70,6 +72,9 @@ void LocationCompleterModel::refreshCompletions(const QString &string)
item->setData(query.value(3), CountRole);
item->setData(QVariant(true), BookmarkRole);
item->setData(string, SearchStringRole);
if(qzSettings->showSwitchTab) {
item->setData(QVariant::fromValue<TabPosition>(tabPositionForUrl(url)), TabPositionRole);
}
urlList.append(url);
itemList.append(item);
@ -93,6 +98,9 @@ void LocationCompleterModel::refreshCompletions(const QString &string)
item->setData(query.value(3), CountRole);
item->setData(QVariant(false), BookmarkRole);
item->setData(string, SearchStringRole);
if(qzSettings->showSwitchTab) {
item->setData(QVariant::fromValue<TabPosition>(tabPositionForUrl(url)), TabPositionRole);
}
itemList.append(item);
}
@ -120,6 +128,9 @@ void LocationCompleterModel::showMostVisited()
item->setData(query.value(0), IdRole);
item->setData(query.value(2), TitleRole);
item->setData(QVariant(false), BookmarkRole);
if(qzSettings->showSwitchTab) {
item->setData(QVariant::fromValue<TabPosition>(tabPositionForUrl(url)), TabPositionRole);
}
appendRow(item);
}
@ -186,3 +197,20 @@ QSqlQuery LocationCompleterModel::createQuery(const QString &searchString, const
return sqlQuery;
}
TabPosition LocationCompleterModel::tabPositionForUrl(const QUrl& url) const
{
for(int win=0; win < mApp->windowCount(); ++win) {
QupZilla* mainWin = mApp->mainWindows().at(win);
QList<WebTab*> tabs = mainWin->tabWidget()->allTabs();
for(int tab=0; tab < tabs.count(); ++tab) {
if(tabs[tab]->url() == url) {
TabPosition pos;
pos.windowIndex = win;
pos.tabIndex = tab;
return pos;
}
}
}
return TabPosition();
}

View File

@ -20,9 +20,21 @@
#include <QStandardItemModel>
#include "qz_namespace.h"
class QSqlQuery;
class QUrl;
struct TabPosition {
int windowIndex;
int tabIndex;
TabPosition()
: windowIndex(-1)
, tabIndex(-1)
{}
};
Q_DECLARE_METATYPE(TabPosition)
class LocationCompleterModel : public QStandardItemModel
{
public:
@ -31,17 +43,14 @@ public:
BookmarkRole = Qt::UserRole + 2,
IdRole = Qt::UserRole + 3,
SearchStringRole = Qt::UserRole + 4,
CountRole = Qt::UserRole + 5
CountRole = Qt::UserRole + 5,
TabPositionRole = Qt::UserRole + 6
};
explicit LocationCompleterModel(QObject* parent = 0);
void refreshCompletions(const QString &string);
void showMostVisited();
signals:
public slots:
private:
enum Type {
HistoryAndBookmarks = 0,
@ -52,9 +61,9 @@ private:
QSqlQuery createQuery(const QString &searchString, const QString &orderBy, const QList<QUrl> &alreadyFound,
int limit, bool bookmarks = false, bool exactMatch = false);
TabPosition tabPositionForUrl(const QUrl& url) const;
QString m_lastCompletion;
};
#endif // LOCATIONCOMPLETERMODEL_H

View File

@ -17,8 +17,12 @@
* ============================================================ */
#include "locationcompleterview.h"
#include "locationcompletermodel.h"
#include "locationcompleterdelegate.h"
#include "mainapplication.h"
#include "qupzilla.h"
#include "history.h"
#include "tabwidget.h"
#include "qzsettings.h"
#include <QKeyEvent>
#include <QApplication>
@ -63,6 +67,21 @@ bool LocationCompleterView::eventFilter(QObject* object, QEvent* event)
}
switch (keyEvent->key()) {
case Qt::Key_Return:
case Qt::Key_Enter:
if(qzSettings->showSwitchTab && !(keyEvent->modifiers() & Qt::ShiftModifier)) {
QModelIndex idx = selectionModel()->currentIndex();
if(idx.isValid()) {
TabPosition pos = idx.data(LocationCompleterModel::TabPositionRole).value<TabPosition>();
if(pos.windowIndex!= -1) {
activateTab(pos);
close();
return true;
}
}
}
break;
case Qt::Key_End:
case Qt::Key_Home:
if (keyEvent->modifiers() & Qt::ControlModifier) {
@ -134,12 +153,35 @@ bool LocationCompleterView::eventFilter(QObject* object, QEvent* event)
case Qt::Key_PageUp:
case Qt::Key_PageDown:
return false;
case Qt::Key_Shift:
// don't switch if there is no hovered or selected index to not disturb typing
if(qzSettings->showSwitchTab && (selectionModel()->currentIndex().isValid() || m_hoveredIndex.isValid())) {
static_cast<LocationCompleterDelegate*>(itemDelegate())->drawSwitchToTab(false);
viewport()->update();
return true;
}
break;
} // switch (keyEvent->key())
(static_cast<QObject*>(focusProxy()))->event(keyEvent);
return true;
}
case QEvent::KeyRelease: {
QKeyEvent* keyEvent = static_cast<QKeyEvent*>(event);
switch(keyEvent->key()) {
case Qt::Key_Shift:
if(qzSettings->showSwitchTab) {
static_cast<LocationCompleterDelegate*>(itemDelegate())->drawSwitchToTab(true);
viewport()->update();
return true;
}
}
}
case QEvent::Show:
m_ignoreNextMouseMove = true;
break;
@ -170,6 +212,9 @@ void LocationCompleterView::close()
QListView::hide();
verticalScrollBar()->setValue(0);
if(qzSettings->showSwitchTab) {
static_cast<LocationCompleterDelegate*>(itemDelegate())->drawSwitchToTab(true);
}
}
void LocationCompleterView::currentChanged(const QModelIndex &current, const QModelIndex &previous)
@ -203,3 +248,29 @@ void LocationCompleterView::mouseMoveEvent(QMouseEvent* event)
QListView::mouseMoveEvent(event);
}
void LocationCompleterView::mouseReleaseEvent(QMouseEvent* event)
{
if(qzSettings->showSwitchTab && !(event->modifiers() & Qt::ShiftModifier) && m_hoveredIndex.isValid()) {
TabPosition pos = m_hoveredIndex.data(LocationCompleterModel::TabPositionRole).value<TabPosition>();
if(pos.windowIndex != -1) {
event->accept();
activateTab(pos);
close();
}
else {
QListView::mouseReleaseEvent(event);
}
}
else {
QListView::mouseReleaseEvent(event);
}
}
void LocationCompleterView::activateTab(TabPosition pos)
{
emit aboutToActivateTab(pos);
QupZilla* win = mApp->mainWindows().at(pos.windowIndex);
win->activateWindow();
win->tabWidget()->setCurrentIndex(pos.tabIndex);
}

View File

@ -21,6 +21,7 @@
#include <QListView>
#include "qz_namespace.h"
#include "locationcompletermodel.h"
class QT_QUPZILLA_EXPORT LocationCompleterView : public QListView
{
@ -34,15 +35,18 @@ public:
signals:
void closed();
void aboutToActivateTab(TabPosition pos);
public slots:
void close();
private slots:
void currentChanged(const QModelIndex &current, const QModelIndex &previous);
void activateTab(TabPosition pos);
protected:
void mouseMoveEvent(QMouseEvent* event);
void mouseReleaseEvent(QMouseEvent* event);
private:
bool m_ignoreNextMouseMove;

View File

@ -174,6 +174,8 @@ void WebSearchBar::setupEngines()
void WebSearchBar::searchChanged(const ButtonWithMenu::Item &item)
{
selectAll();
setFocus();
setPlaceholderText(item.text);
m_completerModel->setStringList(QStringList());

View File

@ -32,6 +32,7 @@ void QzSettings::loadSettings()
addCountryWithAlt = settings.value("AddCountryDomainWithAltKey", true).toBool();
showLoadingProgress = settings.value("ShowLoadingProgress", false).toBool();
showLocationSuggestions = settings.value("showSuggestions", 0).toInt();
showSwitchTab = settings.value("showSwitchTab", true).toBool();
settings.endGroup();
settings.beginGroup("SearchEngines");

View File

@ -37,6 +37,7 @@ public:
bool addCountryWithAlt;
bool showLoadingProgress;
int showLocationSuggestions;
bool showSwitchTab;
// SearchEngines
bool showSearchSuggestions;

View File

@ -214,6 +214,7 @@ Preferences::Preferences(QupZilla* mainClass, QWidget* parent)
//AddressBar
settings.beginGroup("AddressBar");
ui->addressbarCompletion->setCurrentIndex(settings.value("showSuggestions", 0).toInt());
ui->completionShowSwitchTab->setChecked(settings.value("showSwitchTab", true).toBool());
ui->selectAllOnFocus->setChecked(settings.value("SelectAllTextOnDoubleClick", true).toBool());
ui->selectAllOnClick->setChecked(settings.value("SelectAllTextOnClick", false).toBool());
ui->addCountryWithAlt->setChecked(settings.value("AddCountryDomainWithAltKey", true).toBool());
@ -937,6 +938,7 @@ void Preferences::saveSettings()
//AddressBar
settings.beginGroup("AddressBar");
settings.setValue("showSuggestions", ui->addressbarCompletion->currentIndex());
settings.setValue("showSwitchTab", ui->completionShowSwitchTab->isChecked());
settings.setValue("SelectAllTextOnDoubleClick", ui->selectAllOnFocus->isChecked());
settings.setValue("SelectAllTextOnClick", ui->selectAllOnClick->isChecked());
settings.setValue("AddCountryDomainWithAltKey", ui->addCountryWithAlt->isChecked());

View File

@ -160,9 +160,9 @@
<enum>Qt::NoFocus</enum>
</property>
<property name="currentIndex">
<number>5</number>
<number>0</number>
</property>
<widget class="QWidget" name="stackedWidgetPage1">
<widget class="QWidget" name="generalPage">
<layout class="QGridLayout" name="gridLayout_6">
<item row="4" column="2">
<widget class="QFrame" name="newTabFrame">
@ -486,7 +486,7 @@
</item>
</layout>
</widget>
<widget class="QWidget" name="stackedWidgetPage2">
<widget class="QWidget" name="appearancePage">
<layout class="QGridLayout" name="gridLayout_21">
<item row="0" column="0">
<widget class="QTabWidget" name="tabWidget_2">
@ -647,14 +647,14 @@
</item>
</layout>
</widget>
<widget class="QWidget" name="stackedWidgetPage3">
<widget class="QWidget" name="tabsPage">
<layout class="QVBoxLayout" name="verticalLayout_4">
<item>
<widget class="QTabWidget" name="tabWidget_3">
<property name="currentIndex">
<number>0</number>
</property>
<widget class="QWidget" name="tab_6">
<widget class="QWidget" name="tabsBehaviourPage">
<attribute name="title">
<string>Tabs behavior</string>
</attribute>
@ -770,7 +770,7 @@
</item>
</layout>
</widget>
<widget class="QWidget" name="tab_7">
<widget class="QWidget" name="addressBarBehaviourPage">
<attribute name="title">
<string>Address Bar behavior</string>
</attribute>
@ -832,6 +832,16 @@
</item>
</layout>
</item>
<item>
<widget class="QCheckBox" name="completionShowSwitchTab">
<property name="toolTip">
<string>Press &quot;Shift&quot; to not switch the tab but load the url in the current tab.</string>
</property>
<property name="text">
<string>Propose to switch tab if completed url is already loaded.</string>
</property>
</widget>
</item>
<item>
<widget class="QCheckBox" name="showLoadingInAddressBar">
<property name="text">
@ -963,7 +973,7 @@
</item>
</layout>
</widget>
<widget class="QWidget" name="stackedWidgetPage4">
<widget class="QWidget" name="browsingPage">
<layout class="QGridLayout" name="gridLayout_9">
<item row="0" column="0">
<widget class="QTabWidget" name="tabWidget">
@ -1552,7 +1562,7 @@
</item>
</layout>
</widget>
<widget class="QWidget" name="page_2">
<widget class="QWidget" name="fontsPage">
<layout class="QGridLayout" name="gridLayout_15">
<item row="0" column="0" rowspan="2" colspan="3">
<widget class="QLabel" name="label_27">
@ -1744,7 +1754,7 @@
</item>
</layout>
</widget>
<widget class="QWidget" name="page_4">
<widget class="QWidget" name="shortcutsPage">
<layout class="QGridLayout" name="gridLayout">
<item row="0" column="0">
<widget class="QLabel" name="label_13">
@ -1782,7 +1792,7 @@
</item>
</layout>
</widget>
<widget class="QWidget" name="downloadPage">
<widget class="QWidget" name="downloadsPage">
<layout class="QGridLayout" name="gridLayout_10">
<item row="0" column="0" colspan="4">
<widget class="QLabel" name="label_23">
@ -1941,7 +1951,7 @@
</item>
</layout>
</widget>
<widget class="QWidget" name="stackedWidgetPage5">
<widget class="QWidget" name="passwordManagerPage">
<layout class="QGridLayout" name="gridLayout_11">
<item row="0" column="0" colspan="2">
<widget class="QLabel" name="label_20">
@ -2003,7 +2013,7 @@
</item>
</layout>
</widget>
<widget class="QWidget" name="stackedWidgetPage6">
<widget class="QWidget" name="privacyPage">
<layout class="QGridLayout" name="gridLayout_12">
<item row="26" column="1" colspan="4">
<widget class="QCheckBox" name="jscanAccessClipboard">
@ -2188,7 +2198,7 @@
</item>
</layout>
</widget>
<widget class="QWidget" name="page_3">
<widget class="QWidget" name="notificationsPage">
<layout class="QGridLayout" name="gridLayout_17">
<item row="0" column="0" colspan="4">
<widget class="QLabel" name="label_41">
@ -2315,7 +2325,7 @@
</item>
</layout>
</widget>
<widget class="QWidget" name="page">
<widget class="QWidget" name="extensionsPage">
<layout class="QGridLayout" name="gridLayout_14">
<item row="0" column="0" colspan="2">
<widget class="QFrame" name="horizontalFrame">
@ -2334,7 +2344,7 @@
</item>
</layout>
</widget>
<widget class="QWidget" name="stackedWidgetPage7">
<widget class="QWidget" name="otherPage">
<layout class="QGridLayout" name="gridLayout_13">
<item row="9" column="0" colspan="4">
<widget class="QLabel" name="label_9">