From 11e2ff168e2571071a9d186bba0f87485f1eb222 Mon Sep 17 00:00:00 2001 From: David Rosca Date: Thu, 25 Jan 2018 11:01:19 +0100 Subject: [PATCH] LocationCompleterView: Change into QWidget --- .../completer/locationcompleter.cpp | 5 +- .../completer/locationcompleterview.cpp | 164 +++++++++++------- .../completer/locationcompleterview.h | 20 ++- 3 files changed, 114 insertions(+), 75 deletions(-) diff --git a/src/lib/navigation/completer/locationcompleter.cpp b/src/lib/navigation/completer/locationcompleter.cpp index 28228101b..37de7ea28 100644 --- a/src/lib/navigation/completer/locationcompleter.cpp +++ b/src/lib/navigation/completer/locationcompleter.cpp @@ -375,14 +375,11 @@ void LocationCompleter::showPopup() void LocationCompleter::adjustPopupSize() { - const int maxItemsCount = 12; - const int popupHeight = s_view->sizeHintForRow(0) * qMin(maxItemsCount, s_model->rowCount()) + 2 * s_view->frameWidth(); - if (s_view->currentIndex().row() == 0) { m_originalText = m_locationBar->text(); s_view->setOriginalText(m_originalText); } - s_view->resize(s_view->width(), popupHeight); + s_view->adjustSize(); s_view->show(); } diff --git a/src/lib/navigation/completer/locationcompleterview.cpp b/src/lib/navigation/completer/locationcompleterview.cpp index 585221984..b826d52d5 100644 --- a/src/lib/navigation/completer/locationcompleterview.cpp +++ b/src/lib/navigation/completer/locationcompleterview.cpp @@ -1,6 +1,6 @@ /* ============================================================ * Falkon - Qt web browser -* Copyright (C) 2010-2017 David Rosca +* Copyright (C) 2010-2018 David Rosca * * 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 @@ -22,9 +22,10 @@ #include #include #include +#include LocationCompleterView::LocationCompleterView() - : QListView(0) + : QWidget(nullptr) , m_ignoreNextMouseMove(false) { setAttribute(Qt::WA_ShowWithoutActivating); @@ -36,18 +37,51 @@ LocationCompleterView::LocationCompleterView() setWindowFlags(Qt::Popup); } - setUniformItemSizes(true); - setEditTriggers(QAbstractItemView::NoEditTriggers); - setVerticalScrollMode(QAbstractItemView::ScrollPerPixel); - setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff); - setSelectionBehavior(QAbstractItemView::SelectRows); - setSelectionMode(QAbstractItemView::SingleSelection); + QVBoxLayout *layout = new QVBoxLayout(this); + layout->setContentsMargins(0, 0, 0, 0); + layout->setSpacing(0); + setLayout(layout); - setMouseTracking(true); + m_view = new QListView(this); + layout->addWidget(m_view); + + m_view->setUniformItemSizes(true); + m_view->setEditTriggers(QAbstractItemView::NoEditTriggers); + m_view->setVerticalScrollMode(QAbstractItemView::ScrollPerPixel); + m_view->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff); + m_view->setSelectionBehavior(QAbstractItemView::SelectRows); + m_view->setSelectionMode(QAbstractItemView::SingleSelection); + + m_view->setMouseTracking(true); qApp->installEventFilter(this); m_delegate = new LocationCompleterDelegate(this); - setItemDelegate(m_delegate); + m_view->setItemDelegate(m_delegate); +} + +QAbstractItemModel *LocationCompleterView::model() const +{ + return m_view->model(); +} + +void LocationCompleterView::setModel(QAbstractItemModel *model) +{ + m_view->setModel(model); +} + +QModelIndex LocationCompleterView::currentIndex() const +{ + return m_view->currentIndex(); +} + +void LocationCompleterView::setCurrentIndex(const QModelIndex &index) +{ + m_view->setCurrentIndex(index); +} + +QItemSelectionModel *LocationCompleterView::selectionModel() const +{ + return m_view->selectionModel(); } void LocationCompleterView::setOriginalText(const QString &originalText) @@ -55,11 +89,47 @@ void LocationCompleterView::setOriginalText(const QString &originalText) m_delegate->setOriginalText(originalText); } +void LocationCompleterView::adjustSize() +{ + const int maxItemsCount = 12; + m_view->setFixedHeight(m_view->sizeHintForRow(0) * qMin(maxItemsCount, model()->rowCount()) + 2 * m_view->frameWidth()); + setFixedHeight(sizeHint().height()); +} + bool LocationCompleterView::eventFilter(QObject* object, QEvent* event) { // Event filter based on QCompleter::eventFilter from qcompleter.cpp - if (object == this || !isVisible()) { + if (object == this || object == m_view || !isVisible()) { + return false; + } + + if (object == m_view->viewport()) { + if (event->type() == QEvent::MouseButtonRelease) { + QMouseEvent *e = static_cast(event); + QModelIndex idx = m_view->indexAt(e->pos()); + if (!idx.isValid()) { + return false; + } + + Qt::MouseButton button = e->button(); + Qt::KeyboardModifiers modifiers = e->modifiers(); + + if (button == Qt::LeftButton && modifiers == Qt::NoModifier) { + emit indexActivated(idx); + return true; + } + + if (button == Qt::MiddleButton || (button == Qt::LeftButton && modifiers == Qt::ControlModifier)) { + emit indexCtrlActivated(idx); + return true; + } + + if (button == Qt::LeftButton && modifiers == Qt::ShiftModifier) { + emit indexShiftActivated(idx); + return true; + } + } return false; } @@ -67,11 +137,11 @@ bool LocationCompleterView::eventFilter(QObject* object, QEvent* event) case QEvent::KeyPress: { QKeyEvent* keyEvent = static_cast(event); Qt::KeyboardModifiers modifiers = keyEvent->modifiers(); - const QModelIndex idx = currentIndex(); + const QModelIndex idx = m_view->currentIndex(); 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); + if ((keyEvent->key() == Qt::Key_Up || keyEvent->key() == Qt::Key_Down) && m_view->currentIndex() != idx) { + m_view->setCurrentIndex(idx); } switch (keyEvent->key()) { @@ -99,7 +169,7 @@ bool LocationCompleterView::eventFilter(QObject* object, QEvent* event) case Qt::Key_End: if (modifiers & Qt::ControlModifier) { - setCurrentIndex(model()->index(model()->rowCount() - 1, 0)); + m_view->setCurrentIndex(model()->index(model()->rowCount() - 1, 0)); return true; } else { close(); @@ -108,8 +178,8 @@ bool LocationCompleterView::eventFilter(QObject* object, QEvent* event) case Qt::Key_Home: if (modifiers & Qt::ControlModifier) { - setCurrentIndex(model()->index(0, 0)); - scrollToTop(); + m_view->setCurrentIndex(model()->index(0, 0)); + m_view->scrollToTop(); return true; } else { close(); @@ -142,52 +212,46 @@ bool LocationCompleterView::eventFilter(QObject* object, QEvent* event) if (!idx.isValid() || idx == visitSearchIdx) { int rowCount = model()->rowCount(); QModelIndex lastIndex = model()->index(rowCount - 1, 0); - setCurrentIndex(lastIndex); + m_view->setCurrentIndex(lastIndex); } else if (idx.row() == 0) { - setCurrentIndex(QModelIndex()); + m_view->setCurrentIndex(QModelIndex()); } else { - setCurrentIndex(model()->index(idx.row() - 1, 0)); + m_view->setCurrentIndex(model()->index(idx.row() - 1, 0)); } return true; case Qt::Key_Down: if (!idx.isValid()) { QModelIndex firstIndex = model()->index(0, 0); - setCurrentIndex(firstIndex); + m_view->setCurrentIndex(firstIndex); } else if (idx != visitSearchIdx && idx.row() == model()->rowCount() - 1) { - setCurrentIndex(visitSearchIdx); - scrollToTop(); + m_view->setCurrentIndex(visitSearchIdx); + m_view->scrollToTop(); } else { - setCurrentIndex(model()->index(idx.row() + 1, 0)); + m_view->setCurrentIndex(model()->index(idx.row() + 1, 0)); } return true; case Qt::Key_Delete: - if (idx != visitSearchIdx && viewport()->rect().contains(visualRect(idx))) { + if (idx != visitSearchIdx && m_view->viewport()->rect().contains(m_view->visualRect(idx))) { emit indexDeleteRequested(idx); return true; } break; case Qt::Key_PageUp: - if (keyEvent->modifiers() != Qt::NoModifier) { - return false; - } - selectionModel()->setCurrentIndex(moveCursor(QAbstractItemView::MovePageUp, Qt::NoModifier), QItemSelectionModel::SelectCurrent); - return true; - case Qt::Key_PageDown: if (keyEvent->modifiers() != Qt::NoModifier) { return false; } - selectionModel()->setCurrentIndex(moveCursor(QAbstractItemView::MovePageDown, Qt::NoModifier), QItemSelectionModel::SelectCurrent); + QApplication::sendEvent(m_view, event); return true; case Qt::Key_Shift: // don't switch if there is no hovered or selected index to not disturb typing if (idx != visitSearchIdx || underMouse()) { m_delegate->setShowSwitchToTab(false); - viewport()->update(); + m_view->viewport()->update(); return true; } break; @@ -205,7 +269,7 @@ bool LocationCompleterView::eventFilter(QObject* object, QEvent* event) switch (keyEvent->key()) { case Qt::Key_Shift: m_delegate->setShowSwitchToTab(true); - viewport()->update(); + m_view->viewport()->update(); return true; } break; @@ -250,38 +314,10 @@ bool LocationCompleterView::eventFilter(QObject* object, QEvent* event) void LocationCompleterView::close() { - QListView::hide(); - verticalScrollBar()->setValue(0); + hide(); + m_view->verticalScrollBar()->setValue(0); m_delegate->setShowSwitchToTab(true); emit closed(); } - -void LocationCompleterView::mouseReleaseEvent(QMouseEvent* event) -{ - QModelIndex idx = indexAt(event->pos()); - if (!idx.isValid()) { - return; - } - - Qt::MouseButton button = event->button(); - Qt::KeyboardModifiers modifiers = event->modifiers(); - - if (button == Qt::LeftButton && modifiers == Qt::NoModifier) { - emit indexActivated(idx); - return; - } - - if (button == Qt::MiddleButton || (button == Qt::LeftButton && modifiers == Qt::ControlModifier)) { - emit indexCtrlActivated(idx); - return; - } - - if (button == Qt::LeftButton && modifiers == Qt::ShiftModifier) { - emit indexShiftActivated(idx); - return; - } - - QListView::mouseReleaseEvent(event); -} diff --git a/src/lib/navigation/completer/locationcompleterview.h b/src/lib/navigation/completer/locationcompleterview.h index eb3f53856..6fcf33386 100644 --- a/src/lib/navigation/completer/locationcompleterview.h +++ b/src/lib/navigation/completer/locationcompleterview.h @@ -1,6 +1,6 @@ /* ============================================================ * Falkon - Qt web browser -* Copyright (C) 2010-2017 David Rosca +* Copyright (C) 2010-2018 David Rosca * * 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 @@ -24,16 +24,24 @@ class LocationCompleterDelegate; -class FALKON_EXPORT LocationCompleterView : public QListView +class FALKON_EXPORT LocationCompleterView : public QWidget { Q_OBJECT public: explicit LocationCompleterView(); - QPersistentModelIndex hoveredIndex() const; + QAbstractItemModel *model() const; + void setModel(QAbstractItemModel *model); + + QItemSelectionModel *selectionModel() const; + + QModelIndex currentIndex() const; + void setCurrentIndex(const QModelIndex &index); void setOriginalText(const QString &originalText); + void adjustSize(); + bool eventFilter(QObject* object, QEvent* event); signals: @@ -47,13 +55,11 @@ signals: public slots: void close(); -protected: - void mouseReleaseEvent(QMouseEvent* event); - private: bool m_ignoreNextMouseMove; - LocationCompleterDelegate* m_delegate; + QListView *m_view; + LocationCompleterDelegate *m_delegate; }; #endif // LOCATIONCOMPLETERVIEW_H