diff --git a/.gitignore b/.gitignore index d70a4e91e..cebe534ab 100644 --- a/.gitignore +++ b/.gitignore @@ -26,3 +26,4 @@ Thumbs.db tests/modeltest *.pdb *.ilk +*.kdev4 diff --git a/src/lib/lib.pro b/src/lib/lib.pro index 4fcfc4ec1..6ac168f8e 100644 --- a/src/lib/lib.pro +++ b/src/lib/lib.pro @@ -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 \ diff --git a/src/lib/navigation/completer/locationcompleter.cpp b/src/lib/navigation/completer/locationcompleter.cpp index d758c5aa4..5a9f81fd9 100644 --- a/src/lib/navigation/completer/locationcompleter.cpp +++ b/src/lib/navigation/completer/locationcompleter.cpp @@ -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(); } diff --git a/src/lib/navigation/completer/locationcompleterdelegate.cpp b/src/lib/navigation/completer/locationcompleterdelegate.cpp index 09e0f9d20..a92b2109d 100644 --- a/src/lib/navigation/completer/locationcompleterdelegate.cpp +++ b/src/lib/navigation/completer/locationcompleterdelegate.cpp @@ -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(); + 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; +} + diff --git a/src/lib/navigation/completer/locationcompleterdelegate.h b/src/lib/navigation/completer/locationcompleterdelegate.h index f1585557e..bd448c676 100644 --- a/src/lib/navigation/completer/locationcompleterdelegate.h +++ b/src/lib/navigation/completer/locationcompleterdelegate.h @@ -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; }; diff --git a/src/lib/navigation/completer/locationcompletermodel.cpp b/src/lib/navigation/completer/locationcompletermodel.cpp index 8629f50a6..88ab9a6fe 100644 --- a/src/lib/navigation/completer/locationcompletermodel.cpp +++ b/src/lib/navigation/completer/locationcompletermodel.cpp @@ -19,6 +19,8 @@ #include "iconprovider.h" #include "qzsettings.h" #include "mainapplication.h" +#include "qupzilla.h" +#include "tabwidget.h" #include @@ -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(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(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(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 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(); +} diff --git a/src/lib/navigation/completer/locationcompletermodel.h b/src/lib/navigation/completer/locationcompletermodel.h index a91b05797..d3f046eab 100644 --- a/src/lib/navigation/completer/locationcompletermodel.h +++ b/src/lib/navigation/completer/locationcompletermodel.h @@ -20,9 +20,21 @@ #include +#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 &alreadyFound, int limit, bool bookmarks = false, bool exactMatch = false); + TabPosition tabPositionForUrl(const QUrl& url) const; QString m_lastCompletion; - }; #endif // LOCATIONCOMPLETERMODEL_H diff --git a/src/lib/navigation/completer/locationcompleterview.cpp b/src/lib/navigation/completer/locationcompleterview.cpp index 173e64d60..d178d20eb 100644 --- a/src/lib/navigation/completer/locationcompleterview.cpp +++ b/src/lib/navigation/completer/locationcompleterview.cpp @@ -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 #include @@ -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(); + 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(itemDelegate())->drawSwitchToTab(false); + viewport()->update(); + return true; + } + break; } // switch (keyEvent->key()) (static_cast(focusProxy()))->event(keyEvent); return true; } + case QEvent::KeyRelease: { + QKeyEvent* keyEvent = static_cast(event); + + switch(keyEvent->key()) { + case Qt::Key_Shift: + if(qzSettings->showSwitchTab) { + static_cast(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(itemDelegate())->drawSwitchToTab(true); + } } void LocationCompleterView::currentChanged(const QModelIndex ¤t, 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(); + 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); +} diff --git a/src/lib/navigation/completer/locationcompleterview.h b/src/lib/navigation/completer/locationcompleterview.h index b6a8545fd..f1ab04088 100644 --- a/src/lib/navigation/completer/locationcompleterview.h +++ b/src/lib/navigation/completer/locationcompleterview.h @@ -21,6 +21,7 @@ #include #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 ¤t, const QModelIndex &previous); + void activateTab(TabPosition pos); protected: void mouseMoveEvent(QMouseEvent* event); + void mouseReleaseEvent(QMouseEvent* event); private: bool m_ignoreNextMouseMove; diff --git a/src/lib/navigation/websearchbar.cpp b/src/lib/navigation/websearchbar.cpp index 1361f9472..42a759ac3 100644 --- a/src/lib/navigation/websearchbar.cpp +++ b/src/lib/navigation/websearchbar.cpp @@ -174,6 +174,8 @@ void WebSearchBar::setupEngines() void WebSearchBar::searchChanged(const ButtonWithMenu::Item &item) { + selectAll(); + setFocus(); setPlaceholderText(item.text); m_completerModel->setStringList(QStringList()); diff --git a/src/lib/other/qzsettings.cpp b/src/lib/other/qzsettings.cpp index d0aae3d10..6fce57f39 100644 --- a/src/lib/other/qzsettings.cpp +++ b/src/lib/other/qzsettings.cpp @@ -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"); diff --git a/src/lib/other/qzsettings.h b/src/lib/other/qzsettings.h index f341e6ba2..b5a452606 100644 --- a/src/lib/other/qzsettings.h +++ b/src/lib/other/qzsettings.h @@ -37,6 +37,7 @@ public: bool addCountryWithAlt; bool showLoadingProgress; int showLocationSuggestions; + bool showSwitchTab; // SearchEngines bool showSearchSuggestions; diff --git a/src/lib/preferences/preferences.cpp b/src/lib/preferences/preferences.cpp index 015342467..67d3a413a 100644 --- a/src/lib/preferences/preferences.cpp +++ b/src/lib/preferences/preferences.cpp @@ -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()); diff --git a/src/lib/preferences/preferences.ui b/src/lib/preferences/preferences.ui index 9ba0631b6..3d37a15ba 100644 --- a/src/lib/preferences/preferences.ui +++ b/src/lib/preferences/preferences.ui @@ -160,9 +160,9 @@ Qt::NoFocus - 5 + 0 - + @@ -486,7 +486,7 @@ - + @@ -647,14 +647,14 @@ - + 0 - + Tabs behavior @@ -770,7 +770,7 @@ - + Address Bar behavior @@ -832,6 +832,16 @@ + + + + Press "Shift" to not switch the tab but load the url in the current tab. + + + Propose to switch tab if completed url is already loaded. + + + @@ -963,7 +973,7 @@ - + @@ -1552,7 +1562,7 @@ - + @@ -1744,7 +1754,7 @@ - + @@ -1782,7 +1792,7 @@ - + @@ -1941,7 +1951,7 @@ - + @@ -2003,7 +2013,7 @@ - + @@ -2188,7 +2198,7 @@ - + @@ -2315,7 +2325,7 @@ - + @@ -2334,7 +2344,7 @@ - +