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

Simplified location completer (it is now QListView)

- make sure items won't be duplicated - in case you
  have the same url in bookmarks and history
This commit is contained in:
nowrep 2012-04-20 14:03:08 +02:00
parent f95065107a
commit 0a5c245811
6 changed files with 68 additions and 126 deletions

1
TODO
View File

@ -8,7 +8,6 @@ The list is not sorted by priority.
* FTP Protocol support * FTP Protocol support
* Zoom Widget in statusbar * Zoom Widget in statusbar
* Password Manager: save more than one account for site + input completer * Password Manager: save more than one account for site + input completer
* New LocationBar completer
* (KDE) Nepomuk integration * (KDE) Nepomuk integration
* Support for remote Web inspector * Support for remote Web inspector
* option to save RSS feeds in external reader * option to save RSS feeds in external reader

View File

@ -22,96 +22,47 @@
#include "mainapplication.h" #include "mainapplication.h"
#include <QStandardItemModel> #include <QStandardItemModel>
#include <QTreeView>
#include <QHeaderView>
#include <QSqlQuery> #include <QSqlQuery>
LocationCompleter::LocationCompleter(QObject* parent) LocationCompleter::LocationCompleter(QObject* parent)
: QCompleter(parent) : QCompleter(parent)
{ {
QStandardItemModel* completeModel = new QStandardItemModel(); QStandardItemModel* completeModel = new QStandardItemModel();
setModel(completeModel); setModel(completeModel);
m_treeView = new CompleterTreeView();
setPopup(m_treeView); m_listView = new CompleterListView();
m_treeView->setRootIsDecorated(false); m_listView->setItemDelegateForColumn(0, new LocationCompleterDelegate(m_listView));
m_treeView->header()->hide(); setPopup(m_listView);
m_treeView->header()->setStretchLastSection(false);
m_treeView->header()->setResizeMode(0, QHeaderView::Stretch);
m_treeView->header()->resizeSection(1, 0);
m_treeView->setItemDelegateForColumn(0, new LocationCompleterDelegate(m_treeView));
setCompletionMode(QCompleter::PopupCompletion); setCompletionMode(QCompleter::PopupCompletion);
setCaseSensitivity(Qt::CaseInsensitive);
setWrapAround(true);
setCompletionColumn(1);
setMaxVisibleItems(6); setMaxVisibleItems(6);
} }
QStringList LocationCompleter::splitPath(const QString &path) const QStringList LocationCompleter::splitPath(const QString &path) const
{ {
Q_UNUSED(path); Q_UNUSED(path);
return QStringList(""); return QStringList();
#if 0
QStringList returned = QCompleter::splitPath(path);
QStringList returned2;
QSqlQuery query;
query.exec("SELECT url FROM history WHERE title LIKE '%" + path + "%' OR url LIKE '%" + path + "%' ORDER BY count DESC LIMIT 1");
if (query.next()) {
QString url = query.value(0).toString();
bool titleSearching = false;
if (!url.contains(path)) {
titleSearching = true;
}
QString prefix = url.mid(0, url.indexOf(path));
foreach(const QString & string, returned) {
if (titleSearching) {
returned2.append(url);
}
else {
returned2.append(prefix + string);
}
}
return returned2;
}
else {
foreach(const QString & string, returned)
returned2.append("http://www.google.com/search?client=qupzilla&q=" + string);
return returned2;
}
#endif
} }
void LocationCompleter::showMostVisited() void LocationCompleter::showMostVisited()
{ {
QSqlQuery query;
query.exec("SELECT title, url FROM history ORDER BY count DESC LIMIT 15");
int i = 0;
QStandardItemModel* cModel = qobject_cast<QStandardItemModel*>(model()); QStandardItemModel* cModel = qobject_cast<QStandardItemModel*>(model());
cModel->clear(); cModel->clear();
QSqlQuery query;
query.exec("SELECT url, title FROM history ORDER BY count DESC LIMIT 15");
while (query.next()) { while (query.next()) {
QStandardItem* iconText = new QStandardItem(); QStandardItem* item = new QStandardItem();
QStandardItem* findUrl = new QStandardItem(); const QUrl &url = query.value(0).toUrl();
QString url = query.value(1).toUrl().toEncoded();
iconText->setIcon(_iconForUrl(query.value(1).toUrl()).pixmap(16, 16)); item->setIcon(_iconForUrl(url));
iconText->setText(query.value(0).toString()); item->setText(url.toEncoded());
iconText->setData(query.value(1), Qt::UserRole); item->setData(query.value(1), Qt::UserRole);
findUrl->setText(url); cModel->appendRow(item);
QList<QStandardItem*> items;
items.append(iconText);
items.append(findUrl);
cModel->insertRow(i, items);
i++;
} }
m_treeView->header()->setResizeMode(0, QHeaderView::Stretch);
m_treeView->header()->resizeSection(1, 0);
popup()->setMinimumHeight(190); popup()->setMinimumHeight(190);
QCompleter::complete(); QCompleter::complete();
@ -120,68 +71,60 @@ void LocationCompleter::showMostVisited()
void LocationCompleter::refreshCompleter(const QString &string) void LocationCompleter::refreshCompleter(const QString &string)
{ {
int limit = string.size() < 3 ? 25 : 15; int limit = string.size() < 3 ? 25 : 15;
int i = 0;
QString searchString = QString("%%1%").arg(string); QString searchString = QString("%%1%").arg(string);
QList<QUrl> urlList;
QStandardItemModel* cModel = qobject_cast<QStandardItemModel*>(model()); QStandardItemModel* cModel = qobject_cast<QStandardItemModel*>(model());
cModel->clear(); cModel->clear();
QSqlQuery query; QSqlQuery query;
query.prepare("SELECT title, url, icon FROM bookmarks WHERE title LIKE ? OR url LIKE ? LIMIT ?"); query.prepare("SELECT url, title, icon FROM bookmarks WHERE title LIKE ? OR url LIKE ? LIMIT ?");
query.addBindValue(searchString); query.addBindValue(searchString);
query.addBindValue(searchString); query.addBindValue(searchString);
query.addBindValue(limit); query.addBindValue(limit);
query.exec(); query.exec();
while (query.next()) { while (query.next()) {
QStandardItem* iconText = new QStandardItem(); QStandardItem* item = new QStandardItem();
QStandardItem* findUrl = new QStandardItem(); const QUrl &url = query.value(0).toUrl();
QString url = query.value(1).toUrl().toEncoded();
iconText->setIcon(IconProvider::iconFromImage(QImage::fromData(query.value(2).toByteArray()))); item->setText(url.toEncoded());
iconText->setText(query.value(0).toString()); item->setData(query.value(1), Qt::UserRole);
iconText->setData(query.value(1), Qt::UserRole); item->setIcon(IconProvider::iconFromImage(QImage::fromData(query.value(2).toByteArray())));
findUrl->setText(url); cModel->appendRow(item);
QList<QStandardItem*> items; urlList.append(url);
items.append(iconText);
items.append(findUrl);
cModel->insertRow(i, items);
i++;
} }
query.prepare("SELECT title, url FROM history WHERE title LIKE ? OR url LIKE ? ORDER BY count DESC LIMIT ?"); limit -= query.size();
query.prepare("SELECT url, title FROM history WHERE title LIKE ? OR url LIKE ? ORDER BY count DESC LIMIT ?");
query.addBindValue(searchString); query.addBindValue(searchString);
query.addBindValue(searchString); query.addBindValue(searchString);
query.addBindValue(limit - i); query.addBindValue(limit);
query.exec(); query.exec();
while (query.next()) { while (query.next()) {
QStandardItem* iconText = new QStandardItem(); QStandardItem* item = new QStandardItem();
QStandardItem* findUrl = new QStandardItem(); const QUrl &url = query.value(0).toUrl();
QString url = query.value(1).toUrl().toEncoded();
iconText->setIcon(_iconForUrl(query.value(1).toUrl()).pixmap(16, 16)); if (urlList.contains(url)) {
iconText->setText(query.value(0).toString()); continue;
iconText->setData(query.value(1), Qt::UserRole); }
findUrl->setText(url); item->setIcon(_iconForUrl(url));
QList<QStandardItem*> items; item->setText(url.toEncoded());
items.append(iconText); item->setData(query.value(1), Qt::UserRole);
items.append(findUrl);
cModel->insertRow(i, items); cModel->appendRow(item);
i++;
} }
m_treeView->header()->setResizeMode(0, QHeaderView::Stretch); if (cModel->rowCount() > 6) {
m_treeView->header()->resizeSection(1, 0); m_listView->setMinimumHeight(6 * m_listView->rowHeight());
if (i > 6) {
m_treeView->setMinimumHeight(6 * m_treeView->rowHeight());
} }
else { else {
m_treeView->setMinimumHeight(0); m_listView->setMinimumHeight(0);
} }
m_treeView->setUpdatesEnabled(true); m_listView->setUpdatesEnabled(true);
} }

View File

@ -22,7 +22,7 @@
#include "qz_namespace.h" #include "qz_namespace.h"
class CompleterTreeView; class CompleterListView;
class QT_QUPZILLA_EXPORT LocationCompleter : public QCompleter class QT_QUPZILLA_EXPORT LocationCompleter : public QCompleter
{ {
@ -39,7 +39,7 @@ public slots:
void showMostVisited(); void showMostVisited();
private: private:
CompleterTreeView* m_treeView; CompleterListView* m_listView;
}; };
#endif // LOCATIONCOMPLETER_H #endif // LOCATIONCOMPLETER_H

View File

@ -18,46 +18,45 @@
#include "locationcompleterdelegate.h" #include "locationcompleterdelegate.h"
#include <QPainter> #include <QPainter>
#include <QTreeView>
#include <QApplication> #include <QApplication>
#include <QMouseEvent> #include <QMouseEvent>
#include <QDebug> #include <QDebug>
CompleterTreeView::CompleterTreeView(QWidget* parent) CompleterListView::CompleterListView(QWidget* parent)
: QTreeView(parent) : QListView(parent)
, m_selectedItemByMousePosition(false) , m_selectedItemByMousePosition(false)
, m_rowHeight(0) , m_rowHeight(0)
{ {
setMouseTracking(true); setMouseTracking(true);
} }
bool CompleterTreeView::ignoreSelectedFlag() const bool CompleterListView::ignoreSelectedFlag() const
{ {
return m_selectedItemByMousePosition; return m_selectedItemByMousePosition;
} }
int CompleterTreeView::rowHeight() const int CompleterListView::rowHeight() const
{ {
return m_rowHeight; return m_rowHeight;
} }
void CompleterTreeView::setRowHeight(int height) void CompleterListView::setRowHeight(int height)
{ {
m_rowHeight = height; m_rowHeight = height;
} }
void CompleterTreeView::currentChanged(const QModelIndex &current, const QModelIndex &previous) void CompleterListView::currentChanged(const QModelIndex &current, const QModelIndex &previous)
{ {
m_selectedItemByMousePosition = false; m_selectedItemByMousePosition = false;
m_lastMouseIndex = current; m_lastMouseIndex = current;
QTreeView::currentChanged(current, previous); QListView::currentChanged(current, previous);
viewport()->repaint(); viewport()->repaint();
} }
void CompleterTreeView::mouseMoveEvent(QMouseEvent* event) void CompleterListView::mouseMoveEvent(QMouseEvent* event)
{ {
QModelIndex last = m_lastMouseIndex; QModelIndex last = m_lastMouseIndex;
QModelIndex atCursor = indexAt(mapFromGlobal(QCursor::pos())); QModelIndex atCursor = indexAt(mapFromGlobal(QCursor::pos()));
@ -71,23 +70,23 @@ void CompleterTreeView::mouseMoveEvent(QMouseEvent* event)
viewport()->repaint(); viewport()->repaint();
} }
QTreeView::mouseMoveEvent(event); QListView::mouseMoveEvent(event);
} }
void CompleterTreeView::keyPressEvent(QKeyEvent* event) void CompleterListView::keyPressEvent(QKeyEvent* event)
{ {
if (currentIndex() != m_lastMouseIndex) { if (currentIndex() != m_lastMouseIndex) {
setCurrentIndex(m_lastMouseIndex); setCurrentIndex(m_lastMouseIndex);
} }
QTreeView::keyPressEvent(event); QListView::keyPressEvent(event);
} }
LocationCompleterDelegate::LocationCompleterDelegate(CompleterTreeView* parent) LocationCompleterDelegate::LocationCompleterDelegate(CompleterListView* parent)
: QStyledItemDelegate(parent) : QStyledItemDelegate(parent)
, m_rowHeight(0) , m_rowHeight(0)
, m_padding(0) , m_padding(0)
, m_treeView(parent) , m_listView(parent)
{ {
} }
@ -110,7 +109,7 @@ void LocationCompleterDelegate::paint(QPainter* painter, const QStyleOptionViewI
int leftPosition = m_padding * 2; int leftPosition = m_padding * 2;
int rightPosition = opt.rect.right() - m_padding; int rightPosition = opt.rect.right() - m_padding;
if (m_treeView->ignoreSelectedFlag()) { if (m_listView->ignoreSelectedFlag()) {
if (opt.state.testFlag(QStyle::State_MouseOver)) { if (opt.state.testFlag(QStyle::State_MouseOver)) {
opt.state |= QStyle::State_Selected; opt.state |= QStyle::State_Selected;
} }
@ -137,14 +136,14 @@ void LocationCompleterDelegate::paint(QPainter* painter, const QStyleOptionViewI
const int leftTitleEdge = leftPosition + 2; const int leftTitleEdge = leftPosition + 2;
const int rightTitleEdge = rightPosition - m_padding; const int rightTitleEdge = rightPosition - m_padding;
QRect titleRect(leftTitleEdge, opt.rect.top() + m_padding, rightTitleEdge - leftTitleEdge, titleMetrics.height()); QRect titleRect(leftTitleEdge, opt.rect.top() + m_padding, rightTitleEdge - leftTitleEdge, titleMetrics.height());
QString title(titleMetrics.elidedText(index.data(Qt::DisplayRole).toString(), Qt::ElideRight, titleRect.width())); QString title(titleMetrics.elidedText(index.data(Qt::UserRole).toString(), Qt::ElideRight, titleRect.width()));
painter->setFont(titleFont); painter->setFont(titleFont);
style->drawItemText(painter, titleRect, Qt::AlignLeft | Qt::TextSingleLine, opt.palette, true, title, colorRole); style->drawItemText(painter, titleRect, Qt::AlignLeft | Qt::TextSingleLine, opt.palette, true, title, colorRole);
// Draw link // Draw link
const int infoYPos = titleRect.bottom() + opt.fontMetrics.leading(); const int infoYPos = titleRect.bottom() + opt.fontMetrics.leading();
QRect linkRect(titleRect.x(), infoYPos, titleRect.width(), opt.fontMetrics.height()); QRect linkRect(titleRect.x(), infoYPos, titleRect.width(), opt.fontMetrics.height());
const QString &link = opt.fontMetrics.elidedText(index.data(Qt::UserRole).toString(), Qt::ElideRight, linkRect.width()); const QString &link = opt.fontMetrics.elidedText(index.data(Qt::DisplayRole).toString(), Qt::ElideRight, linkRect.width());
painter->setFont(opt.font); painter->setFont(opt.font);
style->drawItemText(painter, linkRect, Qt::TextSingleLine | Qt::AlignLeft, opt.palette, true, link, colorLinkRole); style->drawItemText(painter, linkRect, Qt::TextSingleLine | Qt::AlignLeft, opt.palette, true, link, colorLinkRole);
} }
@ -170,8 +169,8 @@ QSize LocationCompleterDelegate::sizeHint(const QStyleOptionViewItem &option, co
m_rowHeight = 2 * m_padding + opt.fontMetrics.leading() + opt.fontMetrics.height() + titleMetrics.height(); m_rowHeight = 2 * m_padding + opt.fontMetrics.leading() + opt.fontMetrics.height() + titleMetrics.height();
m_treeView->setRowHeight(m_rowHeight); m_listView->setRowHeight(m_rowHeight);
m_treeView->setMaximumHeight(6 * m_rowHeight); m_listView->setMaximumHeight(6 * m_rowHeight);
} }
return QSize(200, m_rowHeight); return QSize(200, m_rowHeight);

View File

@ -19,15 +19,15 @@
#define LOCATIONCOMPLETERDELEGATE_H #define LOCATIONCOMPLETERDELEGATE_H
#include <QStyledItemDelegate> #include <QStyledItemDelegate>
#include <QTreeView> #include <QListView>
#include "qz_namespace.h" #include "qz_namespace.h"
class QT_QUPZILLA_EXPORT CompleterTreeView : public QTreeView class QT_QUPZILLA_EXPORT CompleterListView : public QListView
{ {
Q_OBJECT Q_OBJECT
public: public:
explicit CompleterTreeView(QWidget* parent = 0); explicit CompleterListView(QWidget* parent = 0);
bool ignoreSelectedFlag() const; bool ignoreSelectedFlag() const;
@ -50,7 +50,7 @@ private:
class QT_QUPZILLA_EXPORT LocationCompleterDelegate : public QStyledItemDelegate class QT_QUPZILLA_EXPORT LocationCompleterDelegate : public QStyledItemDelegate
{ {
public: public:
explicit LocationCompleterDelegate(CompleterTreeView* parent = 0); explicit LocationCompleterDelegate(CompleterListView* parent = 0);
void paint(QPainter* painter, const QStyleOptionViewItem &option, const QModelIndex &index) const; void paint(QPainter* painter, const QStyleOptionViewItem &option, const QModelIndex &index) const;
QSize sizeHint(const QStyleOptionViewItem &option, const QModelIndex &index) const; QSize sizeHint(const QStyleOptionViewItem &option, const QModelIndex &index) const;
@ -59,7 +59,7 @@ private:
mutable int m_rowHeight; mutable int m_rowHeight;
mutable int m_padding; mutable int m_padding;
CompleterTreeView* m_treeView; CompleterListView* m_listView;
}; };
#endif // LOCATIONCOMPLETERDELEGATE_H #endif // LOCATIONCOMPLETERDELEGATE_H

View File

@ -55,8 +55,9 @@ void PluginListDelegate::paint(QPainter* painter, const QStyleOptionViewItem &op
const int checkboxSize = 18; const int checkboxSize = 18;
const int checkboxYPos = center - (checkboxSize / 2); const int checkboxYPos = center - (checkboxSize / 2);
QStyleOptionViewItemV4 opt2 = opt; QStyleOptionViewItemV4 opt2 = opt;
opt2.rect = QRect(leftPosition, checkboxYPos, checkboxSize, checkboxSize);
opt2.checkState == Qt::Checked ? opt2.state |= QStyle::State_On : opt2.state |= QStyle::State_Off; opt2.checkState == Qt::Checked ? opt2.state |= QStyle::State_On : opt2.state |= QStyle::State_Off;
QRect styleCheckBoxRect = style->subElementRect(QStyle::SE_ViewItemCheckIndicator, &opt2, w);
opt2.rect = QRect(leftPosition, checkboxYPos, styleCheckBoxRect.width(), styleCheckBoxRect.height());
style->drawPrimitive(QStyle::PE_IndicatorViewItemCheck, &opt2, painter, w); style->drawPrimitive(QStyle::PE_IndicatorViewItemCheck, &opt2, painter, w);
leftPosition = opt2.rect.right() + m_padding; leftPosition = opt2.rect.right() + m_padding;