diff --git a/src/lib/navigation/completer/locationcompleter.cpp b/src/lib/navigation/completer/locationcompleter.cpp index f11e9a13b..5ae9176c6 100644 --- a/src/lib/navigation/completer/locationcompleter.cpp +++ b/src/lib/navigation/completer/locationcompleter.cpp @@ -1,6 +1,6 @@ /* ============================================================ -* QupZilla - WebKit based browser -* Copyright (C) 2010-2014 David Rosca +* QupZilla - Qt web browser +* Copyright (C) 2010-2017 David Rosca * * 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 @@ -97,6 +97,12 @@ void LocationCompleter::refreshJobFinished() showPopup(); + if (!s_view->currentIndex().isValid() && s_model->index(0, 0).data(LocationCompleterModel::VisitSearchItemRole).toBool()) { + m_ignoreCurrentChanged = true; + s_view->setCurrentIndex(s_model->index(0, 0)); + m_ignoreCurrentChanged = false; + } + if (qzSettings->useInlineCompletion) { emit showDomainCompletion(job->domainCompletion()); } @@ -119,23 +125,32 @@ void LocationCompleter::slotPopupClosed() void LocationCompleter::currentChanged(const QModelIndex &index) { + if (m_ignoreCurrentChanged) { + return; + } + QString completion = index.data().toString(); - bool isOriginal = false; + bool completeDomain = index.data(LocationCompleterModel::VisitSearchItemRole).toBool(); + + // Domain completion was dismissed + if (completeDomain && completion == m_originalText) { + completeDomain = false; + } if (completion.isEmpty()) { - isOriginal = true; + completeDomain = true; completion = m_originalText; } - emit showCompletion(completion, isOriginal); + emit showCompletion(completion, completeDomain); } void LocationCompleter::indexActivated(const QModelIndex &index) { Q_ASSERT(index.isValid()); - const QUrl url = index.data(LocationCompleterModel::UrlRole).toUrl(); + QUrl url = index.data(LocationCompleterModel::UrlRole).toUrl(); bool ok; const int tabPos = index.data(LocationCompleterModel::TabPositionTabRole).toInt(&ok); @@ -153,6 +168,10 @@ void LocationCompleter::indexActivated(const QModelIndex &index) bookmark->updateVisitCount(); } + if (index.data(LocationCompleterModel::VisitSearchItemRole).toBool()) { + url = QUrl(m_originalText); + } + loadUrl(url); } @@ -308,8 +327,9 @@ void LocationCompleter::adjustPopupSize() const int maxItemsCount = 6; const int popupHeight = s_view->sizeHintForRow(0) * qMin(maxItemsCount, s_model->rowCount()) + 2 * s_view->frameWidth(); + m_originalText = m_locationBar->text(); + + s_view->setOriginalText(m_originalText); s_view->resize(s_view->width(), popupHeight); s_view->show(); - - m_originalText = m_locationBar->text(); } diff --git a/src/lib/navigation/completer/locationcompleter.h b/src/lib/navigation/completer/locationcompleter.h index c2a0e13a9..31d6a5676 100644 --- a/src/lib/navigation/completer/locationcompleter.h +++ b/src/lib/navigation/completer/locationcompleter.h @@ -1,6 +1,6 @@ /* ============================================================ -* QupZilla - WebKit based browser -* Copyright (C) 2010-2014 David Rosca +* QupZilla - Qt web browser +* Copyright (C) 2010-2017 David Rosca * * 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 @@ -46,7 +46,7 @@ public slots: void showMostVisited(); signals: - void showCompletion(const QString &completion, bool isOriginal); + void showCompletion(const QString &completion, bool completeDomain); void showDomainCompletion(const QString &completion); void loadCompletion(); void clearCompletion(); @@ -76,6 +76,7 @@ private: qint64 m_lastRefreshTimestamp; QString m_originalText; bool m_popupClosed; + bool m_ignoreCurrentChanged = false; static LocationCompleterView* s_view; static LocationCompleterModel* s_model; diff --git a/src/lib/navigation/completer/locationcompleterdelegate.cpp b/src/lib/navigation/completer/locationcompleterdelegate.cpp index 14f5882e5..d69afcfc4 100644 --- a/src/lib/navigation/completer/locationcompleterdelegate.cpp +++ b/src/lib/navigation/completer/locationcompleterdelegate.cpp @@ -18,6 +18,7 @@ #include "locationcompleterdelegate.h" #include "locationcompleterview.h" #include "locationcompletermodel.h" +#include "locationbar.h" #include "iconprovider.h" #include "qzsettings.h" @@ -28,6 +29,21 @@ #include #include +static bool isUrlOrDomain(const QString &text) +{ + QUrl url(text); + if (!url.scheme().isEmpty() && (!url.host().isEmpty() || !url.path().isEmpty())) { + return true; + } + if (text.contains(QL1C('.')) && !text.contains(QL1C(' '))) { + return true; + } + if (text == QL1S("localhost")) { + return true; + } + return false; +} + LocationCompleterDelegate::LocationCompleterDelegate(LocationCompleterView* parent) : QStyledItemDelegate(parent) , m_rowHeight(0) @@ -84,11 +100,17 @@ void LocationCompleterDelegate::paint(QPainter* painter, const QStyleOptionViewI // Draw background style->drawPrimitive(QStyle::PE_PanelItemViewItem, &opt, painter, w); + const bool isVisitSearchItem = index.data(LocationCompleterModel::VisitSearchItemRole).toBool(); + const bool isWebSearch = qzSettings->searchFromAddressBar && !isUrlOrDomain(m_originalText.trimmed()); + // Draw icon const int iconSize = 16; const int iconYPos = center - (iconSize / 2); QRect iconRect(leftPosition, iconYPos, iconSize, iconSize); QPixmap pixmap = index.data(Qt::DecorationRole).value().pixmap(iconSize); + if (isVisitSearchItem && isWebSearch) { + pixmap = QIcon::fromTheme(QSL("edit-find"), QIcon(QSL(":icons/menu/search-icon.svg"))).pixmap(iconSize); + } painter->drawPixmap(iconRect, pixmap); leftPosition = iconRect.right() + m_padding * 2; @@ -103,7 +125,7 @@ void LocationCompleterDelegate::paint(QPainter* painter, const QStyleOptionViewI painter->drawPixmap(starRect, icon.pixmap(starSize)); } - const QString searchText = index.data(LocationCompleterModel::SearchStringRole).toString(); + QString searchText = index.data(LocationCompleterModel::SearchStringRole).toString(); // Draw title const int leftTitleEdge = leftPosition + 2; @@ -113,6 +135,13 @@ void LocationCompleterDelegate::paint(QPainter* painter, const QStyleOptionViewI QString title = index.data(LocationCompleterModel::TitleRole).toString(); painter->setFont(titleFont); + if (isVisitSearchItem) { + title = m_originalText.trimmed(); + if (searchText == title) { + searchText.clear(); + } + } + viewItemDrawText(painter, &opt, titleRect, title, textPalette.color(colorRole), searchText); // Draw link @@ -147,8 +176,14 @@ void LocationCompleterDelegate::paint(QPainter* painter, const QStyleOptionViewI QRect textRect(linkRect); textRect.setX(textRect.x() + m_padding + 16 + m_padding); viewItemDrawText(painter, &opt, textRect, LocationCompleterView::tr("Switch to tab"), textPalette.color(colorLinkRole)); - } - else { + } else if (isVisitSearchItem) { + if (!isWebSearch) { + link = LocationCompleterView::tr("Visit"); + } else { + link = LocationCompleterView::tr("Search on %1").arg(LocationBar::searchEngineName()); + } + viewItemDrawText(painter, &opt, linkRect, link, textPalette.color(colorLinkRole)); + } else { viewItemDrawText(painter, &opt, linkRect, link, textPalette.color(colorLinkRole), searchText); } @@ -190,6 +225,11 @@ void LocationCompleterDelegate::setShowSwitchToTab(bool enable) m_drawSwitchToTab = enable; } +void LocationCompleterDelegate::setOriginalText(const QString &originalText) +{ + m_originalText = originalText; +} + bool LocationCompleterDelegate::drawSwitchToTab() const { return qzSettings->showSwitchTab && m_drawSwitchToTab; diff --git a/src/lib/navigation/completer/locationcompleterdelegate.h b/src/lib/navigation/completer/locationcompleterdelegate.h index c6fe491c4..b8279ea37 100644 --- a/src/lib/navigation/completer/locationcompleterdelegate.h +++ b/src/lib/navigation/completer/locationcompleterdelegate.h @@ -1,6 +1,6 @@ /* ============================================================ -* QupZilla - WebKit based browser -* Copyright (C) 2010-2016 David Rosca +* QupZilla - Qt web browser +* Copyright (C) 2010-2017 David Rosca * * 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 @@ -33,6 +33,7 @@ public: QSize sizeHint(const QStyleOptionViewItem &option, const QModelIndex &index) const; void setShowSwitchToTab(bool enable); + void setOriginalText(const QString &originalText); private: bool drawSwitchToTab() const; @@ -44,6 +45,7 @@ private: mutable int m_rowHeight; mutable int m_padding; bool m_drawSwitchToTab; + QString m_originalText; LocationCompleterView* m_view; }; diff --git a/src/lib/navigation/completer/locationcompletermodel.h b/src/lib/navigation/completer/locationcompletermodel.h index 14fb400b6..cc8526010 100644 --- a/src/lib/navigation/completer/locationcompletermodel.h +++ b/src/lib/navigation/completer/locationcompletermodel.h @@ -1,6 +1,6 @@ /* ============================================================ -* QupZilla - WebKit based browser -* Copyright (C) 2010-2014 David Rosca +* QupZilla - Qt web browser +* Copyright (C) 2010-2017 David Rosca * * 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 @@ -30,15 +30,16 @@ class LocationCompleterModel : public QStandardItemModel public: enum Role { IdRole = Qt::UserRole + 1, - TitleRole = Qt::UserRole + 2, - UrlRole = Qt::UserRole + 3, - CountRole = Qt::UserRole + 4, - BookmarkRole = Qt::UserRole + 5, - BookmarkItemRole = Qt::UserRole + 6, - SearchStringRole = Qt::UserRole + 7, - TabPositionWindowRole = Qt::UserRole + 8, - TabPositionTabRole = Qt::UserRole + 9, - ImageRole = Qt::UserRole + 10 + TitleRole, + UrlRole, + CountRole, + BookmarkRole, + BookmarkItemRole, + SearchStringRole, + TabPositionWindowRole, + TabPositionTabRole, + ImageRole, + VisitSearchItemRole }; explicit LocationCompleterModel(QObject* parent = 0); diff --git a/src/lib/navigation/completer/locationcompleterrefreshjob.cpp b/src/lib/navigation/completer/locationcompleterrefreshjob.cpp index e2cb99876..1952da107 100644 --- a/src/lib/navigation/completer/locationcompleterrefreshjob.cpp +++ b/src/lib/navigation/completer/locationcompleterrefreshjob.cpp @@ -1,6 +1,6 @@ /* ============================================================ -* QupZilla - WebKit based browser -* Copyright (C) 2014 David Rosca +* QupZilla - Qt web browser +* Copyright (C) 2014-2017 David Rosca * * 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 @@ -116,6 +116,20 @@ void LocationCompleterRefreshJob::runJob() m_domainCompletion = createDomainCompletion(domainQuery.value(0).toUrl().host()); } } + + // Add search/visit item + if (!m_searchString.isEmpty()) { + QStandardItem* item = new QStandardItem(); + item->setText(m_searchString); + item->setData(m_searchString, LocationCompleterModel::UrlRole); + item->setData(m_searchString, LocationCompleterModel::SearchStringRole); + item->setData(QVariant(true), LocationCompleterModel::VisitSearchItemRole); + if (!m_domainCompletion.isEmpty()) { + const QUrl url = QUrl(QSL("http://%1").arg(m_domainCompletion)); + item->setData(IconProvider::imageForDomain(url), LocationCompleterModel::ImageRole); + } + m_items.prepend(item); + } } void LocationCompleterRefreshJob::completeFromHistory() diff --git a/src/lib/navigation/completer/locationcompleterview.cpp b/src/lib/navigation/completer/locationcompleterview.cpp index 08d3ee24f..336c1e7e9 100644 --- a/src/lib/navigation/completer/locationcompleterview.cpp +++ b/src/lib/navigation/completer/locationcompleterview.cpp @@ -21,7 +21,6 @@ #include #include -#include #include LocationCompleterView::LocationCompleterView() @@ -56,6 +55,11 @@ QPersistentModelIndex LocationCompleterView::hoveredIndex() const return m_hoveredIndex; } +void LocationCompleterView::setOriginalText(const QString &originalText) +{ + m_delegate->setOriginalText(originalText); +} + bool LocationCompleterView::eventFilter(QObject* object, QEvent* event) { // Event filter based on QCompleter::eventFilter from qcompleter.cpp @@ -68,7 +72,8 @@ bool LocationCompleterView::eventFilter(QObject* object, QEvent* event) case QEvent::KeyPress: { QKeyEvent* keyEvent = static_cast(event); Qt::KeyboardModifiers modifiers = keyEvent->modifiers(); - QModelIndex idx = m_hoveredIndex; + const QModelIndex idx = m_hoveredIndex; + const QModelIndex visitSearchIdx = model()->index(0, 0).data(LocationCompleterModel::VisitSearchItemRole).toBool() ? model()->index(0, 0) : QModelIndex(); if ((keyEvent->key() == Qt::Key_Up || keyEvent->key() == Qt::Key_Down) && currentIndex() != idx) { setCurrentIndex(idx); @@ -139,7 +144,7 @@ bool LocationCompleterView::eventFilter(QObject* object, QEvent* event) } case Qt::Key_Up: - if (!idx.isValid()) { + if (!idx.isValid() || idx == visitSearchIdx) { int rowCount = model()->rowCount(); QModelIndex lastIndex = model()->index(rowCount - 1, 0); setCurrentIndex(lastIndex); @@ -154,8 +159,8 @@ bool LocationCompleterView::eventFilter(QObject* object, QEvent* event) if (!idx.isValid()) { QModelIndex firstIndex = model()->index(0, 0); setCurrentIndex(firstIndex); - } else if (idx.row() == model()->rowCount() - 1) { - setCurrentIndex(QModelIndex()); + } else if (idx != visitSearchIdx && idx.row() == model()->rowCount() - 1) { + setCurrentIndex(visitSearchIdx); scrollToTop(); } else { setCurrentIndex(model()->index(idx.row() + 1, 0)); diff --git a/src/lib/navigation/completer/locationcompleterview.h b/src/lib/navigation/completer/locationcompleterview.h index f7813671d..34e80f654 100644 --- a/src/lib/navigation/completer/locationcompleterview.h +++ b/src/lib/navigation/completer/locationcompleterview.h @@ -1,6 +1,6 @@ /* ============================================================ -* QupZilla - WebKit based browser -* Copyright (C) 2010-2014 David Rosca +* QupZilla - Qt web browser +* Copyright (C) 2010-2017 David Rosca * * 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 @@ -32,6 +32,8 @@ public: QPersistentModelIndex hoveredIndex() const; + void setOriginalText(const QString &originalText); + bool eventFilter(QObject* object, QEvent* event); signals: diff --git a/src/lib/navigation/locationbar.cpp b/src/lib/navigation/locationbar.cpp index e3715dd06..c24f33fe8 100644 --- a/src/lib/navigation/locationbar.cpp +++ b/src/lib/navigation/locationbar.cpp @@ -1,6 +1,6 @@ /* ============================================================ -* QupZilla - WebKit based browser -* Copyright (C) 2010-2016 David Rosca +* QupZilla - Qt web browser +* Copyright (C) 2010-2017 David Rosca * * 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 @@ -146,22 +146,19 @@ void LocationBar::setText(const QString &text) void LocationBar::updatePlaceHolderText() { if (qzSettings->searchFromAddressBar) { - QString engineName = qzSettings->searchWithDefaultEngine ? - mApp->searchEnginesManager()->defaultEngine().name : - mApp->searchEnginesManager()->activeEngine().name; - setPlaceholderText(tr("Enter URL address or search on %1").arg(engineName)); + setPlaceholderText(tr("Enter URL address or search on %1").arg(searchEngineName())); } else setPlaceholderText(tr("Enter URL address")); } -void LocationBar::showCompletion(const QString &completion, bool isOriginal) +void LocationBar::showCompletion(const QString &completion, bool completeDomain) { LineEdit::setText(completion); // Move cursor to the end end(false); - if (isOriginal) { + if (completeDomain) { completer()->complete(); } } @@ -242,6 +239,17 @@ QString LocationBar::convertUrlToText(const QUrl &url) return stringUrl; } +QString LocationBar::searchEngineName() +{ + if (!qzSettings->searchFromAddressBar) { + return QString(); + } else if (qzSettings->searchWithDefaultEngine) { + return mApp->searchEnginesManager()->defaultEngine().name; + } else { + return mApp->searchEnginesManager()->activeEngine().name; + } +} + void LocationBar::refreshTextFormat() { if (!m_webView) { diff --git a/src/lib/navigation/locationbar.h b/src/lib/navigation/locationbar.h index edda35576..7f7399a68 100644 --- a/src/lib/navigation/locationbar.h +++ b/src/lib/navigation/locationbar.h @@ -1,6 +1,6 @@ /* ============================================================ -* QupZilla - WebKit based browser -* Copyright (C) 2010-2016 David Rosca +* QupZilla - Qt web browser +* Copyright (C) 2010-2017 David Rosca * * 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 @@ -44,6 +44,7 @@ public: void setWebView(TabbedWebView* view); static QString convertUrlToText(const QUrl &url); + static QString searchEngineName(); public slots: void setText(const QString &text); @@ -60,7 +61,7 @@ private slots: void setPrivacyState(bool state); void setGoIconVisible(bool state); - void showCompletion(const QString &completion, bool isOriginal); + void showCompletion(const QString &completion, bool completeDomain); void showDomainCompletion(const QString &completion); void clearCompletion();