mirror of
https://invent.kde.org/network/falkon.git
synced 2024-12-24 04:36:34 +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:
parent
3c60b8417a
commit
16b3a74aa1
@ -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();
|
||||
}
|
||||
|
@ -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;
|
||||
|
@ -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 {
|
||||
} 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;
|
||||
|
@ -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;
|
||||
};
|
||||
|
@ -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);
|
||||
|
@ -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()
|
||||
|
@ -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));
|
||||
|
@ -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:
|
||||
|
@ -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) {
|
||||
|
@ -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();
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user