1
mirror of https://invent.kde.org/network/falkon.git synced 2024-12-20 02:36:34 +01:00

Add "Switch to Tab" mode for completion plopup, to just seitch to the tab

that displays the url currently completed.
Also add an option to disable the "switch tab" offer.
If enabled the user can press "Shift" to load the url in the current tab instead of switching tab.
I tried to copy behaviour of firefox. I hope I did not miss a bit...
This commit is contained in:
Franz Fellner 2012-12-04 14:29:27 +01:00
parent 1add5b51ca
commit 4c33d3563d
9 changed files with 210 additions and 19 deletions

View File

@ -33,7 +33,6 @@ LocationCompleter::LocationCompleter(QObject* parent)
s_view = new LocationCompleterView;
s_view->setModel(s_model);
s_view->setItemDelegate(new LocationCompleterDelegate(s_view));
}
}
@ -77,6 +76,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 +102,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);
drawHighlightedTextLine(linkRect, link, searchText, painter, style, opt, colorLinkRole);
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>
@ -26,6 +28,8 @@ LocationCompleterModel::LocationCompleterModel(QObject* parent)
: QStandardItemModel(parent)
, m_lastCompletion(QChar(QChar::Nbsp))
{
connect(mApp, SIGNAL(message(Qz::AppMessageType,bool)), this, SLOT(receiveMessage(Qz::AppMessageType,bool)));
loadSettings();
}
bool countBiggerThan(const QStandardItem* i1, const QStandardItem* i2)
@ -70,6 +74,9 @@ void LocationCompleterModel::refreshCompletions(const QString &string)
item->setData(query.value(3), CountRole);
item->setData(QVariant(true), BookmarkRole);
item->setData(string, SearchStringRole);
if(m_switchTabs) {
item->setData(QVariant::fromValue<TabPosition>(tabPositionForUrl(url)), TabPositionRole);
}
urlList.append(url);
itemList.append(item);
@ -93,6 +100,9 @@ void LocationCompleterModel::refreshCompletions(const QString &string)
item->setData(query.value(3), CountRole);
item->setData(QVariant(false), BookmarkRole);
item->setData(string, SearchStringRole);
if(m_switchTabs) {
item->setData(QVariant::fromValue<TabPosition>(tabPositionForUrl(url)), TabPositionRole);
}
itemList.append(item);
}
@ -120,6 +130,9 @@ void LocationCompleterModel::showMostVisited()
item->setData(query.value(0), IdRole);
item->setData(query.value(2), TitleRole);
item->setData(QVariant(false), BookmarkRole);
if(m_switchTabs) {
item->setData(QVariant::fromValue<TabPosition>(tabPositionForUrl(url)), TabPositionRole);
}
appendRow(item);
}
@ -186,3 +199,34 @@ 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();
}
void LocationCompleterModel::receiveMessage(Qz::AppMessageType mes, bool state)
{
Q_UNUSED(state)
if(mes == Qz::AM_ReloadSettings) {
loadSettings();
}
}
void LocationCompleterModel::loadSettings()
{
Settings settings;
m_switchTabs = settings.value("AddressBar/showSwitchTab", true).toBool();
}

View File

@ -20,18 +20,32 @@
#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
{
Q_OBJECT
public:
enum Role {
TitleRole = Qt::UserRole + 1,
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);
@ -52,9 +66,14 @@ 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;
void loadSettings();
QString m_lastCompletion;
bool m_switchTabs;
private slots:
void receiveMessage(Qz::AppMessageType mes, bool state);
};
#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 "settings.h"
#include <QKeyEvent>
#include <QApplication>
@ -40,6 +44,11 @@ LocationCompleterView::LocationCompleterView()
setMouseTracking(true);
installEventFilter(this);
connect(mApp, SIGNAL(message(Qz::AppMessageType,bool)), this, SLOT(receiveMessage(Qz::AppMessageType,bool)));
setItemDelegate(new LocationCompleterDelegate(this));
loadSettings();
}
QPersistentModelIndex LocationCompleterView::hoveredIndex() const
@ -63,6 +72,21 @@ bool LocationCompleterView::eventFilter(QObject* object, QEvent* event)
}
switch (keyEvent->key()) {
case Qt::Key_Return:
case Qt::Key_Enter:
if(m_switchTabs && !(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 +158,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(m_switchTabs && (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(m_switchTabs) {
static_cast<LocationCompleterDelegate*>(itemDelegate())->drawSwitchToTab(true);
viewport()->update();
return true;
}
}
}
case QEvent::Show:
m_ignoreNextMouseMove = true;
break;
@ -170,6 +217,9 @@ void LocationCompleterView::close()
QListView::hide();
verticalScrollBar()->setValue(0);
if(m_switchTabs) {
static_cast<LocationCompleterDelegate*>(itemDelegate())->drawSwitchToTab(true);
}
}
void LocationCompleterView::currentChanged(const QModelIndex &current, const QModelIndex &previous)
@ -203,3 +253,44 @@ void LocationCompleterView::mouseMoveEvent(QMouseEvent* event)
QListView::mouseMoveEvent(event);
}
void LocationCompleterView::mouseReleaseEvent(QMouseEvent* event)
{
if(m_switchTabs && !(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);
}
void LocationCompleterView::receiveMessage(Qz::AppMessageType mes, bool state)
{
Q_UNUSED(state)
if(mes == Qz::AM_ReloadSettings) {
loadSettings();
}
}
void LocationCompleterView::loadSettings()
{
Settings settings;
m_switchTabs = settings.value("AddressBar/showSwitchTab", true).toBool();
static_cast<LocationCompleterDelegate*>(itemDelegate())->drawSwitchToTab(m_switchTabs);
}

View File

@ -21,6 +21,7 @@
#include <QListView>
#include "qz_namespace.h"
#include "locationcompletermodel.h"
class QT_QUPZILLA_EXPORT LocationCompleterView : public QListView
{
@ -34,20 +35,27 @@ 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);private slots:
void receiveMessage(Qz::AppMessageType mes, bool state);
protected:
void mouseMoveEvent(QMouseEvent* event);
void mouseReleaseEvent(QMouseEvent* event);
private:
void loadSettings();
bool m_ignoreNextMouseMove;
QPersistentModelIndex m_hoveredIndex;
bool m_switchTabs;
};
#endif // LOCATIONCOMPLETERVIEW_H

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">