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

LocationCompleter: Show search suggestions

This commit is contained in:
David Rosca 2017-08-11 15:20:30 +02:00
parent c3bead5ed7
commit 2867f9fed5
7 changed files with 87 additions and 19 deletions

View File

@ -28,6 +28,8 @@
#include "bookmarks.h"
#include "bookmarkitem.h"
#include "qzsettings.h"
#include "opensearchengine.h"
#include "networkmanager.h"
#include <QWindow>
@ -77,6 +79,18 @@ void LocationCompleter::complete(const QString &string)
LocationCompleterRefreshJob* job = new LocationCompleterRefreshJob(trimmedStr);
connect(job, SIGNAL(finished()), this, SLOT(refreshJobFinished()));
connect(this, SIGNAL(cancelRefreshJob()), job, SLOT(jobCancelled()));
if (qzSettings->searchFromAddressBar && trimmedStr.length() > 2) {
if (!m_openSearchEngine) {
m_openSearchEngine = new OpenSearchEngine(this);
m_openSearchEngine->setNetworkAccessManager(mApp->networkManager());
connect(m_openSearchEngine, &OpenSearchEngine::suggestions, this, &LocationCompleter::addSuggestions);
}
m_openSearchEngine->setSuggestionsUrl(LocationBar::searchEngine().suggestionsUrl);
m_openSearchEngine->setSuggestionsParameters(LocationBar::searchEngine().suggestionsParameters);
m_suggestionsTerm = trimmedStr;
m_openSearchEngine->requestSuggestions(m_suggestionsTerm);
}
}
void LocationCompleter::showMostVisited()
@ -96,6 +110,7 @@ void LocationCompleter::refreshJobFinished()
m_lastRefreshTimestamp = job->timestamp();
showPopup();
addSuggestions(m_oldSuggestions);
if (!s_view->currentIndex().isValid() && s_model->index(0, 0).data(LocationCompleterModel::VisitSearchItemRole).toBool()) {
m_ignoreCurrentChanged = true;
@ -113,6 +128,8 @@ void LocationCompleter::refreshJobFinished()
void LocationCompleter::slotPopupClosed()
{
m_oldSuggestions.clear();
disconnect(s_view, SIGNAL(closed()), this, SLOT(slotPopupClosed()));
disconnect(s_view, SIGNAL(indexActivated(QModelIndex)), this, SLOT(indexActivated(QModelIndex)));
disconnect(s_view, SIGNAL(indexCtrlActivated(QModelIndex)), this, SLOT(indexCtrlActivated(QModelIndex)));
@ -123,6 +140,33 @@ void LocationCompleter::slotPopupClosed()
emit popupClosed();
}
void LocationCompleter::addSuggestions(const QStringList &suggestions)
{
const auto suggestionItems = s_model->suggestionItems();
// Delete existing suggestions
for (QStandardItem *item : suggestionItems) {
s_model->takeRow(item->row());
delete item;
}
// Add new suggestions
QList<QStandardItem*> items;
for (const QString &suggestion : suggestions) {
QStandardItem* item = new QStandardItem();
item->setText(suggestion);
item->setData(suggestion, LocationCompleterModel::TitleRole);
item->setData(suggestion, LocationCompleterModel::UrlRole);
item->setData(m_suggestionsTerm, LocationCompleterModel::SearchStringRole);
item->setData(true, LocationCompleterModel::SearchSuggestionRole);
items.append(item);
}
s_model->addCompletions(items);
adjustPopupSize();
m_oldSuggestions = suggestions;
}
void LocationCompleter::currentChanged(const QModelIndex &index)
{
if (m_ignoreCurrentChanged) {

View File

@ -27,6 +27,7 @@ class QModelIndex;
class LocationBar;
class BrowserWindow;
class OpenSearchEngine;
class LocationCompleterModel;
class LocationCompleterView;
@ -56,9 +57,9 @@ signals:
private slots:
void refreshJobFinished();
void slotPopupClosed();
void addSuggestions(const QStringList &suggestions);
void currentChanged(const QModelIndex &index);
void indexActivated(const QModelIndex &index);
void indexCtrlActivated(const QModelIndex &index);
void indexShiftActivated(const QModelIndex &index);
@ -77,6 +78,9 @@ private:
QString m_originalText;
bool m_popupClosed;
bool m_ignoreCurrentChanged = false;
OpenSearchEngine* m_openSearchEngine = nullptr;
QStringList m_oldSuggestions;
QString m_suggestionsTerm;
static LocationCompleterView* s_view;
static LocationCompleterModel* s_model;

View File

@ -93,6 +93,7 @@ void LocationCompleterDelegate::paint(QPainter* painter, const QStyleOptionViewI
style->drawPrimitive(QStyle::PE_PanelItemViewItem, &opt, painter, w);
const bool isVisitSearchItem = index.data(LocationCompleterModel::VisitSearchItemRole).toBool();
const bool isSearchSuggestion = index.data(LocationCompleterModel::SearchSuggestionRole).toBool();
const bool isWebSearch = qzSettings->searchFromAddressBar && !isUrlOrDomain(m_originalText.trimmed());
// Draw icon
@ -100,7 +101,7 @@ void LocationCompleterDelegate::paint(QPainter* painter, const QStyleOptionViewI
const int iconYPos = center - (iconSize / 2);
QRect iconRect(leftPosition, iconYPos, iconSize, iconSize);
QPixmap pixmap = index.data(Qt::DecorationRole).value<QIcon>().pixmap(iconSize);
if (isVisitSearchItem && isWebSearch) {
if (isSearchSuggestion || (isVisitSearchItem && isWebSearch)) {
pixmap = QIcon::fromTheme(QSL("edit-find"), QIcon(QSL(":icons/menu/search-icon.svg"))).pixmap(iconSize);
}
painter->drawPixmap(iconRect, pixmap);
@ -166,11 +167,11 @@ void LocationCompleterDelegate::paint(QPainter* painter, const QStyleOptionViewI
QRect textRect(linkRect);
textRect.setX(textRect.x() + m_padding + 16 + m_padding);
viewItemDrawText(painter, &opt, textRect, tr("Switch to tab"), textPalette.color(colorLinkRole));
} else if (isVisitSearchItem) {
if (!isWebSearch) {
} else if (isVisitSearchItem || isSearchSuggestion) {
if (!isSearchSuggestion && !isWebSearch) {
link = tr("Visit");
} else {
link = tr("Search on %1").arg(LocationBar::searchEngineName());
link = tr("Search on %1").arg(LocationBar::searchEngine().name);
}
viewItemDrawText(painter, &opt, linkRect, link, textPalette.color(colorLinkRole));
} else {

View File

@ -1,6 +1,6 @@
/* ============================================================
* QupZilla - WebKit based browser
* Copyright (C) 2010-2014 David Rosca <nowrep@gmail.com>
* QupZilla - Qt web browser
* Copyright (C) 2010-2017 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
@ -33,17 +33,32 @@ LocationCompleterModel::LocationCompleterModel(QObject* parent)
void LocationCompleterModel::setCompletions(const QList<QStandardItem*> &items)
{
foreach (QStandardItem* item, items) {
clear();
addCompletions(items);
}
void LocationCompleterModel::addCompletions(const QList<QStandardItem*> &items)
{
for (QStandardItem *item : items) {
item->setIcon(QPixmap::fromImage(item->data(ImageRole).value<QImage>()));
setTabPosition(item);
if (item->icon().isNull()) {
item->setIcon(IconProvider::emptyWebIcon());
}
appendRow({item});
}
}
clear();
appendColumn(items);
QList<QStandardItem*> LocationCompleterModel::suggestionItems() const
{
QList<QStandardItem*> items;
for (int i = 0; i < rowCount(); ++i) {
QStandardItem *it = item(i);
if (it->data(SearchSuggestionRole).toBool()) {
items.append(it);
}
}
return items;
}
QSqlQuery LocationCompleterModel::createDomainQuery(const QString &text)

View File

@ -39,12 +39,16 @@ public:
TabPositionWindowRole,
TabPositionTabRole,
ImageRole,
VisitSearchItemRole
VisitSearchItemRole,
SearchSuggestionRole
};
explicit LocationCompleterModel(QObject* parent = 0);
void setCompletions(const QList<QStandardItem*> &items);
void addCompletions(const QList<QStandardItem*> &items);
QList<QStandardItem*> suggestionItems() const;
static QSqlQuery createHistoryQuery(const QString &searchString, int limit, bool exactMatch = false);
static QSqlQuery createDomainQuery(const QString &text);

View File

@ -33,7 +33,6 @@
#include "qzsettings.h"
#include "colors.h"
#include "autofillicon.h"
#include "searchenginesmanager.h"
#include "completer/locationcompleter.h"
#include <QTimer>
@ -146,7 +145,7 @@ void LocationBar::setText(const QString &text)
void LocationBar::updatePlaceHolderText()
{
if (qzSettings->searchFromAddressBar) {
setPlaceholderText(tr("Enter URL address or search on %1").arg(searchEngineName()));
setPlaceholderText(tr("Enter URL address or search on %1").arg(searchEngine().name));
} else
setPlaceholderText(tr("Enter URL address"));
}
@ -239,14 +238,14 @@ QString LocationBar::convertUrlToText(const QUrl &url)
return stringUrl;
}
QString LocationBar::searchEngineName()
SearchEnginesManager::Engine LocationBar::searchEngine()
{
if (!qzSettings->searchFromAddressBar) {
return QString();
return SearchEnginesManager::Engine();
} else if (qzSettings->searchWithDefaultEngine) {
return mApp->searchEnginesManager()->defaultEngine().name;
return mApp->searchEnginesManager()->defaultEngine();
} else {
return mApp->searchEnginesManager()->activeEngine().name;
return mApp->searchEnginesManager()->activeEngine();
}
}

View File

@ -20,6 +20,7 @@
#include "qzcommon.h"
#include "lineedit.h"
#include "searchenginesmanager.h"
class QStringListModel;
@ -44,7 +45,7 @@ public:
void setWebView(TabbedWebView* view);
static QString convertUrlToText(const QUrl &url);
static QString searchEngineName();
static SearchEnginesManager::Engine searchEngine();
public slots:
void setText(const QString &text);