From 95e2993f70ee8430cf0d207c75b08d4fff21dccf Mon Sep 17 00:00:00 2001 From: Tobias Fella Date: Sun, 8 Nov 2020 16:13:53 +0000 Subject: [PATCH] Implement sorting rooms by category --- CMakeLists.txt | 2 +- qml/RoomListPage.qml | 28 +++++++++++--------- src/CMakeLists.txt | 1 + src/main.cpp | 2 ++ src/roomlistmodel.cpp | 35 +++++++++++++++++++++++++ src/roomlistmodel.h | 7 +++++ src/sortfilterroomlistmodel.cpp | 46 +++++++++++++++++++++++++++++++++ src/sortfilterroomlistmodel.h | 41 +++++++++++++++++++++++++++++ 8 files changed, 149 insertions(+), 13 deletions(-) create mode 100644 src/sortfilterroomlistmodel.cpp create mode 100644 src/sortfilterroomlistmodel.h diff --git a/CMakeLists.txt b/CMakeLists.txt index 700d414be..47219ea35 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -25,7 +25,7 @@ ecm_setup_version(0.1.0 ) find_package(Qt5 ${QT_MIN_VERSION} REQUIRED NO_MODULE COMPONENTS Widgets Core Quick Gui QuickControls2 Multimedia Svg) -find_package(KF5 ${REQUIRED_KF5_VERSION} REQUIRED COMPONENTS Kirigami2 ItemModels I18n Notifications Config CoreAddons) +find_package(KF5 ${REQUIRED_KF5_VERSION} REQUIRED COMPONENTS Kirigami2 I18n Notifications Config CoreAddons) if(ANDROID) find_package(OpenSSL REQUIRED) diff --git a/qml/RoomListPage.qml b/qml/RoomListPage.qml index 2de9a1cdf..1c9170f24 100644 --- a/qml/RoomListPage.qml +++ b/qml/RoomListPage.qml @@ -14,6 +14,8 @@ import org.kde.kitemmodels 1.0 import Spectral.Component 2.0 import Spectral 0.1 +import org.kde.neochat 1.0 + Kirigami.ScrollablePage { id: page @@ -21,7 +23,7 @@ Kirigami.ScrollablePage { property var enteredRoom property var searchText: "" - onSearchTextChanged: sortedFilteredRoomListModel.invalidateFilter() + onSearchTextChanged: sortFilterRoomListModel.setFilterText(searchText) signal enterRoom(var room) signal leaveRoom(var room) @@ -37,23 +39,25 @@ Kirigami.ScrollablePage { } ListView { - model: KSortFilterProxyModel { - id: sortedFilteredRoomListModel + model: SortFilterRoomListModel { + id: sortFilterRoomListModel sourceModel: roomListModel + roomSortOrder: SortFilterRoomListModel.Categories + } - sortRole: "name" - sortOrder: Qt.AscendingOrder - filterRowCallback: function(row, parent) { - return (roomListModel.data(roomListModel.index(row, 0), RoomListModel.JoinStateRole) !== "upgraded") && roomListModel.data(roomListModel.index(row, 0), RoomListModel.NameRole).toLowerCase().includes(page.searchText.toLowerCase()) + section.property: "category" + section.delegate: Kirigami.ListSectionHeader { + id: sectionHeader + label: roomListModel.categoryName(section) + MouseArea { + Layout.fillWidth: true + Layout.fillHeight: true + onClicked: roomListModel.setCategoryVisible(section, !roomListModel.categoryVisible(section)) } } - section.property: "categoryName" - section.delegate: Kirigami.ListSectionHeader { - label: section - } - delegate: Kirigami.AbstractListItem { + visible: model.categoryVisible topPadding: Kirigami.Units.largeSpacing bottomPadding: Kirigami.Units.largeSpacing diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 69b2fc7e3..093bd41e4 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -15,6 +15,7 @@ add_executable(neochat utils.cpp main.cpp notificationsmanager.cpp + sortfilterroomlistmodel.cpp ../res.qrc ) diff --git a/src/main.cpp b/src/main.cpp index 2c37e234b..02d4d74d6 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -30,6 +30,7 @@ #include "publicroomlistmodel.h" #include "room.h" #include "roomlistmodel.h" +#include "sortfilterroomlistmodel.h" #include "spectralroom.h" #include "spectraluser.h" #include "trayicon.h" @@ -70,6 +71,7 @@ int main(int argc, char *argv[]) qmlRegisterType("Spectral", 0, 1, "EmojiModel"); qmlRegisterType("Spectral", 0, 1, "NotificationsManager"); qmlRegisterType("Spectral", 0, 1, "TrayIcon"); + qmlRegisterType("org.kde.neochat", 1, 0, "SortFilterRoomListModel"); qmlRegisterUncreatableType("Spectral", 0, 1, "RoomMessageEvent", "ENUM"); qmlRegisterUncreatableType("Spectral", 0, 1, "RoomType", "ENUM"); qmlRegisterUncreatableType("Spectral", 0, 1, "UserType", "ENUM"); diff --git a/src/roomlistmodel.cpp b/src/roomlistmodel.cpp index b76b99d02..b3ecd55af 100644 --- a/src/roomlistmodel.cpp +++ b/src/roomlistmodel.cpp @@ -10,6 +10,8 @@ #include #include +#include + RoomListModel::RoomListModel(QObject *parent) : QAbstractListModel(parent) { @@ -249,6 +251,8 @@ QVariant RoomListModel::data(const QModelIndex &index, int role) const } if (role == CurrentRoomRole) return QVariant::fromValue(room); + if (role == CategoryVisibleRole) + return m_categoryVisibility.value(data(index, CategoryRole).toInt(), true); return QVariant(); } @@ -277,5 +281,36 @@ QHash RoomListModel::roleNames() const roles[LastActiveTimeRole] = "lastActiveTime"; roles[JoinStateRole] = "joinState"; roles[CurrentRoomRole] = "currentRoom"; + roles[CategoryVisibleRole] = "categoryVisible"; return roles; } + +QString RoomListModel::categoryName(int section) const +{ + switch (section) { + case 1: + return i18n("Invited"); + case 2: + return i18n("Favorite"); + case 3: + return i18n("Direct Messages"); + case 4: + return i18n("Normal"); + case 5: + return i18n("Low priority"); + default: + return i18n("Deadbeef"); + } +} + +void RoomListModel::setCategoryVisible(int category, bool visible) +{ + beginResetModel(); + m_categoryVisibility[category] = visible; + endResetModel(); +} + +bool RoomListModel::categoryVisible(int category) const +{ + return m_categoryVisibility.value(category, true); +} diff --git a/src/roomlistmodel.h b/src/roomlistmodel.h index e2640130f..b1fbcb11e 100644 --- a/src/roomlistmodel.h +++ b/src/roomlistmodel.h @@ -44,6 +44,7 @@ public: LastActiveTimeRole, JoinStateRole, CurrentRoomRole, + CategoryVisibleRole, }; Q_ENUM(EventRoles) @@ -64,6 +65,10 @@ public: QHash roleNames() const override; + Q_INVOKABLE QString categoryName(int category) const; + Q_INVOKABLE void setCategoryVisible(int category, bool visible); + Q_INVOKABLE bool categoryVisible(int category) const; + int notificationCount() const { return m_notificationCount; @@ -80,6 +85,8 @@ private: Connection *m_connection = nullptr; QList m_rooms; + QMap m_categoryVisibility; + int m_notificationCount = 0; void connectRoomSignals(SpectralRoom *room); diff --git a/src/sortfilterroomlistmodel.cpp b/src/sortfilterroomlistmodel.cpp new file mode 100644 index 000000000..ffbd68e55 --- /dev/null +++ b/src/sortfilterroomlistmodel.cpp @@ -0,0 +1,46 @@ +/** + * SPDX-FileCopyrightText: Tobias Fella + * + * SPDX-LicenseIdentifier: GPL-2.0-only OR GPL-3.0-only OR LicenseRef-KDE-Accepted-GPL + */ + +#include "sortfilterroomlistmodel.h" + +#include "roomlistmodel.h" + +SortFilterRoomListModel::SortFilterRoomListModel(QObject *parent) + : QSortFilterProxyModel(parent) +{ + setFilterRole(RoomListModel::NameRole); + setFilterCaseSensitivity(Qt::CaseInsensitive); + sort(0); +} + +void SortFilterRoomListModel::setRoomSortOrder(SortFilterRoomListModel::RoomSortOrder sortOrder) +{ + m_sortOrder = sortOrder; + Q_EMIT roomSortOrderChanged(); + if (sortOrder == SortFilterRoomListModel::Alphabetical) + setSortRole(RoomListModel::NameRole); + else if (sortOrder == SortFilterRoomListModel::LastActivity) + setSortRole(RoomListModel::LastActiveTimeRole); +} + +SortFilterRoomListModel::RoomSortOrder SortFilterRoomListModel::roomSortOrder() const +{ + return m_sortOrder; +} + +bool SortFilterRoomListModel::lessThan(const QModelIndex &source_left, const QModelIndex &source_right) const +{ + if (m_sortOrder != SortFilterRoomListModel::Categories) + return QSortFilterProxyModel::lessThan(source_left, source_right); + if (sourceModel()->data(source_left, RoomListModel::CategoryRole) != sourceModel()->data(source_right, RoomListModel::CategoryRole)) + return sourceModel()->data(source_left, RoomListModel::CategoryRole) < sourceModel()->data(source_right, RoomListModel::CategoryRole); + return sourceModel()->data(source_left, RoomListModel::NameRole) < sourceModel()->data(source_right, RoomListModel::NameRole); +} + +void SortFilterRoomListModel::setFilterText(const QString &text) +{ + setFilterFixedString(text); +} diff --git a/src/sortfilterroomlistmodel.h b/src/sortfilterroomlistmodel.h new file mode 100644 index 000000000..74f13c568 --- /dev/null +++ b/src/sortfilterroomlistmodel.h @@ -0,0 +1,41 @@ +/** + * SPDX-FileCopyrightText: Tobias Fella + * + * SPDX-LicenseIdentifier: GPL-2.0-only OR GPL-3.0-only OR LicenseRef-KDE-Accepted-GPL + */ + +#pragma once + +#include + +class SortFilterRoomListModel : public QSortFilterProxyModel +{ + Q_OBJECT + + Q_PROPERTY(RoomSortOrder roomSortOrder READ roomSortOrder WRITE setRoomSortOrder NOTIFY roomSortOrderChanged) + Q_PROPERTY(QAbstractItemModel *sourceModel READ sourceModel WRITE setSourceModel NOTIFY sourceModelChanged) + +public: + enum RoomSortOrder { + Alphabetical, + LastActivity, + Categories, + }; + Q_ENUM(RoomSortOrder) + + SortFilterRoomListModel(QObject *parent = nullptr); + + void setRoomSortOrder(RoomSortOrder sortOrder); + RoomSortOrder roomSortOrder() const; + + Q_INVOKABLE void setFilterText(const QString &text); + + bool lessThan(const QModelIndex &source_left, const QModelIndex &source_right) const override; + +Q_SIGNALS: + void roomSortOrderChanged(); + void sourceModelChanged(); + +private: + RoomSortOrder m_sortOrder; +};