remved tokenQueue from IdDetailsDialog and attempt to fix crash in Circles due to deleting an item that is still in the tree

This commit is contained in:
csoler 2020-02-24 22:21:38 +01:00
parent 35ebc03904
commit a050669a93
No known key found for this signature in database
GPG Key ID: 7BCA522266C0804C
4 changed files with 67 additions and 201 deletions

View File

@ -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<RsGxsIdGroup> 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<RsGxsGroupId> groupIds;
groupIds.push_back(mId);
std::set<RsGxsId> ids( { RsGxsId(mId) } ) ;
std::vector<RsGxsIdGroup> 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()
{

View File

@ -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 */

View File

@ -1,7 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>IdDetailsDialog</class>
<widget class="QDialog" name="IdDetailsDialog">
<widget class="QWidget" name="IdDetailsWidget">
<property name="geometry">
<rect>
<x>0</x>
@ -10,14 +10,7 @@
<height>475</height>
</rect>
</property>
<property name="windowTitle">
<string>Person Details</string>
</property>
<property name="windowIcon">
<iconset resource="../images.qrc">
<normaloff>:/images/logo/logo_32.png</normaloff>:/images/logo/logo_32.png</iconset>
</property>
<layout class="QGridLayout" name="gridLayout_3">
<layout class="QGridLayout" name="gridLayout_3">
<property name="leftMargin">
<number>0</number>
</property>
@ -500,16 +493,12 @@ p, li { white-space: pre-wrap; }
</layout>
</widget>
<customwidgets>
<customwidget>
<class>HeaderFrame</class>
<extends>QFrame</extends>
<header>gui/common/HeaderFrame.h</header>
<container>1</container>
<customwidget>
<class>HeaderFrame</class>
<extends>QFrame</extends>
<header>gui/common/HeaderFrame.h</header>
<container>1</container>
</customwidget>
</customwidgets>
<resources>
<include location="../images.qrc"/>
<include location="../icons.qrc"/>
</resources>
<connections/>
</customwidgets>
</ui>

View File

@ -709,14 +709,14 @@ void IdDialog::loadCircles(const std::list<RsGroupMetaData>& 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<QTreeWidgetItem*> to_delete ;
std::list<int> 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;k<to_delete.size();++k)
delete to_delete[k] ;
for(auto index:to_delete)
delete item->takeChild(index); // delete items starting from the largest index, because otherwise the count changes while deleting...
for(std::map<RsGxsId,uint32_t>::const_iterator it(details.mSubscriptionFlags.begin());it!=details.mSubscriptionFlags.end();++it)
{
@ -730,13 +730,13 @@ void IdDialog::loadCircles(const std::list<RsGroupMetaData>& 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<RSTreeWidgetItem*>(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<RsGroupMetaData>& 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<RsGroupMetaData>& 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<RsGroupMetaData>& 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<RsPgpId> &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);