1
mirror of https://invent.kde.org/network/falkon.git synced 2024-11-11 09:32:12 +01:00

LocationCompleter: Add persistent first item that shows used search engine

Or in case searching from location bar is disabled or entered text
is valid URL, it indicates that this URL will be loaded.
This commit is contained in:
David Rosca 2017-08-11 12:26:50 +02:00
parent 3c60b8417a
commit 16b3a74aa1
10 changed files with 141 additions and 47 deletions

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
@ -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();
}

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
@ -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;

View File

@ -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 <QMouseEvent>
#include <QTextLayout>
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<QIcon>().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 if (isVisitSearchItem) {
if (!isWebSearch) {
link = LocationCompleterView::tr("Visit");
} else {
link = LocationCompleterView::tr("Search on %1").arg(LocationBar::searchEngineName());
}
else {
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;

View File

@ -1,6 +1,6 @@
/* ============================================================
* QupZilla - WebKit based browser
* Copyright (C) 2010-2016 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,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;
};

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
@ -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);

View File

@ -1,6 +1,6 @@
/* ============================================================
* QupZilla - WebKit based browser
* Copyright (C) 2014 David Rosca <nowrep@gmail.com>
* QupZilla - Qt web browser
* Copyright (C) 2014-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
@ -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()

View File

@ -21,7 +21,6 @@
#include <QKeyEvent>
#include <QApplication>
#include <QStyle>
#include <QScrollBar>
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<QKeyEvent*>(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));

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
@ -32,6 +32,8 @@ public:
QPersistentModelIndex hoveredIndex() const;
void setOriginalText(const QString &originalText);
bool eventFilter(QObject* object, QEvent* event);
signals:

View File

@ -1,6 +1,6 @@
/* ============================================================
* QupZilla - WebKit based browser
* Copyright (C) 2010-2016 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
@ -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) {

View File

@ -1,6 +1,6 @@
/* ============================================================
* QupZilla - WebKit based browser
* Copyright (C) 2010-2016 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
@ -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();