From 040d19c946148f3891950dd7a5370a16b974f2cf Mon Sep 17 00:00:00 2001 From: jolavillette Date: Mon, 31 Aug 2026 05:47:37 +0200 Subject: [PATCH] ShareManager: stop discarding pending edits on every friend-list event The "Configure shared directories" dialog edits a local copy of the shared directories and only commits it when Apply is pressed. Since 0ce2dd848 it reloads that copy from the core on *any* FRIEND_LIST event, while the intent was only to follow friend-group changes. NODE_CONNECTED, NODE_STATUS_CHANGED, NODE_STATE_STRING_CHANGED... fire every few seconds as soon as a friend is online, so a directory added or removed in the dialog reverts to the saved state before the user can press Apply. Only react to GROUP_ADDED/REMOVED/CHANGED, and on those refresh the group names column (dropping groups that no longer exist) instead of reloading everything. Also do not reload when showYourself() is called while the dialog is already open, for the same reason. Co-Authored-By: Claude Fable 5 --- retroshare-gui/src/gui/ShareManager.cpp | 49 ++++++++++++++++++++----- retroshare-gui/src/gui/ShareManager.h | 1 + 2 files changed, 41 insertions(+), 9 deletions(-) diff --git a/retroshare-gui/src/gui/ShareManager.cpp b/retroshare-gui/src/gui/ShareManager.cpp index d4426d3ae..2dedba13a 100644 --- a/retroshare-gui/src/gui/ShareManager.cpp +++ b/retroshare-gui/src/gui/ShareManager.cpp @@ -75,18 +75,30 @@ ShareManager::ShareManager() mEventHandlerId = 0; + // The dialog edits a local copy of the shared directories (mDirInfos) and + // only commits it in applyAndClose(). FRIEND_LIST events fire constantly + // while friends are online (status, connection, avatar, state string...), + // so they must NOT reload the list from the core: that silently discards + // the pending edits. Only the friend-group events matter here, and they + // only need the group names column to be refreshed, not a reload. + rsEvents->registerEventsHandler( [this](std::shared_ptr e) { - RsQThreadUtils::postToObject([=]() + auto fe = dynamic_cast(e.get()); + + if(!fe) + return; + + switch(fe->mEventCode) { - auto fe = dynamic_cast(e.get()); - - if(!fe) - return; - - reload(); + case RsFriendListEventCode::GROUP_ADDED: + case RsFriendListEventCode::GROUP_REMOVED: + case RsFriendListEventCode::GROUP_CHANGED: + RsQThreadUtils::postToObject([this]() { refreshGroups(); }, this ); + break; + default: + break; } - , this ); }, mEventHandlerId, RsEventType::FRIEND_LIST ); QHeaderView* header = ui.shareddirList->horizontalHeader(); @@ -215,6 +227,24 @@ void ShareManager::shareddirListCustomPopupMenu( QPoint /*point*/ ) contextMnu.exec(QCursor::pos()); } +// Friend groups changed: drop the groups that no longer exist from the +// pending edits and redraw the group names, keeping the user's changes. +void ShareManager::refreshGroups() +{ + for(uint32_t i=0;igetGroupInfo(*it,groupInfo)) + ++it; + else + it = mDirInfos[i].parent_groups.erase(it); + } + + load(); +} + void ShareManager::reload() { std::list dirs ; @@ -297,8 +327,9 @@ void ShareManager::showYourself() { if(_instance == NULL) _instance = new ShareManager() ; + else if(_instance->isHidden()) + _instance->reload() ; // do not discard pending edits when the dialog is already open - _instance->reload() ; _instance->show() ; _instance->activateWindow(); } diff --git a/retroshare-gui/src/gui/ShareManager.h b/retroshare-gui/src/gui/ShareManager.h index b6d579894..e0891cdd5 100644 --- a/retroshare-gui/src/gui/ShareManager.h +++ b/retroshare-gui/src/gui/ShareManager.h @@ -64,6 +64,7 @@ private slots: void applyAndClose() ; void cancel() ; void reload() ; + void refreshGroups() ; static QString getGroupString(const std::list& groups); private: