From bf8bd4b023626a8970921b7e2ca27ec304a6be70 Mon Sep 17 00:00:00 2001 From: Phenom Date: Wed, 7 Feb 2018 19:00:08 +0100 Subject: [PATCH] Add Only Connected in FriendSelectionWidget. Add Select All if Multi Selection allowed. Clean Some Code duplicated from RSTreeWidget. --- .../src/gui/common/FriendSelectionWidget.cpp | 83 +++++++++---------- .../src/gui/common/FriendSelectionWidget.h | 4 +- .../src/gui/common/RSTreeWidget.cpp | 75 +++++++++++++++-- retroshare-gui/src/gui/common/RSTreeWidget.h | 7 ++ 4 files changed, 119 insertions(+), 50 deletions(-) diff --git a/retroshare-gui/src/gui/common/FriendSelectionWidget.cpp b/retroshare-gui/src/gui/common/FriendSelectionWidget.cpp index dce1b39f4..5bd3c1789 100644 --- a/retroshare-gui/src/gui/common/FriendSelectionWidget.cpp +++ b/retroshare-gui/src/gui/common/FriendSelectionWidget.cpp @@ -45,11 +45,12 @@ #define IDDIALOG_IDLIST 1 -#define ROLE_ID Qt::UserRole -#define ROLE_SORT_GROUP Qt::UserRole + 1 -#define ROLE_SORT_STANDARD_GROUP Qt::UserRole + 2 -#define ROLE_SORT_NAME Qt::UserRole + 3 -#define ROLE_SORT_STATE Qt::UserRole + 4 +#define ROLE_ID Qt::UserRole +#define ROLE_SORT_GROUP Qt::UserRole + 1 +#define ROLE_SORT_STANDARD_GROUP Qt::UserRole + 2 +#define ROLE_SORT_NAME Qt::UserRole + 3 +#define ROLE_SORT_STATE Qt::UserRole + 4 +#define ROLE_FILTER_REASON Qt::UserRole + 5 #define IMAGE_GROUP16 ":/images/user/group16.png" #define IMAGE_FRIENDINFO ":/images/peerdetails_16x16.png" @@ -109,10 +110,15 @@ FriendSelectionWidget::FriendSelectionWidget(QWidget *parent) mActionSortByState->setCheckable(true); connect(mActionSortByState, SIGNAL(toggled(bool)), this, SLOT(sortByState(bool))); ui->friendList->addContextMenuAction(mActionSortByState); + mActionFilterConnected = new QAction(tr("Filter only connected"), this); + mActionFilterConnected->setCheckable(true); + connect(mActionFilterConnected, SIGNAL(toggled(bool)), this, SLOT(filterConnected(bool))); + ui->friendList->addContextMenuAction(mActionFilterConnected); /* initialize list */ ui->friendList->setColumnCount(COLUMN_COUNT); ui->friendList->headerItem()->setText(COLUMN_NAME, tr("Name")); + ui->friendList->setFilterReasonRole(ROLE_FILTER_REASON); /* sort list by name ascending */ ui->friendList->sortItems(COLUMN_NAME, Qt::AscendingOrder); @@ -216,8 +222,8 @@ static void initSslItem(QTreeWidgetItem *item, const RsPeerDetails &detail, cons item->setData(COLUMN_NAME, ROLE_SORT_GROUP, 1); item->setData(COLUMN_NAME, ROLE_SORT_STANDARD_GROUP, 0); - item->setData(COLUMN_NAME, ROLE_SORT_STATE, (state != (int) RS_STATUS_OFFLINE) ? 0 : 1); item->setData(COLUMN_NAME, ROLE_SORT_NAME, name); + item->setData(COLUMN_NAME, ROLE_SORT_STATE, state); } void FriendSelectionWidget::fillList() @@ -359,8 +365,8 @@ void FriendSelectionWidget::secured_fillList() groupItem->setData(COLUMN_NAME, ROLE_SORT_GROUP, 0); groupItem->setData(COLUMN_NAME, ROLE_SORT_STANDARD_GROUP, (groupInfo->flag & RS_GROUP_FLAG_STANDARD) ? 0 : 1); - groupItem->setData(COLUMN_NAME, ROLE_SORT_STATE, 0); groupItem->setData(COLUMN_NAME, ROLE_SORT_NAME, groupName); + groupItem->setData(COLUMN_NAME, ROLE_SORT_STATE, 0); if (mListModus == MODUS_CHECK) { groupItem->setCheckState(0, Qt::Unchecked); @@ -426,8 +432,8 @@ void FriendSelectionWidget::secured_fillList() gpgItem->setData(COLUMN_NAME, ROLE_SORT_GROUP, 1); gpgItem->setData(COLUMN_NAME, ROLE_SORT_STANDARD_GROUP, 0); - gpgItem->setData(COLUMN_NAME, ROLE_SORT_STATE, (state != (int) RS_STATUS_OFFLINE) ? 0 : 1); gpgItem->setData(COLUMN_NAME, ROLE_SORT_NAME, name); + gpgItem->setData(COLUMN_NAME, ROLE_SORT_STATE, state); if (mListModus == MODUS_CHECK) { gpgItem->setCheckState(0, Qt::Unchecked); @@ -561,9 +567,9 @@ void FriendSelectionWidget::secured_fillList() gxsItem->setData(COLUMN_NAME, ROLE_SORT_GROUP, 1); gxsItem->setData(COLUMN_NAME, ROLE_SORT_STANDARD_GROUP, 0); + gxsItem->setData(COLUMN_NAME, ROLE_SORT_NAME, name); //TODO: online state for gxs items gxsItem->setData(COLUMN_NAME, ROLE_SORT_STATE, 1); - gxsItem->setData(COLUMN_NAME, ROLE_SORT_NAME, name); if (mListModus == MODUS_CHECK) gxsItem->setCheckState(0, Qt::Unchecked); @@ -615,9 +621,9 @@ void FriendSelectionWidget::secured_fillList() gxsItem->setData(COLUMN_NAME, ROLE_SORT_GROUP, 1); gxsItem->setData(COLUMN_NAME, ROLE_SORT_STANDARD_GROUP, 0); + gxsItem->setData(COLUMN_NAME, ROLE_SORT_NAME, name); //TODO: online state for gxs items gxsItem->setData(COLUMN_NAME, ROLE_SORT_STATE, 1); - gxsItem->setData(COLUMN_NAME, ROLE_SORT_NAME, name); if (mListModus == MODUS_CHECK) gxsItem->setCheckState(0, Qt::Unchecked); @@ -650,6 +656,7 @@ void FriendSelectionWidget::secured_fillList() mInFillList = false; ui->friendList->resort(); + filterConnected(isFilterConnected()); emit contentChanged(); } @@ -751,7 +758,7 @@ void FriendSelectionWidget::peerStatusChanged(const QString& peerId, int status) item->setTextColor(COLUMN_NAME, color); item->setIcon(COLUMN_NAME, QIcon(StatusDefs::imageUser(gpgStatus))); - item->setData(COLUMN_NAME, ROLE_SORT_STATE, (gpgStatus != (int) RS_STATUS_OFFLINE) ? 0 : 1); + item->setData(COLUMN_NAME, ROLE_SORT_STATE, gpgStatus); bFoundGPG = true; } @@ -770,7 +777,7 @@ void FriendSelectionWidget::peerStatusChanged(const QString& peerId, int status) item->setTextColor(COLUMN_NAME, color); item->setIcon(COLUMN_NAME, QIcon(StatusDefs::imageUser(status))); - item->setData(COLUMN_NAME, ROLE_SORT_STATE, (status != (int) RS_STATUS_OFFLINE) ? 0 : 1); + item->setData(COLUMN_NAME, ROLE_SORT_STATE, status); bFoundSSL = true; } @@ -799,6 +806,7 @@ void FriendSelectionWidget::peerStatusChanged(const QString& peerId, int status) } ui->friendList->resort(); + filterConnected(isFilterConnected()); } void FriendSelectionWidget::addContextMenuAction(QAction *action) @@ -810,7 +818,7 @@ void FriendSelectionWidget::contextMenuRequested(const QPoint &/*pos*/) { QMenu *contextMenu = new QMenu(this); - if (mListModus == MODUS_CHECK) { + if (mListModus == MODUS_MULTI) { contextMenu->addAction(QIcon(), tr("Mark all"), this, SLOT(selectAll())); contextMenu->addAction(QIcon(), tr("Mark none"), this, SLOT(deselectAll())); } @@ -953,37 +961,9 @@ void FriendSelectionWidget::itemChanged(QTreeWidgetItem *item, int column) void FriendSelectionWidget::filterItems(const QString& text) { - int count = ui->friendList->topLevelItemCount(); - for (int index = 0; index < count; ++index) { - filterItem(ui->friendList->topLevelItem(index), text); - } -} - -bool FriendSelectionWidget::filterItem(QTreeWidgetItem *item, const QString &text) -{ - bool visible = true; - - if (text.isEmpty() == false) { - if (item->text(0).contains(text, Qt::CaseInsensitive) == false) { - visible = false; - } - } - - int visibleChildCount = 0; - int count = item->childCount(); - for (int index = 0; index < count; ++index) { - if (filterItem(item->child(index), text)) { - ++visibleChildCount; - } - } - - if (visible || visibleChildCount) { - item->setHidden(false); - } else { - item->setHidden(true); - } - - return (visible || visibleChildCount); + ui->friendList->filterItems(COLUMN_NAME, text); + ui->friendList->resort(); + filterConnected(isFilterConnected()); } int FriendSelectionWidget::selectedItemCount() @@ -1168,9 +1148,24 @@ void FriendSelectionWidget::sortByState(bool sort) mActionSortByState->setChecked(sort); ui->friendList->resort(); + filterConnected(isFilterConnected()); } bool FriendSelectionWidget::isSortByState() { return mActionSortByState->isChecked(); } + +void FriendSelectionWidget::filterConnected(bool filter) +{ + ui->friendList->filterMinValItems(COLUMN_NAME, filter ? RS_STATUS_AWAY : RS_STATUS_OFFLINE, ROLE_SORT_STATE); + + mActionFilterConnected->setChecked(filter); + + ui->friendList->resort(); +} + +bool FriendSelectionWidget::isFilterConnected() +{ + return mActionFilterConnected->isChecked(); +} diff --git a/retroshare-gui/src/gui/common/FriendSelectionWidget.h b/retroshare-gui/src/gui/common/FriendSelectionWidget.h index c83aa716e..5cb3198f0 100644 --- a/retroshare-gui/src/gui/common/FriendSelectionWidget.h +++ b/retroshare-gui/src/gui/common/FriendSelectionWidget.h @@ -82,6 +82,7 @@ public: void start(); bool isSortByState(); + bool isFilterConnected(); int selectedItemCount(); std::string selectedId(IdType &idType); @@ -130,6 +131,7 @@ signals: public slots: void sortByState(bool sort); + void filterConnected(bool filter); private slots: void groupsChanged(int type); @@ -144,7 +146,6 @@ private slots: private: void fillList(); void secured_fillList(); - bool filterItem(QTreeWidgetItem *item, const QString &text); void selectedIds(IdType idType, std::set &ids, bool onlyDirectSelected); void setSelectedIds(IdType idType, const std::set &ids, bool add); @@ -161,6 +162,7 @@ private: bool mInSslItemChanged; bool mInFillList; QAction *mActionSortByState; + QAction *mActionFilterConnected; /* Color definitions (for standard see qss.default) */ QColor mTextColorOnline; diff --git a/retroshare-gui/src/gui/common/RSTreeWidget.cpp b/retroshare-gui/src/gui/common/RSTreeWidget.cpp index a261bff80..e4bd8be36 100644 --- a/retroshare-gui/src/gui/common/RSTreeWidget.cpp +++ b/retroshare-gui/src/gui/common/RSTreeWidget.cpp @@ -34,6 +34,7 @@ RSTreeWidget::RSTreeWidget(QWidget *parent) : QTreeWidget(parent) { mEnableColumnCustomize = false; mSettingsVersion = 0; // disabled + mFilterReasonRole = -1; // disabled QHeaderView *h = header(); h->setContextMenuPolicy(Qt::CustomContextMenu); @@ -84,6 +85,12 @@ void RSTreeWidget::mousePressEvent(QMouseEvent *event) QTreeWidget::mousePressEvent(event); } +void RSTreeWidget::setFilterReasonRole(int role /*=-1*/) +{ + if (role > Qt::UserRole) + mFilterReasonRole = role; +} + void RSTreeWidget::filterItems(int filterColumn, const QString &text, int role) { int count = topLevelItemCount(); @@ -101,6 +108,13 @@ void RSTreeWidget::filterItems(int filterColumn, const QString &text, int role) bool RSTreeWidget::filterItem(QTreeWidgetItem *item, int filterColumn, const QString &text, int role) { bool itemVisible = true; + //Get who hide this item + int filterReason = 0; + if (mFilterReasonRole >= Qt::UserRole) + filterReason = item->data(filterColumn, mFilterReasonRole).toInt(); + //Remove this filter for last test + if (filterReason & FILTER_REASON_TEXT) + filterReason -= FILTER_REASON_TEXT; if (!text.isEmpty()) { if (!item->data(filterColumn, role).toString().contains(text, Qt::CaseInsensitive)) { @@ -116,11 +130,62 @@ bool RSTreeWidget::filterItem(QTreeWidgetItem *item, int filterColumn, const QSt } } - if (itemVisible || visibleChildCount) { - item->setHidden(false); - } else { - item->setHidden(true); + if (!itemVisible && !visibleChildCount) { + filterReason |= FILTER_REASON_TEXT; } + item->setHidden(filterReason != 0); + //Update hiding reason + if (mFilterReasonRole >= Qt::UserRole) + item->setData(filterColumn, mFilterReasonRole, filterReason); + + return (itemVisible || visibleChildCount); +} + +void RSTreeWidget::filterMinValItems(int filterColumn, const double &value, int role) +{ + int count = topLevelItemCount(); + for (int index = 0; index < count; ++index) { + filterMinValItem(topLevelItem(index), filterColumn, value, role); + } + + QTreeWidgetItem *item = currentItem(); + if (item && item->isHidden()) { + // active item is hidden, deselect it + setCurrentItem(NULL); + } +} + +bool RSTreeWidget::filterMinValItem(QTreeWidgetItem *item, int filterColumn, const double &value, int role) +{ + bool itemVisible = true; + //Get who hide this item + int filterReason = 0; + if (mFilterReasonRole >= Qt::UserRole) + filterReason = item->data(filterColumn, mFilterReasonRole).toInt(); + //Remove this filter for last test + if (filterReason & FILTER_REASON_MINVAL) + filterReason -= FILTER_REASON_MINVAL; + + bool ok = false; + if ((item->data(filterColumn, role).toDouble(&ok) < value) && ok ) { + itemVisible = false; + } + + int visibleChildCount = 0; + int count = item->childCount(); + for (int index = 0; index < count; ++index) { + if (filterMinValItem(item->child(index), filterColumn, value, role)) { + ++visibleChildCount; + } + } + + if (!itemVisible && !visibleChildCount) { + filterReason |= FILTER_REASON_MINVAL; + } + item->setHidden(filterReason != 0); + //Update hiding reason + if (mFilterReasonRole >= Qt::UserRole) + item->setData(filterColumn, mFilterReasonRole, filterReason); return (itemVisible || visibleChildCount); } @@ -294,6 +359,6 @@ void RSTreeWidget::columnVisible() void RSTreeWidget::resort() { if (isSortingEnabled()) { - sortByColumn(header()->sortIndicatorSection(), header()->sortIndicatorOrder()); + sortItems(header()->sortIndicatorSection(), header()->sortIndicatorOrder()); } } diff --git a/retroshare-gui/src/gui/common/RSTreeWidget.h b/retroshare-gui/src/gui/common/RSTreeWidget.h index cffa9975f..2d42088b9 100644 --- a/retroshare-gui/src/gui/common/RSTreeWidget.h +++ b/retroshare-gui/src/gui/common/RSTreeWidget.h @@ -24,6 +24,9 @@ #include +#define FILTER_REASON_TEXT 0x0001 +#define FILTER_REASON_MINVAL 0x0002 + /* Subclassing QTreeWidget */ class RSTreeWidget : public QTreeWidget { @@ -35,7 +38,9 @@ public: QString placeholderText() { return mPlaceholderText; } void setPlaceholderText(const QString &text); + void setFilterReasonRole(int role = -1); void filterItems(int filterColumn, const QString &text, int role = Qt::DisplayRole); + void filterMinValItems(int filterColumn, const double &value, int role = Qt::DisplayRole); void setSettingsVersion(qint32 version); void processSettings(bool load); @@ -58,6 +63,7 @@ signals: private: bool filterItem(QTreeWidgetItem *item, int filterColumn, const QString &text, int role); + bool filterMinValItem(QTreeWidgetItem *item, int filterColumn, const double &value, int role); private slots: void headerContextMenuRequested(const QPoint &pos); @@ -74,6 +80,7 @@ private: QMap mColumnCustomizable; QList mContextMenuActions; QList mContextMenuMenus; + int mFilterReasonRole; }; #endif