From 5408427ea88376b24e0dd356ca3be41ccc6f9785 Mon Sep 17 00:00:00 2001 From: csoler Date: Tue, 17 Mar 2020 00:13:29 +0100 Subject: [PATCH 01/15] added auto delete active token feature to RsGxsIfaceHelper --- .../src/retroshare/rsgxsifacehelper.h | 139 ++++++++++++++++-- libretroshare/src/retroshare/rsidentity.h | 3 +- .../gui/gxsforums/GxsForumThreadWidget.cpp | 14 +- 3 files changed, 133 insertions(+), 23 deletions(-) diff --git a/libretroshare/src/retroshare/rsgxsifacehelper.h b/libretroshare/src/retroshare/rsgxsifacehelper.h index 99d029361..c04f13306 100644 --- a/libretroshare/src/retroshare/rsgxsifacehelper.h +++ b/libretroshare/src/retroshare/rsgxsifacehelper.h @@ -38,14 +38,25 @@ * To properly fix the API design many changes with the implied chain reactions * are necessary, so at this point this workaround seems acceptable. */ -struct RsGxsIfaceHelper + +enum class TokenRequestType: uint8_t { + GROUP_INFO = 0x01, + MSG_INFO = 0x02, + MSG_RELATED_INFO = 0x03, + GROUP_STATISTICS = 0x04, + SERVICE_STATISTICS = 0x05, +}; + +class RsGxsIfaceHelper +{ +public: /*! * @param gxs handle to RsGenExchange instance of service (Usually the * service class itself) */ RsGxsIfaceHelper(RsGxsIface& gxs) : - mGxs(gxs), mTokenService(*gxs.getTokenService()) {} + mGxs(gxs), mTokenService(*gxs.getTokenService()),mMtx("GxsIfaceHelper") {} ~RsGxsIfaceHelper(){} @@ -235,28 +246,80 @@ struct RsGxsIfaceHelper /// @see RsTokenService::requestGroupInfo bool requestGroupInfo( uint32_t& token, const RsTokReqOptions& opts, const std::list &groupIds ) - { return mTokenService.requestGroupInfo(token, 0, opts, groupIds); } + { + cancelActiveRequestTokens(TokenRequestType::GROUP_INFO); + + if( mTokenService.requestGroupInfo(token, 0, opts, groupIds)) + { + RS_STACK_MUTEX(mMtx); + mActiveTokens[token]=TokenRequestType::GROUP_INFO; + locked_dumpTokens(); + return true; + } + else + return false; + } /// @see RsTokenService::requestGroupInfo bool requestGroupInfo(uint32_t& token, const RsTokReqOptions& opts) - { return mTokenService.requestGroupInfo(token, 0, opts); } + { + cancelActiveRequestTokens(TokenRequestType::GROUP_INFO); + + if( mTokenService.requestGroupInfo(token, 0, opts)) + { + RS_STACK_MUTEX(mMtx); + mActiveTokens[token]=TokenRequestType::GROUP_INFO; + locked_dumpTokens(); + return true; + } + else + return false; + } /// @see RsTokenService::requestMsgInfo bool requestMsgInfo( uint32_t& token, const RsTokReqOptions& opts, const GxsMsgReq& msgIds ) - { return mTokenService.requestMsgInfo(token, 0, opts, msgIds); } + { + if(mTokenService.requestMsgInfo(token, 0, opts, msgIds)) + { + RS_STACK_MUTEX(mMtx); + mActiveTokens[token]=TokenRequestType::MSG_INFO; + locked_dumpTokens(); + return true; + } + else + return false; + } /// @see RsTokenService::requestMsgInfo - bool requestMsgInfo( - uint32_t& token, const RsTokReqOptions& opts, - const std::list& grpIds ) - { return mTokenService.requestMsgInfo(token, 0, opts, grpIds); } + bool requestMsgInfo( uint32_t& token, const RsTokReqOptions& opts, const std::list& grpIds ) + { + if(mTokenService.requestMsgInfo(token, 0, opts, grpIds)) + { + RS_STACK_MUTEX(mMtx); + mActiveTokens[token]=TokenRequestType::MSG_INFO; + locked_dumpTokens(); + return true; + } + else + return false; + } /// @see RsTokenService::requestMsgRelatedInfo bool requestMsgRelatedInfo( uint32_t& token, const RsTokReqOptions& opts, const std::vector& msgIds ) - { return mTokenService.requestMsgRelatedInfo(token, 0, opts, msgIds); } + { + if( mTokenService.requestMsgRelatedInfo(token, 0, opts, msgIds)) + { + RS_STACK_MUTEX(mMtx); + mActiveTokens[token]=TokenRequestType::MSG_RELATED_INFO; + locked_dumpTokens(); + return true; + } + else + return false; + } /** * @jsonapi{development} @@ -267,14 +330,46 @@ struct RsGxsIfaceHelper /// @see RsTokenService::requestServiceStatistic void requestServiceStatistic(uint32_t& token) - { mTokenService.requestServiceStatistic(token); } + { + mTokenService.requestServiceStatistic(token); + + RS_STACK_MUTEX(mMtx); + mActiveTokens[token]=TokenRequestType::SERVICE_STATISTICS; + + locked_dumpTokens(); + } /// @see RsTokenService::requestGroupStatistic void requestGroupStatistic(uint32_t& token, const RsGxsGroupId& grpId) - { mTokenService.requestGroupStatistic(token, grpId); } + { + mTokenService.requestGroupStatistic(token, grpId); + + RS_STACK_MUTEX(mMtx); + mActiveTokens[token]=TokenRequestType::GROUP_STATISTICS; + locked_dumpTokens(); + } + + bool cancelActiveRequestTokens(TokenRequestType type) + { + RS_STACK_MUTEX(mMtx); + for(auto it = mActiveTokens.begin();it!=mActiveTokens.end();) + if(it->second == type) + { + mTokenService.cancelRequest(it->first); + it = mActiveTokens.erase(it); + } + return true; + } /// @see RsTokenService::cancelRequest - bool cancelRequest(uint32_t token) { return mTokenService.cancelRequest(token); } + bool cancelRequest(uint32_t token) + { + { + RS_STACK_MUTEX(mMtx); + mActiveTokens.erase(token); + } + return mTokenService.cancelRequest(token); + } /** * @deprecated @@ -294,7 +389,7 @@ protected: */ RsTokenService::GxsRequestStatus waitToken( uint32_t token, - std::chrono::milliseconds maxWait = std::chrono::milliseconds(2000), + std::chrono::milliseconds maxWait = std::chrono::milliseconds(10000), std::chrono::milliseconds checkEvery = std::chrono::milliseconds(20), bool auto_delete_if_unsuccessful=true) { @@ -302,6 +397,11 @@ protected: if(res != RsTokenService::COMPLETE && auto_delete_if_unsuccessful) cancelRequest(token); + else + { + RS_STACK_MUTEX(mMtx); + mActiveTokens.erase(token); + } return res; } @@ -309,4 +409,15 @@ protected: private: RsGxsIface& mGxs; RsTokenService& mTokenService; + RsMutex mMtx; + + std::map mActiveTokens; + + void locked_dumpTokens() + { + std::cerr << "Active tokens (this=" << (void*)this << "): " ; + for(auto it: mActiveTokens) + std::cerr << std::dec << it.first << " (" << static_cast(it.second) << ") " ; + std::cerr << std::endl; + } }; diff --git a/libretroshare/src/retroshare/rsidentity.h b/libretroshare/src/retroshare/rsidentity.h index d30e55978..afd8f5544 100644 --- a/libretroshare/src/retroshare/rsidentity.h +++ b/libretroshare/src/retroshare/rsidentity.h @@ -383,8 +383,9 @@ struct RsIdentityDetails : RsSerializable /** The Main Interface Class for GXS people identities */ -struct RsIdentity : RsGxsIfaceHelper +class RsIdentity: public RsGxsIfaceHelper { +public: explicit RsIdentity(RsGxsIface& gxs) : RsGxsIfaceHelper(gxs) {} /** diff --git a/retroshare-gui/src/gui/gxsforums/GxsForumThreadWidget.cpp b/retroshare-gui/src/gui/gxsforums/GxsForumThreadWidget.cpp index b071673b3..e57dbe040 100644 --- a/retroshare-gui/src/gui/gxsforums/GxsForumThreadWidget.cpp +++ b/retroshare-gui/src/gui/gxsforums/GxsForumThreadWidget.cpp @@ -1444,7 +1444,7 @@ void GxsForumThreadWidget::async_msg_action(const MsgMethod &action) if(!rsGxsForums->getForumContent(groupId(),msgs_to_request,msgs)) { - std::cerr << __PRETTY_FUNCTION__ << " failed to retrieve forum group info for forum " << groupId() << std::endl; + std::cerr << __PRETTY_FUNCTION__ << " failed to retrieve forum message info for forum " << groupId() << " and thread " << mThreadId << std::endl; return; } @@ -1719,7 +1719,7 @@ void GxsForumThreadWidget::updateGroupData() // 2 - sort the messages into a proper hierarchy - RsGxsForumGroup *group = new RsGxsForumGroup(groups[0]); // we use a pointer in order to avoid group deletion while we're in the thread. + RsGxsForumGroup group(groups[0]); // we use a copy to share the object in order to avoid group deletion while we're in the thread. // 3 - update the model in the UI thread. @@ -1729,8 +1729,7 @@ void GxsForumThreadWidget::updateGroupData() * thread, for example to update the data model with new information * after a blocking call to RetroShare API complete */ - mForumGroup = *group; - delete group; + mForumGroup = group; ui->threadTreeWidget->setColumnHidden(RsGxsForumModel::COLUMN_THREAD_DISTRIBUTION, !IS_GROUP_PGP_KNOWN_AUTHED(mForumGroup.mMeta.mSignFlags) && !(IS_GROUP_PGP_AUTHED(mForumGroup.mMeta.mSignFlags))); ui->subscribeToolButton->setHidden(IS_GROUP_SUBSCRIBED(mForumGroup.mMeta.mSubscribeFlags)) ; @@ -1759,7 +1758,7 @@ void GxsForumThreadWidget::updateMessageData(const RsGxsMessageId& msgId) if(!rsGxsForums->getForumContent(groupId(),msgs_to_request,msgs)) { - std::cerr << __PRETTY_FUNCTION__ << " failed to retrieve forum group info for forum " << groupId() << std::endl; + std::cerr << __PRETTY_FUNCTION__ << " failed to retrieve message info for forum " << groupId() << " and MsgId " << msgId << std::endl; return; } @@ -1778,7 +1777,7 @@ void GxsForumThreadWidget::updateMessageData(const RsGxsMessageId& msgId) // 2 - sort the messages into a proper hierarchy - RsGxsForumMsg *msg = new RsGxsForumMsg(msgs[0]); + RsGxsForumMsg msg(msgs[0]); // 3 - update the model in the UI thread. @@ -1788,9 +1787,8 @@ void GxsForumThreadWidget::updateMessageData(const RsGxsMessageId& msgId) * thread, for example to update the data model with new information * after a blocking call to RetroShare API complete */ - insertMessageData(*msg); + insertMessageData(msg); - delete msg; ui->threadTreeWidget->setColumnHidden(RsGxsForumModel::COLUMN_THREAD_DISTRIBUTION, !IS_GROUP_PGP_KNOWN_AUTHED(mForumGroup.mMeta.mSignFlags) && !(IS_GROUP_PGP_AUTHED(mForumGroup.mMeta.mSignFlags))); ui->subscribeToolButton->setHidden(IS_GROUP_SUBSCRIBED(mForumGroup.mMeta.mSubscribeFlags)) ; }, this ); From 676ddfbfb5910128b2e65dffd1e48c4be1268050 Mon Sep 17 00:00:00 2001 From: csoler Date: Tue, 17 Mar 2020 23:33:03 +0100 Subject: [PATCH 02/15] removed waitToken from GxsTokenService since it was only used directly by rsGenExchange to export keys --- libretroshare/src/gxs/rsgenexchange.cc | 24 +++++++--- .../src/retroshare/rsgxsifacehelper.h | 47 ++++++++++++++++--- libretroshare/src/retroshare/rstokenservice.h | 6 ++- 3 files changed, 63 insertions(+), 14 deletions(-) diff --git a/libretroshare/src/gxs/rsgenexchange.cc b/libretroshare/src/gxs/rsgenexchange.cc index ff54d48a1..a6d995c26 100644 --- a/libretroshare/src/gxs/rsgenexchange.cc +++ b/libretroshare/src/gxs/rsgenexchange.cc @@ -3461,20 +3461,32 @@ bool RsGenExchange::exportGroupBase64( if(groupId.isNull()) return failure("groupId cannot be null"); + // We have no blocking API here, so we need to const std::list groupIds({groupId}); RsTokReqOptions opts; opts.mReqType = GXS_REQUEST_TYPE_GROUP_DATA; uint32_t token; - mDataAccess->requestGroupInfo( - token, RS_TOKREQ_ANSTYPE_DATA, opts, groupIds); - RsTokenService::GxsRequestStatus wtStatus = mDataAccess->waitToken(token); - if(wtStatus != RsTokenService::COMPLETE) - return failure( "waitToken(...) failed with: " + - std::to_string(wtStatus) ); + mDataAccess->requestGroupInfo( token, RS_TOKREQ_ANSTYPE_DATA, opts, groupIds); + + // provide a sync response: actually wait for the token. + std::chrono::milliseconds maxWait = std::chrono::milliseconds(10000); + std::chrono::milliseconds checkEvery = std::chrono::milliseconds(100); + + auto timeout = std::chrono::steady_clock::now() + maxWait; // wait for 10 secs at most + auto st = mDataAccess->requestStatus(token); + + while( !(st == RsTokenService::FAILED || st >= RsTokenService::COMPLETE) && std::chrono::steady_clock::now() < timeout ) + { + std::this_thread::sleep_for(checkEvery); + st = mDataAccess->requestStatus(token); + } + if(st != RsTokenService::COMPLETE) + return failure( "waitToken(...) failed with: " + std::to_string(st) ); uint8_t* buf = nullptr; uint32_t size; RsGxsGroupId grpId; + if(!getSerializedGroupData(token, grpId, buf, size)) return failure("failed retrieving GXS data"); diff --git a/libretroshare/src/retroshare/rsgxsifacehelper.h b/libretroshare/src/retroshare/rsgxsifacehelper.h index c04f13306..33015e1f0 100644 --- a/libretroshare/src/retroshare/rsgxsifacehelper.h +++ b/libretroshare/src/retroshare/rsgxsifacehelper.h @@ -390,20 +390,55 @@ protected: RsTokenService::GxsRequestStatus waitToken( uint32_t token, std::chrono::milliseconds maxWait = std::chrono::milliseconds(10000), - std::chrono::milliseconds checkEvery = std::chrono::milliseconds(20), + std::chrono::milliseconds checkEvery = std::chrono::milliseconds(100), bool auto_delete_if_unsuccessful=true) { - RsTokenService::GxsRequestStatus res = mTokenService.waitToken(token, maxWait, checkEvery); + #if defined(__ANDROID__) && (__ANDROID_API__ < 24) + auto wkStartime = std::chrono::steady_clock::now(); + int maxWorkAroundCnt = 10; +LLwaitTokenBeginLabel: +#endif + auto timeout = std::chrono::steady_clock::now() + maxWait; + auto st = requestStatus(token); - if(res != RsTokenService::COMPLETE && auto_delete_if_unsuccessful) + while( !(st == RsTokenService::FAILED || st >= RsTokenService::COMPLETE) && std::chrono::steady_clock::now() < timeout ) + { + std::this_thread::sleep_for(checkEvery); + st = requestStatus(token); + } + if(st != RsTokenService::COMPLETE && auto_delete_if_unsuccessful) cancelRequest(token); - else - { + +#if defined(__ANDROID__) && (__ANDROID_API__ < 24) + /* Work around for very slow/old android devices, we don't expect this + * to be necessary on newer devices. If it take unreasonably long + * something worser is already happening elsewere and we return anyway. + */ + if( st > RsTokenService::FAILED && st < RsTokenService::COMPLETE + && maxWorkAroundCnt-- > 0 ) + { + maxWait *= 10; + checkEvery *= 3; + Dbg3() << __PRETTY_FUNCTION__ << " Slow Android device " + << " workaround st: " << st + << " maxWorkAroundCnt: " << maxWorkAroundCnt + << " maxWait: " << maxWait.count() + << " checkEvery: " << checkEvery.count() << std::endl; + goto LLwaitTokenBeginLabel; + } + Dbg3() << __PRETTY_FUNCTION__ << " lasted: " + << std::chrono::duration_cast( + std::chrono::steady_clock::now() - wkStartime ).count() + << "ms" << std::endl; + +#endif + + { RS_STACK_MUTEX(mMtx); mActiveTokens.erase(token); } - return res; + return st; } private: diff --git a/libretroshare/src/retroshare/rstokenservice.h b/libretroshare/src/retroshare/rstokenservice.h index e48df29ad..7f801927f 100644 --- a/libretroshare/src/retroshare/rstokenservice.h +++ b/libretroshare/src/retroshare/rstokenservice.h @@ -222,6 +222,7 @@ public: */ virtual bool cancelRequest(const uint32_t &token) = 0; +#ifdef TO_REMOVE /** * Block caller while request is being processed. * Useful for blocking API implementation. @@ -231,8 +232,8 @@ public: */ RsTokenService::GxsRequestStatus waitToken( uint32_t token, - std::chrono::milliseconds maxWait = std::chrono::milliseconds(500), - std::chrono::milliseconds checkEvery = std::chrono::milliseconds(2), + std::chrono::milliseconds maxWait = std::chrono::milliseconds(10000), + std::chrono::milliseconds checkEvery = std::chrono::milliseconds(20), bool auto_delete_if_unsuccessful=true) { #if defined(__ANDROID__) && (__ANDROID_API__ < 24) @@ -276,6 +277,7 @@ LLwaitTokenBeginLabel: return st; } +#endif RS_SET_CONTEXT_DEBUG_LEVEL(2) }; From b6667a2c5a4d111c04a94c181c1381ef86ccb6d6 Mon Sep 17 00:00:00 2001 From: csoler Date: Wed, 18 Mar 2020 22:33:58 +0100 Subject: [PATCH 03/15] fixed bug causing RS to eat all the memory, slow down GxsId access and ultimately make forums and other Gxs services to not load properly --- libretroshare/src/gxs/rsgenexchange.cc | 2 +- libretroshare/src/services/p3idservice.cc | 28 +++++++++++++++++------ 2 files changed, 22 insertions(+), 8 deletions(-) diff --git a/libretroshare/src/gxs/rsgenexchange.cc b/libretroshare/src/gxs/rsgenexchange.cc index a6d995c26..c7c274fa4 100644 --- a/libretroshare/src/gxs/rsgenexchange.cc +++ b/libretroshare/src/gxs/rsgenexchange.cc @@ -3461,7 +3461,7 @@ bool RsGenExchange::exportGroupBase64( if(groupId.isNull()) return failure("groupId cannot be null"); - // We have no blocking API here, so we need to + // We have no blocking API here, so we need to make a blocking request manually. const std::list groupIds({groupId}); RsTokReqOptions opts; opts.mReqType = GXS_REQUEST_TYPE_GROUP_DATA; diff --git a/libretroshare/src/services/p3idservice.cc b/libretroshare/src/services/p3idservice.cc index 4d4d5ac5e..fe0cba89f 100644 --- a/libretroshare/src/services/p3idservice.cc +++ b/libretroshare/src/services/p3idservice.cc @@ -639,25 +639,28 @@ void p3IdService::notifyChanges(std::vector &changes) std::cerr << "p3IdService::notifyChanges() Auto Subscribe to Incoming Groups: " << *git; std::cerr << std::endl; #endif + if(!rsReputations->isIdentityBanned(RsGxsId(*git))) { - uint32_t token; - RsGenExchange::subscribeToGroup(token, *git, true); - - // also time_stamp the key that this group represents - - timeStampKey(RsGxsId(*git),RsIdentityUsage(serviceType(),RsIdentityUsage::IDENTITY_DATA_UPDATE)) ; - // notify that a new identity is received, if needed + bool should_subscribe = false; + switch(groupChange->getType()) { + case RsGxsNotify::TYPE_PROCESSED: break ; // Happens when the group is subscribed. This is triggered by RsGenExchange::subscribeToGroup, so better not + // call it again from here!! + case RsGxsNotify::TYPE_PUBLISHED: { auto ev = std::make_shared(); ev->mIdentityId = *git; ev->mIdentityEventCode = RsGxsIdentityEventCode::UPDATED_IDENTITY; rsEvents->postEvent(ev); + + // also time_stamp the key that this group represents + timeStampKey(RsGxsId(*git),RsIdentityUsage(serviceType(),RsIdentityUsage::IDENTITY_DATA_UPDATE)) ; + should_subscribe = true; } break; @@ -667,12 +670,23 @@ void p3IdService::notifyChanges(std::vector &changes) ev->mIdentityId = *git; ev->mIdentityEventCode = RsGxsIdentityEventCode::NEW_IDENTITY; rsEvents->postEvent(ev); + + // also time_stamp the key that this group represents + timeStampKey(RsGxsId(*git),RsIdentityUsage(serviceType(),RsIdentityUsage::IDENTITY_DATA_UPDATE)) ; + should_subscribe = true; } break; default: break; } + + if(should_subscribe) + { + uint32_t token; + RsGenExchange::subscribeToGroup(token, *git, true); + } + } } } From 1a9ac1654600b35bdd50e4b9b10add1af10f4245 Mon Sep 17 00:00:00 2001 From: csoler Date: Thu, 19 Mar 2020 21:20:52 +0100 Subject: [PATCH 04/15] fixed bug due to missing iterator increment --- libretroshare/src/retroshare/rsgxsifacehelper.h | 3 +++ 1 file changed, 3 insertions(+) diff --git a/libretroshare/src/retroshare/rsgxsifacehelper.h b/libretroshare/src/retroshare/rsgxsifacehelper.h index 33015e1f0..65cd356ed 100644 --- a/libretroshare/src/retroshare/rsgxsifacehelper.h +++ b/libretroshare/src/retroshare/rsgxsifacehelper.h @@ -358,6 +358,9 @@ public: mTokenService.cancelRequest(it->first); it = mActiveTokens.erase(it); } + else + ++it; + return true; } From 2387150f64bf2bcfc134d403e8824deb321a63ca Mon Sep 17 00:00:00 2001 From: csoler Date: Sat, 21 Mar 2020 15:25:34 +0100 Subject: [PATCH 05/15] 1/4 convertion of GxsGroupFrameDialog to blocking API --- libretroshare/src/gxs/rsdataservice.cc | 4 + libretroshare/src/gxs/rsgxsdataaccess.cc | 1 + libretroshare/src/retroshare/rsgxschannels.h | 3 +- libretroshare/src/retroshare/rsgxsforums.h | 5 +- .../src/retroshare/rsgxsifacetypes.h | 7 + libretroshare/src/retroshare/rsposted.h | 5 +- libretroshare/src/services/p3gxschannels.cc | 18 ++- libretroshare/src/services/p3gxsforums.cc | 17 ++- libretroshare/src/services/p3posted.cc | 10 ++ libretroshare/src/services/p3posted.h | 2 + .../src/gui/Posted/PostedDialog.cpp | 44 ++++-- retroshare-gui/src/gui/Posted/PostedDialog.h | 5 +- .../src/gui/gxs/GxsGroupFrameDialog.cpp | 133 +++++++++--------- .../src/gui/gxs/GxsGroupFrameDialog.h | 13 +- .../src/gui/gxschannels/GxsChannelDialog.cpp | 72 +++++++--- .../src/gui/gxschannels/GxsChannelDialog.h | 5 +- .../src/gui/gxsforums/GxsForumsDialog.cpp | 34 ++++- .../src/gui/gxsforums/GxsForumsDialog.h | 4 +- 18 files changed, 251 insertions(+), 131 deletions(-) diff --git a/libretroshare/src/gxs/rsdataservice.cc b/libretroshare/src/gxs/rsdataservice.cc index 2f2940541..ee546be06 100644 --- a/libretroshare/src/gxs/rsdataservice.cc +++ b/libretroshare/src/gxs/rsdataservice.cc @@ -25,6 +25,9 @@ * #define RS_DATA_SERVICE_DEBUG_TIME 1 * #define RS_DATA_SERVICE_DEBUG_CACHE 1 ****/ +#define RS_DATA_SERVICE_DEBUG 1 +#define RS_DATA_SERVICE_DEBUG_TIME 1 +#define RS_DATA_SERVICE_DEBUG_CACHE 1 #include #include @@ -1343,6 +1346,7 @@ int RsDataService::retrieveGxsMsgMetaData(const GxsMsgReq& reqIds, GxsMsgMetaRes } #ifdef RS_DATA_SERVICE_DEBUG_TIME + if(mDbName==std::string("gxsforums_db")) std::cerr << "RsDataService::retrieveGxsMsgMetaData() " << mDbName << ", Requests: " << reqIds.size() << ", Results: " << resultCount << ", Time: " << timer.duration() << std::endl; #endif diff --git a/libretroshare/src/gxs/rsgxsdataaccess.cc b/libretroshare/src/gxs/rsgxsdataaccess.cc index 59c828e60..0eeccba63 100644 --- a/libretroshare/src/gxs/rsgxsdataaccess.cc +++ b/libretroshare/src/gxs/rsgxsdataaccess.cc @@ -29,6 +29,7 @@ /*********** * #define DATA_DEBUG 1 **********/ +#define DATA_DEBUG 1 RsGxsDataAccess::RsGxsDataAccess(RsGeneralDataService* ds) : mDataStore(ds), mDataMutex("RsGxsDataAccess"), mNextToken(0) {} diff --git a/libretroshare/src/retroshare/rsgxschannels.h b/libretroshare/src/retroshare/rsgxschannels.h index 6f14552c2..f96f371f5 100644 --- a/libretroshare/src/retroshare/rsgxschannels.h +++ b/libretroshare/src/retroshare/rsgxschannels.h @@ -45,11 +45,10 @@ class RsGxsChannels; extern RsGxsChannels* rsGxsChannels; -struct RsGxsChannelGroup : RsSerializable +struct RsGxsChannelGroup : RsSerializable, RsGxsGenericGroupData { RsGxsChannelGroup() : mAutoDownload(false) {} - RsGroupMetaData mMeta; std::string mDescription; RsGxsImage mImage; diff --git a/libretroshare/src/retroshare/rsgxsforums.h b/libretroshare/src/retroshare/rsgxsforums.h index f9a54ebc4..319bcf2b8 100644 --- a/libretroshare/src/retroshare/rsgxsforums.h +++ b/libretroshare/src/retroshare/rsgxsforums.h @@ -54,11 +54,8 @@ static const uint32_t RS_GXS_FORUM_MSG_FLAGS_MODERATED = 0x00000001; #define IS_FORUM_MSG_MODERATION(flags) (flags & RS_GXS_FORUM_MSG_FLAGS_MODERATED) -struct RsGxsForumGroup : RsSerializable +struct RsGxsForumGroup : RsSerializable, RsGxsGenericGroupData { - /** Forum GXS metadata */ - RsGroupMetaData mMeta; - /** @brief Forum desciption */ std::string mDescription; diff --git a/libretroshare/src/retroshare/rsgxsifacetypes.h b/libretroshare/src/retroshare/rsgxsifacetypes.h index d0e6e0372..36b224c01 100644 --- a/libretroshare/src/retroshare/rsgxsifacetypes.h +++ b/libretroshare/src/retroshare/rsgxsifacetypes.h @@ -118,8 +118,15 @@ struct RsGroupMetaData : RsSerializable } }; +// This is the parent class of all interface-level GXS group data. Derived classes +// will include service-specific information, such as icon, description, etc +struct RsGxsGenericGroupData +{ + virtual ~RsGxsGenericGroupData() = default; // making the type polymorphic + RsGroupMetaData mMeta; +}; struct RsMsgMetaData : RsSerializable { diff --git a/libretroshare/src/retroshare/rsposted.h b/libretroshare/src/retroshare/rsposted.h index 474136466..5552496c0 100644 --- a/libretroshare/src/retroshare/rsposted.h +++ b/libretroshare/src/retroshare/rsposted.h @@ -40,9 +40,8 @@ class RsPosted; */ extern RsPosted* rsPosted; -struct RsPostedGroup +struct RsPostedGroup: RsGxsGenericGroupData { - RsGroupMetaData mMeta; std::string mDescription; RsGxsImage mGroupImage; }; @@ -150,6 +149,8 @@ public: const std::list& boardsIds, std::vector& boardsInfo ) = 0; + virtual bool getBoardsSummaries(std::list& groupInfo) =0; + virtual bool getBoardContent( const RsGxsGroupId& boardId, const std::set& contentsIds, diff --git a/libretroshare/src/services/p3gxschannels.cc b/libretroshare/src/services/p3gxschannels.cc index 2d141f57e..b58685e07 100644 --- a/libretroshare/src/services/p3gxschannels.cc +++ b/libretroshare/src/services/p3gxschannels.cc @@ -1033,15 +1033,23 @@ bool p3GxsChannels::getChannelsSummaries( return getGroupSummary(token, channels); } -bool p3GxsChannels::getChannelsInfo( - const std::list& chanIds, - std::vector& channelsInfo ) +bool p3GxsChannels::getChannelsInfo( const std::list& chanIds, std::vector& channelsInfo ) { uint32_t token; RsTokReqOptions opts; opts.mReqType = GXS_REQUEST_TYPE_GROUP_DATA; - if( !requestGroupInfo(token, opts, chanIds) - || waitToken(token) != RsTokenService::COMPLETE ) return false; + + if(chanIds.empty()) + { + if( !requestGroupInfo(token, opts) || waitToken(token) != RsTokenService::COMPLETE ) + return false; + } + else + { + if( !requestGroupInfo(token, opts, chanIds) || waitToken(token) != RsTokenService::COMPLETE ) + return false; + } + return getGroupData(token, channelsInfo) && !channelsInfo.empty(); } diff --git a/libretroshare/src/services/p3gxsforums.cc b/libretroshare/src/services/p3gxsforums.cc index 5a6b0e568..8d3db91c8 100644 --- a/libretroshare/src/services/p3gxsforums.cc +++ b/libretroshare/src/services/p3gxsforums.cc @@ -666,15 +666,22 @@ bool p3GxsForums::getForumsSummaries( std::list& forums ) return getGroupSummary(token, forums); } -bool p3GxsForums::getForumsInfo( - const std::list& forumIds, - std::vector& forumsInfo ) +bool p3GxsForums::getForumsInfo( const std::list& forumIds, std::vector& forumsInfo ) { uint32_t token; RsTokReqOptions opts; opts.mReqType = GXS_REQUEST_TYPE_GROUP_DATA; - if( !requestGroupInfo(token, opts, forumIds) - || waitToken(token,std::chrono::milliseconds(5000)) != RsTokenService::COMPLETE ) return false; + + if(forumIds.empty()) + { + if( !requestGroupInfo(token, opts) || waitToken(token,std::chrono::milliseconds(5000)) != RsTokenService::COMPLETE ) + return false; + } + else + { + if( !requestGroupInfo(token, opts, forumIds) || waitToken(token,std::chrono::milliseconds(5000)) != RsTokenService::COMPLETE ) + return false; + } return getGroupData(token, forumsInfo); } diff --git a/libretroshare/src/services/p3posted.cc b/libretroshare/src/services/p3posted.cc index 006127918..9afb9c417 100644 --- a/libretroshare/src/services/p3posted.cc +++ b/libretroshare/src/services/p3posted.cc @@ -330,5 +330,15 @@ bool p3Posted::getBoardContent( const RsGxsGroupId& groupId, return getPostData(token, posts, comments); } +bool p3Posted::getBoardsSummaries(std::list& boards ) +{ + uint32_t token; + RsTokReqOptions opts; + opts.mReqType = GXS_REQUEST_TYPE_GROUP_META; + if( !requestGroupInfo(token, opts) || waitToken(token) != RsTokenService::COMPLETE ) return false; + + return getGroupSummary(token, boards); +} + RsPosted::~RsPosted() = default; RsGxsPostedEvent::~RsGxsPostedEvent() = default; diff --git a/libretroshare/src/services/p3posted.h b/libretroshare/src/services/p3posted.h index a0802722c..b2accf2ba 100644 --- a/libretroshare/src/services/p3posted.h +++ b/libretroshare/src/services/p3posted.h @@ -66,6 +66,8 @@ virtual void receiveHelperChanges(std::vector& changes) std::vector& posts, std::vector& comments ) override; + bool getBoardsSummaries(std::list& groupInfo) override; + virtual bool getGroupData(const uint32_t &token, std::vector &groups); virtual bool getPostData(const uint32_t &token, std::vector &posts, std::vector &cmts); virtual bool getPostData(const uint32_t &token, std::vector &posts) { std::vector cmts; return getPostData( token, posts, cmts);} diff --git a/retroshare-gui/src/gui/Posted/PostedDialog.cpp b/retroshare-gui/src/gui/Posted/PostedDialog.cpp index 9d51613f5..722348ebe 100644 --- a/retroshare-gui/src/gui/Posted/PostedDialog.cpp +++ b/retroshare-gui/src/gui/Posted/PostedDialog.cpp @@ -150,6 +150,21 @@ QString PostedDialog::icon(IconType type) return ""; } +bool PostedDialog::getGroupData(std::list& groupInfo) +{ + std::vector groups; + + // request all group infos at once + + if(! rsPosted->getBoardsInfo(std::list(),groups)) + return false; + + /* Save groups to fill icons and description */ + + for (auto& group: groups) + groupInfo.push_back(new RsPostedGroup(group)); +} + GxsGroupDialog *PostedDialog::createNewGroupDialog(TokenQueue *tokenQueue) { return new PostedGroupDialog(tokenQueue, this); @@ -180,6 +195,7 @@ QWidget *PostedDialog::createCommentHeaderWidget(const RsGxsGroupId &grpId, cons return new PostedItem(NULL, 0, grpId, msgId, true, false); } +#ifdef TO_REMOVE void PostedDialog::loadGroupSummaryToken(const uint32_t &token, std::list &groupInfo, RsUserdata *&userdata) { std::vector groups; @@ -205,25 +221,23 @@ void PostedDialog::loadGroupSummaryToken(const uint32_t &token, std::list(userdata); - if (!postedData) { - std::cerr << "PostedDialog::groupInfoToGroupItemInfo() Failed to cast data to PostedGroupInfoData"; - std::cerr << std::endl; + const RsPostedGroup *postedGroupData = dynamic_cast(groupData); + + if (!postedGroupData) + { + std::cerr << "PostedDialog::groupInfoToGroupItemInfo() Failed to cast data to RsPostedGroup"<< std::endl; return; } - QMap::const_iterator descriptionIt = postedData->mDescription.find(groupInfo.mGroupId); - if (descriptionIt != postedData->mDescription.end()) { - groupItemInfo.description = descriptionIt.value(); - } - - QMap::const_iterator iconIt = postedData->mIcon.find(groupInfo.mGroupId); - if (iconIt != postedData->mIcon.end()) { - groupItemInfo.icon = iconIt.value(); - } + QPixmap image; + GxsIdDetails::loadPixmapFromData(postedGroupData->mGroupImage.mData, postedGroupData->mGroupImage.mSize, image,GxsIdDetails::ORIGINAL); + + groupItemInfo.description = QString::fromUtf8(postedGroupData->mDescription.c_str()); + groupItemInfo.icon = image; } diff --git a/retroshare-gui/src/gui/Posted/PostedDialog.h b/retroshare-gui/src/gui/Posted/PostedDialog.h index 6a4d79479..17a679993 100644 --- a/retroshare-gui/src/gui/Posted/PostedDialog.h +++ b/retroshare-gui/src/gui/Posted/PostedDialog.h @@ -45,7 +45,9 @@ protected: virtual QString getHelpString() const ; virtual RetroShareLink::enumType getLinkType() { return RetroShareLink::TYPE_POSTED; } virtual GroupFrameSettings::Type groupFrameSettingsType() { return GroupFrameSettings::Posted; } - virtual void groupInfoToGroupItemInfo(const RsGroupMetaData &groupInfo, GroupItemInfo &groupItemInfo, const RsUserdata *userdata); + + void groupInfoToGroupItemInfo(const RsGxsGenericGroupData *groupData, GroupItemInfo &groupItemInfo) override; + bool getGroupData(std::list& groupInfo) override; private: /* GxsGroupFrameDialog */ @@ -59,7 +61,6 @@ private: virtual RsGxsCommentService *getCommentService(); virtual QWidget *createCommentHeaderWidget(const RsGxsGroupId &grpId, const RsGxsMessageId &msgId); virtual uint32_t requestGroupSummaryType() { return GXS_REQUEST_TYPE_GROUP_DATA; } // request complete group data - virtual void loadGroupSummaryToken(const uint32_t &token, std::list &groupInfo, RsUserdata* &userdata); void handleEvent_main_thread(std::shared_ptr event); RsEventsHandlerId_t mEventHandlerId; diff --git a/retroshare-gui/src/gui/gxs/GxsGroupFrameDialog.cpp b/retroshare-gui/src/gui/gxs/GxsGroupFrameDialog.cpp index 65e07087f..ef84d9ce9 100644 --- a/retroshare-gui/src/gui/gxs/GxsGroupFrameDialog.cpp +++ b/retroshare-gui/src/gui/gxs/GxsGroupFrameDialog.cpp @@ -33,6 +33,8 @@ #include "gui/notifyqt.h" #include "gui/common/UIStateHelper.h" #include "gui/common/UserNotify.h" +#include "util/qtthreadsutils.h" +#include "retroshare/rsgxsifacetypes.h" #include "GxsCommentDialog.h" //#define DEBUG_GROUPFRAMEDIALOG @@ -134,7 +136,7 @@ void GxsGroupFrameDialog::getGroupList(std::map & group_list = mCachedGroupMetas ; if(group_list.empty()) - requestGroupSummary(); + updateGroupSummary(); } void GxsGroupFrameDialog::initUi() { @@ -242,7 +244,7 @@ void GxsGroupFrameDialog::setHideTabBarWithOneTab(bool hideTabBarWithOneTab) void GxsGroupFrameDialog::updateDisplay(bool complete) { if(complete) // || !getGrpIds().empty() || !getGrpIdsMeta().empty()) { - requestGroupSummary(); /* Update group list */ + updateGroupSummary(); /* Update group list */ updateSearchResults() ; } @@ -896,16 +898,16 @@ void GxsGroupFrameDialog::messageTabWaitingChanged(QWidget *widget) } ///***** INSERT GROUP LISTS *****/ -void GxsGroupFrameDialog::groupInfoToGroupItemInfo(const RsGroupMetaData &groupInfo, GroupItemInfo &groupItemInfo, const RsUserdata */*userdata*/) +void GxsGroupFrameDialog::groupInfoToGroupItemInfo(const RsGxsGenericGroupData *groupInfo, GroupItemInfo &groupItemInfo) { - groupItemInfo.id = QString::fromStdString(groupInfo.mGroupId.toStdString()); - groupItemInfo.name = QString::fromUtf8(groupInfo.mGroupName.c_str()); - groupItemInfo.popularity = groupInfo.mPop; - groupItemInfo.lastpost = QDateTime::fromTime_t(groupInfo.mLastPost); - groupItemInfo.subscribeFlags = groupInfo.mSubscribeFlags; - groupItemInfo.publishKey = IS_GROUP_PUBLISHER(groupInfo.mSubscribeFlags) ; - groupItemInfo.adminKey = IS_GROUP_ADMIN(groupInfo.mSubscribeFlags) ; - groupItemInfo.max_visible_posts = groupInfo.mVisibleMsgCount ; + groupItemInfo.id = QString::fromStdString(groupInfo->mMeta.mGroupId.toStdString()); + groupItemInfo.name = QString::fromUtf8(groupInfo->mMeta.mGroupName.c_str()); + groupItemInfo.popularity = groupInfo->mMeta.mPop; + groupItemInfo.lastpost = QDateTime::fromTime_t(groupInfo->mMeta.mLastPost); + groupItemInfo.subscribeFlags = groupInfo->mMeta.mSubscribeFlags; + groupItemInfo.publishKey = IS_GROUP_PUBLISHER(groupInfo->mMeta.mSubscribeFlags) ; + groupItemInfo.adminKey = IS_GROUP_ADMIN(groupInfo->mMeta.mSubscribeFlags) ; + groupItemInfo.max_visible_posts = groupInfo->mMeta.mVisibleMsgCount ; #if TOGXS if (groupInfo.mGroupFlags & RS_DISTRIB_AUTHEN_REQ) { @@ -919,7 +921,7 @@ void GxsGroupFrameDialog::groupInfoToGroupItemInfo(const RsGroupMetaData &groupI } } -void GxsGroupFrameDialog::insertGroupsData(const std::map &groupList, const RsUserdata *userdata) +void GxsGroupFrameDialog::insertGroupsData(const std::list& groupList) { if (!mInitialized) { return; @@ -933,54 +935,38 @@ void GxsGroupFrameDialog::insertGroupsData(const std::map otherList; std::multimap popMap; - for (auto it = groupList.begin(); it != groupList.end(); ++it) { + for (auto& g:groupList) + { /* sort it into Publish (Own), Subscribed, Popular and Other */ - uint32_t flags = it->second.mSubscribeFlags; + uint32_t flags = g->mMeta.mSubscribeFlags; GroupItemInfo groupItemInfo; - groupInfoToGroupItemInfo(it->second, groupItemInfo, userdata); + groupInfoToGroupItemInfo(g, groupItemInfo); if (IS_GROUP_SUBSCRIBED(flags)) { if (IS_GROUP_ADMIN(flags)) - { adminList.push_back(groupItemInfo); - } else - { - /* subscribed group */ - subList.push_back(groupItemInfo); - } + subList.push_back(groupItemInfo); /* subscribed group */ } else - { - //popMap.insert(std::make_pair(it->mPop, groupItemInfo)); /* rate the others by popularity */ - popMap.insert(std::make_pair(it->second.mLastPost, groupItemInfo)); /* rate the others by time of last post */ - } + popMap.insert(std::make_pair(g->mMeta.mLastPost, groupItemInfo)); /* rate the others by time of last post */ } /* iterate backwards through popMap - take the top 5 or 10% of list */ uint32_t popCount = 5; if (popCount < popMap.size() / 10) - { popCount = popMap.size() / 10; - } uint32_t i = 0; std::multimap::reverse_iterator rit; - //uint32_t popLimit = 0; - //for(rit = popMap.rbegin(); ((rit != popMap.rend()) && (i < popCount)); ++rit, ++i) ; - //if (rit != popMap.rend()) { - // popLimit = rit->first; - //} - for (rit = popMap.rbegin(); rit != popMap.rend(); ++rit,++i) { - //if (rit->second.popularity > (int) popLimit) { + for (rit = popMap.rbegin(); rit != popMap.rend(); ++rit,++i) if(i < popCount) popList.append(rit->second); else otherList.append(rit->second); - } /* now we can add them in as a tree! */ ui->groupTreeWidget->fillGroupItems(mYourGroups, adminList); @@ -995,9 +981,8 @@ void GxsGroupFrameDialog::insertGroupsData(const std::mapgroupTreeWidget->activateId(QString::fromStdString(mGroupId.toStdString()), true)) { + if (!ui->groupTreeWidget->activateId(QString::fromStdString(mGroupId.toStdString()), true)) mGroupId.clear(); - } updateMessageSummaryList(RsGxsGroupId()); } @@ -1032,6 +1017,48 @@ void GxsGroupFrameDialog::updateMessageSummaryList(RsGxsGroupId groupId) /** Request / Response of Data ********************************/ /*********************** **** **** **** ***********************/ +void GxsGroupFrameDialog::updateGroupSummary() +{ + RsThread::async([this]() + { + std::list groupInfo; + + if(!getGroupData(groupInfo)) + { + std::cerr << __PRETTY_FUNCTION__ << " failed to collect group info " << std::endl; + return; + } + + RsQThreadUtils::postToObject( [this,groupInfo]() + { + /* Here it goes any code you want to be executed on the Qt Gui + * thread, for example to update the data model with new information + * after a blocking call to RetroShare API complete, note that + * Qt::QueuedConnection is important! + */ + + insertGroupsData(groupInfo); + updateSearchResults(); + + mStateHelper->setLoading(TOKEN_TYPE_GROUP_SUMMARY, false); + + if (!mNavigatePendingGroupId.isNull()) { + /* Navigate pending */ + navigate(mNavigatePendingGroupId, mNavigatePendingMsgId); + + mNavigatePendingGroupId.clear(); + mNavigatePendingMsgId.clear(); + } + // now delete the data that is not used anymore + + for(auto& g:groupInfo) + delete g; + + }, this ); + }); +} + +#ifdef TO_REMOVE void GxsGroupFrameDialog::requestGroupSummary() { mStateHelper->setLoading(TOKEN_TYPE_GROUP_SUMMARY, true); @@ -1056,37 +1083,14 @@ void GxsGroupFrameDialog::loadGroupSummaryToken(const uint32_t &token, std::list mInterface->getGroupSummary(token, groupInfo); } -void GxsGroupFrameDialog::loadGroupSummary(const uint32_t &token) +void GxsGroupFrameDialog::loadGroupSummary(const std::list& groupInfo) { #ifdef DEBUG_GROUPFRAMEDIALOG std::cerr << "GxsGroupFrameDialog::loadGroupSummary()"; std::cerr << std::endl; #endif - std::list groupInfo; - RsUserdata *userdata = NULL; - loadGroupSummaryToken(token, groupInfo, userdata); - mCachedGroupMetas.clear(); - for(auto it(groupInfo.begin());it!=groupInfo.end();++it) - mCachedGroupMetas[(*it).mGroupId] = *it; - - insertGroupsData(mCachedGroupMetas, userdata); - updateSearchResults(); - - mStateHelper->setLoading(TOKEN_TYPE_GROUP_SUMMARY, false); - - if (userdata) { - delete(userdata); - } - - if (!mNavigatePendingGroupId.isNull()) { - /* Navigate pending */ - navigate(mNavigatePendingGroupId, mNavigatePendingMsgId); - - mNavigatePendingGroupId.clear(); - mNavigatePendingMsgId.clear(); - } } /*********************** **** **** **** ***********************/ @@ -1145,6 +1149,7 @@ void GxsGroupFrameDialog::loadGroupSummary(const uint32_t &token) // setValid(true); //} +#endif /*********************** **** **** **** ***********************/ /*********************** **** **** **** ***********************/ @@ -1186,9 +1191,9 @@ void GxsGroupFrameDialog::loadRequest(const TokenQueue *queue, const TokenReques /* now switch on req */ switch(req.mUserType) { - case TOKEN_TYPE_GROUP_SUMMARY: - loadGroupSummary(req.mToken); - break; +// case TOKEN_TYPE_GROUP_SUMMARY: +// loadGroupSummary(req.mToken); +// break; // case TOKEN_TYPE_SUBSCRIBE_CHANGE: // acknowledgeSubscribeChange(req.mToken); diff --git a/retroshare-gui/src/gui/gxs/GxsGroupFrameDialog.h b/retroshare-gui/src/gui/gxs/GxsGroupFrameDialog.h index 86cf3252a..61bca3a9f 100644 --- a/retroshare-gui/src/gui/gxs/GxsGroupFrameDialog.h +++ b/retroshare-gui/src/gui/gxs/GxsGroupFrameDialog.h @@ -93,12 +93,14 @@ protected: bool getCurrentGroupName(QString& name); virtual RetroShareLink::enumType getLinkType() = 0; virtual GroupFrameSettings::Type groupFrameSettingsType() { return GroupFrameSettings::Nothing; } - virtual void groupInfoToGroupItemInfo(const RsGroupMetaData &groupInfo, GroupItemInfo &groupItemInfo, const RsUserdata *userdata); + virtual void groupInfoToGroupItemInfo(const RsGxsGenericGroupData *groupInfo, GroupItemInfo &groupItemInfo); virtual void checkRequestGroup(const RsGxsGroupId& /* grpId */) {} // overload this one in order to retrieve full group data when the group is browsed void updateMessageSummaryList(RsGxsGroupId groupId); virtual const std::set getSearchRequests() const { return std::set(); } // overload this for subclasses that provide distant search + + virtual bool getGroupData(std::list& groupInfo) =0; private slots: void todo(); @@ -162,12 +164,13 @@ private: void processSettings(bool load); // New Request/Response Loading Functions. - void insertGroupsData(const std::map &groupList, const RsUserdata *userdata); + void insertGroupsData(const std::list &groupList); + + //void requestGroupSummary(); + void updateGroupSummary(); + void loadGroupSummary(const std::list &groupInfo); - void requestGroupSummary(); - void loadGroupSummary(const uint32_t &token); virtual uint32_t requestGroupSummaryType() { return GXS_REQUEST_TYPE_GROUP_META; } // request only meta data - virtual void loadGroupSummaryToken(const uint32_t &token, std::list &groupInfo, RsUserdata* &userdata); // use with requestGroupSummaryType void requestGroupStatistics(const RsGxsGroupId &groupId); void loadGroupStatistics(const uint32_t &token); diff --git a/retroshare-gui/src/gui/gxschannels/GxsChannelDialog.cpp b/retroshare-gui/src/gui/gxschannels/GxsChannelDialog.cpp index 2e9ba897b..fe83d60b5 100644 --- a/retroshare-gui/src/gui/gxschannels/GxsChannelDialog.cpp +++ b/retroshare-gui/src/gui/gxschannels/GxsChannelDialog.cpp @@ -36,15 +36,15 @@ #include "gui/common/GroupTreeWidget.h" #include "util/qtthreadsutils.h" -class GxsChannelGroupInfoData : public RsUserdata -{ -public: - GxsChannelGroupInfoData() : RsUserdata() {} - -public: - QMap mIcon; - QMap mDescription; -}; +// class GxsChannelGroupInfoData : public RsUserdata +// { +// public: +// GxsChannelGroupInfoData() : RsUserdata() {} +// +// public: +// QMap mIcon; +// QMap mDescription; +// }; /** Constructor */ GxsChannelDialog::GxsChannelDialog(QWidget *parent) @@ -344,6 +344,34 @@ void GxsChannelDialog::toggleAutoDownload() }); } +bool GxsChannelDialog::getGroupData(std::list& groupInfo) +{ + std::vector groups; + + // request all group infos at once + + if(! rsGxsChannels->getChannelsInfo(std::list(),groups)) + return false; + + /* Save groups to fill icons and description */ + + for (auto& group: groups) + groupInfo.push_back(new RsGxsChannelGroup(group)); + +// if (group.mImage.mData != NULL) { +// QPixmap image; +// GxsIdDetails::loadPixmapFromData(group.mImage.mData, group.mImage.mSize, image,GxsIdDetails::ORIGINAL); +// channelData->mIcon[group.mMeta.mGroupId] = image; +// } +// +// if (!group.mDescription.empty()) { +// channelData->mDescription[group.mMeta.mGroupId] = QString::fromUtf8(group.mDescription.c_str()); +// } + + return true; +} + +#ifdef TO_REMOVE void GxsChannelDialog::loadGroupSummaryToken(const uint32_t &token, std::list &groupInfo, RsUserdata *&userdata) { std::vector groups; @@ -369,27 +397,25 @@ void GxsChannelDialog::loadGroupSummaryToken(const uint32_t &token, std::list(userdata); - if (!channelData) { - std::cerr << "GxsChannelDialog::groupInfoToGroupItemInfo() Failed to cast data to GxsChannelGroupInfoData"; - std::cerr << std::endl; + const RsGxsChannelGroup *channelGroupData = dynamic_cast(groupData); + + if (!channelGroupData) + { + std::cerr << "GxsChannelDialog::groupInfoToGroupItemInfo() Failed to cast data to GxsChannelGroupInfoData"<< std::endl; return; } - QMap::const_iterator descriptionIt = channelData->mDescription.find(groupInfo.mGroupId); - if (descriptionIt != channelData->mDescription.end()) { - groupItemInfo.description = descriptionIt.value(); - } + QPixmap image; + GxsIdDetails::loadPixmapFromData(channelGroupData->mImage.mData, channelGroupData->mImage.mSize, image,GxsIdDetails::ORIGINAL); - QMap::const_iterator iconIt = channelData->mIcon.find(groupInfo.mGroupId); - if (iconIt != channelData->mIcon.end()) { - groupItemInfo.icon = iconIt.value(); - } + groupItemInfo.description = QString::fromUtf8(channelGroupData->mDescription.c_str()); + groupItemInfo.icon = image; } TurtleRequestId GxsChannelDialog::distantSearch(const QString& search_string) diff --git a/retroshare-gui/src/gui/gxschannels/GxsChannelDialog.h b/retroshare-gui/src/gui/gxschannels/GxsChannelDialog.h index 9413b3057..89df4287d 100644 --- a/retroshare-gui/src/gui/gxschannels/GxsChannelDialog.h +++ b/retroshare-gui/src/gui/gxschannels/GxsChannelDialog.h @@ -46,7 +46,7 @@ protected: virtual RetroShareLink::enumType getLinkType() { return RetroShareLink::TYPE_CHANNEL; } virtual GroupFrameSettings::Type groupFrameSettingsType() { return GroupFrameSettings::Channel; } virtual QString getHelpString() const ; - virtual void groupInfoToGroupItemInfo(const RsGroupMetaData &groupInfo, GroupItemInfo &groupItemInfo, const RsUserdata *userdata); + virtual void groupInfoToGroupItemInfo(const RsGxsGenericGroupData *groupData, GroupItemInfo &groupItemInfo); virtual bool getDistantSearchResults(TurtleRequestId id, std::map& group_infos); virtual const std::set getSearchRequests() const override { return mSearchResults ; } @@ -73,7 +73,8 @@ private: virtual RsGxsCommentService *getCommentService(); virtual QWidget *createCommentHeaderWidget(const RsGxsGroupId &grpId, const RsGxsMessageId &msgId); virtual uint32_t requestGroupSummaryType() { return GXS_REQUEST_TYPE_GROUP_DATA; } // request complete group data - virtual void loadGroupSummaryToken(const uint32_t &token, std::list &groupInfo, RsUserdata* &userdata); + + bool getGroupData(std::list& groupInfo) override; void handleEvent_main_thread(std::shared_ptr event); diff --git a/retroshare-gui/src/gui/gxsforums/GxsForumsDialog.cpp b/retroshare-gui/src/gui/gxsforums/GxsForumsDialog.cpp index e4c14ae83..a647d071c 100644 --- a/retroshare-gui/src/gui/gxsforums/GxsForumsDialog.cpp +++ b/retroshare-gui/src/gui/gxsforums/GxsForumsDialog.cpp @@ -80,6 +80,18 @@ GxsForumsDialog::~GxsForumsDialog() rsEvents->unregisterEventsHandler(mEventHandlerId); } +bool GxsForumsDialog::getGroupData(std::list& groupInfo) +{ + std::vector groups; + + if(! rsGxsForums->getForumsInfo(std::list(),groups)) + return false; + + for (auto& group: groups) + groupInfo.push_back(new RsGxsForumGroup(group)); +} + + QString GxsForumsDialog::getHelpString() const { QString hlp_str = tr( @@ -207,7 +219,26 @@ void GxsForumsDialog::loadGroupSummaryToken(const uint32_t &token, std::list(groupData); + + if (!forumGroupData) + { + std::cerr << "GxsChannelDialog::groupInfoToGroupItemInfo() Failed to cast data to GxsChannelGroupInfoData"<< std::endl; + return; + } + + groupItemInfo.description = QString::fromUtf8(forumGroupData->mDescription.c_str()); + + if ((IS_GROUP_PGP_AUTHED(groupData->mMeta.mSignFlags)) || (IS_GROUP_MESSAGE_TRACKING(groupData->mMeta.mSignFlags)) ) + groupItemInfo.icon = QIcon(":icons/png/forums-signed.png"); +} + +#ifdef TO_REMOVE +void ::groupInfoToGroupItemInfo(const RsGroupMetaData &groupInfo, GroupItemInfo &groupItemInfo, const RsUserdata *userdata) { GxsGroupFrameDialog::groupInfoToGroupItemInfo(groupInfo, groupItemInfo, userdata); @@ -229,3 +260,4 @@ void GxsForumsDialog::groupInfoToGroupItemInfo(const RsGroupMetaData &groupInfo, groupItemInfo.icon = QIcon(":icons/png/forums-signed.png"); } +#endif diff --git a/retroshare-gui/src/gui/gxsforums/GxsForumsDialog.h b/retroshare-gui/src/gui/gxsforums/GxsForumsDialog.h index 9b6da9d00..cbf6f1af7 100644 --- a/retroshare-gui/src/gui/gxsforums/GxsForumsDialog.h +++ b/retroshare-gui/src/gui/gxsforums/GxsForumsDialog.h @@ -45,7 +45,9 @@ protected: virtual QString getHelpString() const ; virtual RetroShareLink::enumType getLinkType() { return RetroShareLink::TYPE_FORUM; } virtual GroupFrameSettings::Type groupFrameSettingsType() { return GroupFrameSettings::Forum; } - virtual void groupInfoToGroupItemInfo(const RsGroupMetaData &groupInfo, GroupItemInfo &groupItemInfo, const RsUserdata *userdata); + + void groupInfoToGroupItemInfo(const RsGxsGenericGroupData *groupData, GroupItemInfo &groupItemInfo) override; + bool getGroupData(std::list& groupInfo) override; private: /* GxsGroupFrameDialog */ From b8ec91aac564e8212bb983c01308992787c8c23b Mon Sep 17 00:00:00 2001 From: csoler Date: Sat, 21 Mar 2020 15:46:52 +0100 Subject: [PATCH 06/15] fixed missing returns --- libretroshare/src/services/p3posted.cc | 14 ++++++++++++-- retroshare-gui/src/gui/Posted/PostedDialog.cpp | 2 ++ .../src/gui/gxschannels/GxsChannelDialog.cpp | 10 ---------- .../src/gui/gxschannels/GxsChannelDialog.h | 10 +++++----- .../src/gui/gxsforums/GxsForumsDialog.cpp | 4 ++++ retroshare-gui/src/gui/gxsforums/GxsForumsDialog.h | 6 ++---- 6 files changed, 25 insertions(+), 21 deletions(-) diff --git a/libretroshare/src/services/p3posted.cc b/libretroshare/src/services/p3posted.cc index 9afb9c417..e040aa8eb 100644 --- a/libretroshare/src/services/p3posted.cc +++ b/libretroshare/src/services/p3posted.cc @@ -307,8 +307,18 @@ bool p3Posted::getBoardsInfo( uint32_t token; RsTokReqOptions opts; opts.mReqType = GXS_REQUEST_TYPE_GROUP_DATA; - if( !requestGroupInfo(token, opts, boardsIds) - || waitToken(token) != RsTokenService::COMPLETE ) return false; + + if(boardsIds.empty()) + { + if( !requestGroupInfo(token, opts) || waitToken(token) != RsTokenService::COMPLETE ) + return false; + } + else + { + if( !requestGroupInfo(token, opts, boardsIds) || waitToken(token) != RsTokenService::COMPLETE ) + return false; + } + return getGroupData(token, groupsInfo) && !groupsInfo.empty(); } diff --git a/retroshare-gui/src/gui/Posted/PostedDialog.cpp b/retroshare-gui/src/gui/Posted/PostedDialog.cpp index 722348ebe..17003c317 100644 --- a/retroshare-gui/src/gui/Posted/PostedDialog.cpp +++ b/retroshare-gui/src/gui/Posted/PostedDialog.cpp @@ -163,6 +163,8 @@ bool PostedDialog::getGroupData(std::list& groupInfo) for (auto& group: groups) groupInfo.push_back(new RsPostedGroup(group)); + + return true; } GxsGroupDialog *PostedDialog::createNewGroupDialog(TokenQueue *tokenQueue) diff --git a/retroshare-gui/src/gui/gxschannels/GxsChannelDialog.cpp b/retroshare-gui/src/gui/gxschannels/GxsChannelDialog.cpp index fe83d60b5..a24573f16 100644 --- a/retroshare-gui/src/gui/gxschannels/GxsChannelDialog.cpp +++ b/retroshare-gui/src/gui/gxschannels/GxsChannelDialog.cpp @@ -358,16 +358,6 @@ bool GxsChannelDialog::getGroupData(std::list& groupInfo for (auto& group: groups) groupInfo.push_back(new RsGxsChannelGroup(group)); -// if (group.mImage.mData != NULL) { -// QPixmap image; -// GxsIdDetails::loadPixmapFromData(group.mImage.mData, group.mImage.mSize, image,GxsIdDetails::ORIGINAL); -// channelData->mIcon[group.mMeta.mGroupId] = image; -// } -// -// if (!group.mDescription.empty()) { -// channelData->mDescription[group.mMeta.mGroupId] = QString::fromUtf8(group.mDescription.c_str()); -// } - return true; } diff --git a/retroshare-gui/src/gui/gxschannels/GxsChannelDialog.h b/retroshare-gui/src/gui/gxschannels/GxsChannelDialog.h index 89df4287d..c4233c428 100644 --- a/retroshare-gui/src/gui/gxschannels/GxsChannelDialog.h +++ b/retroshare-gui/src/gui/gxschannels/GxsChannelDialog.h @@ -46,14 +46,16 @@ protected: virtual RetroShareLink::enumType getLinkType() { return RetroShareLink::TYPE_CHANNEL; } virtual GroupFrameSettings::Type groupFrameSettingsType() { return GroupFrameSettings::Channel; } virtual QString getHelpString() const ; - virtual void groupInfoToGroupItemInfo(const RsGxsGenericGroupData *groupData, GroupItemInfo &groupItemInfo); virtual bool getDistantSearchResults(TurtleRequestId id, std::map& group_infos); - virtual const std::set getSearchRequests() const override { return mSearchResults ; } virtual TurtleRequestId distantSearch(const QString& search_string) ; virtual void checkRequestGroup(const RsGxsGroupId& grpId) ; - virtual UserNotify *createUserNotify(QObject *parent) override; + const std::set getSearchRequests() const override { return mSearchResults ; } + UserNotify *createUserNotify(QObject *parent) override; + bool getGroupData(std::list& groupInfo) override; + void groupInfoToGroupItemInfo(const RsGxsGenericGroupData *groupData, GroupItemInfo &groupItemInfo) override; + private slots: void toggleAutoDownload(); void setDefaultDirectory(); @@ -74,8 +76,6 @@ private: virtual QWidget *createCommentHeaderWidget(const RsGxsGroupId &grpId, const RsGxsMessageId &msgId); virtual uint32_t requestGroupSummaryType() { return GXS_REQUEST_TYPE_GROUP_DATA; } // request complete group data - bool getGroupData(std::list& groupInfo) override; - void handleEvent_main_thread(std::shared_ptr event); std::set mSearchResults; diff --git a/retroshare-gui/src/gui/gxsforums/GxsForumsDialog.cpp b/retroshare-gui/src/gui/gxsforums/GxsForumsDialog.cpp index a647d071c..e2e5defba 100644 --- a/retroshare-gui/src/gui/gxsforums/GxsForumsDialog.cpp +++ b/retroshare-gui/src/gui/gxsforums/GxsForumsDialog.cpp @@ -89,6 +89,8 @@ bool GxsForumsDialog::getGroupData(std::list& groupInfo) for (auto& group: groups) groupInfo.push_back(new RsGxsForumGroup(group)); + + return true; } @@ -199,6 +201,7 @@ GxsMessageFrameWidget *GxsForumsDialog::createMessageFrameWidget(const RsGxsGrou return new GxsForumThreadWidget(groupId); } +#ifdef TO_REMOVE void GxsForumsDialog::loadGroupSummaryToken(const uint32_t &token, std::list &groupInfo, RsUserdata *&userdata) { std::vector groups; @@ -218,6 +221,7 @@ void GxsForumsDialog::loadGroupSummaryToken(const uint32_t &token, std::list& file_link) ; protected: - virtual UserNotify *createUserNotify(QObject *parent) override; - virtual QString getHelpString() const ; virtual RetroShareLink::enumType getLinkType() { return RetroShareLink::TYPE_FORUM; } virtual GroupFrameSettings::Type groupFrameSettingsType() { return GroupFrameSettings::Forum; } - void groupInfoToGroupItemInfo(const RsGxsGenericGroupData *groupData, GroupItemInfo &groupItemInfo) override; + UserNotify *createUserNotify(QObject *parent) override; bool getGroupData(std::list& groupInfo) override; + void groupInfoToGroupItemInfo(const RsGxsGenericGroupData *groupData, GroupItemInfo &groupItemInfo) override; private: /* GxsGroupFrameDialog */ @@ -59,7 +58,6 @@ private: virtual int shareKeyType(); virtual GxsMessageFrameWidget *createMessageFrameWidget(const RsGxsGroupId &groupId); virtual uint32_t requestGroupSummaryType() { return GXS_REQUEST_TYPE_GROUP_DATA; } // request complete group data - virtual void loadGroupSummaryToken(const uint32_t &token, std::list &groupInfo, RsUserdata* &userdata); void handleEvent_main_thread(std::shared_ptr event); From 05afc4080403520e63b7a7cf30a5016ef9dbf7e2 Mon Sep 17 00:00:00 2001 From: csoler Date: Sat, 21 Mar 2020 17:44:58 +0100 Subject: [PATCH 07/15] fixed a few bugs --- retroshare-gui/src/gui/Posted/PostedDialog.cpp | 7 ++++++- retroshare-gui/src/gui/gxs/GxsGroupFrameDialog.cpp | 2 ++ .../src/gui/gxschannels/GxsChannelDialog.cpp | 11 ++++++++--- retroshare-gui/src/gui/gxsforums/GxsForumsDialog.cpp | 4 +++- 4 files changed, 19 insertions(+), 5 deletions(-) diff --git a/retroshare-gui/src/gui/Posted/PostedDialog.cpp b/retroshare-gui/src/gui/Posted/PostedDialog.cpp index 17003c317..e3e990c7c 100644 --- a/retroshare-gui/src/gui/Posted/PostedDialog.cpp +++ b/retroshare-gui/src/gui/Posted/PostedDialog.cpp @@ -237,9 +237,14 @@ void PostedDialog::groupInfoToGroupItemInfo(const RsGxsGenericGroupData *groupDa return; } + if(postedGroupData->mGroupImage.mSize > 0) + { QPixmap image; GxsIdDetails::loadPixmapFromData(postedGroupData->mGroupImage.mData, postedGroupData->mGroupImage.mSize, image,GxsIdDetails::ORIGINAL); + groupItemInfo.icon = image; + } + else + groupItemInfo.icon = QIcon(":icons/png/postedlinks.png"); groupItemInfo.description = QString::fromUtf8(postedGroupData->mDescription.c_str()); - groupItemInfo.icon = image; } diff --git a/retroshare-gui/src/gui/gxs/GxsGroupFrameDialog.cpp b/retroshare-gui/src/gui/gxs/GxsGroupFrameDialog.cpp index ef84d9ce9..10bb1f696 100644 --- a/retroshare-gui/src/gui/gxs/GxsGroupFrameDialog.cpp +++ b/retroshare-gui/src/gui/gxs/GxsGroupFrameDialog.cpp @@ -951,7 +951,9 @@ void GxsGroupFrameDialog::insertGroupsData(const std::listmMeta.mLastPost, groupItemInfo)); /* rate the others by time of last post */ + } } /* iterate backwards through popMap - take the top 5 or 10% of list */ diff --git a/retroshare-gui/src/gui/gxschannels/GxsChannelDialog.cpp b/retroshare-gui/src/gui/gxschannels/GxsChannelDialog.cpp index a24573f16..0f707f84b 100644 --- a/retroshare-gui/src/gui/gxschannels/GxsChannelDialog.cpp +++ b/retroshare-gui/src/gui/gxschannels/GxsChannelDialog.cpp @@ -401,11 +401,16 @@ void GxsChannelDialog::groupInfoToGroupItemInfo(const RsGxsGenericGroupData *gro return; } - QPixmap image; - GxsIdDetails::loadPixmapFromData(channelGroupData->mImage.mData, channelGroupData->mImage.mSize, image,GxsIdDetails::ORIGINAL); + if(channelGroupData->mImage.mSize > 0) + { + QPixmap image; + GxsIdDetails::loadPixmapFromData(channelGroupData->mImage.mData, channelGroupData->mImage.mSize, image,GxsIdDetails::ORIGINAL); + groupItemInfo.icon = image; + } + else + groupItemInfo.icon = QIcon(":icons/png/channel.png"); groupItemInfo.description = QString::fromUtf8(channelGroupData->mDescription.c_str()); - groupItemInfo.icon = image; } TurtleRequestId GxsChannelDialog::distantSearch(const QString& search_string) diff --git a/retroshare-gui/src/gui/gxsforums/GxsForumsDialog.cpp b/retroshare-gui/src/gui/gxsforums/GxsForumsDialog.cpp index e2e5defba..e8208e705 100644 --- a/retroshare-gui/src/gui/gxsforums/GxsForumsDialog.cpp +++ b/retroshare-gui/src/gui/gxsforums/GxsForumsDialog.cpp @@ -237,7 +237,9 @@ void GxsForumsDialog::groupInfoToGroupItemInfo(const RsGxsGenericGroupData *grou groupItemInfo.description = QString::fromUtf8(forumGroupData->mDescription.c_str()); - if ((IS_GROUP_PGP_AUTHED(groupData->mMeta.mSignFlags)) || (IS_GROUP_MESSAGE_TRACKING(groupData->mMeta.mSignFlags)) ) + if(IS_GROUP_ADMIN(groupData->mMeta.mSubscribeFlags)) + groupItemInfo.icon = QIcon(":images/konv_message2.png"); + else if ((IS_GROUP_PGP_AUTHED(groupData->mMeta.mSignFlags)) || (IS_GROUP_MESSAGE_TRACKING(groupData->mMeta.mSignFlags)) ) groupItemInfo.icon = QIcon(":icons/png/forums-signed.png"); } From 83b130fa9030a2e3698fe90a793265cf701dd6a5 Mon Sep 17 00:00:00 2001 From: csoler Date: Sun, 22 Mar 2020 02:11:56 +0100 Subject: [PATCH 08/15] fixed icon for own forums --- retroshare-gui/src/gui/gxsforums/GxsForumsDialog.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/retroshare-gui/src/gui/gxsforums/GxsForumsDialog.cpp b/retroshare-gui/src/gui/gxsforums/GxsForumsDialog.cpp index e8208e705..87396f9a1 100644 --- a/retroshare-gui/src/gui/gxsforums/GxsForumsDialog.cpp +++ b/retroshare-gui/src/gui/gxsforums/GxsForumsDialog.cpp @@ -238,7 +238,7 @@ void GxsForumsDialog::groupInfoToGroupItemInfo(const RsGxsGenericGroupData *grou groupItemInfo.description = QString::fromUtf8(forumGroupData->mDescription.c_str()); if(IS_GROUP_ADMIN(groupData->mMeta.mSubscribeFlags)) - groupItemInfo.icon = QIcon(":images/konv_message2.png"); + groupItemInfo.icon = QIcon(":icons/png/forums.png"); else if ((IS_GROUP_PGP_AUTHED(groupData->mMeta.mSignFlags)) || (IS_GROUP_MESSAGE_TRACKING(groupData->mMeta.mSignFlags)) ) groupItemInfo.icon = QIcon(":icons/png/forums-signed.png"); } From 7ba83272cf97ef633d8c06d34bbe4439d0acaa67 Mon Sep 17 00:00:00 2001 From: csoler Date: Sun, 22 Mar 2020 02:33:51 +0100 Subject: [PATCH 09/15] re-enabled GroupMetaCache in GxsGroupFrameDialog and only reload fully when needed --- retroshare-gui/src/gui/gxs/GxsGroupFrameDialog.cpp | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/retroshare-gui/src/gui/gxs/GxsGroupFrameDialog.cpp b/retroshare-gui/src/gui/gxs/GxsGroupFrameDialog.cpp index 10bb1f696..21f3f8ade 100644 --- a/retroshare-gui/src/gui/gxs/GxsGroupFrameDialog.cpp +++ b/retroshare-gui/src/gui/gxs/GxsGroupFrameDialog.cpp @@ -137,6 +137,8 @@ void GxsGroupFrameDialog::getGroupList(std::map & if(group_list.empty()) updateGroupSummary(); + else + std::cerr << "************** Using cached GroupMetaData" << std::endl; } void GxsGroupFrameDialog::initUi() { @@ -181,9 +183,7 @@ void GxsGroupFrameDialog::showEvent(QShowEvent *event) initUi(); } - updateDisplay(true); - -// RsGxsUpdateBroadcastPage::showEvent(event); + updateDisplay( mCachedGroupMetas.empty() ); } void GxsGroupFrameDialog::processSettings(bool load) @@ -1051,10 +1051,17 @@ void GxsGroupFrameDialog::updateGroupSummary() mNavigatePendingGroupId.clear(); mNavigatePendingMsgId.clear(); } + // update the local cache in order to avoid re-asking the data when the UI wants it (this happens on ::show() for instance) + + mCachedGroupMetas.clear(); + // now delete the data that is not used anymore for(auto& g:groupInfo) + { + mCachedGroupMetas[g->mMeta.mGroupId] = g->mMeta; delete g; + } }, this ); }); From 6c1f09a53baa95092ee17b69b24c9e53d49851e2 Mon Sep 17 00:00:00 2001 From: csoler Date: Sun, 22 Mar 2020 21:47:14 +0100 Subject: [PATCH 10/15] completely removed TokenQueue from GxsGroupDialog and GxsGroupFrameDialog --- libretroshare/src/retroshare/rsgxschannels.h | 9 +++ libretroshare/src/retroshare/rsgxsforums.h | 11 ++- .../src/retroshare/rsgxsifacehelper.h | 3 +- libretroshare/src/retroshare/rsposted.h | 6 ++ libretroshare/src/services/p3gxschannels.cc | 9 +++ libretroshare/src/services/p3gxschannels.h | 3 + libretroshare/src/services/p3gxsforums.cc | 11 ++- libretroshare/src/services/p3gxsforums.h | 20 +++-- libretroshare/src/services/p3posted.cc | 57 ++++++++++++++ libretroshare/src/services/p3posted.h | 6 ++ .../src/gui/Posted/PostedDialog.cpp | 13 +++- retroshare-gui/src/gui/Posted/PostedDialog.h | 5 +- .../src/gui/Posted/PostedGroupDialog.cpp | 60 ++++++++------- .../src/gui/Posted/PostedGroupDialog.h | 15 ++-- retroshare-gui/src/gui/gxs/GxsGroupDialog.cpp | 75 +++++++++++++------ retroshare-gui/src/gui/gxs/GxsGroupDialog.h | 42 ++++++----- .../src/gui/gxs/GxsGroupFrameDialog.cpp | 59 ++++++++++----- .../src/gui/gxs/GxsGroupFrameDialog.h | 15 ++-- .../src/gui/gxschannels/GxsChannelDialog.cpp | 13 +++- .../src/gui/gxschannels/GxsChannelDialog.h | 15 ++-- .../gui/gxschannels/GxsChannelGroupDialog.cpp | 60 +++++++-------- .../gui/gxschannels/GxsChannelGroupDialog.h | 15 ++-- .../src/gui/gxsforums/GxsForumGroupDialog.cpp | 70 +++++++++-------- .../src/gui/gxsforums/GxsForumGroupDialog.h | 15 ++-- .../src/gui/gxsforums/GxsForumsDialog.cpp | 14 +++- .../src/gui/gxsforums/GxsForumsDialog.h | 19 +++-- 26 files changed, 423 insertions(+), 217 deletions(-) diff --git a/libretroshare/src/retroshare/rsgxschannels.h b/libretroshare/src/retroshare/rsgxschannels.h index f96f371f5..0134ada9c 100644 --- a/libretroshare/src/retroshare/rsgxschannels.h +++ b/libretroshare/src/retroshare/rsgxschannels.h @@ -398,6 +398,15 @@ public: virtual bool subscribeToChannel( const RsGxsGroupId& channelId, bool subscribe ) = 0; + /** + * \brief Retrieve statistics about the given channel + * @jsonapi{development} + * \param[in] channelId Id of the channel group + * \param[out] stat Statistics structure + * \return + */ + virtual bool getChannelStatistics(const RsGxsGroupId& channelId,GxsGroupStatistic& stat) =0; + /** * @brief Request remote channels search * @jsonapi{development} diff --git a/libretroshare/src/retroshare/rsgxsforums.h b/libretroshare/src/retroshare/rsgxsforums.h index 319bcf2b8..4e368792e 100644 --- a/libretroshare/src/retroshare/rsgxsforums.h +++ b/libretroshare/src/retroshare/rsgxsforums.h @@ -219,6 +219,15 @@ public: */ virtual bool getForumsSummaries(std::list& forums) = 0; + /** + * @brief returns statistics about a particular forum + * @jsonapi{development} + * @param[in] forumId Id of the forum + * @param[out] stat statistics struct + * @return false when the object doesn't exist or when the timeout is reached requesting the data + */ + virtual bool getForumStatistics(const RsGxsGroupId& forumId,GxsGroupStatistic& stat)=0; + /** * @brief Get forums information (description, thumbnail...). * Blocking API. @@ -361,5 +370,5 @@ public: RS_DEPRECATED_FOR(createMessage) virtual bool createMsg(uint32_t &token, RsGxsForumMsg &msg) = 0; RS_DEPRECATED_FOR(editForum) - virtual bool updateGroup(uint32_t &token, RsGxsForumGroup &group) = 0; + virtual bool updateGroup(uint32_t &token, const RsGxsForumGroup &group) = 0; }; diff --git a/libretroshare/src/retroshare/rsgxsifacehelper.h b/libretroshare/src/retroshare/rsgxsifacehelper.h index 65cd356ed..7be714103 100644 --- a/libretroshare/src/retroshare/rsgxsifacehelper.h +++ b/libretroshare/src/retroshare/rsgxsifacehelper.h @@ -340,13 +340,14 @@ public: } /// @see RsTokenService::requestGroupStatistic - void requestGroupStatistic(uint32_t& token, const RsGxsGroupId& grpId) + bool requestGroupStatistic(uint32_t& token, const RsGxsGroupId& grpId) { mTokenService.requestGroupStatistic(token, grpId); RS_STACK_MUTEX(mMtx); mActiveTokens[token]=TokenRequestType::GROUP_STATISTICS; locked_dumpTokens(); + return true; } bool cancelActiveRequestTokens(TokenRequestType type) diff --git a/libretroshare/src/retroshare/rsposted.h b/libretroshare/src/retroshare/rsposted.h index 5552496c0..11f7ac643 100644 --- a/libretroshare/src/retroshare/rsposted.h +++ b/libretroshare/src/retroshare/rsposted.h @@ -157,6 +157,12 @@ public: std::vector& posts, std::vector& comments ) = 0; + virtual bool editBoard(RsPostedGroup& board) =0; + + virtual bool createBoard(RsPostedGroup& board) =0; + + virtual bool getBoardStatistics(const RsGxsGroupId& boardId,GxsGroupStatistic& stat) =0; + enum RS_DEPRECATED RankType {TopRankType, HotRankType, NewRankType }; RS_DEPRECATED_FOR(getBoardsInfo) diff --git a/libretroshare/src/services/p3gxschannels.cc b/libretroshare/src/services/p3gxschannels.cc index b58685e07..93c85d8d0 100644 --- a/libretroshare/src/services/p3gxschannels.cc +++ b/libretroshare/src/services/p3gxschannels.cc @@ -1053,6 +1053,15 @@ bool p3GxsChannels::getChannelsInfo( const std::list& chanIds, std return getGroupData(token, channelsInfo) && !channelsInfo.empty(); } +bool p3GxsChannels::getChannelStatistics(const RsGxsGroupId& channelId,GxsGroupStatistic& stat) +{ + uint32_t token; + if(!RsGxsIfaceHelper::requestGroupStatistic(token, channelId) || waitToken(token) != RsTokenService::COMPLETE) + return false; + + return RsGenExchange::getGroupStatistic(token,stat); +} + bool p3GxsChannels::getContentSummaries( const RsGxsGroupId& channelId, std::vector& summaries ) { diff --git a/libretroshare/src/services/p3gxschannels.h b/libretroshare/src/services/p3gxschannels.h index c83fbc4df..81eb75f5f 100644 --- a/libretroshare/src/services/p3gxschannels.h +++ b/libretroshare/src/services/p3gxschannels.h @@ -196,6 +196,9 @@ virtual bool ExtraFileRemove(const RsFileHash &hash); const RsGxsGroupId& channelId, std::vector& summaries ) override; + /// Implementation of @see RsGxsChannels::getChannelStatistics + bool getChannelStatistics(const RsGxsGroupId& channelId,GxsGroupStatistic& stat) override; + /// Implementation of @see RsGxsChannels::createChannelV2 bool createChannelV2( const std::string& name, const std::string& description, diff --git a/libretroshare/src/services/p3gxsforums.cc b/libretroshare/src/services/p3gxsforums.cc index 8d3db91c8..442878bba 100644 --- a/libretroshare/src/services/p3gxsforums.cc +++ b/libretroshare/src/services/p3gxsforums.cc @@ -819,7 +819,16 @@ bool p3GxsForums::createGroup(uint32_t &token, RsGxsForumGroup &group) return true; } -bool p3GxsForums::updateGroup(uint32_t &token, RsGxsForumGroup &group) +bool p3GxsForums::getForumStatistics(const RsGxsGroupId& ForumId,GxsGroupStatistic& stat) +{ + uint32_t token; + if(!RsGxsIfaceHelper::requestGroupStatistic(token, ForumId) || waitToken(token) != RsTokenService::COMPLETE) + return false; + + return RsGenExchange::getGroupStatistic(token,stat); +} + +bool p3GxsForums::updateGroup(uint32_t &token, const RsGxsForumGroup &group) { std::cerr << "p3GxsForums::updateGroup()" << std::endl; diff --git a/libretroshare/src/services/p3gxsforums.h b/libretroshare/src/services/p3gxsforums.h index ae2bf74bf..c95acf447 100644 --- a/libretroshare/src/services/p3gxsforums.h +++ b/libretroshare/src/services/p3gxsforums.h @@ -94,6 +94,9 @@ public: const std::list& forumIds, std::vector& forumsInfo ); + /// Implementation of @see RsGxsForums::getForumStatistics + bool getForumStatistics(const RsGxsGroupId& ForumId,GxsGroupStatistic& stat) override; + /// @see RsGxsForums::getForumMsgMetaData virtual bool getForumMsgMetaData(const RsGxsGroupId& forumId, std::vector& msg_metas) ; @@ -125,13 +128,16 @@ public: std::string& errMsg = RS_DEFAULT_STORAGE_PARAM(std::string) ) override; - virtual bool getGroupData(const uint32_t &token, std::vector &groups); - virtual bool getMsgData(const uint32_t &token, std::vector &msgs); - virtual bool getMsgMetaData(const uint32_t &token, GxsMsgMetaMap& msg_metas); - virtual void setMessageReadStatus(uint32_t& token, const RsGxsGrpMsgIdPair& msgId, bool read); - virtual bool createGroup(uint32_t &token, RsGxsForumGroup &group); - virtual bool createMsg(uint32_t &token, RsGxsForumMsg &msg); - virtual bool updateGroup(uint32_t &token, RsGxsForumGroup &group); + /// implementation of rsGxsGorums + /// + bool getGroupData(const uint32_t &token, std::vector &groups) override; + bool getMsgData(const uint32_t &token, std::vector &msgs) override; + void setMessageReadStatus(uint32_t& token, const RsGxsGrpMsgIdPair& msgId, bool read) override; + bool createGroup(uint32_t &token, RsGxsForumGroup &group) override; + bool createMsg(uint32_t &token, RsGxsForumMsg &msg) override; + bool updateGroup(uint32_t &token, const RsGxsForumGroup &group) override; + + bool getMsgMetaData(const uint32_t &token, GxsMsgMetaMap& msg_metas) ; private: diff --git a/libretroshare/src/services/p3posted.cc b/libretroshare/src/services/p3posted.cc index e040aa8eb..8ecad994f 100644 --- a/libretroshare/src/services/p3posted.cc +++ b/libretroshare/src/services/p3posted.cc @@ -350,5 +350,62 @@ bool p3Posted::getBoardsSummaries(std::list& boards ) return getGroupSummary(token, boards); } +bool p3Posted::getBoardStatistics(const RsGxsGroupId& boardId,GxsGroupStatistic& stat) +{ + uint32_t token; + if(!RsGxsIfaceHelper::requestGroupStatistic(token, boardId) || waitToken(token) != RsTokenService::COMPLETE) + return false; + + return RsGenExchange::getGroupStatistic(token,stat); +} + +bool p3Posted::createBoard(RsPostedGroup& board) +{ + uint32_t token; + if(!createGroup(token, board)) + { + std::cerr << __PRETTY_FUNCTION__ << "Error! Failed creating group." << std::endl; + return false; + } + + if(waitToken(token,std::chrono::milliseconds(5000)) != RsTokenService::COMPLETE) + { + std::cerr << __PRETTY_FUNCTION__ << "Error! GXS operation failed." << std::endl; + return false; + } + + if(!RsGenExchange::getPublishedGroupMeta(token, board.mMeta)) + { + std::cerr << __PRETTY_FUNCTION__ << "Error! Failure getting updated " << " group data." << std::endl; + return false; + } + + return true; +} + +bool p3Posted::editBoard(RsPostedGroup& board) +{ + uint32_t token; + if(!updateGroup(token, board)) + { + std::cerr << __PRETTY_FUNCTION__ << " Error! Failed updating group." << std::endl; + return false; + } + + if(waitToken(token) != RsTokenService::COMPLETE) + { + std::cerr << __PRETTY_FUNCTION__ << " Error! GXS operation failed." << std::endl; + return false; + } + + if(!RsGenExchange::getPublishedGroupMeta(token, board.mMeta)) + { + std::cerr << __PRETTY_FUNCTION__ << " Error! Failure getting updated " << " group data." << std::endl; + return false; + } + + return true; +} + RsPosted::~RsPosted() = default; RsGxsPostedEvent::~RsGxsPostedEvent() = default; diff --git a/libretroshare/src/services/p3posted.h b/libretroshare/src/services/p3posted.h index b2accf2ba..5fe5b0718 100644 --- a/libretroshare/src/services/p3posted.h +++ b/libretroshare/src/services/p3posted.h @@ -68,6 +68,12 @@ virtual void receiveHelperChanges(std::vector& changes) bool getBoardsSummaries(std::list& groupInfo) override; + bool getBoardStatistics(const RsGxsGroupId& boardId,GxsGroupStatistic& stat) override; + + bool editBoard(RsPostedGroup& board) override; + + bool createBoard(RsPostedGroup& board) override; + virtual bool getGroupData(const uint32_t &token, std::vector &groups); virtual bool getPostData(const uint32_t &token, std::vector &posts, std::vector &cmts); virtual bool getPostData(const uint32_t &token, std::vector &posts) { std::vector cmts; return getPostData( token, posts, cmts);} diff --git a/retroshare-gui/src/gui/Posted/PostedDialog.cpp b/retroshare-gui/src/gui/Posted/PostedDialog.cpp index e3e990c7c..cbf7426d9 100644 --- a/retroshare-gui/src/gui/Posted/PostedDialog.cpp +++ b/retroshare-gui/src/gui/Posted/PostedDialog.cpp @@ -167,14 +167,19 @@ bool PostedDialog::getGroupData(std::list& groupInfo) return true; } -GxsGroupDialog *PostedDialog::createNewGroupDialog(TokenQueue *tokenQueue) +bool PostedDialog::getGroupStatistics(const RsGxsGroupId& groupId,GxsGroupStatistic& stat) { - return new PostedGroupDialog(tokenQueue, this); + return rsPosted->getBoardStatistics(groupId,stat); } -GxsGroupDialog *PostedDialog::createGroupDialog(TokenQueue *tokenQueue, RsTokenService *tokenService, GxsGroupDialog::Mode mode, RsGxsGroupId groupId) +GxsGroupDialog *PostedDialog::createNewGroupDialog() { - return new PostedGroupDialog(tokenQueue, tokenService, mode, groupId, this); + return new PostedGroupDialog(this); +} + +GxsGroupDialog *PostedDialog::createGroupDialog(GxsGroupDialog::Mode mode, RsGxsGroupId groupId) +{ + return new PostedGroupDialog(mode, groupId, this); } int PostedDialog::shareKeyType() diff --git a/retroshare-gui/src/gui/Posted/PostedDialog.h b/retroshare-gui/src/gui/Posted/PostedDialog.h index 17a679993..5931ec25b 100644 --- a/retroshare-gui/src/gui/Posted/PostedDialog.h +++ b/retroshare-gui/src/gui/Posted/PostedDialog.h @@ -48,14 +48,15 @@ protected: void groupInfoToGroupItemInfo(const RsGxsGenericGroupData *groupData, GroupItemInfo &groupItemInfo) override; bool getGroupData(std::list& groupInfo) override; + bool getGroupStatistics(const RsGxsGroupId& groupId,GxsGroupStatistic& stat) override; private: /* GxsGroupFrameDialog */ virtual QString text(TextType type); virtual QString icon(IconType type); virtual QString settingsGroupName() { return "PostedDialog"; } - virtual GxsGroupDialog *createNewGroupDialog(TokenQueue *tokenQueue); - virtual GxsGroupDialog *createGroupDialog(TokenQueue *tokenQueue, RsTokenService *tokenService, GxsGroupDialog::Mode mode, RsGxsGroupId groupId); + virtual GxsGroupDialog *createNewGroupDialog(); + virtual GxsGroupDialog *createGroupDialog(GxsGroupDialog::Mode mode, RsGxsGroupId groupId); virtual int shareKeyType(); virtual GxsMessageFrameWidget *createMessageFrameWidget(const RsGxsGroupId &groupId); virtual RsGxsCommentService *getCommentService(); diff --git a/retroshare-gui/src/gui/Posted/PostedGroupDialog.cpp b/retroshare-gui/src/gui/Posted/PostedGroupDialog.cpp index a2627d167..957abfc0d 100644 --- a/retroshare-gui/src/gui/Posted/PostedGroupDialog.cpp +++ b/retroshare-gui/src/gui/Posted/PostedGroupDialog.cpp @@ -56,13 +56,13 @@ uint32_t PostedCreateDefaultsFlags = ( GXS_GROUP_DEFAULTS_DISTRIB_PUBLIC | uint32_t PostedEditEnabledFlags = PostedCreateEnabledFlags; uint32_t PostedEditDefaultsFlags = PostedCreateDefaultsFlags; -PostedGroupDialog::PostedGroupDialog(TokenQueue *tokenQueue, QWidget *parent) - : GxsGroupDialog(tokenQueue, PostedCreateEnabledFlags, PostedCreateDefaultsFlags, parent) +PostedGroupDialog::PostedGroupDialog(QWidget *parent) + : GxsGroupDialog(PostedCreateEnabledFlags, PostedCreateDefaultsFlags, parent) { } -PostedGroupDialog::PostedGroupDialog(TokenQueue *tokenExternalQueue, RsTokenService *tokenService, Mode mode, RsGxsGroupId groupId, QWidget *parent) - : GxsGroupDialog(tokenExternalQueue, tokenService, mode, groupId, PostedEditEnabledFlags, PostedEditDefaultsFlags, parent) +PostedGroupDialog::PostedGroupDialog(Mode mode, RsGxsGroupId groupId, QWidget *parent) + : GxsGroupDialog(mode, groupId, PostedEditEnabledFlags, PostedEditDefaultsFlags, parent) { } @@ -112,18 +112,19 @@ void PostedGroupDialog::preparePostedGroup(RsPostedGroup &group, const RsGroupMe } } -bool PostedGroupDialog::service_CreateGroup(uint32_t &token, const RsGroupMetaData &meta) +bool PostedGroupDialog::service_createGroup(RsGroupMetaData& meta) { // Specific Function. RsPostedGroup grp; preparePostedGroup(grp, meta); - rsPosted->createGroup(token, grp); + if(rsPosted->createBoard(grp)) + meta = grp.mMeta; return true; } -bool PostedGroupDialog::service_EditGroup(uint32_t &token, RsGroupMetaData &editedMeta) +bool PostedGroupDialog::service_updateGroup(const RsGroupMetaData& editedMeta) { RsPostedGroup grp; preparePostedGroup(grp, editedMeta); @@ -131,45 +132,48 @@ bool PostedGroupDialog::service_EditGroup(uint32_t &token, RsGroupMetaData &edit std::cerr << "PostedGroupDialog::service_EditGroup() submitting changes"; std::cerr << std::endl; - rsPosted->updateGroup(token, grp); - return true; + return rsPosted->editBoard(grp); } -bool PostedGroupDialog::service_loadGroup(uint32_t token, Mode /*mode*/, RsGroupMetaData& groupMetaData, QString &description) +bool PostedGroupDialog::service_loadGroup(const RsGxsGenericGroupData *data, Mode mode, QString& description) { - std::cerr << "PostedGroupDialog::service_loadGroup(" << token << ")"; - std::cerr << std::endl; + const RsPostedGroup *pgroup = dynamic_cast(data); - std::vector groups; - if (!rsPosted->getGroupData(token, groups)) + if(pgroup == nullptr) { - std::cerr << "PostedGroupDialog::service_loadGroup() Error getting GroupData"; - std::cerr << std::endl; - return false; - } - - if (groups.size() != 1) - { - std::cerr << "PostedGroupDialog::service_loadGroup() Error Group.size() != 1"; - std::cerr << std::endl; + std::cerr << "PostedGroupDialog::service_loadGroup() Error not a RsPostedGroup" << std::endl; return false; } std::cerr << "PostedGroupDialog::service_loadGroup() Unfinished Loading"; std::cerr << std::endl; - const RsPostedGroup &group = groups[0]; - groupMetaData = group.mMeta; + const RsPostedGroup& group = *pgroup; description = QString::fromUtf8(group.mDescription.c_str()); - if (group.mGroupImage.mData) { + if (group.mGroupImage.mData) + { QPixmap pixmap; if (GxsIdDetails::loadPixmapFromData(group.mGroupImage.mData, group.mGroupImage.mSize, pixmap,GxsIdDetails::ORIGINAL)) setLogo(pixmap); - } else { - setLogo(QPixmap(":/icons/png/posted.png")); } + else + setLogo(QPixmap(":/icons/png/posted.png")); return true; } + +bool PostedGroupDialog::service_getGroupData(const RsGxsGroupId& grpId,RsGxsGenericGroupData *& data) +{ + std::vector boardsInfo ; + + if( rsPosted->getBoardsInfo(std::list({grpId}),boardsInfo) && boardsInfo.size() == 1) + { + data = new RsPostedGroup(boardsInfo[0]); + return true; + } + else + return false; + +} diff --git a/retroshare-gui/src/gui/Posted/PostedGroupDialog.h b/retroshare-gui/src/gui/Posted/PostedGroupDialog.h index c0d860b96..ce3d25a5d 100644 --- a/retroshare-gui/src/gui/Posted/PostedGroupDialog.h +++ b/retroshare-gui/src/gui/Posted/PostedGroupDialog.h @@ -30,15 +30,16 @@ class PostedGroupDialog : public GxsGroupDialog Q_OBJECT public: - PostedGroupDialog(TokenQueue *tokenQueue, QWidget *parent); - PostedGroupDialog(TokenQueue *tokenExternalQueue, RsTokenService *tokenService, Mode mode, RsGxsGroupId groupId, QWidget *parent); + PostedGroupDialog(QWidget *parent); + PostedGroupDialog(Mode mode, RsGxsGroupId groupId, QWidget *parent); protected: - virtual void initUi(); - virtual QPixmap serviceImage(); - virtual bool service_CreateGroup(uint32_t &token, const RsGroupMetaData &meta); - virtual bool service_loadGroup(uint32_t token, Mode mode, RsGroupMetaData& groupMetaData, QString &description); - virtual bool service_EditGroup(uint32_t &token, RsGroupMetaData &editedMeta); + void initUi() override; + QPixmap serviceImage() override; + bool service_createGroup(RsGroupMetaData& meta) override; + bool service_loadGroup(const RsGxsGenericGroupData *data,Mode mode, QString &description) override; + bool service_updateGroup(const RsGroupMetaData& editedMeta) override; + bool service_getGroupData(const RsGxsGroupId& grpId,RsGxsGenericGroupData *& data) override; private: void preparePostedGroup(RsPostedGroup &group, const RsGroupMetaData &meta); diff --git a/retroshare-gui/src/gui/gxs/GxsGroupDialog.cpp b/retroshare-gui/src/gui/gxs/GxsGroupDialog.cpp index ef0099faa..30a4e6578 100644 --- a/retroshare-gui/src/gui/gxs/GxsGroupDialog.cpp +++ b/retroshare-gui/src/gui/gxs/GxsGroupDialog.cpp @@ -23,6 +23,7 @@ #include "util/misc.h" #include "util/DateTime.h" +#include "util/qtthreadsutils.h" #include "GxsGroupDialog.h" #include "gui/common/PeerDefs.h" #include "gui/RetroShareLink.h" @@ -63,25 +64,21 @@ #define GXSGROUP_INTERNAL_LOADGROUP 3 /** Constructor */ -GxsGroupDialog::GxsGroupDialog(TokenQueue *tokenExternalQueue, uint32_t enableFlags, uint32_t defaultFlags, QWidget *parent) - : QDialog(parent, Qt::WindowSystemMenuHint | Qt::WindowTitleHint | Qt::WindowCloseButtonHint), mTokenService(NULL), mExternalTokenQueue(tokenExternalQueue), mInternalTokenQueue(NULL), mGrpMeta(), mMode(MODE_CREATE), mEnabledFlags(enableFlags), mReadonlyFlags(0), mDefaultsFlags(defaultFlags) +GxsGroupDialog::GxsGroupDialog(uint32_t enableFlags, uint32_t defaultFlags, QWidget *parent) + : QDialog(parent, Qt::WindowSystemMenuHint | Qt::WindowTitleHint | Qt::WindowCloseButtonHint), mGrpMeta(), mMode(MODE_CREATE), mEnabledFlags(enableFlags), mReadonlyFlags(0), mDefaultsFlags(defaultFlags) { /* Invoke the Qt Designer generated object setup routine */ ui.setupUi(this); - mInternalTokenQueue = NULL; - init(); } -GxsGroupDialog::GxsGroupDialog(TokenQueue *tokenExternalQueue, RsTokenService *tokenService, Mode mode, RsGxsGroupId groupId, uint32_t enableFlags, uint32_t defaultFlags, QWidget *parent) - : QDialog(parent, Qt::WindowSystemMenuHint | Qt::WindowTitleHint | Qt::WindowCloseButtonHint), mTokenService(NULL), mExternalTokenQueue(tokenExternalQueue), mInternalTokenQueue(NULL), mGrpMeta(), mMode(mode), mEnabledFlags(enableFlags), mReadonlyFlags(0), mDefaultsFlags(defaultFlags) +GxsGroupDialog::GxsGroupDialog(Mode mode, RsGxsGroupId groupId, uint32_t enableFlags, uint32_t defaultFlags, QWidget *parent) + : QDialog(parent, Qt::WindowSystemMenuHint | Qt::WindowTitleHint | Qt::WindowCloseButtonHint), mGrpMeta(), mMode(mode), mEnabledFlags(enableFlags), mReadonlyFlags(0), mDefaultsFlags(defaultFlags) { /* Invoke the Qt Designer generated object setup routine */ ui.setupUi(this); - mTokenService = tokenService; - mInternalTokenQueue = new TokenQueue(tokenService, this); mGrpMeta.mGroupId = groupId; init(); @@ -90,9 +87,6 @@ GxsGroupDialog::GxsGroupDialog(TokenQueue *tokenExternalQueue, RsTokenService *t GxsGroupDialog::~GxsGroupDialog() { Settings->saveWidgetInformation(this); - if (mInternalTokenQueue) { - delete(mInternalTokenQueue); - } } void GxsGroupDialog::init() @@ -179,6 +173,9 @@ void GxsGroupDialog::showEvent(QShowEvent*) setWindowIcon(serviceWindowIcon()); initUi(); + + if(!mGrpMeta.mGroupId.isNull() && mGrpMeta.mPublishTs == 0) // group not actually loaded yet + loadGroup(mGrpMeta.mGroupId); } void GxsGroupDialog::setUiText(UiType uiType, const QString &text) @@ -237,7 +234,6 @@ void GxsGroupDialog::initMode() ui.stackedWidget->setCurrentIndex(1); mReadonlyFlags = 0xffffffff; // Force all to readonly. ui.buttonBox->setStandardButtons(QDialogButtonBox::Close); - requestGroup(mGrpMeta.mGroupId); } break; @@ -246,7 +242,6 @@ void GxsGroupDialog::initMode() ui.stackedWidget->setCurrentIndex(0); ui.buttonBox->setStandardButtons(QDialogButtonBox::Ok | QDialogButtonBox::Cancel); ui.buttonBox->button(QDialogButtonBox::Ok)->setText(tr("Submit Group Changes")); - requestGroup(mGrpMeta.mGroupId); } break; } @@ -596,14 +591,7 @@ void GxsGroupDialog::editGroup() std::cerr << "GxsGroupDialog::editGroup() calling service_EditGroup"; std::cerr << std::endl; - uint32_t token; - if (service_EditGroup(token, newMeta)) - { - // get the Queue to handle response. - if(mExternalTokenQueue != NULL) - mExternalTokenQueue->queueRequest(token, TOKENREQ_GROUPINFO, RS_TOKREQ_ANSTYPE_ACK, GXSGROUP_NEWGROUPID); - } - else + if (!service_updateGroup(newMeta)) { std::cerr << "GxsGroupDialog::editGroup() ERROR"; std::cerr << std::endl; @@ -676,7 +664,6 @@ void GxsGroupDialog::createGroup() return; //Don't add a empty name!! } - uint32_t token; RsGroupMetaData meta; QString reason; if (!prepareGroupMetaData(meta, reason)) @@ -686,11 +673,16 @@ void GxsGroupDialog::createGroup() return; //Don't add with invalid circle. } - if (service_CreateGroup(token, meta)) + if (service_createGroup(meta)) { - // get the Queue to handle response. + // now update the UI +#warning Missing code here! +#ifdef TODO + // + // get the Queue to handle response. What is this for? if(mExternalTokenQueue != NULL) mExternalTokenQueue->queueRequest(token, TOKENREQ_GROUPINFO, RS_TOKREQ_ANSTYPE_ACK, GXSGROUP_NEWGROUPID); +#endif } close(); @@ -984,6 +976,40 @@ void GxsGroupDialog::filterComboBoxChanged(int i) Loading Group. ***********************************************************************************/ +void GxsGroupDialog::loadGroup(const RsGxsGroupId& grpId) +{ + RsThread::async([this,grpId]() + { + RsGxsGenericGroupData *groupData; + + if(!service_getGroupData(grpId,groupData)) + { + std::cerr << __PRETTY_FUNCTION__ << " failed to collect group info " << std::endl; + return; + } + + RsQThreadUtils::postToObject( [this,groupData]() + { + /* Here it goes any code you want to be executed on the Qt Gui + * thread, for example to update the data model with new information + * after a blocking call to RetroShare API complete, note that + * Qt::QueuedConnection is important! + */ + + mGrpMeta = groupData->mMeta; + + QString description; + + if (service_loadGroup(groupData, mMode, description)) + updateFromExistingMeta(description); + + delete groupData; + + }, this ); + }); +} + +#ifdef TO_REMOVE void GxsGroupDialog::requestGroup(const RsGxsGroupId &groupId) { RsTokReqOptions opts; @@ -1032,3 +1058,4 @@ void GxsGroupDialog::loadRequest(const TokenQueue *queue, const TokenRequest &re } } } +#endif diff --git a/retroshare-gui/src/gui/gxs/GxsGroupDialog.h b/retroshare-gui/src/gui/gxs/GxsGroupDialog.h index 49225dd1d..4860f52a8 100644 --- a/retroshare-gui/src/gui/gxs/GxsGroupDialog.h +++ b/retroshare-gui/src/gui/gxs/GxsGroupDialog.h @@ -108,7 +108,7 @@ public: * The long term plan is perhap logic structure (i.e. code) will be moved into each GXS \n * service for better customisation of group creation, or perhaps not! */ -class GxsGroupDialog : public QDialog, public TokenResponse +class GxsGroupDialog : public QDialog { Q_OBJECT @@ -131,15 +131,12 @@ public: /*! * Constructs a GxsGroupDialog for creating group - * @param tokenQueue This should be the TokenQueue of the (parent) service - * in order to receive acknowledgement of group creation, if set to NULL with create mode \n - * creation will not happen * @param enableFlags This determines what options are enabled such as Icon, Description, publish type and key sharing * @param defaultFlags This deter * @param parent The parent dialog * @param mode */ - GxsGroupDialog(TokenQueue* tokenQueue, uint32_t enableFlags, uint32_t defaultFlags, QWidget *parent = NULL); + GxsGroupDialog(uint32_t enableFlags, uint32_t defaultFlags, QWidget *parent = NULL); /*! * Contructs a GxsGroupDialog for display a group or editing @@ -147,15 +144,12 @@ public: * @param mode This determines whether the dialog starts in show or edit mode (Edit not supported yet) * @param parent */ - GxsGroupDialog(TokenQueue *tokenExternalQueue, RsTokenService *tokenService, Mode mode, RsGxsGroupId groupId, uint32_t enableFlags, uint32_t defaultFlags, QWidget *parent = NULL); + GxsGroupDialog(Mode mode, RsGxsGroupId groupId, uint32_t enableFlags, uint32_t defaultFlags, QWidget *parent = NULL); ~GxsGroupDialog(); uint32_t mode() { return mMode; } - // overloaded from TokenResponse - virtual void loadRequest(const TokenQueue *queue, const TokenRequest &req); - private: void newGroup(); void init(); @@ -191,24 +185,37 @@ protected: void setUiToolTip(UiType uiType, const QString &text); void setUiText (UiType uiType, const QString &text); + /*! + * It is up to the service to retrieve its own group data, which derives from RsGxsGenericGroupData. That data will be passed down + * to the service itself for specific tasks. + * \param grpId Id of the group to retrieve + * \param data Generic group data for this group. /!\ The pointer should be deleted by the client when released. + * \return True if everything does fine. + */ + virtual bool service_getGroupData(const RsGxsGroupId& grpId,RsGxsGenericGroupData *& data) = 0; + /*! * It is up to the service to do the actual group creation * Service can also modify initial meta going into group - * @param token This should be set to the token retrieved * @param meta The deriving GXS service should set their grp meta to this value */ - virtual bool service_CreateGroup(uint32_t &token, const RsGroupMetaData &meta) = 0; + virtual bool service_createGroup(RsGroupMetaData& meta) = 0; /*! * It is up to the service to do the actual group editing - * @param token This should be set to the token retrieved * @param meta The deriving GXS service should set their grp meta to this value */ - virtual bool service_EditGroup(uint32_t &token, RsGroupMetaData &editedMeta) = 0; + virtual bool service_updateGroup(const RsGroupMetaData& editedMeta) = 0; - // To be overloaded by users. - // use Token to retrieve from service, fill in metaData. - virtual bool service_loadGroup(uint32_t token, Mode mode, RsGroupMetaData& groupMetaData, QString &description) = 0; + /*! + * Should be overloaded by the service in order to extract meaningful information from the group data (that is usually group-specific). + * One of them however, common to all groups is the description. So it is returned by this method so that the GxsGroupDialog updates it. + * \param data Generic group data, to be dynamic_cast by the client to specific service-level group data + * \param mode Editing mode (?) + * \param description Description string for the group. Common to all services, but still present in the service-specific data part. + * \return + */ + virtual bool service_loadGroup(const RsGxsGenericGroupData *data, Mode mode, QString &description) = 0; /*! * This returns a group logo from the ui \n @@ -270,8 +277,7 @@ private: void loadNewGroupId(const uint32_t &token); // loading existing Groups. - void requestGroup(const RsGxsGroupId &groupId); - void loadGroup(uint32_t token); + void loadGroup(const RsGxsGroupId &groupId); void updateFromExistingMeta(const QString &description); bool prepareGroupMetaData(RsGroupMetaData &meta, QString &reason); diff --git a/retroshare-gui/src/gui/gxs/GxsGroupFrameDialog.cpp b/retroshare-gui/src/gui/gxs/GxsGroupFrameDialog.cpp index 21f3f8ade..d07c73358 100644 --- a/retroshare-gui/src/gui/gxs/GxsGroupFrameDialog.cpp +++ b/retroshare-gui/src/gui/gxs/GxsGroupFrameDialog.cpp @@ -88,8 +88,6 @@ GxsGroupFrameDialog::GxsGroupFrameDialog(RsGxsIfaceHelper *ifaceImpl, QWidget *p /* Setup Queue */ mInterface = ifaceImpl; - mTokenService = mInterface->getTokenService(); - mTokenQueue = new TokenQueue(mInterface->getTokenService(), this); /* Setup UI helper */ mStateHelper = new UIStateHelper(this); @@ -127,7 +125,6 @@ GxsGroupFrameDialog::~GxsGroupFrameDialog() // save settings processSettings(false); - delete(mTokenQueue); delete(ui); } @@ -548,7 +545,8 @@ void GxsGroupFrameDialog::restoreGroupKeys(void) void GxsGroupFrameDialog::newGroup() { - GxsGroupDialog *dialog = createNewGroupDialog(mTokenQueue); + GxsGroupDialog *dialog = createNewGroupDialog(); + if (!dialog) { return; } @@ -575,8 +573,6 @@ void GxsGroupFrameDialog::groupSubscribe(bool subscribe) uint32_t token; mInterface->subscribeToGroup(token, mGroupId, subscribe); -// Replaced by meta data changed -// mTokenQueue->queueRequest(token, 0, RS_TOKREQ_ANSTYPE_ACK, TOKEN_TYPE_SUBSCRIBE_CHANGE); } void GxsGroupFrameDialog::showGroupDetails() @@ -585,7 +581,7 @@ void GxsGroupFrameDialog::showGroupDetails() return; } - GxsGroupDialog *dialog = createGroupDialog(mTokenQueue, mInterface->getTokenService(), GxsGroupDialog::MODE_SHOW, mGroupId); + GxsGroupDialog *dialog = createGroupDialog(GxsGroupDialog::MODE_SHOW, mGroupId); if (!dialog) { return; } @@ -600,7 +596,7 @@ void GxsGroupFrameDialog::editGroupDetails() return; } - GxsGroupDialog *dialog = createGroupDialog(mTokenQueue, mInterface->getTokenService(), GxsGroupDialog::MODE_EDIT, mGroupId); + GxsGroupDialog *dialog = createGroupDialog(GxsGroupDialog::MODE_EDIT, mGroupId); if (!dialog) { return; } @@ -995,7 +991,8 @@ void GxsGroupFrameDialog::updateMessageSummaryList(RsGxsGroupId groupId) return; } - if (groupId.isNull()) { + if (groupId.isNull()) + { QTreeWidgetItem *items[2] = { mYourGroups, mSubscribedGroups }; for (int item = 0; item < 2; ++item) { int child; @@ -1003,16 +1000,15 @@ void GxsGroupFrameDialog::updateMessageSummaryList(RsGxsGroupId groupId) for (child = 0; child < childCount; ++child) { QTreeWidgetItem *childItem = items[item]->child(child); QString childId = ui->groupTreeWidget->itemId(childItem); - if (childId.isEmpty()) { + if (childId.isEmpty()) continue; - } - requestGroupStatistics(RsGxsGroupId(childId.toLatin1().constData())); + updateGroupStatistics(RsGxsGroupId(childId.toLatin1().constData())); } } - } else { - requestGroupStatistics(groupId); } + else + updateGroupStatistics(groupId); } /*********************** **** **** **** ***********************/ @@ -1163,13 +1159,39 @@ void GxsGroupFrameDialog::loadGroupSummary(const std::listrequestGroupStatistic(token, groupId); - mTokenQueue->queueRequest(token, 0, RS_TOKREQ_ANSTYPE_ACK, TOKEN_TYPE_STATISTICS); + RsThread::async([this,groupId]() + { + GxsGroupStatistic stats; + + if(! getGroupStatistics(groupId, stats)) + { + std::cerr << __PRETTY_FUNCTION__ << " failed to collect group statistics for group " << groupId << std::endl; + return; + } + + RsQThreadUtils::postToObject( [this,stats]() + { + /* Here it goes any code you want to be executed on the Qt Gui + * thread, for example to update the data model with new information + * after a blocking call to RetroShare API complete, note that + * Qt::QueuedConnection is important! + */ + + QTreeWidgetItem *item = ui->groupTreeWidget->getItemFromId(QString::fromStdString(stats.mGrpId.toStdString())); + if (!item) + return; + + ui->groupTreeWidget->setUnreadCount(item, mCountChildMsgs ? (stats.mNumThreadMsgsUnread + stats.mNumChildMsgsUnread) : stats.mNumThreadMsgsUnread); + + getUserNotify()->updateIcon(); + + }, this ); + }); } +#ifdef TO_REMOVE void GxsGroupFrameDialog::loadGroupStatistics(const uint32_t &token) { GxsGroupStatistic stats; @@ -1222,6 +1244,7 @@ void GxsGroupFrameDialog::loadRequest(const TokenQueue *queue, const TokenReques } } } +#endif TurtleRequestId GxsGroupFrameDialog::distantSearch(const QString& search_string) // this should be overloaded in the child class { diff --git a/retroshare-gui/src/gui/gxs/GxsGroupFrameDialog.h b/retroshare-gui/src/gui/gxs/GxsGroupFrameDialog.h index 61bca3a9f..4aef6a6b1 100644 --- a/retroshare-gui/src/gui/gxs/GxsGroupFrameDialog.h +++ b/retroshare-gui/src/gui/gxs/GxsGroupFrameDialog.h @@ -44,7 +44,7 @@ class UIStateHelper; struct RsGxsCommentService; class GxsCommentDialog; -class GxsGroupFrameDialog : public MainPage, public TokenResponse +class GxsGroupFrameDialog : public MainPage { Q_OBJECT @@ -76,9 +76,6 @@ public: bool navigate(const RsGxsGroupId &groupId, const RsGxsMessageId& msgId); - // Callback for all Loads. - virtual void loadRequest(const TokenQueue *queue, const TokenRequest &req); - virtual QString getHelpString() const =0; virtual void getGroupList(std::map &groups) ; @@ -97,10 +94,14 @@ protected: virtual void checkRequestGroup(const RsGxsGroupId& /* grpId */) {} // overload this one in order to retrieve full group data when the group is browsed void updateMessageSummaryList(RsGxsGroupId groupId); + void updateGroupStatistics(const RsGxsGroupId &groupId); virtual const std::set getSearchRequests() const { return std::set(); } // overload this for subclasses that provide distant search + // These two need to be overloaded by subsclasses, possibly calling the blocking API, since they are used asynchroneously. + virtual bool getGroupData(std::list& groupInfo) =0; + virtual bool getGroupStatistics(const RsGxsGroupId& groupId,GxsGroupStatistic& stat) =0; private slots: void todo(); @@ -147,8 +148,8 @@ private: virtual QString settingsGroupName() = 0; virtual TurtleRequestId distantSearch(const QString& search_string) ; - virtual GxsGroupDialog *createNewGroupDialog(TokenQueue *tokenQueue) = 0; - virtual GxsGroupDialog *createGroupDialog(TokenQueue *tokenQueue, RsTokenService *tokenService, GxsGroupDialog::Mode mode, RsGxsGroupId groupId) = 0; + virtual GxsGroupDialog *createNewGroupDialog() = 0; + virtual GxsGroupDialog *createGroupDialog(GxsGroupDialog::Mode mode, RsGxsGroupId groupId) = 0; virtual int shareKeyType() = 0; virtual GxsMessageFrameWidget *createMessageFrameWidget(const RsGxsGroupId &groupId) = 0; virtual void groupTreeCustomActions(RsGxsGroupId /*grpId*/, int /*subscribeFlags*/, QList &/*actions*/) {} @@ -198,8 +199,6 @@ private: QString mSettingsName; RsGxsGroupId mGroupId; RsGxsIfaceHelper *mInterface; - RsTokenService *mTokenService; - TokenQueue *mTokenQueue; GxsMessageFrameWidget *mMessageWidget; QTreeWidgetItem *mYourGroups; diff --git a/retroshare-gui/src/gui/gxschannels/GxsChannelDialog.cpp b/retroshare-gui/src/gui/gxschannels/GxsChannelDialog.cpp index 0f707f84b..693457eea 100644 --- a/retroshare-gui/src/gui/gxschannels/GxsChannelDialog.cpp +++ b/retroshare-gui/src/gui/gxschannels/GxsChannelDialog.cpp @@ -181,14 +181,14 @@ QString GxsChannelDialog::icon(IconType type) return ""; } -GxsGroupDialog *GxsChannelDialog::createNewGroupDialog(TokenQueue *tokenQueue) +GxsGroupDialog *GxsChannelDialog::createNewGroupDialog() { - return new GxsChannelGroupDialog(tokenQueue, this); + return new GxsChannelGroupDialog(this); } -GxsGroupDialog *GxsChannelDialog::createGroupDialog(TokenQueue *tokenQueue, RsTokenService *tokenService, GxsGroupDialog::Mode mode, RsGxsGroupId groupId) +GxsGroupDialog *GxsChannelDialog::createGroupDialog(GxsGroupDialog::Mode mode, RsGxsGroupId groupId) { - return new GxsChannelGroupDialog(tokenQueue, tokenService, mode, groupId, this); + return new GxsChannelGroupDialog(mode, groupId, this); } int GxsChannelDialog::shareKeyType() @@ -344,6 +344,11 @@ void GxsChannelDialog::toggleAutoDownload() }); } +bool GxsChannelDialog::getGroupStatistics(const RsGxsGroupId& groupId,GxsGroupStatistic& stat) +{ + return rsGxsChannels->getChannelStatistics(groupId,stat); +} + bool GxsChannelDialog::getGroupData(std::list& groupInfo) { std::vector groups; diff --git a/retroshare-gui/src/gui/gxschannels/GxsChannelDialog.h b/retroshare-gui/src/gui/gxschannels/GxsChannelDialog.h index c4233c428..b0b46205d 100644 --- a/retroshare-gui/src/gui/gxschannels/GxsChannelDialog.h +++ b/retroshare-gui/src/gui/gxschannels/GxsChannelDialog.h @@ -43,18 +43,21 @@ public: protected: /* GxsGroupFrameDialog */ - virtual RetroShareLink::enumType getLinkType() { return RetroShareLink::TYPE_CHANNEL; } - virtual GroupFrameSettings::Type groupFrameSettingsType() { return GroupFrameSettings::Channel; } - virtual QString getHelpString() const ; virtual bool getDistantSearchResults(TurtleRequestId id, std::map& group_infos); virtual TurtleRequestId distantSearch(const QString& search_string) ; virtual void checkRequestGroup(const RsGxsGroupId& grpId) ; + // Implementation of some abstract methods in GxsGroupFrameDialog + + virtual QString getHelpString() const override; + GroupFrameSettings::Type groupFrameSettingsType() override { return GroupFrameSettings::Channel; } + RetroShareLink::enumType getLinkType() override { return RetroShareLink::TYPE_CHANNEL; } + void groupInfoToGroupItemInfo(const RsGxsGenericGroupData *groupData, GroupItemInfo &groupItemInfo) override; const std::set getSearchRequests() const override { return mSearchResults ; } UserNotify *createUserNotify(QObject *parent) override; bool getGroupData(std::list& groupInfo) override; - void groupInfoToGroupItemInfo(const RsGxsGenericGroupData *groupData, GroupItemInfo &groupItemInfo) override; + bool getGroupStatistics(const RsGxsGroupId& groupId,GxsGroupStatistic& stat) override; private slots: void toggleAutoDownload(); @@ -67,8 +70,8 @@ private: virtual QString text(TextType type); virtual QString icon(IconType type); virtual QString settingsGroupName() { return "ChannelDialog"; } - virtual GxsGroupDialog *createNewGroupDialog(TokenQueue *tokenQueue); - virtual GxsGroupDialog *createGroupDialog(TokenQueue *tokenQueue, RsTokenService *tokenService, GxsGroupDialog::Mode mode, RsGxsGroupId groupId); + virtual GxsGroupDialog *createNewGroupDialog(); + virtual GxsGroupDialog *createGroupDialog(GxsGroupDialog::Mode mode, RsGxsGroupId groupId); virtual int shareKeyType(); virtual GxsMessageFrameWidget *createMessageFrameWidget(const RsGxsGroupId &groupId); virtual void groupTreeCustomActions(RsGxsGroupId grpId, int subscribeFlags, QList &actions); diff --git a/retroshare-gui/src/gui/gxschannels/GxsChannelGroupDialog.cpp b/retroshare-gui/src/gui/gxschannels/GxsChannelGroupDialog.cpp index 5732a706a..25ad04c30 100644 --- a/retroshare-gui/src/gui/gxschannels/GxsChannelGroupDialog.cpp +++ b/retroshare-gui/src/gui/gxschannels/GxsChannelGroupDialog.cpp @@ -59,15 +59,15 @@ const uint32_t ChannelCreateDefaultsFlags = ( GXS_GROUP_DEFAULTS_DISTRIB_PUBLIC const uint32_t ChannelEditEnabledFlags = ChannelCreateEnabledFlags; const uint32_t ChannelEditDefaultsFlags = ChannelCreateDefaultsFlags; -GxsChannelGroupDialog::GxsChannelGroupDialog(TokenQueue *tokenQueue, QWidget *parent) - : GxsGroupDialog(tokenQueue, ChannelCreateEnabledFlags, ChannelCreateDefaultsFlags, parent) +GxsChannelGroupDialog::GxsChannelGroupDialog(QWidget *parent) + : GxsGroupDialog(ChannelCreateEnabledFlags, ChannelCreateDefaultsFlags, parent) { ui.commentGroupBox->setEnabled(false); // These are here because comments_allowed are actually not used yet, so the group will not be changed by the setting and when ui.comments_allowed->setChecked(true); // the group info is displayed it will therefore be set to "disabled" in all cases although it is enabled. } -GxsChannelGroupDialog::GxsChannelGroupDialog(TokenQueue *tokenExternalQueue, RsTokenService *tokenService, Mode mode, RsGxsGroupId groupId, QWidget *parent) - : GxsGroupDialog(tokenExternalQueue, tokenService, mode, groupId, ChannelEditEnabledFlags, ChannelEditDefaultsFlags, parent) +GxsChannelGroupDialog::GxsChannelGroupDialog(Mode mode, RsGxsGroupId groupId, QWidget *parent) + : GxsGroupDialog(mode, groupId, ChannelEditEnabledFlags, ChannelEditDefaultsFlags, parent) { ui.commentGroupBox->setEnabled(false); // These are here because comments_allowed are actually not used yet, so the group will not be changed by the setting and when ui.comments_allowed->setChecked(true); // the group info is displayed it will therefore be set to "disabled" in all cases although it is enabled. @@ -129,17 +129,19 @@ void GxsChannelGroupDialog::prepareChannelGroup(RsGxsChannelGroup &group, const } } -bool GxsChannelGroupDialog::service_CreateGroup(uint32_t &token, const RsGroupMetaData &meta) +bool GxsChannelGroupDialog::service_createGroup(RsGroupMetaData& meta) { // Specific Function. RsGxsChannelGroup grp; prepareChannelGroup(grp, meta); - rsGxsChannels->createGroup(token, grp); + rsGxsChannels->createChannel(grp); + + meta = grp.mMeta; return true; } -bool GxsChannelGroupDialog::service_EditGroup(uint32_t &token, RsGroupMetaData &editedMeta) +bool GxsChannelGroupDialog::service_updateGroup(const RsGroupMetaData& editedMeta) { RsGxsChannelGroup grp; prepareChannelGroup(grp, editedMeta); @@ -147,44 +149,42 @@ bool GxsChannelGroupDialog::service_EditGroup(uint32_t &token, RsGroupMetaData & std::cerr << "GxsChannelGroupDialog::service_EditGroup() submitting changes"; std::cerr << std::endl; - rsGxsChannels->updateGroup(token, grp); - return true; + return rsGxsChannels->editChannel(grp); } -bool GxsChannelGroupDialog::service_loadGroup(uint32_t token, Mode /*mode*/, RsGroupMetaData& groupMetaData, QString &description) +bool GxsChannelGroupDialog::service_loadGroup(const RsGxsGenericGroupData *data, Mode /*mode*/, QString& description) { - std::cerr << "GxsChannelGroupDialog::service_loadGroup(" << token << ")"; - std::cerr << std::endl; + const RsGxsChannelGroup *pgroup = dynamic_cast(data); - std::vector groups; - if (!rsGxsChannels->getGroupData(token, groups)) + if (!pgroup) { - std::cerr << "GxsChannelGroupDialog::service_loadGroup() Error getting GroupData"; - std::cerr << std::endl; + std::cerr << "GxsChannelGroupDialog::service_loadGroup() Error supplied generic group data is not a RsGxsChannelGroup" << std::endl; return false; } - if (groups.size() != 1) - { - std::cerr << "GxsChannelGroupDialog::service_loadGroup() Error Group.size() != 1"; - std::cerr << std::endl; - return false; - } - - std::cerr << "GxsChannelsGroupDialog::service_loadGroup() Unfinished Loading"; - std::cerr << std::endl; - - const RsGxsChannelGroup &group = groups[0]; - groupMetaData = group.mMeta; + const RsGxsChannelGroup& group = *pgroup; description = QString::fromUtf8(group.mDescription.c_str()); if (group.mImage.mData) { QPixmap pixmap; - if (GxsIdDetails::loadPixmapFromData(group.mImage.mData, group.mImage.mSize,pixmap,GxsIdDetails::ORIGINAL)) { + if (GxsIdDetails::loadPixmapFromData(group.mImage.mData, group.mImage.mSize,pixmap,GxsIdDetails::ORIGINAL)) setLogo(pixmap); - } } return true; } + +bool GxsChannelGroupDialog::service_getGroupData(const RsGxsGroupId& grpId,RsGxsGenericGroupData *& data) +{ + std::vector forumsInfo ; + + if( rsGxsChannels->getChannelsInfo(std::list({grpId}),forumsInfo) && forumsInfo.size() == 1) + { + data = new RsGxsChannelGroup(forumsInfo[0]); + return true; + } + else + return false; + +} diff --git a/retroshare-gui/src/gui/gxschannels/GxsChannelGroupDialog.h b/retroshare-gui/src/gui/gxschannels/GxsChannelGroupDialog.h index c500912df..025d6a47d 100644 --- a/retroshare-gui/src/gui/gxschannels/GxsChannelGroupDialog.h +++ b/retroshare-gui/src/gui/gxschannels/GxsChannelGroupDialog.h @@ -29,15 +29,16 @@ class GxsChannelGroupDialog : public GxsGroupDialog Q_OBJECT public: - GxsChannelGroupDialog(TokenQueue *tokenQueue, QWidget *parent); - GxsChannelGroupDialog(TokenQueue *tokenExternalQueue, RsTokenService *tokenService, Mode mode, RsGxsGroupId groupId, QWidget *parent = NULL); + GxsChannelGroupDialog(QWidget *parent); + GxsChannelGroupDialog(Mode mode, RsGxsGroupId groupId, QWidget *parent = NULL); protected: - virtual void initUi(); - virtual QPixmap serviceImage(); - virtual bool service_CreateGroup(uint32_t &token, const RsGroupMetaData &meta); - virtual bool service_loadGroup(uint32_t token, Mode mode, RsGroupMetaData& groupMetaData, QString &description); - virtual bool service_EditGroup(uint32_t &token, RsGroupMetaData &editedMeta); + void initUi() override; + QPixmap serviceImage() override; + bool service_createGroup(RsGroupMetaData &meta) override; + bool service_loadGroup(const RsGxsGenericGroupData *data,Mode mode, QString& description) override; + bool service_updateGroup(const RsGroupMetaData& editedMeta) override; + bool service_getGroupData(const RsGxsGroupId& grpId,RsGxsGenericGroupData *& data) override; private: void prepareChannelGroup(RsGxsChannelGroup &group, const RsGroupMetaData &meta); diff --git a/retroshare-gui/src/gui/gxsforums/GxsForumGroupDialog.cpp b/retroshare-gui/src/gui/gxsforums/GxsForumGroupDialog.cpp index 20ab13c52..966115905 100644 --- a/retroshare-gui/src/gui/gxsforums/GxsForumGroupDialog.cpp +++ b/retroshare-gui/src/gui/gxsforums/GxsForumGroupDialog.cpp @@ -58,15 +58,15 @@ const uint32_t ForumCreateDefaultsFlags = ( GXS_GROUP_DEFAULTS_DISTRIB_PUBLIC const uint32_t ForumEditEnabledFlags = ForumCreateEnabledFlags; const uint32_t ForumEditDefaultsFlags = ForumCreateDefaultsFlags; -GxsForumGroupDialog::GxsForumGroupDialog(TokenQueue *tokenQueue, QWidget *parent) - : GxsGroupDialog(tokenQueue, ForumCreateEnabledFlags, ForumCreateDefaultsFlags, parent) +GxsForumGroupDialog::GxsForumGroupDialog(QWidget *parent) + : GxsGroupDialog(ForumCreateEnabledFlags, ForumCreateDefaultsFlags, parent) { ui.pubKeyShare_cb->setEnabled(true) ; ui.label_2->setToolTip(tr("

Put one of your identities here to allow others to send feedback and also have moderator rights on the forum. You may as well leave that field blank and keep the forum anonymously administrated.

")); } -GxsForumGroupDialog::GxsForumGroupDialog(TokenQueue *tokenExternalQueue, RsTokenService *tokenService, Mode mode, RsGxsGroupId groupId, QWidget *parent) - : GxsGroupDialog(tokenExternalQueue, tokenService, mode, groupId, ForumEditEnabledFlags, ForumEditDefaultsFlags, parent) +GxsForumGroupDialog::GxsForumGroupDialog(Mode mode, RsGxsGroupId groupId, QWidget *parent) + : GxsGroupDialog(mode, groupId, ForumEditEnabledFlags, ForumEditDefaultsFlags, parent) { ui.pubKeyShare_cb->setEnabled(true) ; } @@ -99,7 +99,7 @@ QPixmap GxsForumGroupDialog::serviceImage() return QPixmap(":/icons/png/forums.png"); } -bool GxsForumGroupDialog::service_CreateGroup(uint32_t &token, const RsGroupMetaData &meta) +bool GxsForumGroupDialog::service_createGroup(RsGroupMetaData& meta) { // Specific Function. RsGxsForumGroup grp; @@ -107,11 +107,16 @@ bool GxsForumGroupDialog::service_CreateGroup(uint32_t &token, const RsGroupMeta grp.mDescription = getDescription().toUtf8().constData(); getSelectedModerators(grp.mAdminList.ids); - rsGxsForums->createGroup(token, grp); - return true; + if(rsGxsForums->createForum(grp)) + { + meta = grp.mMeta; + return true; + } + else + return false; } -bool GxsForumGroupDialog::service_EditGroup(uint32_t &token, RsGroupMetaData &editedMeta) +bool GxsForumGroupDialog::service_updateGroup(const RsGroupMetaData& editedMeta) { RsGxsForumGroup grp(mGroupData); // start again from cached information. That allows to keep the pinned posts for instance. @@ -125,44 +130,45 @@ bool GxsForumGroupDialog::service_EditGroup(uint32_t &token, RsGroupMetaData &ed std::cerr << "GxsForumGroupDialog::service_EditGroup() submitting changes"; std::cerr << std::endl; - rsGxsForums->updateGroup(token, grp); - return true; + return rsGxsForums->editForum(grp); } -bool GxsForumGroupDialog::service_loadGroup(uint32_t token, Mode /*mode*/, RsGroupMetaData& groupMetaData, QString &description) +bool GxsForumGroupDialog::service_loadGroup(const RsGxsGenericGroupData *data, Mode /*mode*/, QString &description) { - std::cerr << "GxsForumGroupDialog::service_loadGroup(" << token << ")"; - std::cerr << std::endl; + const RsGxsForumGroup *pgroup = dynamic_cast(data); - std::vector groups; - - if (!rsGxsForums->getGroupData(token, groups)) + if (!pgroup) { - std::cerr << "GxsForumGroupDialog::service_loadGroup() Error getting GroupData"; - std::cerr << std::endl; + RsErr() << "GxsForumGroupDialog::service_loadGroup() supplied generic group is not a RsGxsForumGroup"<< std::endl; return false; } - if (groups.size() != 1) - { - std::cerr << "GxsForumGroupDialog::service_loadGroup() Error Group.size() != 1"; - std::cerr << std::endl; - return false; - } - - std::cerr << "GxsForumsGroupDialog::service_loadGroup() Unfinished Loading"; - std::cerr << std::endl; - // Information handled by GxsGroupDialog. description should rather be handled here in the service part! - groupMetaData = groups[0].mMeta; - description = QString::fromUtf8(groups[0].mDescription.c_str()); + description = QString::fromUtf8(pgroup->mDescription.c_str()); // Local information. Description should be handled here. - setSelectedModerators(groups[0].mAdminList.ids); + setSelectedModerators(pgroup->mAdminList.ids); - mGroupData = groups[0]; // keeps the private information + mGroupData = *pgroup; // keeps the private information return true; } + +bool GxsForumGroupDialog::service_getGroupData(const RsGxsGroupId& grpId,RsGxsGenericGroupData *& data) +{ + std::vector forumsInfo ; + + if( rsGxsForums->getForumsInfo(std::list({grpId}),forumsInfo) && forumsInfo.size() == 1) + { + data = new RsGxsForumGroup(forumsInfo[0]); + return true; + } + else + return false; + +} + + + diff --git a/retroshare-gui/src/gui/gxsforums/GxsForumGroupDialog.h b/retroshare-gui/src/gui/gxsforums/GxsForumGroupDialog.h index 51ca29082..de24a9bd6 100644 --- a/retroshare-gui/src/gui/gxsforums/GxsForumGroupDialog.h +++ b/retroshare-gui/src/gui/gxsforums/GxsForumGroupDialog.h @@ -29,15 +29,16 @@ class GxsForumGroupDialog : public GxsGroupDialog Q_OBJECT public: - GxsForumGroupDialog(TokenQueue *tokenQueue, QWidget *parent); - GxsForumGroupDialog(TokenQueue *tokenExternalQueue, RsTokenService *tokenService, Mode mode, RsGxsGroupId groupId, QWidget *parent); + GxsForumGroupDialog(QWidget *parent); + GxsForumGroupDialog(Mode mode, RsGxsGroupId groupId, QWidget *parent); protected: - virtual void initUi(); - virtual QPixmap serviceImage(); - virtual bool service_CreateGroup(uint32_t &token, const RsGroupMetaData &meta); - virtual bool service_loadGroup(uint32_t token, Mode mode, RsGroupMetaData& groupMetaData, QString &description); - virtual bool service_EditGroup(uint32_t &token, RsGroupMetaData &editedMeta); + void initUi() override; + QPixmap serviceImage() override; + bool service_createGroup(RsGroupMetaData& meta) override; + bool service_loadGroup(const RsGxsGenericGroupData *data,Mode mode, QString &description) override; + bool service_updateGroup(const RsGroupMetaData& editedMeta) override; + bool service_getGroupData(const RsGxsGroupId& grpId,RsGxsGenericGroupData *& data) override; private: RsGxsForumGroup mGroupData; diff --git a/retroshare-gui/src/gui/gxsforums/GxsForumsDialog.cpp b/retroshare-gui/src/gui/gxsforums/GxsForumsDialog.cpp index 87396f9a1..787ebbb2d 100644 --- a/retroshare-gui/src/gui/gxsforums/GxsForumsDialog.cpp +++ b/retroshare-gui/src/gui/gxsforums/GxsForumsDialog.cpp @@ -93,6 +93,12 @@ bool GxsForumsDialog::getGroupData(std::list& groupInfo) return true; } +bool GxsForumsDialog::getGroupStatistics(const RsGxsGroupId& groupId,GxsGroupStatistic& stat) +{ + return rsGxsForums->getForumStatistics(groupId,stat); +} + + QString GxsForumsDialog::getHelpString() const { @@ -181,14 +187,14 @@ QString GxsForumsDialog::icon(IconType type) return ""; } -GxsGroupDialog *GxsForumsDialog::createNewGroupDialog(TokenQueue *tokenQueue) +GxsGroupDialog *GxsForumsDialog::createNewGroupDialog() { - return new GxsForumGroupDialog(tokenQueue, this); + return new GxsForumGroupDialog(this); } -GxsGroupDialog *GxsForumsDialog::createGroupDialog(TokenQueue *tokenQueue, RsTokenService *tokenService, GxsGroupDialog::Mode mode, RsGxsGroupId groupId) +GxsGroupDialog *GxsForumsDialog::createGroupDialog(GxsGroupDialog::Mode mode, RsGxsGroupId groupId) { - return new GxsForumGroupDialog(tokenQueue, tokenService, mode, groupId, this); + return new GxsForumGroupDialog(mode, groupId, this); } int GxsForumsDialog::shareKeyType() diff --git a/retroshare-gui/src/gui/gxsforums/GxsForumsDialog.h b/retroshare-gui/src/gui/gxsforums/GxsForumsDialog.h index 8854ea32e..75d10a1e1 100644 --- a/retroshare-gui/src/gui/gxsforums/GxsForumsDialog.h +++ b/retroshare-gui/src/gui/gxsforums/GxsForumsDialog.h @@ -46,18 +46,21 @@ protected: UserNotify *createUserNotify(QObject *parent) override; bool getGroupData(std::list& groupInfo) override; + bool getGroupStatistics(const RsGxsGroupId& groupId,GxsGroupStatistic& stat) override; void groupInfoToGroupItemInfo(const RsGxsGenericGroupData *groupData, GroupItemInfo &groupItemInfo) override; private: /* GxsGroupFrameDialog */ - virtual QString text(TextType type); - virtual QString icon(IconType type); - virtual QString settingsGroupName() { return "ForumsDialog"; } - virtual GxsGroupDialog *createNewGroupDialog(TokenQueue *tokenQueue); - virtual GxsGroupDialog *createGroupDialog(TokenQueue *tokenQueue, RsTokenService *tokenService, GxsGroupDialog::Mode mode, RsGxsGroupId groupId); - virtual int shareKeyType(); - virtual GxsMessageFrameWidget *createMessageFrameWidget(const RsGxsGroupId &groupId); - virtual uint32_t requestGroupSummaryType() { return GXS_REQUEST_TYPE_GROUP_DATA; } // request complete group data + QString text(TextType type)override ; + QString icon(IconType type)override ; + QString settingsGroupName() override { return "ForumsDialog"; } + + GxsGroupDialog *createNewGroupDialog() override; + GxsGroupDialog *createGroupDialog(GxsGroupDialog::Mode mode, RsGxsGroupId groupId) override; + + int shareKeyType() override; + GxsMessageFrameWidget *createMessageFrameWidget(const RsGxsGroupId &groupId) override; + uint32_t requestGroupSummaryType() override { return GXS_REQUEST_TYPE_GROUP_DATA; } // request complete group data void handleEvent_main_thread(std::shared_ptr event); From 0f5fd198a4af0cedc0afe3ea27df46708529ffd9 Mon Sep 17 00:00:00 2001 From: csoler Date: Sun, 22 Mar 2020 22:06:49 +0100 Subject: [PATCH 11/15] removed debug info in db access --- libretroshare/src/gxs/rsdataservice.cc | 3 --- libretroshare/src/gxs/rsgxsdataaccess.cc | 1 - retroshare-gui/src/gui/gxsforums/GxsForumThreadWidget.cpp | 2 ++ 3 files changed, 2 insertions(+), 4 deletions(-) diff --git a/libretroshare/src/gxs/rsdataservice.cc b/libretroshare/src/gxs/rsdataservice.cc index ee546be06..3dc99a85f 100644 --- a/libretroshare/src/gxs/rsdataservice.cc +++ b/libretroshare/src/gxs/rsdataservice.cc @@ -25,9 +25,6 @@ * #define RS_DATA_SERVICE_DEBUG_TIME 1 * #define RS_DATA_SERVICE_DEBUG_CACHE 1 ****/ -#define RS_DATA_SERVICE_DEBUG 1 -#define RS_DATA_SERVICE_DEBUG_TIME 1 -#define RS_DATA_SERVICE_DEBUG_CACHE 1 #include #include diff --git a/libretroshare/src/gxs/rsgxsdataaccess.cc b/libretroshare/src/gxs/rsgxsdataaccess.cc index 0eeccba63..59c828e60 100644 --- a/libretroshare/src/gxs/rsgxsdataaccess.cc +++ b/libretroshare/src/gxs/rsgxsdataaccess.cc @@ -29,7 +29,6 @@ /*********** * #define DATA_DEBUG 1 **********/ -#define DATA_DEBUG 1 RsGxsDataAccess::RsGxsDataAccess(RsGeneralDataService* ds) : mDataStore(ds), mDataMutex("RsGxsDataAccess"), mNextToken(0) {} diff --git a/retroshare-gui/src/gui/gxsforums/GxsForumThreadWidget.cpp b/retroshare-gui/src/gui/gxsforums/GxsForumThreadWidget.cpp index 1d246c43f..2b82fd530 100644 --- a/retroshare-gui/src/gui/gxsforums/GxsForumThreadWidget.cpp +++ b/retroshare-gui/src/gui/gxsforums/GxsForumThreadWidget.cpp @@ -872,6 +872,7 @@ static QString getDurationString(uint32_t days) void GxsForumThreadWidget::updateForumDescription() { + std::cerr << "Updating forum description" << std::endl; if (!mThreadId.isNull()) return; @@ -1731,6 +1732,7 @@ void GxsForumThreadWidget::updateGroupData() * after a blocking call to RetroShare API complete */ mForumGroup = group; + mThreadId.clear(); ui->threadTreeWidget->setColumnHidden(RsGxsForumModel::COLUMN_THREAD_DISTRIBUTION, !IS_GROUP_PGP_KNOWN_AUTHED(mForumGroup.mMeta.mSignFlags) && !(IS_GROUP_PGP_AUTHED(mForumGroup.mMeta.mSignFlags))); ui->subscribeToolButton->setHidden(IS_GROUP_SUBSCRIBED(mForumGroup.mMeta.mSubscribeFlags)) ; From 6616e8a6b308e0a02c78423d56d1d774dc068c68 Mon Sep 17 00:00:00 2001 From: csoler Date: Sun, 22 Mar 2020 23:35:34 +0100 Subject: [PATCH 12/15] fixed priority problem in async request of group data tht shows up in RsGxsForumThreadWidget --- libretroshare/src/retroshare/rsgxsifacehelper.h | 14 +++++++------- libretroshare/src/services/p3gxsforums.cc | 2 +- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/libretroshare/src/retroshare/rsgxsifacehelper.h b/libretroshare/src/retroshare/rsgxsifacehelper.h index 7be714103..8d12893f4 100644 --- a/libretroshare/src/retroshare/rsgxsifacehelper.h +++ b/libretroshare/src/retroshare/rsgxsifacehelper.h @@ -46,6 +46,7 @@ enum class TokenRequestType: uint8_t MSG_RELATED_INFO = 0x03, GROUP_STATISTICS = 0x04, SERVICE_STATISTICS = 0x05, + NO_KILL_TYPE = 0x06, }; class RsGxsIfaceHelper @@ -244,15 +245,14 @@ public: } /// @see RsTokenService::requestGroupInfo - bool requestGroupInfo( uint32_t& token, const RsTokReqOptions& opts, - const std::list &groupIds ) + bool requestGroupInfo( uint32_t& token, const RsTokReqOptions& opts, const std::list &groupIds, bool high_priority_request = false ) { - cancelActiveRequestTokens(TokenRequestType::GROUP_INFO); + cancelActiveRequestTokens(TokenRequestType::GROUP_INFO); if( mTokenService.requestGroupInfo(token, 0, opts, groupIds)) { RS_STACK_MUTEX(mMtx); - mActiveTokens[token]=TokenRequestType::GROUP_INFO; + mActiveTokens[token]=high_priority_request? (TokenRequestType::NO_KILL_TYPE) : (TokenRequestType::GROUP_INFO); locked_dumpTokens(); return true; } @@ -261,14 +261,14 @@ public: } /// @see RsTokenService::requestGroupInfo - bool requestGroupInfo(uint32_t& token, const RsTokReqOptions& opts) + bool requestGroupInfo(uint32_t& token, const RsTokReqOptions& opts, bool high_priority_request = false) { - cancelActiveRequestTokens(TokenRequestType::GROUP_INFO); + cancelActiveRequestTokens(TokenRequestType::GROUP_INFO); if( mTokenService.requestGroupInfo(token, 0, opts)) { RS_STACK_MUTEX(mMtx); - mActiveTokens[token]=TokenRequestType::GROUP_INFO; + mActiveTokens[token]=high_priority_request? (TokenRequestType::NO_KILL_TYPE) : (TokenRequestType::GROUP_INFO); locked_dumpTokens(); return true; } diff --git a/libretroshare/src/services/p3gxsforums.cc b/libretroshare/src/services/p3gxsforums.cc index 442878bba..c7f3fddcf 100644 --- a/libretroshare/src/services/p3gxsforums.cc +++ b/libretroshare/src/services/p3gxsforums.cc @@ -679,7 +679,7 @@ bool p3GxsForums::getForumsInfo( const std::list& forumIds, std::v } else { - if( !requestGroupInfo(token, opts, forumIds) || waitToken(token,std::chrono::milliseconds(5000)) != RsTokenService::COMPLETE ) + if( !requestGroupInfo(token, opts, forumIds, forumIds.size()==1) || waitToken(token,std::chrono::milliseconds(5000)) != RsTokenService::COMPLETE ) return false; } return getGroupData(token, forumsInfo); From 5dcbb978c3c2b479d23cea32623faf2f3e9e99d5 Mon Sep 17 00:00:00 2001 From: csoler Date: Thu, 26 Mar 2020 16:47:37 +0100 Subject: [PATCH 13/15] improvement of autoloading of GxsGroupFrameDialog --- libretroshare/src/retroshare/rsgxsifacehelper.h | 2 +- retroshare-gui/src/gui/gxs/GxsGroupFrameDialog.cpp | 6 ++++-- retroshare-gui/src/gui/gxsforums/GxsForumThreadWidget.cpp | 3 +-- 3 files changed, 6 insertions(+), 5 deletions(-) diff --git a/libretroshare/src/retroshare/rsgxsifacehelper.h b/libretroshare/src/retroshare/rsgxsifacehelper.h index 8d12893f4..0d9965c6c 100644 --- a/libretroshare/src/retroshare/rsgxsifacehelper.h +++ b/libretroshare/src/retroshare/rsgxsifacehelper.h @@ -393,7 +393,7 @@ protected: */ RsTokenService::GxsRequestStatus waitToken( uint32_t token, - std::chrono::milliseconds maxWait = std::chrono::milliseconds(10000), + std::chrono::milliseconds maxWait = std::chrono::milliseconds(20000), std::chrono::milliseconds checkEvery = std::chrono::milliseconds(100), bool auto_delete_if_unsuccessful=true) { diff --git a/retroshare-gui/src/gui/gxs/GxsGroupFrameDialog.cpp b/retroshare-gui/src/gui/gxs/GxsGroupFrameDialog.cpp index d07c73358..08833d9e0 100644 --- a/retroshare-gui/src/gui/gxs/GxsGroupFrameDialog.cpp +++ b/retroshare-gui/src/gui/gxs/GxsGroupFrameDialog.cpp @@ -169,13 +169,15 @@ void GxsGroupFrameDialog::initUi() connect(NotifyQt::getInstance(), SIGNAL(settingsChanged()), this, SLOT(settingsChanged())); settingsChanged(); } + + mInitialized = true; } void GxsGroupFrameDialog::showEvent(QShowEvent *event) { - if (!mInitialized) { + if (!mInitialized || ui->groupTreeWidget->treeWidget()->topLevelItemCount() == 0) + { /* Problem: virtual methods cannot be used in constructor */ - mInitialized = true; initUi(); } diff --git a/retroshare-gui/src/gui/gxsforums/GxsForumThreadWidget.cpp b/retroshare-gui/src/gui/gxsforums/GxsForumThreadWidget.cpp index 2b82fd530..1314c1b1d 100644 --- a/retroshare-gui/src/gui/gxsforums/GxsForumThreadWidget.cpp +++ b/retroshare-gui/src/gui/gxsforums/GxsForumThreadWidget.cpp @@ -392,11 +392,10 @@ void GxsForumThreadWidget::blank() //mThreadModel->clear(); -#ifdef SUSPENDED_CODE mStateHelper->setWidgetEnabled(ui->newthreadButton, false); mStateHelper->setWidgetEnabled(ui->previousButton, false); mStateHelper->setWidgetEnabled(ui->nextButton, false); -#endif + ui->versions_CB->hide(); } From 8cf78b072be282768d2e626c1b30f1c80c1b9d40 Mon Sep 17 00:00:00 2001 From: csoler Date: Thu, 26 Mar 2020 17:10:29 +0100 Subject: [PATCH 14/15] added more info when loading forums --- .../src/gui/feeds/GxsChannelPostItem.cpp | 2 +- .../src/gui/feeds/GxsForumGroupItem.cpp | 2 +- .../src/gui/feeds/GxsForumMsgItem.cpp | 2 +- .../src/gui/feeds/PostedGroupItem.cpp | 2 +- retroshare-gui/src/gui/gxs/GxsIdDetails.cpp | 2 +- .../src/gui/gxs/GxsMessageFramePostWidget.cpp | 2 +- .../gui/gxsforums/GxsForumThreadWidget.cpp | 39 +++++++++++++------ .../src/gui/gxsforums/GxsForumThreadWidget.h | 5 ++- 8 files changed, 38 insertions(+), 18 deletions(-) diff --git a/retroshare-gui/src/gui/feeds/GxsChannelPostItem.cpp b/retroshare-gui/src/gui/feeds/GxsChannelPostItem.cpp index c7cc02a11..1e0fc57b9 100644 --- a/retroshare-gui/src/gui/feeds/GxsChannelPostItem.cpp +++ b/retroshare-gui/src/gui/feeds/GxsChannelPostItem.cpp @@ -116,7 +116,7 @@ void GxsChannelPostItem::setup() mCloseOnRead = false; /* clear ui */ - ui->titleLabel->setText(tr("Loading")); + ui->titleLabel->setText(tr("Loading...")); ui->datetimelabel->clear(); ui->filelabel->clear(); ui->newCommentLabel->hide(); diff --git a/retroshare-gui/src/gui/feeds/GxsForumGroupItem.cpp b/retroshare-gui/src/gui/feeds/GxsForumGroupItem.cpp index 57cf259ab..ee96c068e 100644 --- a/retroshare-gui/src/gui/feeds/GxsForumGroupItem.cpp +++ b/retroshare-gui/src/gui/feeds/GxsForumGroupItem.cpp @@ -59,7 +59,7 @@ void GxsForumGroupItem::setup() setAttribute(Qt::WA_DeleteOnClose, true); /* clear ui */ - ui->nameLabel->setText(tr("Loading")); + ui->nameLabel->setText(tr("Loading...")); ui->titleLabel->clear(); ui->descLabel->clear(); diff --git a/retroshare-gui/src/gui/feeds/GxsForumMsgItem.cpp b/retroshare-gui/src/gui/feeds/GxsForumMsgItem.cpp index 50decda82..f6afc8cdd 100644 --- a/retroshare-gui/src/gui/feeds/GxsForumMsgItem.cpp +++ b/retroshare-gui/src/gui/feeds/GxsForumMsgItem.cpp @@ -97,7 +97,7 @@ void GxsForumMsgItem::setup() mCloseOnRead = false; /* clear ui */ - ui->titleLabel->setText(tr("Loading")); + ui->titleLabel->setText(tr("Loading...")); ui->subjectLabel->clear(); ui->timestamplabel->clear(); ui->parentNameLabel->clear(); diff --git a/retroshare-gui/src/gui/feeds/PostedGroupItem.cpp b/retroshare-gui/src/gui/feeds/PostedGroupItem.cpp index d512a0b7a..6b39566aa 100644 --- a/retroshare-gui/src/gui/feeds/PostedGroupItem.cpp +++ b/retroshare-gui/src/gui/feeds/PostedGroupItem.cpp @@ -60,7 +60,7 @@ void PostedGroupItem::setup() setAttribute(Qt::WA_DeleteOnClose, true); /* clear ui */ - ui->nameLabel->setText(tr("Loading")); + ui->nameLabel->setText(tr("Loading...")); ui->titleLabel->clear(); ui->descLabel->clear(); diff --git a/retroshare-gui/src/gui/gxs/GxsIdDetails.cpp b/retroshare-gui/src/gui/gxs/GxsIdDetails.cpp index aa2210bee..22469575f 100644 --- a/retroshare-gui/src/gui/gxs/GxsIdDetails.cpp +++ b/retroshare-gui/src/gui/gxs/GxsIdDetails.cpp @@ -935,7 +935,7 @@ QPixmap GxsIdDetails::drawIdentIcon( QString hash, quint16 width, bool rotate) QString GxsIdDetails::getLoadingText(const RsGxsId &id) { - return QString("%1... %2").arg(QApplication::translate("GxsIdDetails", "Loading"), QString::fromStdString(id.toStdString().substr(0, 5))); + return QString("%1... %2").arg(QApplication::translate("GxsIdDetails", "Loading..."), QString::fromStdString(id.toStdString().substr(0, 5))); } QString GxsIdDetails::getFailedText(const RsGxsId &id) diff --git a/retroshare-gui/src/gui/gxs/GxsMessageFramePostWidget.cpp b/retroshare-gui/src/gui/gxs/GxsMessageFramePostWidget.cpp index 906c0d8de..4be7db243 100644 --- a/retroshare-gui/src/gui/gxs/GxsMessageFramePostWidget.cpp +++ b/retroshare-gui/src/gui/gxs/GxsMessageFramePostWidget.cpp @@ -50,7 +50,7 @@ GxsMessageFramePostWidget::~GxsMessageFramePostWidget() void GxsMessageFramePostWidget::groupIdChanged() { - mGroupName = groupId().isNull () ? "" : tr("Loading"); + mGroupName = groupId().isNull () ? "" : tr("Loading..."); groupNameChanged(mGroupName); emit groupChanged(this); diff --git a/retroshare-gui/src/gui/gxsforums/GxsForumThreadWidget.cpp b/retroshare-gui/src/gui/gxsforums/GxsForumThreadWidget.cpp index 1314c1b1d..b0908ce18 100644 --- a/retroshare-gui/src/gui/gxsforums/GxsForumThreadWidget.cpp +++ b/retroshare-gui/src/gui/gxsforums/GxsForumThreadWidget.cpp @@ -869,8 +869,27 @@ static QString getDurationString(uint32_t days) } } -void GxsForumThreadWidget::updateForumDescription() +void GxsForumThreadWidget::setForumDescriptionLoading() { + ui->postText->setText(tr("Loading...")); +} + +void GxsForumThreadWidget::clearForumDescription() +{ + ui->postText->clear(); +} + +void GxsForumThreadWidget::updateForumDescription(bool success) +{ + if(!success) + { + QString forum_description = QString("ERROR: Forum could not be loaded. Database might be in heavy use. Please try later."); + ui->postText->setText(forum_description); + mStateHelper->setWidgetEnabled(ui->newthreadButton, false); + + return; + } + std::cerr << "Updating forum description" << std::endl; if (!mThreadId.isNull()) return; @@ -1697,6 +1716,8 @@ void GxsForumThreadWidget::updateGroupData() // ui->threadTreeWidget->selectionModel()->reset(); // mThreadProxyModel->clear(); + setForumDescriptionLoading(); + RsThread::async([this]() { // 1 - get message data from p3GxsForums @@ -1705,18 +1726,14 @@ void GxsForumThreadWidget::updateGroupData() std::vector groups; forumIds.push_back(groupId()); + bool success = false; if(!rsGxsForums->getForumsInfo(forumIds,groups)) - { std::cerr << __PRETTY_FUNCTION__ << " failed to retrieve forum group info for forum " << groupId() << std::endl; - return; - } - - if(groups.size() != 1) - { + else if(groups.size() != 1) std::cerr << __PRETTY_FUNCTION__ << " obtained more than one group info for forum " << groupId() << std::endl; - return; - } + else + success = true; // 2 - sort the messages into a proper hierarchy @@ -1724,7 +1741,7 @@ void GxsForumThreadWidget::updateGroupData() // 3 - update the model in the UI thread. - RsQThreadUtils::postToObject( [group,this]() + RsQThreadUtils::postToObject( [group,success,this]() { /* Here it goes any code you want to be executed on the Qt Gui * thread, for example to update the data model with new information @@ -1736,7 +1753,7 @@ void GxsForumThreadWidget::updateGroupData() ui->threadTreeWidget->setColumnHidden(RsGxsForumModel::COLUMN_THREAD_DISTRIBUTION, !IS_GROUP_PGP_KNOWN_AUTHED(mForumGroup.mMeta.mSignFlags) && !(IS_GROUP_PGP_AUTHED(mForumGroup.mMeta.mSignFlags))); ui->subscribeToolButton->setHidden(IS_GROUP_SUBSCRIBED(mForumGroup.mMeta.mSubscribeFlags)) ; - updateForumDescription(); + updateForumDescription(success); }, this ); diff --git a/retroshare-gui/src/gui/gxsforums/GxsForumThreadWidget.h b/retroshare-gui/src/gui/gxsforums/GxsForumThreadWidget.h index a548cda07..2dc7f4b78 100644 --- a/retroshare-gui/src/gui/gxsforums/GxsForumThreadWidget.h +++ b/retroshare-gui/src/gui/gxsforums/GxsForumThreadWidget.h @@ -170,11 +170,14 @@ private: static void loadAuthorIdCallback(GxsIdDetailsType type, const RsIdentityDetails &details, QObject *object, const QVariant &/*data*/); void updateMessageData(const RsGxsMessageId& msgId); - void updateForumDescription(); + void updateForumDescription(bool success); void handleEvent_main_thread(std::shared_ptr event); private: + void setForumDescriptionLoading(); + void clearForumDescription(); + RsGxsGroupId mLastForumID; RsGxsMessageId mThreadId; RsGxsMessageId mOrigThreadId; From c18dfb39c3ccb1ad46da2048003818b4e02bb3fa Mon Sep 17 00:00:00 2001 From: csoler Date: Thu, 26 Mar 2020 23:19:34 +0100 Subject: [PATCH 15/15] added some more debug info and proper error output to GxsDb --- libretroshare/src/gxs/rsdataservice.cc | 14 ++-- libretroshare/src/gxs/rsgenexchange.h | 2 +- libretroshare/src/gxs/rsgxsdataaccess.cc | 2 + libretroshare/src/retroshare/rsgxsiface.h | 6 ++ .../src/retroshare/rsgxsifacehelper.h | 17 +++- .../src/gui/gxs/GxsGroupFrameDialog.cpp | 19 +++-- .../gui/gxsforums/GxsForumThreadWidget.cpp | 83 ++++++++++++------- .../src/gui/gxsforums/GxsForumThreadWidget.h | 1 + 8 files changed, 98 insertions(+), 46 deletions(-) diff --git a/libretroshare/src/gxs/rsdataservice.cc b/libretroshare/src/gxs/rsdataservice.cc index 3dc99a85f..cc215dc14 100644 --- a/libretroshare/src/gxs/rsdataservice.cc +++ b/libretroshare/src/gxs/rsdataservice.cc @@ -26,6 +26,10 @@ * #define RS_DATA_SERVICE_DEBUG_CACHE 1 ****/ +#define RS_DATA_SERVICE_DEBUG 1 +#define RS_DATA_SERVICE_DEBUG_TIME 1 +#define RS_DATA_SERVICE_DEBUG_CACHE 1 + #include #include #include @@ -1312,7 +1316,7 @@ int RsDataService::retrieveGxsMsgMetaData(const GxsMsgReq& reqIds, GxsMsgMetaRes { locked_retrieveMsgMeta(c, metaSet); #ifdef RS_DATA_SERVICE_DEBUG_CACHE - std::cerr << "Retrieving (all) Msg metadata grpId=" << grpId << ", " << std::dec << metaSet.size() << " messages" << std::endl; + std::cerr << mDbName << ": Retrieving (all) Msg metadata grpId=" << grpId << ", " << std::dec << metaSet.size() << " messages" << std::endl; #endif } }else{ @@ -1329,7 +1333,7 @@ int RsDataService::retrieveGxsMsgMetaData(const GxsMsgReq& reqIds, GxsMsgMetaRes { locked_retrieveMsgMeta(c, metaSet); #ifdef RS_DATA_SERVICE_DEBUG_CACHE - std::cerr << "Retrieving Msg metadata grpId=" << grpId << ", " << std::dec << metaSet.size() << " messages" << std::endl; + std::cerr << mDbName << ": Retrieving Msg metadata grpId=" << grpId << ", " << std::dec << metaSet.size() << " messages" << std::endl; #endif } } @@ -1414,7 +1418,7 @@ int RsDataService::retrieveGxsGrpMetaData(RsGxsGrpMetaTemporaryMap& grp) { grp[g->mGroupId] = g; #ifdef RS_DATA_SERVICE_DEBUG_CACHE - std::cerr << (void *)this << ": Retrieving (all) Grp metadata grpId=" << g->mGroupId << std::endl; + std::cerr << (void *)this << " " << mDbName << ": Retrieving (all) Grp metadata grpId=" << g->mGroupId << std::endl; #endif } valid = c->moveToNext(); @@ -1441,14 +1445,14 @@ int RsDataService::retrieveGxsGrpMetaData(RsGxsGrpMetaTemporaryMap& grp) if(itt != mGrpMetaDataCache.end()) { #ifdef RS_DATA_SERVICE_DEBUG_CACHE - std::cerr << "Retrieving Grp metadata grpId=" << mit->first << " from cache!" << std::endl; + std::cerr << mDbName << ": Retrieving Grp metadata grpId=" << mit->first << " from cache!" << std::endl; #endif grp[mit->first] = itt->second ; } else { #ifdef RS_DATA_SERVICE_DEBUG_CACHE - std::cerr << "Retrieving Grp metadata grpId=" << mit->first ; + std::cerr << mDbName << ": Retrieving Grp metadata grpId=" << mit->first ; #endif const RsGxsGroupId& grpId = mit->first; diff --git a/libretroshare/src/gxs/rsgenexchange.h b/libretroshare/src/gxs/rsgenexchange.h index 49fd8b2e2..840dc97b3 100644 --- a/libretroshare/src/gxs/rsgenexchange.h +++ b/libretroshare/src/gxs/rsgenexchange.h @@ -726,7 +726,7 @@ public: virtual void setSyncPeriod(const RsGxsGroupId& grpId,uint32_t age_in_secs) ; virtual bool getGroupNetworkStats(const RsGxsGroupId& grpId,RsGroupNetworkStats& stats); - uint16_t serviceType() const { return mServType ; } + uint16_t serviceType() const override { return mServType ; } uint32_t serviceFullType() const { return RsServiceInfo::RsServiceInfoUIn16ToFullServiceId(mServType); } virtual RsReputationLevel minReputationForForwardingMessages( diff --git a/libretroshare/src/gxs/rsgxsdataaccess.cc b/libretroshare/src/gxs/rsgxsdataaccess.cc index 59c828e60..373d9a872 100644 --- a/libretroshare/src/gxs/rsgxsdataaccess.cc +++ b/libretroshare/src/gxs/rsgxsdataaccess.cc @@ -30,6 +30,8 @@ * #define DATA_DEBUG 1 **********/ +#define DATA_DEBUG 1 + RsGxsDataAccess::RsGxsDataAccess(RsGeneralDataService* ds) : mDataStore(ds), mDataMutex("RsGxsDataAccess"), mNextToken(0) {} diff --git a/libretroshare/src/retroshare/rsgxsiface.h b/libretroshare/src/retroshare/rsgxsiface.h index 54a27656d..7bb6bba28 100644 --- a/libretroshare/src/retroshare/rsgxsiface.h +++ b/libretroshare/src/retroshare/rsgxsiface.h @@ -110,6 +110,12 @@ struct RsGxsChanges : RsEvent */ struct RsGxsIface { + /*! + * \brief serviceType + * \return The 16-bits service type. See @serialiser/rsserviceids.h + */ + virtual uint16_t serviceType() const =0; + /*! * Gxs services should call this for automatic handling of * changes, send diff --git a/libretroshare/src/retroshare/rsgxsifacehelper.h b/libretroshare/src/retroshare/rsgxsifacehelper.h index 0d9965c6c..2a9b5bba3 100644 --- a/libretroshare/src/retroshare/rsgxsifacehelper.h +++ b/libretroshare/src/retroshare/rsgxsifacehelper.h @@ -26,6 +26,7 @@ #include #include "retroshare/rsgxsiface.h" +#include "retroshare/rsservicecontrol.h" #include "retroshare/rsreputations.h" #include "rsgxsflags.h" #include "util/rsdeprecate.h" @@ -454,9 +455,19 @@ private: void locked_dumpTokens() { - std::cerr << "Active tokens (this=" << (void*)this << "): " ; - for(auto it: mActiveTokens) - std::cerr << std::dec << it.first << " (" << static_cast(it.second) << ") " ; + uint16_t service_id = mGxs.serviceType(); + + uint32_t count[7] = {0}; + + std::cerr << "Service 0x0" << std::hex << service_id + << " (" << rsServiceControl->getServiceName(RsServiceInfo::RsServiceInfoUIn16ToFullServiceId(service_id)) + << ") this=0x" << (void*)this << ") Active tokens (per type): " ; + + for(auto& it: mActiveTokens) // let's count how many token of each type we've got. + ++count[static_cast(it.second)]; + + for(uint32_t i=0;i<7;++i) + std::cerr /* << i << ":" */ << count[i] << " "; std::cerr << std::endl; } }; diff --git a/retroshare-gui/src/gui/gxs/GxsGroupFrameDialog.cpp b/retroshare-gui/src/gui/gxs/GxsGroupFrameDialog.cpp index 08833d9e0..244676b6c 100644 --- a/retroshare-gui/src/gui/gxs/GxsGroupFrameDialog.cpp +++ b/retroshare-gui/src/gui/gxs/GxsGroupFrameDialog.cpp @@ -175,7 +175,7 @@ void GxsGroupFrameDialog::initUi() void GxsGroupFrameDialog::showEvent(QShowEvent *event) { - if (!mInitialized || ui->groupTreeWidget->treeWidget()->topLevelItemCount() == 0) + if (!mInitialized ) { /* Problem: virtual methods cannot be used in constructor */ @@ -1028,6 +1028,8 @@ void GxsGroupFrameDialog::updateGroupSummary() std::cerr << __PRETTY_FUNCTION__ << " failed to collect group info " << std::endl; return; } + if(groupInfo.empty()) + return; RsQThreadUtils::postToObject( [this,groupInfo]() { @@ -1049,17 +1051,18 @@ void GxsGroupFrameDialog::updateGroupSummary() mNavigatePendingGroupId.clear(); mNavigatePendingMsgId.clear(); } - // update the local cache in order to avoid re-asking the data when the UI wants it (this happens on ::show() for instance) - mCachedGroupMetas.clear(); + // update the local cache in order to avoid re-asking the data when the UI wants it (this happens on ::show() for instance) + + mCachedGroupMetas.clear(); // now delete the data that is not used anymore - for(auto& g:groupInfo) - { - mCachedGroupMetas[g->mMeta.mGroupId] = g->mMeta; - delete g; - } + for(auto& g:groupInfo) + { + mCachedGroupMetas[g->mMeta.mGroupId] = g->mMeta; + delete g; + } }, this ); }); diff --git a/retroshare-gui/src/gui/gxsforums/GxsForumThreadWidget.cpp b/retroshare-gui/src/gui/gxsforums/GxsForumThreadWidget.cpp index b0908ce18..37b479e6a 100644 --- a/retroshare-gui/src/gui/gxsforums/GxsForumThreadWidget.cpp +++ b/retroshare-gui/src/gui/gxsforums/GxsForumThreadWidget.cpp @@ -1102,6 +1102,19 @@ void GxsForumThreadWidget::insertMessage() // markMsgAsRead(); } +void GxsForumThreadWidget::setMessageLoadingError(const QString& error) +{ + ui->time_label->setText(QString("")); + ui->by_label->setId(RsGxsId()); + ui->lineRight->show(); + ui->lineLeft->show(); + ui->by_text_label->show(); + ui->by_label->show(); + ui->threadTreeWidget->setFocus(); + + ui->postText->setText(error); +} + void GxsForumThreadWidget::insertMessageData(const RsGxsForumMsg &msg) { /* As some time has elapsed since request - check that this is still the current msg. @@ -1735,28 +1748,32 @@ void GxsForumThreadWidget::updateGroupData() else success = true; - // 2 - sort the messages into a proper hierarchy - - RsGxsForumGroup group(groups[0]); // we use a copy to share the object in order to avoid group deletion while we're in the thread. - - // 3 - update the model in the UI thread. - - RsQThreadUtils::postToObject( [group,success,this]() + if(success) { - /* Here it goes any code you want to be executed on the Qt Gui + // 2 - sort the messages into a proper hierarchy + + RsGxsForumGroup group(groups[0]); // we use a copy to share the object in order to avoid group deletion while we're in the thread. + + // 3 - update the model in the UI thread. + + RsQThreadUtils::postToObject( [group,this]() + { + /* Here it goes any code you want to be executed on the Qt Gui * thread, for example to update the data model with new information * after a blocking call to RetroShare API complete */ - mForumGroup = group; - mThreadId.clear(); + mForumGroup = group; + mThreadId.clear(); - ui->threadTreeWidget->setColumnHidden(RsGxsForumModel::COLUMN_THREAD_DISTRIBUTION, !IS_GROUP_PGP_KNOWN_AUTHED(mForumGroup.mMeta.mSignFlags) && !(IS_GROUP_PGP_AUTHED(mForumGroup.mMeta.mSignFlags))); - ui->subscribeToolButton->setHidden(IS_GROUP_SUBSCRIBED(mForumGroup.mMeta.mSubscribeFlags)) ; + ui->threadTreeWidget->setColumnHidden(RsGxsForumModel::COLUMN_THREAD_DISTRIBUTION, !IS_GROUP_PGP_KNOWN_AUTHED(mForumGroup.mMeta.mSignFlags) && !(IS_GROUP_PGP_AUTHED(mForumGroup.mMeta.mSignFlags))); + ui->subscribeToolButton->setHidden(IS_GROUP_SUBSCRIBED(mForumGroup.mMeta.mSubscribeFlags)) ; - updateForumDescription(success); - - }, this ); + updateForumDescription(true); + }, this ); + } + else + RsQThreadUtils::postToObject( [this]() { updateForumDescription(false); },this); }); } @@ -1774,17 +1791,18 @@ void GxsForumThreadWidget::updateMessageData(const RsGxsMessageId& msgId) std::vector msgs; msgs_to_request.insert(msgId); + QString error_string; if(!rsGxsForums->getForumContent(groupId(),msgs_to_request,msgs)) { std::cerr << __PRETTY_FUNCTION__ << " failed to retrieve message info for forum " << groupId() << " and MsgId " << msgId << std::endl; - return; + error_string = tr("Failed to retrieve this message. Is the database currently overloaded?"); } if(msgs.empty()) { std::cerr << __PRETTY_FUNCTION__ << " no posts for msgId " << msgId << ". Database corruption?" << std::endl; - return; + error_string = tr("No data for this message. Is the database corrupted?"); } if(msgs.size() > 1) { @@ -1792,25 +1810,32 @@ void GxsForumThreadWidget::updateMessageData(const RsGxsMessageId& msgId) std::cerr << "Messages are:" << std::endl; for(auto it(msgs.begin());it!=msgs.end();++it) std::cerr << (*it).mMeta << std::endl; + + error_string = tr("More than one entry for this message. Is the database corrupted?"); } - // 2 - sort the messages into a proper hierarchy - - RsGxsForumMsg msg(msgs[0]); - - // 3 - update the model in the UI thread. - - RsQThreadUtils::postToObject( [msg,this]() + if(error_string.isNull()) { - /* Here it goes any code you want to be executed on the Qt Gui + // 2 - sort the messages into a proper hierarchy + + RsGxsForumMsg msg(msgs[0]); + + // 3 - update the model in the UI thread. + + RsQThreadUtils::postToObject( [msg,this]() + { + /* Here it goes any code you want to be executed on the Qt Gui * thread, for example to update the data model with new information * after a blocking call to RetroShare API complete */ - insertMessageData(msg); + insertMessageData(msg); - ui->threadTreeWidget->setColumnHidden(RsGxsForumModel::COLUMN_THREAD_DISTRIBUTION, !IS_GROUP_PGP_KNOWN_AUTHED(mForumGroup.mMeta.mSignFlags) && !(IS_GROUP_PGP_AUTHED(mForumGroup.mMeta.mSignFlags))); - ui->subscribeToolButton->setHidden(IS_GROUP_SUBSCRIBED(mForumGroup.mMeta.mSubscribeFlags)) ; - }, this ); + ui->threadTreeWidget->setColumnHidden(RsGxsForumModel::COLUMN_THREAD_DISTRIBUTION, !IS_GROUP_PGP_KNOWN_AUTHED(mForumGroup.mMeta.mSignFlags) && !(IS_GROUP_PGP_AUTHED(mForumGroup.mMeta.mSignFlags))); + ui->subscribeToolButton->setHidden(IS_GROUP_SUBSCRIBED(mForumGroup.mMeta.mSubscribeFlags)) ; + }, this ); + } + else + RsQThreadUtils::postToObject( [error_string,this](){ setMessageLoadingError(error_string); } ); }); } diff --git a/retroshare-gui/src/gui/gxsforums/GxsForumThreadWidget.h b/retroshare-gui/src/gui/gxsforums/GxsForumThreadWidget.h index 2dc7f4b78..a23b859ef 100644 --- a/retroshare-gui/src/gui/gxsforums/GxsForumThreadWidget.h +++ b/retroshare-gui/src/gui/gxsforums/GxsForumThreadWidget.h @@ -92,6 +92,7 @@ protected: /* GxsMessageFrameWidget */ virtual void setAllMessagesReadDo(bool read, uint32_t &token); + void setMessageLoadingError(const QString& error); private slots: /** Create the context popup menu and it's submenus */ void threadListCustomPopupMenu(QPoint point);