[network/ruqola] src/widgets: Use usersinroomtreeview
Laurent Montel <[email protected]>
| Newsgroups | gmane.comp.kde.cvs |
|---|---|
| Message-ID | <[email protected]> |
Git commit ec306049fb9fbd7e3fdbfda555b74c3419e68ac0 by Laurent Montel.
Committed on 29/07/2026 at 06:09.
Pushed by mlaurent into branch 'master'.
Use usersinroomtreeview
M +8 -0 src/widgets/common/usersforroommodeldelegate.cpp
M +20 -0 src/widgets/room/autotests/usersinroomtreeviewtest.cpp
M +1 -0 src/widgets/room/autotests/usersinroomtreeviewtest.h
M +2 -2 src/widgets/room/autotests/usersinroomwidgettest.cpp
M +23 -0 src/widgets/room/usersinroomtreeview.cpp
M +1 -0 src/widgets/room/usersinroomtreeview.h
M +29 -25 src/widgets/room/usersinroomwidget.cpp
M +2 -4 src/widgets/room/usersinroomwidget.h
https://invent.kde.org/network/ruqola/-/commit/ec306049fb9fbd7e3fdbfda555b74c3419e68ac0
diff --git a/src/widgets/common/usersforroommodeldelegate.cpp b/src/widgets/common/usersforroommodeldelegate.cpp
index dbde655f85..e8003d4dfd 100644
--- a/src/widgets/common/usersforroommodeldelegate.cpp
+++ b/src/widgets/common/usersforroommodeldelegate.cpp
@@ -26,6 +26,14 @@ UsersForRoomModelDelegate::~UsersForRoomModelDelegate() = default;
void UsersForRoomModelDelegate::paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const
{
+ // Section rows are top-level rows in tree mode and should use default
+ // painting to show their DisplayRole title (Online, Offline, ...).
+ // We cannot rely on hasChildren() because empty sections would be missed.
+ if (!index.parent().isValid()) {
+ QItemDelegate::paint(painter, option, index);
+ return;
+ }
+
// [M] icon ? status name (username)
drawBackground(painter, option, index);
diff --git a/src/widgets/room/autotests/usersinroomtreeviewtest.cpp b/src/widgets/room/autotests/usersinroomtreeviewtest.cpp
index 7dfc77257a..8adeebf135 100644
--- a/src/widgets/room/autotests/usersinroomtreeviewtest.cpp
+++ b/src/widgets/room/autotests/usersinroomtreeviewtest.cpp
@@ -5,6 +5,9 @@
*/
#include "usersinroomtreeviewtest.h"
+#include "model/usersforroomfilterproxymodel.h"
+#include "model/usersforroomlistheadingsproxymodel.h"
+#include "model/usersforroommodel.h"
#include "room/usersinroomtreeview.h"
#include <QTest>
QTEST_MAIN(UsersInRoomTreeViewTest)
@@ -20,9 +23,26 @@ void UsersInRoomTreeViewTest::shouldHaveDefaultValues()
QVERIFY(!w.dragEnabled());
QVERIFY(!w.rootIsDecorated());
QVERIFY(w.itemsExpandable());
+ QVERIFY(!w.expandsOnDoubleClick());
QCOMPARE(w.indentation(), 0);
QCOMPARE(w.horizontalScrollBarPolicy(), Qt::ScrollBarAlwaysOff);
QVERIFY(w.isHeaderHidden());
}
+void UsersInRoomTreeViewTest::shouldKeepSectionProxyChain()
+{
+ UsersInRoomTreeView w;
+ auto *const filterProxy = w.usersForRoomFilterProxy();
+ QVERIFY(filterProxy);
+
+ auto *const headingsProxy = qobject_cast<UsersForRoomListHeadingsProxyModel *>(filterProxy->sourceModel());
+ QVERIFY(headingsProxy);
+
+ UsersForRoomModel usersModel;
+ headingsProxy->setSourceModel(&usersModel);
+
+ QCOMPARE(headingsProxy->sourceModel(), &usersModel);
+ QVERIFY(filterProxy->sourceModel() != &usersModel);
+}
+
#include "moc_usersinroomtreeviewtest.cpp"
diff --git a/src/widgets/room/autotests/usersinroomtreeviewtest.h b/src/widgets/room/autotests/usersinroomtreeviewtest.h
index 332cce2549..8e9476ae91 100644
--- a/src/widgets/room/autotests/usersinroomtreeviewtest.h
+++ b/src/widgets/room/autotests/usersinroomtreeviewtest.h
@@ -17,4 +17,5 @@ public:
private Q_SLOTS:
void shouldHaveDefaultValues();
+ void shouldKeepSectionProxyChain();
};
diff --git a/src/widgets/room/autotests/usersinroomwidgettest.cpp b/src/widgets/room/autotests/usersinroomwidgettest.cpp
index a77b029728..985bc668fd 100644
--- a/src/widgets/room/autotests/usersinroomwidgettest.cpp
+++ b/src/widgets/room/autotests/usersinroomwidgettest.cpp
@@ -7,7 +7,7 @@
#include "usersinroomwidgettest.h"
#include "room/usersinroomcombobox.h"
-#include "room/usersinroomlistview.h"
+#include "room/usersinroomtreeview.h"
#include "room/usersinroomwidget.h"
#include <QLabel>
#include <QLineEdit>
@@ -29,7 +29,7 @@ void UsersInRoomWidgetTest::shouldHaveDefaultValues()
QVERIFY(mainLayout);
QCOMPARE(mainLayout->contentsMargins(), QMargins{});
- auto mListView = w.findChild<UsersInRoomListView *>(u"mListView"_s);
+ auto mListView = w.findChild<UsersInRoomTreeView *>(u"mListView"_s);
QVERIFY(mListView);
auto mSearchLineEdit = w.findChild<QLineEdit *>(u"mSearchLineEdit"_s);
diff --git a/src/widgets/room/usersinroomtreeview.cpp b/src/widgets/room/usersinroomtreeview.cpp
index a09489e7ed..b9cb9c4f48 100644
--- a/src/widgets/room/usersinroomtreeview.cpp
+++ b/src/widgets/room/usersinroomtreeview.cpp
@@ -24,6 +24,7 @@ UsersInRoomTreeView::UsersInRoomTreeView(QWidget *parent)
setIndentation(0);
setRootIsDecorated(false);
setItemsExpandable(true);
+ setExpandsOnDoubleClick(false);
setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
connect(model(), &QAbstractItemModel::rowsInserted, this, &QTreeView::expandAll);
@@ -31,7 +32,15 @@ UsersInRoomTreeView::UsersInRoomTreeView(QWidget *parent)
connect(model(), &QAbstractItemModel::rowsMoved, this, &QTreeView::expandAll);
connect(model(), &QAbstractItemModel::layoutChanged, this, &QTreeView::expandAll);
+ connect(model(), &QAbstractItemModel::rowsInserted, this, &UsersInRoomTreeView::updateSectionVisibility);
+ connect(model(), &QAbstractItemModel::rowsRemoved, this, &UsersInRoomTreeView::updateSectionVisibility);
+ connect(model(), &QAbstractItemModel::rowsMoved, this, &UsersInRoomTreeView::updateSectionVisibility);
+ connect(model(), &QAbstractItemModel::layoutChanged, this, &UsersInRoomTreeView::updateSectionVisibility);
+ connect(model(), &QAbstractItemModel::modelReset, this, &UsersInRoomTreeView::updateSectionVisibility);
+ connect(model(), &QAbstractItemModel::dataChanged, this, &UsersInRoomTreeView::updateSectionVisibility);
+
expandAll();
+ updateSectionVisibility();
}
UsersInRoomTreeView::~UsersInRoomTreeView() = default;
@@ -70,6 +79,20 @@ UsersForRoomFilterProxyModel *UsersInRoomTreeView::usersForRoomFilterProxy() con
return mUsersForRoomFilterProxy;
}
+void UsersInRoomTreeView::updateSectionVisibility()
+{
+ if (!model()) {
+ return;
+ }
+
+ const int sectionCount = model()->rowCount();
+ for (int row = 0; row < sectionCount; ++row) {
+ const QModelIndex sectionIndex = model()->index(row, 0);
+ const bool hasChildren = model()->rowCount(sectionIndex) > 0;
+ setRowHidden(row, QModelIndex(), !hasChildren);
+ }
+}
+
bool UsersInRoomTreeView::event(QEvent *ev)
{
if (ev->type() == QEvent::ApplicationPaletteChange) {
diff --git a/src/widgets/room/usersinroomtreeview.h b/src/widgets/room/usersinroomtreeview.h
index 669cb78185..a93cf4ebf6 100644
--- a/src/widgets/room/usersinroomtreeview.h
+++ b/src/widgets/room/usersinroomtreeview.h
@@ -24,6 +24,7 @@ protected:
private:
LIBRUQOLAWIDGETS_NO_EXPORT void generalPaletteChanged();
+ LIBRUQOLAWIDGETS_NO_EXPORT void updateSectionVisibility();
QColor mTextColor;
UsersForRoomListHeadingsProxyModel *const mUsersForRoomListHeadingsProxyModel;
UsersForRoomFilterProxyModel *const mUsersForRoomFilterProxy;
diff --git a/src/widgets/room/usersinroomwidget.cpp b/src/widgets/room/usersinroomwidget.cpp
index fead233ab5..3d95c7df7f 100644
--- a/src/widgets/room/usersinroomwidget.cpp
+++ b/src/widgets/room/usersinroomwidget.cpp
@@ -9,9 +9,10 @@
#include "common/usersforroommodeldelegate.h"
#include "dialogs/directchannelinfodialog.h"
#include "model/usersforroomfilterproxymodel.h"
+#include "model/usersforroomlistheadingsproxymodel.h"
#include "model/usersforroommodel.h"
#include "rocketchataccount.h"
-#include "room/usersinroomlistview.h"
+#include "room/usersinroomtreeview.h"
#include "usersinroomcombobox.h"
#include "usersinroommenu.h"
#include <KLineEditEventHandler>
@@ -24,10 +25,9 @@
using namespace Qt::Literals::StringLiterals;
UsersInRoomWidget::UsersInRoomWidget(RocketChatAccount *account, QWidget *parent)
: QWidget(parent)
- , mListView(new UsersInRoomListView(this))
+ , mListView(new UsersInRoomTreeView(this))
, mSearchLineEdit(new QLineEdit(this))
, mMessageListInfo(new QLabel(this))
- , mUsersForRoomFilterProxy(new UsersForRoomFilterProxyModel(this))
, mUsersInRoomComboBox(new UsersInRoomComboBox(account ? account->hasAtLeastVersion(7, 3, 0) : false, this))
, mRocketChatAccount(account)
{
@@ -62,42 +62,39 @@ UsersInRoomWidget::UsersInRoomWidget(RocketChatAccount *account, QWidget *parent
mListView->setObjectName(u"mListView"_s);
mainLayout->addWidget(mListView);
mListView->setContextMenuPolicy(Qt::CustomContextMenu);
- connect(mListView, &QListView::customContextMenuRequested, this, &UsersInRoomWidget::slotCustomContextMenuRequested);
- connect(mListView, &QListView::doubleClicked, this, &UsersInRoomWidget::slotDoubleClick);
- mListView->setModel(mUsersForRoomFilterProxy);
+ connect(mListView, &UsersInRoomTreeView::customContextMenuRequested, this, &UsersInRoomWidget::slotCustomContextMenuRequested);
+ connect(mListView, &UsersInRoomTreeView::doubleClicked, this, &UsersInRoomWidget::slotDoubleClick);
if (account) {
auto delegate = new UsersForRoomModelDelegate(mListView);
delegate->setRocketChatAccount(account);
mListView->setItemDelegate(delegate);
}
mListView->setMouseTracking(true);
- connect(mUsersForRoomFilterProxy, &UsersForRoomFilterProxyModel::hasFullListChanged, this, &UsersInRoomWidget::updateLabel);
- connect(mUsersForRoomFilterProxy, &UsersForRoomFilterProxyModel::loadingInProgressChanged, this, &UsersInRoomWidget::updateLabel);
+ connect(mListView->usersForRoomFilterProxy(), &UsersForRoomFilterProxyModel::hasFullListChanged, this, &UsersInRoomWidget::updateLabel);
+ connect(mListView->usersForRoomFilterProxy(), &UsersForRoomFilterProxyModel::loadingInProgressChanged, this, &UsersInRoomWidget::updateLabel);
}
UsersInRoomWidget::~UsersInRoomWidget()
{
- mUsersForRoomFilterProxy->clearFilter();
+ mListView->usersForRoomFilterProxy()->clearFilter();
}
void UsersInRoomWidget::slotDoubleClick(const QModelIndex &index)
{
-#ifdef USE_TREEVIEW
if (!index.parent().isValid()) {
return;
}
-#endif
slotShowUserInfo(index);
}
void UsersInRoomWidget::slotChangeStatusType([[maybe_unused]] int index)
{
- mUsersForRoomFilterProxy->setStatusType(mUsersInRoomComboBox->currentData().value<UsersForRoomFilterProxyModel::FilterUserType>());
+ mListView->usersForRoomFilterProxy()->setStatusType(mUsersInRoomComboBox->currentData().value<UsersForRoomFilterProxyModel::FilterUserType>());
}
void UsersInRoomWidget::slotTextChanged(const QString &str)
{
- mUsersForRoomFilterProxy->setFilterString(str);
+ mListView->usersForRoomFilterProxy()->setFilterString(str);
mRocketChatAccount->loadMoreUsersInRoom(mRoom->roomId(), mRoom->channelType(), str);
}
@@ -106,19 +103,24 @@ void UsersInRoomWidget::setRoom(Room *room)
mRoom = room;
if (mRoom) {
auto model = mRocketChatAccount->usersModelForRoom(mRoom->roomId());
- auto sourceModel = mUsersForRoomFilterProxy->sourceModel();
- if (sourceModel) {
- auto usersForRoomModel = qobject_cast<UsersForRoomModel *>(mUsersForRoomFilterProxy->sourceModel());
- disconnect(usersForRoomModel, &UsersForRoomModel::hasFullListChanged, mUsersForRoomFilterProxy, &UsersForRoomFilterProxyModel::hasFullListChanged);
+ auto *const roomFilterProxy = mListView->usersForRoomFilterProxy();
+ auto *const headingsProxy = qobject_cast<UsersForRoomListHeadingsProxyModel *>(roomFilterProxy->sourceModel());
+ Q_ASSERT(headingsProxy);
+ if (!headingsProxy) {
+ return;
+ }
+ auto *const usersForRoomModel = qobject_cast<UsersForRoomModel *>(headingsProxy->sourceModel());
+ if (usersForRoomModel) {
+ disconnect(usersForRoomModel, &UsersForRoomModel::hasFullListChanged, roomFilterProxy, &UsersForRoomFilterProxyModel::hasFullListChanged);
disconnect(usersForRoomModel,
&UsersForRoomModel::loadingInProgressChanged,
- mUsersForRoomFilterProxy,
+ roomFilterProxy,
&UsersForRoomFilterProxyModel::loadingInProgressChanged);
}
- connect(model, &UsersForRoomModel::hasFullListChanged, mUsersForRoomFilterProxy, &UsersForRoomFilterProxyModel::hasFullListChanged);
- connect(model, &UsersForRoomModel::loadingInProgressChanged, mUsersForRoomFilterProxy, &UsersForRoomFilterProxyModel::loadingInProgressChanged);
- mUsersForRoomFilterProxy->setSourceModel(model);
+ connect(model, &UsersForRoomModel::hasFullListChanged, roomFilterProxy, &UsersForRoomFilterProxyModel::hasFullListChanged);
+ connect(model, &UsersForRoomModel::loadingInProgressChanged, roomFilterProxy, &UsersForRoomFilterProxyModel::loadingInProgressChanged);
+ headingsProxy->setSourceModel(model);
updateLabel();
}
}
@@ -157,18 +159,20 @@ void UsersInRoomWidget::slotShowUserInfo(const QModelIndex &index)
void UsersInRoomWidget::updateLabel()
{
- if (mUsersForRoomFilterProxy->loadMoreUsersInProgress()) {
+ auto *const roomFilterProxy = mListView->usersForRoomFilterProxy();
+ if (roomFilterProxy->loadMoreUsersInProgress()) {
mMessageListInfo->setText(i18n("Loading…"));
} else {
- mMessageListInfo->setText(mUsersForRoomFilterProxy->numberOfUsers() == 0 ? i18n("No Message found") : displayShowMessageInRoom());
+ mMessageListInfo->setText(roomFilterProxy->numberOfUsers() == 0 ? i18n("No Message found") : displayShowMessageInRoom());
}
}
QString UsersInRoomWidget::displayShowMessageInRoom() const
{
+ auto *const roomFilterProxy = mListView->usersForRoomFilterProxy();
QString displayMessageStr =
- i18np("%1 User in room (Total: %2)", "%1 Users in room (Total: %2)", mUsersForRoomFilterProxy->numberOfUsers(), mUsersForRoomFilterProxy->total());
- if (!mUsersForRoomFilterProxy->hasFullList()) {
+ i18np("%1 User in room (Total: %2)", "%1 Users in room (Total: %2)", roomFilterProxy->numberOfUsers(), roomFilterProxy->total());
+ if (!roomFilterProxy->hasFullList()) {
displayMessageStr += u" <a href=\"loadmoreelement\">%1</a>"_s.arg(i18n("(Click here for Loading more…)"));
}
return displayMessageStr;
diff --git a/src/widgets/room/usersinroomwidget.h b/src/widgets/room/usersinroomwidget.h
index d04c4e0475..412ecbd2ba 100644
--- a/src/widgets/room/usersinroomwidget.h
+++ b/src/widgets/room/usersinroomwidget.h
@@ -14,10 +14,9 @@ class QLineEdit;
class Room;
class UsersInRoomMenu;
class QLabel;
-class UsersForRoomFilterProxyModel;
class UsersInRoomComboBox;
class RocketChatAccount;
-class UsersInRoomListView;
+class UsersInRoomTreeView;
class LIBRUQOLAWIDGETS_TESTS_EXPORT UsersInRoomWidget : public QWidget
{
Q_OBJECT
@@ -35,12 +34,11 @@ private:
LIBRUQOLAWIDGETS_NO_EXPORT void slotChangeStatusType(int index);
LIBRUQOLAWIDGETS_NO_EXPORT void slotShowUserInfo(const QModelIndex &index);
LIBRUQOLAWIDGETS_NO_EXPORT void slotDoubleClick(const QModelIndex &index);
- UsersInRoomListView *const mListView;
+ UsersInRoomTreeView *const mListView;
QLineEdit *const mSearchLineEdit;
QPointer<Room> mRoom;
UsersInRoomMenu *mMenu = nullptr;
QLabel *const mMessageListInfo;
- UsersForRoomFilterProxyModel *const mUsersForRoomFilterProxy;
UsersInRoomComboBox *const mUsersInRoomComboBox;
RocketChatAccount *const mRocketChatAccount;
};