diff options
-rw-r--r-- | Swift/QtUI/MUCSearch/QtLeafSortFilterProxyModel.cpp | 28 | ||||
-rw-r--r-- | Swift/QtUI/MUCSearch/QtLeafSortFilterProxyModel.h | 29 | ||||
-rw-r--r-- | Swift/QtUI/MUCSearch/QtMUCSearchWindow.cpp | 20 | ||||
-rw-r--r-- | Swift/QtUI/MUCSearch/QtMUCSearchWindow.h | 4 | ||||
-rw-r--r-- | Swift/QtUI/MUCSearch/QtMUCSearchWindow.ui | 62 | ||||
-rw-r--r-- | Swift/QtUI/SConscript | 7 |
6 files changed, 116 insertions, 34 deletions
diff --git a/Swift/QtUI/MUCSearch/QtLeafSortFilterProxyModel.cpp b/Swift/QtUI/MUCSearch/QtLeafSortFilterProxyModel.cpp new file mode 100644 index 0000000..b8cf15a --- /dev/null +++ b/Swift/QtUI/MUCSearch/QtLeafSortFilterProxyModel.cpp @@ -0,0 +1,28 @@ +/* + * Copyright (c) 2016 Isode Limited. + * All rights reserved. + * See the COPYING file for more information. + */ + +#include <Swift/QtUI/MUCSearch/QtLeafSortFilterProxyModel.h> + +namespace Swift { + +QtLeafSortFilterProxyModel::QtLeafSortFilterProxyModel(QObject* parent) : QSortFilterProxyModel(parent) { + +} + +QtLeafSortFilterProxyModel::~QtLeafSortFilterProxyModel() { + +} + +bool QtLeafSortFilterProxyModel::filterAcceptsRow(int source_row, const QModelIndex& source_parent) const { + if (!sourceModel()->hasChildren(sourceModel()->index(source_row, 0, source_parent))) { + return QSortFilterProxyModel::filterAcceptsRow(source_row, source_parent); + } + else { + return true; + } +} + +} diff --git a/Swift/QtUI/MUCSearch/QtLeafSortFilterProxyModel.h b/Swift/QtUI/MUCSearch/QtLeafSortFilterProxyModel.h new file mode 100644 index 0000000..b4be622 --- /dev/null +++ b/Swift/QtUI/MUCSearch/QtLeafSortFilterProxyModel.h @@ -0,0 +1,29 @@ +/* + * Copyright (c) 2016 Isode Limited. + * All rights reserved. + * See the COPYING file for more information. + */ + +#pragma once + +#include <QSortFilterProxyModel> + +namespace Swift { + +/** + * @brief The QtLeafSortFilterProxyModel class is similar to the QSortFilterProxyModel + * class. While the basic QSortFilterProxyModel class filters all hierarchical items, + * the QtLeafSortFilterProxyModel class will only filter on items without children. + */ +class QtLeafSortFilterProxyModel : public QSortFilterProxyModel { + Q_OBJECT + +public: + QtLeafSortFilterProxyModel(QObject* parent = nullptr); + virtual ~QtLeafSortFilterProxyModel(); + +protected: + virtual bool filterAcceptsRow(int source_row, const QModelIndex& source_parent) const; +}; + +} diff --git a/Swift/QtUI/MUCSearch/QtMUCSearchWindow.cpp b/Swift/QtUI/MUCSearch/QtMUCSearchWindow.cpp index 114ec1d..f69da41 100644 --- a/Swift/QtUI/MUCSearch/QtMUCSearchWindow.cpp +++ b/Swift/QtUI/MUCSearch/QtMUCSearchWindow.cpp @@ -12,6 +12,7 @@ #include <QMovie> #include <QPushButton> #include <QScrollBar> +#include <QSortFilterProxyModel> #include <QTimer> #include <Swift/Controllers/UIEvents/AddMUCBookmarkUIEvent.h> @@ -20,6 +21,7 @@ #include <Swift/QtUI/MUCSearch/MUCSearchDelegate.h> #include <Swift/QtUI/MUCSearch/MUCSearchEmptyItem.h> #include <Swift/QtUI/MUCSearch/MUCSearchModel.h> +#include <Swift/QtUI/MUCSearch/QtLeafSortFilterProxyModel.h> #include <Swift/QtUI/QtSwiftUtil.h> namespace Swift { @@ -30,10 +32,12 @@ QtMUCSearchWindow::QtMUCSearchWindow() { setWindowIcon(QIcon(":/logo-icon-16.png")); #endif setModal(true); - ui_.filter_->hide(); model_ = new MUCSearchModel(); + sortFilterProxyModel_ = new QtLeafSortFilterProxyModel(this); + sortFilterProxyModel_->setSourceModel(model_); + sortFilterProxyModel_->setDynamicSortFilter(true); delegate_ = new MUCSearchDelegate(); - ui_.results_->setModel(model_); + ui_.results_->setModel(sortFilterProxyModel_); ui_.results_->setItemDelegate(delegate_); ui_.results_->setHeaderHidden(true); ui_.results_->setRootIsDecorated(true); @@ -41,7 +45,7 @@ QtMUCSearchWindow::QtMUCSearchWindow() { ui_.results_->setAlternatingRowColors(true); ui_.results_->setSortingEnabled(true); ui_.results_->sortByColumn(0, Qt::AscendingOrder); - connect(ui_.searchButton, SIGNAL(clicked()), this, SLOT(handleSearch())); + connect(ui_.searchButton_, SIGNAL(clicked()), this, SLOT(handleSearch())); connect(ui_.service_, SIGNAL(activated(const QString&)), this, SLOT(handleSearch(const QString&))); connect(ui_.results_->selectionModel(), SIGNAL(selectionChanged (const QItemSelection&, const QItemSelection&)), this, SLOT(handleSelectionChanged (const QItemSelection&, const QItemSelection&))); connect(ui_.results_, SIGNAL(activated(const QModelIndex&)), this, SLOT(handleActivated(const QModelIndex&))); @@ -50,6 +54,7 @@ QtMUCSearchWindow::QtMUCSearchWindow() { connect(ui_.okButton, SIGNAL(clicked()), this, SLOT(accept())); ui_.okButton->setEnabled(false); connect(ui_.cancelButton, SIGNAL(clicked()), this, SLOT(reject())); + connect(ui_.filter_, SIGNAL(textChanged(const QString&)), this, SLOT(handleFilterStringChanged(const QString&))); throbber_ = new QLabel(tr("Searching"), ui_.results_); throbber_->setMovie(new QMovie(":/icons/throbber.gif", QByteArray(), throbber_)); @@ -104,7 +109,7 @@ void QtMUCSearchWindow::handleActivated(const QModelIndex& index) { if (!index.isValid()) { return; } - if (dynamic_cast<MUCSearchRoomItem*>(static_cast<MUCSearchItem*>(index.internalPointer()))) { + if (dynamic_cast<MUCSearchRoomItem*>(static_cast<MUCSearchItem*>(sortFilterProxyModel_->mapToSource(index).internalPointer()))) { accept(); } } @@ -119,7 +124,12 @@ void QtMUCSearchWindow::handleSearch(const QString& service) { } } +void QtMUCSearchWindow::handleFilterStringChanged(const QString& filterString) { + sortFilterProxyModel_->setFilterRegExp(filterString); +} + void QtMUCSearchWindow::show() { + ui_.filter_->clear(); QWidget::show(); QWidget::activateWindow(); } @@ -197,7 +207,7 @@ MUCSearchRoomItem* QtMUCSearchWindow::getSelectedRoom() const { return nullptr; } else { - return dynamic_cast<MUCSearchRoomItem*>(static_cast<MUCSearchItem*>(lstIndex.first().internalPointer())); + return dynamic_cast<MUCSearchRoomItem*>(static_cast<MUCSearchItem*>(sortFilterProxyModel_->mapToSource(lstIndex.first()).internalPointer())); } } diff --git a/Swift/QtUI/MUCSearch/QtMUCSearchWindow.h b/Swift/QtUI/MUCSearch/QtMUCSearchWindow.h index b115e6f..6f38533 100644 --- a/Swift/QtUI/MUCSearch/QtMUCSearchWindow.h +++ b/Swift/QtUI/MUCSearch/QtMUCSearchWindow.h @@ -10,6 +10,8 @@ #include <Swift/QtUI/MUCSearch/ui_QtMUCSearchWindow.h> +class QSortFilterProxyModel; + namespace Swift { class MUCSearchModel; class MUCSearchDelegate; @@ -36,6 +38,7 @@ namespace Swift { private slots: void handleSearch(); void handleSearch(const QString&); + void handleFilterStringChanged(const QString&); void handleActivated(const QModelIndex& index); void updateThrobberPosition(); void handleSelectionChanged (const QItemSelection&, const QItemSelection&); @@ -47,5 +50,6 @@ namespace Swift { MUCSearchDelegate* delegate_; QLabel* throbber_; bool hasHadScrollBars_; + QSortFilterProxyModel* sortFilterProxyModel_ = nullptr; }; } diff --git a/Swift/QtUI/MUCSearch/QtMUCSearchWindow.ui b/Swift/QtUI/MUCSearch/QtMUCSearchWindow.ui index 49460ab..52714c4 100644 --- a/Swift/QtUI/MUCSearch/QtMUCSearchWindow.ui +++ b/Swift/QtUI/MUCSearch/QtMUCSearchWindow.ui @@ -6,21 +6,14 @@ <rect> <x>0</x> <y>0</y> - <width>523</width> - <height>368</height> + <width>566</width> + <height>264</height> </rect> </property> <property name="windowTitle"> <string>Search Room</string> </property> <layout class="QGridLayout" name="gridLayout"> - <item row="0" column="0"> - <widget class="QLabel" name="label_2"> - <property name="text"> - <string>Service:</string> - </property> - </widget> - </item> <item row="0" column="1"> <widget class="QComboBox" name="service_"> <property name="sizePolicy"> @@ -34,26 +27,14 @@ </property> </widget> </item> - <item row="0" column="3"> - <widget class="QLineEdit" name="filter_"> - <property name="sizePolicy"> - <sizepolicy hsizetype="Expanding" vsizetype="Fixed"> - <horstretch>1</horstretch> - <verstretch>0</verstretch> - </sizepolicy> - </property> + <item row="0" column="0"> + <widget class="QLabel" name="serviceLabel_"> <property name="text"> - <string/> - </property> - <property name="frame"> - <bool>true</bool> + <string>Service:</string> </property> </widget> </item> - <item row="1" column="0" colspan="4"> - <widget class="QTreeView" name="results_"/> - </item> - <item row="2" column="0" colspan="4"> + <item row="2" column="0" colspan="5"> <layout class="QHBoxLayout" name="horizontalLayout"> <item> <spacer name="horizontalSpacer"> @@ -90,13 +71,42 @@ </item> </layout> </item> + <item row="0" column="4"> + <widget class="QLineEdit" name="filter_"> + <property name="sizePolicy"> + <sizepolicy hsizetype="Expanding" vsizetype="Fixed"> + <horstretch>1</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="text"> + <string/> + </property> + <property name="frame"> + <bool>true</bool> + </property> + <property name="placeholderText"> + <string/> + </property> + </widget> + </item> <item row="0" column="2"> - <widget class="QToolButton" name="searchButton"> + <widget class="QToolButton" name="searchButton_"> <property name="text"> <string>List rooms</string> </property> </widget> </item> + <item row="1" column="0" colspan="5"> + <widget class="QTreeView" name="results_"/> + </item> + <item row="0" column="3"> + <widget class="QLabel" name="filterLabel_"> + <property name="text"> + <string>Search for</string> + </property> + </widget> + </item> </layout> </widget> <resources/> diff --git a/Swift/QtUI/SConscript b/Swift/QtUI/SConscript index 1f15c15..2d01672 100644 --- a/Swift/QtUI/SConscript +++ b/Swift/QtUI/SConscript @@ -160,12 +160,13 @@ sources = [ "ChatList/ChatListMUCItem.cpp", "ChatList/ChatListRecentItem.cpp", "ChatList/ChatListWhiteboardItem.cpp", - "MUCSearch/QtMUCSearchWindow.cpp", + "MUCSearch/MUCSearchDelegate.cpp", + "MUCSearch/MUCSearchEmptyItem.cpp", "MUCSearch/MUCSearchModel.cpp", "MUCSearch/MUCSearchRoomItem.cpp", - "MUCSearch/MUCSearchEmptyItem.cpp", - "MUCSearch/MUCSearchDelegate.cpp", "MUCSearch/MUCSearchServiceItem.cpp", + "MUCSearch/QtLeafSortFilterProxyModel.cpp", + "MUCSearch/QtMUCSearchWindow.cpp", "UserSearch/ContactListDelegate.cpp", "UserSearch/ContactListModel.cpp", "UserSearch/QtContactListWidget.cpp", |