From a050669a93fd8bdb839205ab7f00f8662f03f13d Mon Sep 17 00:00:00 2001 From: csoler Date: Mon, 24 Feb 2020 22:21:38 +0100 Subject: [PATCH] remved tokenQueue from IdDetailsDialog and attempt to fix crash in Circles due to deleting an item that is still in the tree --- .../src/gui/Identity/IdDetailsDialog.cpp | 112 ++++++----------- .../src/gui/Identity/IdDetailsDialog.h | 13 +- .../src/gui/Identity/IdDetailsDialog.ui | 29 ++--- retroshare-gui/src/gui/Identity/IdDialog.cpp | 114 +++--------------- 4 files changed, 67 insertions(+), 201 deletions(-) diff --git a/retroshare-gui/src/gui/Identity/IdDetailsDialog.cpp b/retroshare-gui/src/gui/Identity/IdDetailsDialog.cpp index ad0c261c9..3cd4cb93d 100644 --- a/retroshare-gui/src/gui/Identity/IdDetailsDialog.cpp +++ b/retroshare-gui/src/gui/Identity/IdDetailsDialog.cpp @@ -22,6 +22,7 @@ #include "IdDetailsDialog.h" #include "ui_IdDetailsDialog.h" #include "gui/gxs/GxsIdDetails.h" +#include "util/qtthreadsutils.h" #include "gui/settings/rsharesettings.h" #include "gui/common/UIStateHelper.h" #include "gui/msgs/MessageComposer.h" @@ -79,9 +80,6 @@ IdDetailsDialog::IdDetailsDialog(const RsGxsGroupId& id, QWidget *parent) : mStateHelper->setActive(IDDETAILSDIALOG_REPLIST, false); - /* Create token queue */ - mIdQueue = new TokenQueue(rsIdentity->getTokenService(), this); - Settings->loadWidgetInformation(this); ui->headerFrame->setHeaderImage(QPixmap(":/icons/png/person.png")); @@ -94,7 +92,7 @@ IdDetailsDialog::IdDetailsDialog(const RsGxsGroupId& id, QWidget *parent) : connect(ui->inviteButton, SIGNAL(clicked()), this, SLOT(sendInvite())); - requestIdDetails(); + loadIdentity(); } /** Destructor. */ @@ -103,7 +101,6 @@ IdDetailsDialog::~IdDetailsDialog() Settings->saveWidgetInformation(this); delete(ui); - delete(mIdQueue); } void IdDetailsDialog::toggleAutoBanIdentities(bool b) @@ -135,40 +132,8 @@ static QString getHumanReadableDuration(uint32_t seconds) return QString(QObject::tr("%1 days ago")).arg(seconds/86400) ; } -void IdDetailsDialog::insertIdDetails(uint32_t token) +void IdDetailsDialog::loadIdentity(RsGxsIdGroup data) { - mStateHelper->setLoading(IDDETAILSDIALOG_IDDETAILS, false); - - /* get details from libretroshare */ - std::vector datavector; - if (!rsIdentity->getGroupData(token, datavector)) - { - mStateHelper->setActive(IDDETAILSDIALOG_IDDETAILS, false); - mStateHelper->clear(IDDETAILSDIALOG_REPLIST); - - ui->lineEdit_KeyId->setText("ERROR GETTING KEY!"); - - return; - } - - if (datavector.size() != 1) - { -#ifdef ID_DEBUG - std::cerr << "IdDetailsDialog::insertIdDetails() Invalid datavector size"; -#endif - - mStateHelper->setActive(IDDETAILSDIALOG_IDDETAILS, false); - mStateHelper->clear(IDDETAILSDIALOG_IDDETAILS); - - ui->lineEdit_KeyId->setText("INVALID DV SIZE"); - - return; - } - - mStateHelper->setActive(IDDETAILSDIALOG_IDDETAILS, true); - - RsGxsIdGroup &data = datavector[0]; - /* get GPG Details from rsPeers */ RsPgpId ownPgpId = rsPeers->getGPGOwnId(); @@ -361,42 +326,16 @@ void IdDetailsDialog::modifyReputation() } rsReputations->setOwnOpinion(id,op); -#ifdef ID_DEBUG - std::cerr << "IdDialog::modifyReputation() ID: " << id << " Mod: " << mod; - std::cerr << std::endl; -#endif - -#ifdef SUSPENDED - // Cyril: apparently the old reputation system was in used here. It's based on GXS data exchange, and probably not - // very efficient because of this. - - uint32_t token; - if (!rsIdentity->submitOpinion(token, id, false, op)) - { -#ifdef ID_DEBUG - std::cerr << "IdDialog::modifyReputation() Error submitting Opinion"; - std::cerr << std::endl; -#endif - } -#endif - -#ifdef ID_DEBUG - std::cerr << "IdDialog::modifyReputation() queuingRequest(), token: " << token; - std::cerr << std::endl; -#endif - // trigger refresh when finished. // basic / anstype are not needed. - requestIdDetails(); + loadIdentity(); return; } -void IdDetailsDialog::requestIdDetails() +void IdDetailsDialog::loadIdentity() { - mIdQueue->cancelActiveRequestTokens(IDDETAILSDIALOG_IDDETAILS); - - if (mId.isNull()) + if (mId.isNull()) { mStateHelper->setActive(IDDETAILSDIALOG_IDDETAILS, false); mStateHelper->setLoading(IDDETAILSDIALOG_IDDETAILS, false); @@ -407,16 +346,42 @@ void IdDetailsDialog::requestIdDetails() mStateHelper->setLoading(IDDETAILSDIALOG_IDDETAILS, true); - RsTokReqOptions opts; - opts.mReqType = GXS_REQUEST_TYPE_GROUP_DATA; + RsThread::async([this]() + { +#ifdef ID_DEBUG + std::cerr << "Retrieving post data for identity " << mThreadId << std::endl; +#endif - uint32_t token; - std::list groupIds; - groupIds.push_back(mId); + std::set ids( { RsGxsId(mId) } ) ; + std::vector ids_data; + + if(!rsIdentity->getIdentitiesInfo(ids,ids_data)) + { + std::cerr << __PRETTY_FUNCTION__ << " failed to retrieve identities group info for id " << mId << std::endl; + return; + } + + if(ids_data.size() != 1) + { + std::cerr << __PRETTY_FUNCTION__ << " failed to retrieve exactly one group info for id " << mId << std::endl; + return; + } + RsGxsIdGroup group(ids_data[0]); + + 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 */ + + loadIdentity(group); + + }, this ); + }); - mIdQueue->requestGroupInfo(token, RS_TOKREQ_ANSTYPE_DATA, opts, groupIds, IDDETAILSDIALOG_IDDETAILS); } +#ifdef TO_REMOVE void IdDetailsDialog::requestRepList() { // Removing this for the moment. @@ -469,6 +434,7 @@ void IdDetailsDialog::loadRequest(const TokenQueue *queue, const TokenRequest &r std::cerr << std::endl; } } +#endif QString IdDetailsDialog::inviteMessage() { diff --git a/retroshare-gui/src/gui/Identity/IdDetailsDialog.h b/retroshare-gui/src/gui/Identity/IdDetailsDialog.h index 672cb764f..ba53b2bba 100644 --- a/retroshare-gui/src/gui/Identity/IdDetailsDialog.h +++ b/retroshare-gui/src/gui/Identity/IdDetailsDialog.h @@ -32,7 +32,7 @@ class IdDetailsDialog; class UIStateHelper; -class IdDetailsDialog : public QDialog, public TokenResponse +class IdDetailsDialog : public QDialog { Q_OBJECT @@ -42,9 +42,6 @@ public: /** Default destructor */ ~IdDetailsDialog(); - /* TokenResponse */ - void loadRequest(const TokenQueue *queue, const TokenRequest &req); - private slots: void modifyReputation(); void toggleAutoBanIdentities(bool b); @@ -52,15 +49,11 @@ private slots: static QString inviteMessage(); void sendInvite(); private : - void requestIdDetails(); - void insertIdDetails(uint32_t token); - - void requestRepList(); - void insertRepList(uint32_t token); + void loadIdentity(); + void loadIdentity(RsGxsIdGroup data); private: RsGxsGroupId mId; - TokenQueue *mIdQueue; UIStateHelper *mStateHelper; /** Qt Designer generated object */ diff --git a/retroshare-gui/src/gui/Identity/IdDetailsDialog.ui b/retroshare-gui/src/gui/Identity/IdDetailsDialog.ui index 3faad4076..6a681f142 100644 --- a/retroshare-gui/src/gui/Identity/IdDetailsDialog.ui +++ b/retroshare-gui/src/gui/Identity/IdDetailsDialog.ui @@ -1,7 +1,7 @@ IdDetailsDialog - + 0 @@ -10,14 +10,7 @@ 475 - - Person Details - - - - :/images/logo/logo_32.png:/images/logo/logo_32.png - - + 0 @@ -500,16 +493,12 @@ p, li { white-space: pre-wrap; } - - HeaderFrame - QFrame -
gui/common/HeaderFrame.h
- 1 + + HeaderFrame + QFrame +
gui/common/HeaderFrame.h
+ 1
-
- - - - - + +
diff --git a/retroshare-gui/src/gui/Identity/IdDialog.cpp b/retroshare-gui/src/gui/Identity/IdDialog.cpp index f52091eac..bf5502fea 100644 --- a/retroshare-gui/src/gui/Identity/IdDialog.cpp +++ b/retroshare-gui/src/gui/Identity/IdDialog.cpp @@ -709,14 +709,14 @@ void IdDialog::loadCircles(const std::list& groupInfo) std::cerr << " updating status of all identities for this circle:" << std::endl; #endif // remove any identity that has an item, but no subscription flag entry - std::vector to_delete ; + std::list to_delete ; for(uint32_t k=0; k < (uint32_t)item->childCount(); ++k) if(details.mSubscriptionFlags.find(RsGxsId(item->child(k)->data(CIRCLEGROUP_CIRCLE_COL_GROUPID,Qt::UserRole).toString().toStdString())) == details.mSubscriptionFlags.end()) - to_delete.push_back(item->child(k)); + to_delete.push_front(k); // front, so that we delete starting from the last one - for(uint32_t k=0;ktakeChild(index); // delete items starting from the largest index, because otherwise the count changes while deleting... for(std::map::const_iterator it(details.mSubscriptionFlags.begin());it!=details.mSubscriptionFlags.end();++it) { @@ -730,13 +730,13 @@ void IdDialog::loadCircles(const std::list& groupInfo) #ifdef ID_DEBUG std::cerr << "invited: " << invited << ", subscription: " << subscrb ; #endif - RSTreeWidgetItem *subitem = NULL ; + int subitem_index = -1; // see if the item already exists for(uint32_t k=0; k < (uint32_t)item->childCount(); ++k) if(item->child(k)->data(CIRCLEGROUP_CIRCLE_COL_GROUPID,Qt::UserRole).toString().toStdString() == it->first.toStdString()) { - subitem = dynamic_cast(item->child(k)); + subitem_index = k; #ifdef ID_DEBUG std::cerr << " found existing sub item." << std::endl; #endif @@ -745,8 +745,8 @@ void IdDialog::loadCircles(const std::list& groupInfo) if(!(invited || subscrb)) { - if(subitem != NULL) - delete subitem ; + if(subitem_index >= 0) + delete item->takeChild(subitem_index) ; #ifdef ID_DEBUG std::cerr << ". not relevant. Skipping." << std::endl; #endif @@ -754,13 +754,15 @@ void IdDialog::loadCircles(const std::list& groupInfo) } // remove item if flags are not ok. - if(subitem && subitem->data(CIRCLEGROUP_CIRCLE_COL_GROUPFLAGS, Qt::UserRole).toUInt() != it->second) + if(subitem_index >= 0 && item->child(subitem_index)->data(CIRCLEGROUP_CIRCLE_COL_GROUPFLAGS, Qt::UserRole).toUInt() != it->second) { - delete subitem ; - subitem = NULL ; + delete item->takeChild(subitem_index) ; + subitem_index = -1 ; } - if(!subitem) + QTreeWidgetItem *subitem(NULL); + + if(subitem_index == -1) { #ifdef ID_DEBUG std::cerr << " no existing sub item. Creating new one." << std::endl; @@ -804,6 +806,8 @@ void IdDialog::loadCircles(const std::list& groupInfo) item->addChild(subitem) ; } + else + subitem = item->child(subitem_index); if(invited && !subscrb) { @@ -1140,92 +1144,6 @@ void IdDialog::CircleListCustomPopupMenu( QPoint ) contextMnu.exec(QCursor::pos()); } -#ifdef SUSPENDED -static void set_item_background(QTreeWidgetItem *item, uint32_t type) -{ - QBrush brush; - switch(type) - { - default: - case CLEAR_BACKGROUND: - brush = QBrush(Qt::white); - break; - case GREEN_BACKGROUND: - brush = QBrush(Qt::green); - break; - case BLUE_BACKGROUND: - brush = QBrush(Qt::blue); - break; - case RED_BACKGROUND: - brush = QBrush(Qt::red); - break; - case GRAY_BACKGROUND: - brush = QBrush(Qt::gray); - break; - } - item->setBackground (0, brush); -} - -static void update_children_background(QTreeWidgetItem *item, uint32_t type) -{ - int count = item->childCount(); - for(int i = 0; i < count; ++i) - { - QTreeWidgetItem *child = item->child(i); - - if (child->childCount() > 0) - { - update_children_background(child, type); - } - set_item_background(child, type); - } -} - -static void set_tree_background(QTreeWidget *tree, uint32_t type) -{ - std::cerr << "CirclesDialog set_tree_background()"; - std::cerr << std::endl; - - /* grab all toplevel */ - int count = tree->topLevelItemCount(); - for(int i = 0; i < count; ++i) - { - QTreeWidgetItem *item = tree->topLevelItem(i); - /* resursively clear child backgrounds */ - update_children_background(item, type); - set_item_background(item, type); - } -} - -static void check_mark_item(QTreeWidgetItem *item, const std::set &names, uint32_t col, uint32_t type) -{ - QString coltext = item->text(col); - RsPgpId colstr ( coltext.toStdString()); - if (names.end() != names.find(colstr)) - { - set_item_background(item, type); - std::cerr << "CirclesDialog check_mark_item: found match: " << colstr; - std::cerr << std::endl; - } -} - -void IdDialog::circle_selected() -{ - QTreeWidgetItem *item = ui->treeWidget_membership->currentItem(); - -#ifdef ID_DEBUG - std::cerr << "CirclesDialog::circle_selected() valid circle chosen"; - std::cerr << std::endl; -#endif - //set_item_background(item, BLUE_BACKGROUND); - - QString coltext = (item->parent()->parent())? (item->parent()->data(CIRCLEGROUP_CIRCLE_COL_GROUPID,Qt::UserRole).toString()) : (item->data(CIRCLEGROUP_CIRCLE_COL_GROUPID,Qt::UserRole).toString()); - RsGxsCircleId id ( coltext.toStdString()) ; - - requestCircleGroupData(id) ; -} -#endif - IdDialog::~IdDialog() { rsEvents->unregisterEventsHandler(mEventHandlerId_identity);