1
mirror of https://invent.kde.org/network/falkon.git synced 2024-12-24 04:36:34 +01:00

[LocationBar] Added inline completion for domains.

Closes #880
This commit is contained in:
nowrep 2013-05-10 22:33:36 +02:00
parent 1b03cf84e1
commit f651125c5c
6 changed files with 128 additions and 32 deletions

View File

@ -4,6 +4,7 @@ Version 1.5.0
* added option to open another private window from private window * added option to open another private window from private window
* added delete action in edit context menu on page * added delete action in edit context menu on page
* added possibility to remove EasyList from AdBlock * added possibility to remove EasyList from AdBlock
* added inline domain completion to urlbar
* proxy exceptions now supports wildcards (*, ?) * proxy exceptions now supports wildcards (*, ?)
* cancel upload when trying to upload non-readable files * cancel upload when trying to upload non-readable files
* GreaseMonkey: added support for GM_Settings * GreaseMonkey: added support for GM_Settings

View File

@ -44,6 +44,11 @@ void LocationCompleter::setLocationBar(LocationBar* locationBar)
m_locationBar = locationBar; m_locationBar = locationBar;
} }
QString LocationCompleter::domainCompletion() const
{
return m_completedDomain;
}
bool LocationCompleter::showingMostVisited() const bool LocationCompleter::showingMostVisited() const
{ {
return m_showingMostVisited; return m_showingMostVisited;
@ -56,12 +61,14 @@ bool LocationCompleter::isPopupVisible() const
void LocationCompleter::closePopup() void LocationCompleter::closePopup()
{ {
m_completedDomain.clear();
m_showingMostVisited = false; m_showingMostVisited = false;
s_view->close(); s_view->close();
} }
void LocationCompleter::complete(const QString &string) void LocationCompleter::complete(const QString &string)
{ {
m_completedDomain = createDomainCompletionString(string);
m_showingMostVisited = string.isEmpty(); m_showingMostVisited = string.isEmpty();
s_model->refreshCompletions(string); s_model->refreshCompletions(string);
@ -98,6 +105,21 @@ void LocationCompleter::slotPopupClosed()
emit popupClosed(); emit popupClosed();
} }
QString LocationCompleter::createDomainCompletionString(const QString &text)
{
QString completion = s_model->completeDomain(text);
if (text.startsWith(QLatin1String("www."))) {
return completion.mid(text.size());
}
if (completion.startsWith(QLatin1String("www."))) {
completion = completion.mid(4);
}
return completion.mid(text.size());
}
void LocationCompleter::showPopup() void LocationCompleter::showPopup()
{ {
Q_ASSERT(m_locationBar); Q_ASSERT(m_locationBar);

View File

@ -36,6 +36,7 @@ public:
void setLocationBar(LocationBar* locationBar); void setLocationBar(LocationBar* locationBar);
QString domainCompletion() const;
bool showingMostVisited() const; bool showingMostVisited() const;
bool isPopupVisible() const; bool isPopupVisible() const;
void closePopup(); void closePopup();
@ -54,11 +55,14 @@ private slots:
void slotPopupClosed(); void slotPopupClosed();
private: private:
QString createDomainCompletionString(const QString &text);
void showPopup(); void showPopup();
void adjustPopupSize(); void adjustPopupSize();
LocationBar* m_locationBar; LocationBar* m_locationBar;
QString m_originalText; QString m_originalText;
QString m_completedDomain;
bool m_ignoreCurrentChangedSignal; bool m_ignoreCurrentChangedSignal;
bool m_showingMostVisited; bool m_showingMostVisited;

View File

@ -137,6 +137,49 @@ void LocationCompleterModel::showMostVisited()
} }
} }
QString LocationCompleterModel::completeDomain(const QString &text)
{
if (text.isEmpty() || text == QLatin1String("www.")) {
return QString();
}
bool withoutWww = text.startsWith(QLatin1Char('w')) && !text.startsWith(QLatin1String("www."));
QString query = "SELECT url FROM history WHERE ";
if (withoutWww) {
query.append(QLatin1String("url NOT LIKE ? AND url NOT LIKE ? AND "));
}
else {
query.append(QLatin1String("url LIKE ? OR url LIKE ? OR "));
}
query.append(QLatin1String("(url LIKE ? OR url LIKE ?) ORDER BY count DESC LIMIT 1"));
QSqlQuery sqlQuery;
sqlQuery.prepare(query);
if (withoutWww) {
sqlQuery.addBindValue(QString("http://www.%"));
sqlQuery.addBindValue(QString("https://www.%"));
sqlQuery.addBindValue(QString("http://%1%").arg(text));
sqlQuery.addBindValue(QString("https://%1%").arg(text));
}
else {
sqlQuery.addBindValue(QString("http://%1%").arg(text));
sqlQuery.addBindValue(QString("https://%1%").arg(text));
sqlQuery.addBindValue(QString("http://www.%1%").arg(text));
sqlQuery.addBindValue(QString("https://www.%1%").arg(text));
}
sqlQuery.exec();
if (!sqlQuery.next()) {
return QString();
}
return sqlQuery.value(0).toUrl().host();
}
QSqlQuery LocationCompleterModel::createQuery(const QString &searchString, const QString &orderBy, QSqlQuery LocationCompleterModel::createQuery(const QString &searchString, const QString &orderBy,
const QList<QUrl> &alreadyFound, int limit, bool bookmarks, bool exactMatch) const QList<QUrl> &alreadyFound, int limit, bool bookmarks, bool exactMatch)
{ {

View File

@ -51,6 +51,8 @@ public:
void refreshCompletions(const QString &string); void refreshCompletions(const QString &string);
void showMostVisited(); void showMostVisited();
QString completeDomain(const QString &text);
private: private:
enum Type { enum Type {
HistoryAndBookmarks = 0, HistoryAndBookmarks = 0,

View File

@ -151,7 +151,7 @@ QUrl LocationBar::createUrl()
{ {
QUrl urlToLoad; QUrl urlToLoad;
//Check for Search Engine shortcut // Check for Search Engine shortcut
int firstSpacePos = text().indexOf(QLatin1Char(' ')); int firstSpacePos = text().indexOf(QLatin1Char(' '));
if (firstSpacePos != -1) { if (firstSpacePos != -1) {
QString shortcut = text().left(firstSpacePos); QString shortcut = text().left(firstSpacePos);
@ -163,6 +163,11 @@ QUrl LocationBar::createUrl()
} }
} }
// Is inline domain completion active?
if (m_completer.isPopupVisible() && !m_completer.domainCompletion().isEmpty()) {
urlToLoad = WebView::guessUrlFromString(text() + m_completer.domainCompletion());
}
if (urlToLoad.isEmpty()) { if (urlToLoad.isEmpty()) {
QUrl guessedUrl = WebView::guessUrlFromString(text()); QUrl guessedUrl = WebView::guessUrlFromString(text());
if (!guessedUrl.isEmpty()) { if (!guessedUrl.isEmpty()) {
@ -189,10 +194,17 @@ QString LocationBar::convertUrlToText(const QUrl &url) const
void LocationBar::urlEnter() void LocationBar::urlEnter()
{ {
const QUrl &url = createUrl();
const QString &urlString = convertUrlToText(url);
m_completer.closePopup(); m_completer.closePopup();
m_webView->setFocus(); m_webView->setFocus();
emit loadUrl(createUrl()); if (urlString != text()) {
setText(convertUrlToText(url));
}
emit loadUrl(url);
} }
void LocationBar::textEdit() void LocationBar::textEdit()
@ -568,33 +580,61 @@ void LocationBar::hideProgress()
void LocationBar::paintEvent(QPaintEvent* event) void LocationBar::paintEvent(QPaintEvent* event)
{ {
QStyleOptionFrameV3 option;
initStyleOption(&option);
int lm, tm, rm, bm;
getTextMargins(&lm, &tm, &rm, &bm);
QRect contentsRect = style()->subElementRect(QStyle::SE_LineEditContents, &option, this);
contentsRect.adjust(lm, tm, -rm, -bm);
const QFontMetrics &fm = fontMetrics();
const int x = contentsRect.x() + 3;
const int y = contentsRect.y() + (contentsRect.height() - fm.height() + 1) / 2;
const int width = contentsRect.width() - 6;
const int height = fm.height();
const QRect textRect(x, y, width, height);
QTextOption opt;
opt.setWrapMode(QTextOption::NoWrap);
if (hasFocus() && m_completer.isPopupVisible()) {
// Draw inline domain completion if available
const QString &completionText = m_completer.domainCompletion();
if (!completionText.isEmpty()) {
LineEdit::paintEvent(event);
QRect completionRect = textRect;
completionRect.setX(completionRect.x() + fm.width(text()) + 1);
completionRect.setWidth(fm.width(completionText) + 1);
QPainter p(this);
p.fillRect(completionRect, palette().color(QPalette::Highlight));
p.setPen(palette().color(QPalette::HighlightedText));
p.drawText(completionRect, completionText, opt);
return;
}
}
#ifndef Q_OS_MAC #ifndef Q_OS_MAC
if (m_drawCursor && m_completer.isPopupVisible() && !m_completer.showingMostVisited()) { if (m_drawCursor && m_completer.isPopupVisible() && !m_completer.showingMostVisited()) {
// We need to draw cursor when popup is visible // We need to draw cursor when popup is visible
// But don't paint it if we are just showing most visited sites // But don't paint it if we are just showing most visited sites
LineEdit::paintEvent(event); LineEdit::paintEvent(event);
QStyleOptionFrameV3 option;
initStyleOption(&option);
int lm, tm, rm, bm;
getTextMargins(&lm, &tm, &rm, &bm);
QRect contentsRect = style()->subElementRect(QStyle::SE_LineEditContents, &option, this);
contentsRect.adjust(lm, tm, -rm, -bm);
const QFontMetrics &fm = fontMetrics();
QString textPart = text().left(cursorPosition()); QString textPart = text().left(cursorPosition());
int cursorXpos = contentsRect.x() + 3 + fontMetrics().width(textPart); int cursorXpos = x + fontMetrics().width(textPart);
int cursorYpos = contentsRect.y() + (contentsRect.height() - fm.height() + 1) / 2;
int cursorWidth = style()->pixelMetric(QStyle::PM_TextCursorWidth, &option, this); int cursorWidth = style()->pixelMetric(QStyle::PM_TextCursorWidth, &option, this);
int cursorHeight = fontMetrics().height(); int cursorHeight = fontMetrics().height();
QPainter p(this); QRect cursorRect(cursorXpos, y, cursorWidth, cursorHeight);
QRect cursorRect(cursorXpos, cursorYpos, cursorWidth, cursorHeight);
if (isRightToLeft()) { if (isRightToLeft()) {
cursorRect = style()->visualRect(Qt::RightToLeft, contentsRect, cursorRect); cursorRect = style()->visualRect(Qt::RightToLeft, contentsRect, cursorRect);
} }
QPainter p(this);
p.fillRect(cursorRect, option.palette.text().color()); p.fillRect(cursorRect, option.palette.text().color());
return; return;
} }
@ -609,26 +649,12 @@ void LocationBar::paintEvent(QPaintEvent* event)
return; return;
} }
QStyleOptionFrameV3 option;
initStyleOption(&option);
QPainter p(this); QPainter p(this);
p.setRenderHint(QPainter::Antialiasing, true); p.setRenderHint(QPainter::Antialiasing, true);
p.setRenderHint(QPainter::TextAntialiasing, true); p.setRenderHint(QPainter::TextAntialiasing, true);
style()->drawPrimitive(QStyle::PE_PanelLineEdit, &option, &p, this); style()->drawPrimitive(QStyle::PE_PanelLineEdit, &option, &p, this);
QRect contentsRect = style()->subElementRect(QStyle::SE_LineEditContents, &option, this);
int lm, tm, rm, bm;
getTextMargins(&lm, &tm, &rm, &bm);
contentsRect.adjust(lm, tm, -rm, -bm);
QFontMetrics fm = fontMetrics();
const int x = contentsRect.x() + 3;
const int y = contentsRect.y() + (contentsRect.height() - fm.height() + 1) / 2;
const int width = contentsRect.width() - 6;
const int height = fm.height();
QRect textRect(x, y, width, height);
QPen oldPen = p.pen(); QPen oldPen = p.pen();
if (qzSettings->showLoadingProgress && m_progressVisible) { if (qzSettings->showLoadingProgress && m_progressVisible) {
@ -675,8 +701,6 @@ void LocationBar::paintEvent(QPaintEvent* event)
} }
p.setPen(oldPen); p.setPen(oldPen);
QTextOption opt;
opt.setWrapMode(QTextOption::NoWrap);
const QString hostName = m_webView->url().host(); const QString hostName = m_webView->url().host();
QString currentText = text(); QString currentText = text();