Merge pull request #71 from RetroShare/master

update to master
This commit is contained in:
defnax 2020-02-18 23:49:26 +01:00 committed by GitHub
commit d402257090
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
52 changed files with 697 additions and 505 deletions

View File

@ -1112,6 +1112,7 @@ static void addMessageChanged(std::map<RsGxsGroupId, std::set<RsGxsMessageId> >
void RsGenExchange::receiveChanges(std::vector<RsGxsNotify*>& changes)
{
std::cerr << "*********************************** RsGenExchange::receiveChanges()" << std::endl;
#ifdef GEN_EXCH_DEBUG
std::cerr << "RsGenExchange::receiveChanges()" << std::endl;
#endif

View File

@ -187,6 +187,10 @@ enum class RsGxsCircleEventCode: uint8_t
/** mCircleId contains the circle id */
NEW_CIRCLE = 0x06,
/** no additional information. Simply means that the info previously from the cache has changed. */
CACHE_DATA_UPDATED = 0x07,
};
struct RsGxsCircleEvent: RsEvent
@ -312,7 +316,7 @@ public:
RsGxsCircleMsg& msg) =0;
/**
* @brief Invite identities to circle
* @brief Invite identities to circle (admin key is required)
* @jsonapi{development}
* @param[in] identities ids of the identities to invite
* @param[in] circleId Id of the circle you own and want to invite ids in
@ -321,6 +325,16 @@ public:
virtual bool inviteIdsToCircle( const std::set<RsGxsId>& identities,
const RsGxsCircleId& circleId ) = 0;
/**
* @brief Remove identities from circle (admin key is required)
* @jsonapi{development}
* @param[in] identities ids of the identities to remove from the invite list
* @param[in] circleId Id of the circle you own and want to invite ids in
* @return false if something failed, true otherwhise
*/
virtual bool revokeIdsFromCircle( const std::set<RsGxsId>& identities,
const RsGxsCircleId& circleId ) = 0;
/**
* @brief Request circle membership, or accept circle invitation
* @jsonapi{development}

View File

@ -309,6 +309,7 @@ enum class RsGxsIdentityEventCode: uint8_t
UNKNOWN = 0x00,
NEW_IDENTITY = 0x01,
DELETED_IDENTITY = 0x02,
UPDATED_IDENTITY = 0x03,
};
struct RsGxsIdentityEvent: public RsEvent

View File

@ -103,6 +103,7 @@
#define MIN_CIRCLE_LOAD_GAP 5
#define GXS_CIRCLE_DELAY_TO_FORCE_MEMBERSHIP_UPDATE 60 // re-check every 1 mins. Normally this shouldn't be necessary since notifications inform abotu new messages.
#define GXS_CIRCLE_DELAY_TO_CHECK_MEMBERSHIP_UPDATE 60 // re-check every 1 mins. Normally this shouldn't be necessary since notifications inform abotu new messages.
#define GXS_CIRCLE_DELAY_TO_SEND_CACHE_UPDATED_EVENT 10 // do not send cache update events more often than every 10 secs.
/********************************************************************************/
/******************* Startup / Tick ******************************************/
@ -117,11 +118,13 @@ p3GxsCircles::p3GxsCircles(
RsGxsCircles(static_cast<RsGxsIface&>(*this)), GxsTokenQueue(this),
RsTickEvent(), mIdentities(identities), mPgpUtils(pgpUtils),
mCircleMtx("p3GxsCircles"),
mCircleCache(DEFAULT_MEM_CACHE_SIZE, "GxsCircleCache" )
mCircleCache(DEFAULT_MEM_CACHE_SIZE, "GxsCircleCache" ),
mCacheUpdated(false)
{
// Kick off Cache Testing, + Others.
//RsTickEvent::schedule_in(CIRCLE_EVENT_CACHETEST, CACHETEST_PERIOD);
mLastCacheMembershipUpdateTS = 0 ;
mLastCacheUpdateEvent = 0;
RsTickEvent::schedule_now(CIRCLE_EVENT_LOADIDS);
@ -365,6 +368,36 @@ bool p3GxsCircles::inviteIdsToCircle( const std::set<RsGxsId>& identities,
return editCircle(circleGrp);
}
bool p3GxsCircles::revokeIdsFromCircle( const std::set<RsGxsId>& identities, const RsGxsCircleId& circleId )
{
const std::list<RsGxsGroupId> circlesIds{ RsGxsGroupId(circleId) };
std::vector<RsGxsCircleGroup> circlesInfo;
if(!getCirclesInfo(circlesIds, circlesInfo))
{
std::cerr << __PRETTY_FUNCTION__ << "Error! Failure getting group data." << std::endl;
return false;
}
if(circlesInfo.empty())
{
std::cerr << __PRETTY_FUNCTION__ << "Error! Circle: " << circleId.toStdString() << " not found!" << std::endl;
return false;
}
RsGxsCircleGroup& circleGrp = circlesInfo[0];
if(!(circleGrp.mMeta.mSubscribeFlags & GXS_SERV::GROUP_SUBSCRIBE_ADMIN))
{
std::cerr << __PRETTY_FUNCTION__ << "Error! Attempt to edit non-own " << "circle: " << circleId.toStdString() << std::endl;
return false;
}
circleGrp.mInvitedMembers.erase(identities.begin(), identities.end());
return editCircle(circleGrp);
}
bool p3GxsCircles::exportCircleLink(
std::string& link, const RsGxsCircleId& circleId,
bool includeGxsData, const std::string& baseUrl, std::string& errMsg )
@ -460,7 +493,21 @@ void p3GxsCircles::service_tick()
GxsTokenQueue::checkRequests(); // GxsTokenQueue handles all requests.
rstime_t now = time(NULL);
if(now > mLastCacheMembershipUpdateTS + GXS_CIRCLE_DELAY_TO_CHECK_MEMBERSHIP_UPDATE)
if(mCacheUpdated && now > mLastCacheUpdateEvent + GXS_CIRCLE_DELAY_TO_SEND_CACHE_UPDATED_EVENT)
{
if(rsEvents)
{
auto ev = std::make_shared<RsGxsCircleEvent>();
ev->mCircleEventType = RsGxsCircleEventCode::CACHE_DATA_UPDATED;
rsEvents->postEvent(ev);
}
mLastCacheUpdateEvent = now;
mCacheUpdated = false;
}
if(now > mLastCacheMembershipUpdateTS + GXS_CIRCLE_DELAY_TO_CHECK_MEMBERSHIP_UPDATE)
{
checkCircleCache();
mLastCacheMembershipUpdateTS = now ;
@ -484,7 +531,7 @@ void p3GxsCircles::notifyChanges(std::vector<RsGxsNotify *> &changes)
RsGxsMsgChange *msgChange = dynamic_cast<RsGxsMsgChange *>(*it);
RsGxsNotify *c = *it;
if (msgChange && !msgChange->metaChange())
if (msgChange)
{
#ifdef DEBUG_CIRCLES
std::cerr << " Found circle Message Change Notification" << std::endl;
@ -521,6 +568,8 @@ void p3GxsCircles::notifyChanges(std::vector<RsGxsNotify *> &changes)
rsEvents->postEvent(ev);
}
mCircleCache.erase(circle_id);
mCacheUpdated = true;
}
}
@ -546,6 +595,7 @@ void p3GxsCircles::notifyChanges(std::vector<RsGxsNotify *> &changes)
{
RsStackMutex stack(mCircleMtx); /********** STACK LOCKED MTX ******/
mCircleCache.erase(RsGxsCircleId(*git));
mCacheUpdated = true;
}
}
}
@ -615,6 +665,7 @@ void p3GxsCircles::notifyChanges(std::vector<RsGxsNotify *> &changes)
{
RsStackMutex stack(mCircleMtx); /********** STACK LOCKED MTX ******/
mCircleCache.erase(RsGxsCircleId(*git));
mCacheUpdated = true;
}
}
@ -669,7 +720,6 @@ bool p3GxsCircles::getCircleDetails(
}
}
return true;
}
}
@ -1431,6 +1481,7 @@ bool p3GxsCircles::cache_load_for_token(uint32_t token)
RsTickEvent::schedule_in(CIRCLE_EVENT_RELOADIDS, GXSID_LOAD_CYCLE, id.toStdString());
}
mCacheUpdated = true;
}
return true;
@ -1467,6 +1518,8 @@ bool p3GxsCircles::locked_processLoadingCacheEntry(RsGxsCircleCache& cache)
if(mIdentities->haveKey(pit->first))
{
pit->second.subscription_flags |= GXS_EXTERNAL_CIRCLE_FLAGS_KEY_AVAILABLE;
mCacheUpdated = true;
#ifdef DEBUG_CIRCLES
std::cerr << " Key is now available!"<< std::endl;
#endif
@ -1542,8 +1595,8 @@ bool p3GxsCircles::locked_processLoadingCacheEntry(RsGxsCircleCache& cache)
// We can check for self inclusion in the circle right away, since own ids are always loaded.
// that allows to subscribe/unsubscribe uncomplete circles
locked_checkCircleCacheForAutoSubscribe(cache);
locked_checkCircleCacheForAutoSubscribe(cache);
locked_checkCircleCacheForMembershipUpdate(cache);
// always store in cache even if uncomplete. But do not remove the loading items so that they can be kept in loading state.
@ -1687,8 +1740,8 @@ bool p3GxsCircles::locked_checkCircleCacheForAutoSubscribe(RsGxsCircleCache &cac
if(it2 != cache.mMembershipStatus.end())
{
in_admin_list = in_admin_list || bool(it2->second.subscription_flags & GXS_EXTERNAL_CIRCLE_FLAGS_IN_ADMIN_LIST) ;
member_request= member_request|| bool(it2->second.subscription_flags & GXS_EXTERNAL_CIRCLE_FLAGS_SUBSCRIBED) ;
in_admin_list = in_admin_list || bool(it2->second.subscription_flags & GXS_EXTERNAL_CIRCLE_FLAGS_IN_ADMIN_LIST) ;
member_request= member_request|| bool(it2->second.subscription_flags & GXS_EXTERNAL_CIRCLE_FLAGS_SUBSCRIBED) ;
}
}
@ -1717,6 +1770,8 @@ bool p3GxsCircles::locked_checkCircleCacheForAutoSubscribe(RsGxsCircleCache &cac
RsGenExchange::setGroupStatusFlags(token2, RsGxsGroupId(cache.mCircleId), 0, GXS_SERV::GXS_GRP_STATUS_UNPROCESSED);
cache.mGroupStatus &= ~GXS_SERV::GXS_GRP_STATUS_UNPROCESSED;
mCacheUpdated = true;
return true;
}
@ -1740,6 +1795,7 @@ bool p3GxsCircles::locked_checkCircleCacheForAutoSubscribe(RsGxsCircleCache &cac
cache.mGroupStatus &= ~GXS_SERV::GXS_GRP_STATUS_UNPROCESSED;
mCacheUpdated = true;
return true ;
}
}
@ -2396,6 +2452,7 @@ bool p3GxsCircles::processMembershipRequests(uint32_t token)
else
std::cerr << " (EE) unknown subscription order type: " << item->subscription_type ;
mCacheUpdated = true;
#ifdef DEBUG_CIRCLES
std::cerr << " UPDATING" << std::endl;
#endif
@ -2410,7 +2467,8 @@ bool p3GxsCircles::processMembershipRequests(uint32_t token)
}
data.mLastUpdatedMembershipTS = time(NULL) ;
}
mCacheUpdated = true;
}
RsStackMutex stack(mCircleMtx); /********** STACK LOCKED MTX ******/
uint32_t token2;

View File

@ -208,6 +208,10 @@ public:
bool inviteIdsToCircle( const std::set<RsGxsId>& identities,
const RsGxsCircleId& circleId ) override;
/// @see RsGxsCircles
bool revokeIdsFromCircle( const std::set<RsGxsId>& identities,
const RsGxsCircleId& circleId ) override;
/// @see RsGxsCircles
bool getCircleRequest(const RsGxsGroupId& circleId,
const RsGxsMessageId& msgId,
@ -341,6 +345,8 @@ public:
uint32_t mDummyIdToken;
std::list<RsGxsId> mDummyPgpLinkedIds;
std::list<RsGxsId> mDummyOwnIds;
bool mCacheUpdated ;
rstime_t mLastCacheUpdateEvent;
RS_SET_CONTEXT_DEBUG_LEVEL(2)
};

View File

@ -625,7 +625,7 @@ void p3IdService::notifyChanges(std::vector<RsGxsNotify *> &changes)
RsGxsGroupChange *groupChange = dynamic_cast<RsGxsGroupChange *>(changes[i]);
if (groupChange && !groupChange->metaChange())
if (groupChange)
{
#ifdef DEBUG_IDS
std::cerr << "p3IdService::notifyChanges() Found Group Change Notification";
@ -653,6 +653,14 @@ void p3IdService::notifyChanges(std::vector<RsGxsNotify *> &changes)
switch(groupChange->getType())
{
case RsGxsNotify::TYPE_PUBLISHED:
{
auto ev = std::make_shared<RsGxsIdentityEvent>();
ev->mIdentityId = *git;
ev->mIdentityEventCode = RsGxsIdentityEventCode::UPDATED_IDENTITY;
rsEvents->postEvent(ev);
}
break;
case RsGxsNotify::TYPE_RECEIVED_NEW:
{
auto ev = std::make_shared<RsGxsIdentityEvent>();
@ -4724,6 +4732,8 @@ void p3IdService::handle_event(uint32_t event_type, const std::string &/*elabel*
case GXSID_EVENT_REQUEST_IDS:
requestIdsFromNet();
break;
case GXSID_EVENT_REPUTATION:
break;
default:
RsErr() << __PRETTY_FUNCTION__ << " Unknown Event Type: "
<< event_type << std::endl;

View File

@ -174,11 +174,6 @@ void p3PostBase::notifyChanges(std::vector<RsGxsNotify *> &changes)
delete *it;
}
#ifdef POSTBASE_DEBUG
std::cerr << "p3PostBase::notifyChanges() -> receiveChanges()";
std::cerr << std::endl;
#endif
}
void p3PostBase::service_tick()
@ -615,7 +610,9 @@ void p3PostBase::background_loadMsgs(const uint32_t &token, bool unprocessed)
#endif
changes.push_back(msgChanges);
receiveHelperChanges(changes);
//receiveHelperChanges(changes);
notifyChanges(changes);
}
else
{
@ -768,7 +765,8 @@ void p3PostBase::background_updateVoteCounts(const uint32_t &token)
#endif
changes.push_back(msgChanges);
receiveHelperChanges(changes);
//receiveHelperChanges(changes);
notifyChanges(changes);
}
else
{

View File

@ -72,9 +72,6 @@ class p3PostBase: public RsGenExchange, public GxsTokenQueue, public RsTickEvent
virtual void service_tick();
// This should be overloaded to call RsGxsIfaceHelper::receiveChanges().
virtual void receiveHelperChanges(std::vector<RsGxsNotify*>& changes) = 0;
protected:
virtual void notifyChanges(std::vector<RsGxsNotify*>& changes);

View File

@ -102,8 +102,6 @@ void p3Wiki::notifyChanges(std::vector<RsGxsNotify*>& changes)
{
std::cerr << "p3Wiki::notifyChanges() New stuff";
std::cerr << std::endl;
RsGxsIfaceHelper::receiveChanges(changes);
}
/* Specific Service Data */

View File

@ -88,8 +88,6 @@ void p3Wire::notifyChanges(std::vector<RsGxsNotify*>& changes)
{
std::cerr << "p3Wire::notifyChanges() New stuff";
std::cerr << std::endl;
RsGxsIfaceHelper::receiveChanges(changes);
}
/* Specific Service Data */

View File

@ -50,7 +50,7 @@
/** Constructor */
CirclesDialog::CirclesDialog(QWidget *parent)
: RsGxsUpdateBroadcastPage(rsGxsCircles, parent)
: MainPage(parent)
{
/* Invoke the Qt Designer generated object setup routine */
ui.setupUi(this);

View File

@ -31,7 +31,7 @@
class UIStateHelper;
class CirclesDialog : public RsGxsUpdateBroadcastPage, public TokenResponse
class CirclesDialog : public MainPage, public TokenResponse
{
Q_OBJECT

View File

@ -37,7 +37,8 @@
#include "gui/common/UIStateHelper.h"
#include "gui/common/UserNotify.h"
#include "gui/gxs/GxsIdDetails.h"
#include "gui/gxs/RsGxsUpdateBroadcastBase.h"
#include "gui/gxs/GxsIdTreeWidgetItem.h"
//#include "gui/gxs/RsGxsUpdateBroadcastBase.h"
#include "gui/msgs/MessageComposer.h"
#include "gui/settings/rsharesettings.h"
#include "util/qtthreadsutils.h"
@ -142,23 +143,19 @@ class TreeWidgetItem : public QTreeWidgetItem
};
/** Constructor */
IdDialog::IdDialog(QWidget *parent) :
RsGxsUpdateBroadcastPage(rsIdentity, parent),
ui(new Ui::IdDialog)
IdDialog::IdDialog(QWidget *parent) : MainPage(parent), ui(new Ui::IdDialog)
{
ui->setupUi(this);
mIdQueue = NULL;
mEventHandlerId_identity = 0;
rsEvents->registerEventsHandler(RsEventType::GXS_IDENTITY, [this](std::shared_ptr<const RsEvent> event) { RsQThreadUtils::postToObject( [=]() { handleEvent_main_thread(event); }, this ); }, mEventHandlerId_identity );
mEventHandlerId_circles = 0;
rsEvents->registerEventsHandler(RsEventType::GXS_CIRCLES, [this](std::shared_ptr<const RsEvent> event) { RsQThreadUtils::postToObject( [=]() { handleEvent_main_thread(event); }, this ); }, mEventHandlerId_circles );
// This is used to grab the broadcast of changes from p3GxsCircles, which is discarded by the current dialog, since it expects data for p3Identity only.
mCirclesBroadcastBase = new RsGxsUpdateBroadcastBase(rsGxsCircles, this);
connect(mCirclesBroadcastBase, SIGNAL(fillDisplay(bool)), this, SLOT(updateCirclesDisplay(bool)));
// This is used to grab the broadcast of changes from p3GxsCircles, which is discarded by the current dialog, since it expects data for p3Identity only.
//mCirclesBroadcastBase = new RsGxsUpdateBroadcastBase(rsGxsCircles, this);
//connect(mCirclesBroadcastBase, SIGNAL(fillDisplay(bool)), this, SLOT(updateCirclesDisplay(bool)));
ownItem = new QTreeWidgetItem();
ownItem->setText(0, tr("My own identities"));
@ -173,7 +170,8 @@ IdDialog::IdDialog(QWidget *parent) :
contactsItem->setData(RSID_COL_VOTES, Qt::DecorationRole,0xff);
ui->treeWidget_membership->clear();
ui->treeWidget_membership->setItemDelegateForColumn(CIRCLEGROUP_CIRCLE_COL_GROUPNAME,new GxsIdTreeItemDelegate());
mExternalOtherCircleItem = NULL ;
mExternalBelongingCircleItem = NULL ;
@ -360,8 +358,6 @@ IdDialog::IdDialog(QWidget *parent) :
QHeaderView * idheader = ui->idTreeWidget->header();
QHeaderView_setSectionResizeModeColumn(idheader, RSID_COL_VOTES, QHeaderView::ResizeToContents);
mIdQueue = new TokenQueue(rsIdentity->getTokenService(), this);
mStateHelper->setActive(IDDIALOG_IDDETAILS, false);
mStateHelper->setActive(IDDIALOG_REPLIST, false);
@ -391,19 +387,8 @@ IdDialog::IdDialog(QWidget *parent) :
connect(ui->treeWidget_membership, SIGNAL(customContextMenuRequested(QPoint)), this, SLOT(CircleListCustomPopupMenu(QPoint)));
connect(ui->autoBanIdentities_CB, SIGNAL(toggled(bool)), this, SLOT(toggleAutoBanIdentities(bool)));
/* Setup TokenQueue */
mCircleQueue = new TokenQueue(rsGxsCircles->getTokenService(), this);
requestCircleGroupMeta();
// This timer shouldn't be needed, but it is now, because the update of subscribe status and appartenance to the
// circle doesn't trigger a proper GUI update.
QTimer *tmer = new QTimer(this) ;
connect(tmer,SIGNAL(timeout()),this,SLOT(updateCirclesDisplay())) ;
tmer->start(10000) ; // update every 10 secs.
updateCircles();
updateIdList();
}
void IdDialog::handleEvent_main_thread(std::shared_ptr<const RsEvent> event)
@ -419,8 +404,14 @@ void IdDialog::handleEvent_main_thread(std::shared_ptr<const RsEvent> event)
{
case RsGxsIdentityEventCode::DELETED_IDENTITY:
case RsGxsIdentityEventCode::NEW_IDENTITY:
case RsGxsIdentityEventCode::UPDATED_IDENTITY:
requestIdList();
updateIdList();
if(!mId.isNull() && mId == e->mIdentityId)
updateIdentity();
break;
default:
break;
}
@ -440,8 +431,9 @@ void IdDialog::handleEvent_main_thread(std::shared_ptr<const RsEvent> event)
case RsGxsCircleEventCode::CIRCLE_MEMBERSHIP_LEAVE:
case RsGxsCircleEventCode::CIRCLE_MEMBERSHIP_JOIN:
case RsGxsCircleEventCode::CIRCLE_MEMBERSHIP_REVOQUED:
case RsGxsCircleEventCode::CACHE_DATA_UPDATED:
requestCircleGroupMeta();
updateCircles();
default:
break;
}
@ -471,7 +463,7 @@ void IdDialog::toggleAutoBanIdentities(bool b)
if(!id.isNull())
{
rsReputations->banNode(id,b) ;
requestIdList();
updateIdList();
}
}
@ -486,12 +478,13 @@ void IdDialog::updateCirclesDisplay()
#ifdef ID_DEBUG
std::cerr << "!!Updating circles display!" << std::endl;
#endif
requestCircleGroupMeta() ;
updateCircles() ;
}
/************************** Request / Response *************************/
/*** Loading Main Index ***/
#ifdef TO_REMOVE
void IdDialog::requestCircleGroupMeta()
{
mStateHelper->setLoading(CIRCLESDIALOG_GROUPMETA, true);
@ -509,9 +502,6 @@ void IdDialog::requestCircleGroupMeta()
uint32_t token;
mCircleQueue->requestGroupInfo(token, RS_TOKREQ_ANSTYPE_SUMMARY, opts, CIRCLESDIALOG_GROUPMETA);
}
// should update this code to be called and modify the tree widget accordingly
#ifdef SUSPENDED
void IdDialog::requestCircleGroupData(const RsGxsCircleId& circle_id)
{
mStateHelper->setLoading(CIRCLESDIALOG_GROUPDATA, true);
@ -534,26 +524,44 @@ void IdDialog::requestCircleGroupData(const RsGxsCircleId& circle_id)
}
#endif
void IdDialog::loadCircleGroupMeta(const uint32_t &token)
void IdDialog::updateCircles()
{
mStateHelper->setLoading(CIRCLESDIALOG_GROUPMETA, false);
RsThread::async([this]()
{
// 1 - get message data from p3GxsForums
#ifdef DEBUG_FORUMS
std::cerr << "Retrieving post data for post " << mThreadId << std::endl;
#endif
std::list<RsGroupMetaData> circle_metas ;
if(!rsGxsCircles->getCirclesSummaries(circle_metas))
{
std::cerr << __PRETTY_FUNCTION__ << " failed to retrieve circles group info list" << std::endl;
return;
}
RsQThreadUtils::postToObject( [circle_metas,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 */
loadCircles(circle_metas);
}, this );
});
}
void IdDialog::loadCircles(const std::list<RsGroupMetaData>& groupInfo)
{
#ifdef ID_DEBUG
std::cerr << "CirclesDialog::loadCircleGroupMeta()";
std::cerr << std::endl;
#endif
std::list<RsGroupMetaData> groupInfo;
std::list<RsGroupMetaData>::iterator vit;
if (!rsGxsCircles->getGroupSummary(token,groupInfo))
{
std::cerr << "CirclesDialog::loadCircleGroupMeta() Error getting GroupMeta";
std::cerr << std::endl;
mStateHelper->setActive(CIRCLESDIALOG_GROUPMETA, false);
return;
}
mStateHelper->setActive(CIRCLESDIALOG_GROUPMETA, true);
/* add the top level item */
@ -581,7 +589,7 @@ void IdDialog::loadCircleGroupMeta(const uint32_t &token)
std::list<RsGxsId> own_identities ;
rsIdentity->getOwnIds(own_identities) ;
for(vit = groupInfo.begin(); vit != groupInfo.end();++vit)
for(auto vit = groupInfo.begin(); vit != groupInfo.end();++vit)
{
#ifdef ID_DEBUG
std::cerr << "CirclesDialog::loadCircleGroupMeta() GroupId: " << vit->mGroupId << " Group: " << vit->mGroupName << std::endl;
@ -761,13 +769,13 @@ void IdDialog::loadCircleGroupMeta(const uint32_t &token)
#ifdef ID_DEBUG
std::cerr << "invited: " << invited << ", subscription: " << subscrb ;
#endif
QTreeWidgetItem *subitem = NULL ;
RSTreeWidgetItem *subitem = NULL ;
// 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 = item->child(k);
subitem = dynamic_cast<RSTreeWidgetItem*>(item->child(k));
#ifdef ID_DEBUG
std::cerr << " found existing sub item." << std::endl;
#endif
@ -796,20 +804,21 @@ void IdDialog::loadCircleGroupMeta(const uint32_t &token)
#ifdef ID_DEBUG
std::cerr << " no existing sub item. Creating new one." << std::endl;
#endif
subitem = new QTreeWidgetItem(item);
subitem = new RSTreeWidgetItem(NULL);
subitem->setData(CIRCLEGROUP_CIRCLE_COL_GROUPNAME,Qt::UserRole,QString::fromStdString(it->first.toStdString()));
RsIdentityDetails idd ;
bool has_id = rsIdentity->getIdDetails(it->first,idd) ;
QPixmap pixmap ;
// QPixmap pixmap ;
if(idd.mAvatar.mSize == 0 || !GxsIdDetails::loadPixmapFromData(idd.mAvatar.mData, idd.mAvatar.mSize, pixmap,GxsIdDetails::SMALL))
pixmap = GxsIdDetails::makeDefaultIcon(it->first,GxsIdDetails::SMALL) ;
// if(idd.mAvatar.mSize == 0 || !GxsIdDetails::loadPixmapFromData(idd.mAvatar.mData, idd.mAvatar.mSize, pixmap,GxsIdDetails::SMALL))
// pixmap = GxsIdDetails::makeDefaultIcon(it->first,GxsIdDetails::SMALL) ;
if(has_id)
subitem->setText(CIRCLEGROUP_CIRCLE_COL_GROUPNAME, QString::fromUtf8(idd.mNickname.c_str())) ;
else
subitem->setText(CIRCLEGROUP_CIRCLE_COL_GROUPNAME, tr("Unknown ID:")+QString::fromStdString(it->first.toStdString())) ;
// if(has_id)
// subitem->setText(CIRCLEGROUP_CIRCLE_COL_GROUPNAME, QString::fromUtf8(idd.mNickname.c_str())) ;
// else
// subitem->setText(CIRCLEGROUP_CIRCLE_COL_GROUPNAME, tr("Unknown ID:")+QString::fromStdString(it->first.toStdString())) ;
QString tooltip ;
tooltip += tr("Identity ID: ")+QString::fromStdString(it->first.toStdString()) ;
@ -830,7 +839,7 @@ void IdDialog::loadCircleGroupMeta(const uint32_t &token)
subitem->setData(CIRCLEGROUP_CIRCLE_COL_GROUPFLAGS, Qt::UserRole, QVariant(it->second)) ;
subitem->setData(CIRCLEGROUP_CIRCLE_COL_GROUPID, Qt::UserRole, QString::fromStdString(it->first.toStdString())) ;
subitem->setIcon(RSID_COL_NICKNAME, QIcon(pixmap));
//subitem->setIcon(RSID_COL_NICKNAME, QIcon(pixmap));
item->addChild(subitem) ;
}
@ -887,6 +896,7 @@ static void mark_matching_tree(QTreeWidget *w, const std::set<RsGxsId>& members,
}
}
#ifdef TO_REMOVE
void IdDialog::loadCircleGroupData(const uint32_t& token)
{
#ifdef ID_DEBUG
@ -981,8 +991,8 @@ void IdDialog::updateCircleGroup(const uint32_t& token)
rsGxsCircles->updateGroup(token2,cg) ;
mCircleUpdates.erase(it) ;
requestCircleGroupMeta();
}
#endif
bool IdDialog::getItemCircleId(QTreeWidgetItem *item,RsGxsCircleId& id)
{
@ -1007,8 +1017,6 @@ void IdDialog::createExternalCircle()
CreateCircleDialog dlg;
dlg.editNewId(true);
dlg.exec();
requestCircleGroupMeta(); // update GUI
}
void IdDialog::showEditExistingCircle()
{
@ -1023,60 +1031,40 @@ void IdDialog::showEditExistingCircle()
dlg.editExistingId(RsGxsGroupId(id),true,!(subscribe_flags & GXS_SERV::GROUP_SUBSCRIBE_ADMIN)) ;
dlg.exec();
requestCircleGroupMeta(); // update GUI
}
void IdDialog::grantCircleMembership()
{
RsGxsCircleId circle_id ;
RsGxsCircleId circle_id ;
if(!getItemCircleId(ui->treeWidget_membership->currentItem(),circle_id))
return;
RsGxsId gxs_id_to_revoke(qobject_cast<QAction*>(sender())->data().toString().toStdString());
RsGxsId gxs_id_to_grant(qobject_cast<QAction*>(sender())->data().toString().toStdString());
RsTokReqOptions opts;
opts.mReqType = GXS_REQUEST_TYPE_GROUP_DATA;
RsThread::async([circle_id,gxs_id_to_grant]()
{
// 1 - get message data from p3GxsForums
std::list<RsGxsGroupId> grps ;
grps.push_back(RsGxsGroupId(circle_id));
uint32_t token;
mCircleQueue->requestGroupInfo(token, RS_TOKREQ_ANSTYPE_DATA, opts, grps, CIRCLESDIALOG_GROUPUPDATE);
CircleUpdateOrder c ;
c.token = token ;
c.gxs_id = gxs_id_to_revoke ;
c.action = CircleUpdateOrder::GRANT_MEMBERSHIP ;
mCircleUpdates[token] = c ;
rsGxsCircles->inviteIdsToCircle(std::set<RsGxsId>( { gxs_id_to_grant } ),circle_id);
});
}
void IdDialog::revokeCircleMembership()
{
RsGxsCircleId circle_id ;
RsGxsCircleId circle_id ;
if(!getItemCircleId(ui->treeWidget_membership->currentItem(),circle_id))
return;
RsGxsId gxs_id_to_revoke(qobject_cast<QAction*>(sender())->data().toString().toStdString());
RsTokReqOptions opts;
opts.mReqType = GXS_REQUEST_TYPE_GROUP_DATA;
RsThread::async([circle_id,gxs_id_to_revoke]()
{
// 1 - get message data from p3GxsForums
std::list<RsGxsGroupId> grps ;
grps.push_back(RsGxsGroupId(circle_id));
uint32_t token;
mCircleQueue->requestGroupInfo(token, RS_TOKREQ_ANSTYPE_DATA, opts, grps, CIRCLESDIALOG_GROUPUPDATE);
CircleUpdateOrder c ;
c.token = token ;
c.gxs_id = gxs_id_to_revoke ;
c.action = CircleUpdateOrder::REVOKE_MEMBERSHIP ;
mCircleUpdates[token] = c ;
rsGxsCircles->revokeIdsFromCircle(std::set<RsGxsId>( { gxs_id_to_revoke } ),circle_id);
});
}
void IdDialog::acceptCircleSubscription()
@ -1384,7 +1372,6 @@ IdDialog::~IdDialog()
processSettings(false);
delete(ui);
delete(mIdQueue);
}
static QString getHumanReadableDuration(uint32_t seconds)
@ -1449,7 +1436,7 @@ void IdDialog::filterToggled(const bool &value)
QAction *source = qobject_cast<QAction *>(QObject::sender());
if (source) {
filter = source->data().toInt();
requestIdList();
updateIdList();
}
}
}
@ -1465,32 +1452,65 @@ void IdDialog::updateSelection()
if (id != mId) {
mId = id;
requestIdDetails();
requestRepList();
updateIdentity();
//updateRepList();
}
}
void IdDialog::requestIdList()
void IdDialog::updateIdList()
{
//Disable by default, will be enable by insertIdDetails()
ui->removeIdentity->setEnabled(false);
ui->editIdentity->setEnabled(false);
if (!mIdQueue)
return;
int accept = filter;
mStateHelper->setLoading(IDDIALOG_IDLIST, true);
RsThread::async([this]()
{
// 1 - get message data from p3GxsForums
mIdQueue->cancelActiveRequestTokens(IDDIALOG_IDLIST);
#ifdef DEBUG_FORUMS
std::cerr << "Retrieving post data for post " << mThreadId << std::endl;
#endif
RsTokReqOptions opts;
opts.mReqType = GXS_REQUEST_TYPE_GROUP_DATA;
std::list<RsGroupMetaData> identity_metas ;
uint32_t token;
if (!rsIdentity->getIdentitiesSummaries(identity_metas))
{
std::cerr << "IdDialog::insertIdList() Error getting GroupData" << std::endl;
return;
}
mIdQueue->requestGroupInfo(token, RS_TOKREQ_ANSTYPE_DATA, opts, IDDIALOG_IDLIST);
std::set<RsGxsId> ids;
for(auto it(identity_metas.begin());it!=identity_metas.end();++it)
ids.insert(RsGxsId((*it).mGroupId));
std::vector<RsGxsIdGroup> groups;
if(!rsIdentity->getIdentitiesInfo(ids,groups))
{
std::cerr << "IdDialog::insertIdList() Error getting identities info" << std::endl;
return;
}
std::map<RsGxsGroupId,RsGxsIdGroup> ids_set;
for(auto it(groups.begin());it!=groups.end();++it)
ids_set[(*it).mMeta.mGroupId] = *it;
RsQThreadUtils::postToObject( [ids_set,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 */
loadIdentities(ids_set);
}, this );
});
}
bool IdDialog::fillIdListItem(const RsGxsIdGroup& data, QTreeWidgetItem *&item, const RsPgpId &ownPgpId, int accept)
@ -1548,7 +1568,9 @@ bool IdDialog::fillIdListItem(const RsGxsIdGroup& data, QTreeWidgetItem *&item,
return false;
if (!item)
{
item = new TreeWidgetItem();
}
item->setText(RSID_COL_NICKNAME, QString::fromUtf8(data.mMeta.mGroupName.c_str()).left(RSID_MAXIMUM_NICKNAME_SIZE));
@ -1652,8 +1674,10 @@ bool IdDialog::fillIdListItem(const RsGxsIdGroup& data, QTreeWidgetItem *&item,
return true;
}
void IdDialog::insertIdList(uint32_t token)
void IdDialog::loadIdentities(const std::map<RsGxsGroupId,RsGxsIdGroup>& ids_set_const)
{
auto ids_set(ids_set_const);
//First: Get current item to restore after
RsGxsGroupId oldCurrentId = mIdToNavigate;
{
@ -1662,35 +1686,7 @@ void IdDialog::insertIdList(uint32_t token)
oldCurrentId = RsGxsGroupId(oldCurrent->text(RSID_COL_KEYID).toStdString());
}
}
mStateHelper->setLoading(IDDIALOG_IDLIST, false);
int accept = filter;
//RsGxsIdGroup data;
std::vector<RsGxsIdGroup> datavector;
//std::vector<RsGxsIdGroup>::iterator vit;
if (!rsIdentity->getGroupData(token, datavector))
{
#ifdef ID_DEBUG
std::cerr << "IdDialog::insertIdList() Error getting GroupData";
std::cerr << std::endl;
#endif
mStateHelper->setActive(IDDIALOG_IDLIST, false);
mStateHelper->clear(IDDIALOG_IDLIST);
clearPerson();
return;
}
// turn that vector into a std::set, to avoid a linear search
std::map<RsGxsGroupId,RsGxsIdGroup> ids_set ;
for(uint32_t i=0;i<datavector.size();++i)
ids_set[datavector[i].mMeta.mGroupId] = datavector[i] ;
int accept = filter;
mStateHelper->setActive(IDDIALOG_IDLIST, true);
@ -1705,27 +1701,27 @@ void IdDialog::insertIdList(uint32_t token)
while ((item = *itemIterator) != NULL)
{
++itemIterator;
std::map<RsGxsGroupId,RsGxsIdGroup>::iterator it = ids_set.find(RsGxsGroupId(item->text(RSID_COL_KEYID).toStdString())) ;
auto it = ids_set.find(RsGxsGroupId(item->text(RSID_COL_KEYID).toStdString())) ;
if(it == ids_set.end())
{
if(item != allItem && item != contactsItem && item != ownItem)
delete(item);
continue ;
}
QTreeWidgetItem *parent_item = item->parent() ;
if( (parent_item == allItem && it->second.mIsAContact) || (parent_item == contactsItem && !it->second.mIsAContact))
{
delete item ; // do not remove from the list, so that it is added again in the correct place.
continue ;
}
continue ;
}
QTreeWidgetItem *parent_item = item->parent() ;
if( (parent_item == allItem && it->second.mIsAContact) || (parent_item == contactsItem && !it->second.mIsAContact))
{
delete item ; // do not remove from the list, so that it is added again in the correct place.
continue ;
}
if (!fillIdListItem(it->second, item, ownPgpId, accept))
delete(item);
ids_set.erase(it); // erase, so it is not considered to be a new item
}
@ -1756,6 +1752,10 @@ void IdDialog::insertIdList(uint32_t token)
else
allItem->addChild(item);
}
GxsIdLabel *label = new GxsIdLabel();
label->setId(RsGxsId(data.mMeta.mGroupId)) ;
ui->treeWidget_membership->setItemWidget(item,0,label) ;
}
/* count items */
@ -1767,10 +1767,8 @@ void IdDialog::insertIdList(uint32_t token)
updateSelection();
}
void IdDialog::requestIdDetails()
void IdDialog::updateIdentity()
{
mIdQueue->cancelActiveRequestTokens(IDDIALOG_IDDETAILS);
if (mId.isNull())
{
mStateHelper->setActive(IDDIALOG_IDDETAILS, false);
@ -1783,53 +1781,48 @@ void IdDialog::requestIdDetails()
mStateHelper->setLoading(IDDIALOG_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;
mIdQueue->requestGroupInfo(token, RS_TOKREQ_ANSTYPE_DATA, opts, groupIds, IDDIALOG_IDDETAILS);
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 );
});
}
void IdDialog::insertIdDetails(uint32_t token)
void IdDialog::loadIdentity(RsGxsIdGroup data)
{
mStateHelper->setLoading(IDDIALOG_IDDETAILS, false);
/* get details from libretroshare */
RsGxsIdGroup data;
std::vector<RsGxsIdGroup> datavector;
if (!rsIdentity->getGroupData(token, datavector))
{
mStateHelper->setActive(IDDIALOG_IDDETAILS, false);
mStateHelper->clear(IDDIALOG_REPLIST);
clearPerson();
ui->lineEdit_KeyId->setText("ERROR GETTING KEY!");
return;
}
if (datavector.size() != 1)
{
#ifdef ID_DEBUG
std::cerr << "IdDialog::insertIdDetails() Invalid datavector size";
#endif
mStateHelper->setActive(IDDIALOG_IDDETAILS, false);
mStateHelper->clear(IDDIALOG_IDDETAILS);
clearPerson();
ui->lineEdit_KeyId->setText("INVALID DV SIZE");
return;
}
mStateHelper->setActive(IDDIALOG_IDDETAILS, true);
data = datavector[0];
/* get GPG Details from rsPeers */
RsPgpId ownPgpId = rsPeers->getGPGOwnId();
@ -2162,8 +2155,8 @@ void IdDialog::modifyReputation()
// trigger refresh when finished.
// basic / anstype are not needed.
requestIdDetails();
requestIdList();
updateIdentity();
updateIdList();
return;
}
@ -2197,24 +2190,24 @@ void IdDialog::updateDisplay(bool complete)
if (complete) {
/* Fill complete */
requestIdList();
updateIdList();
//requestIdDetails();
requestRepList();
//requestRepList();
updateCircles();
return;
}
requestCircleGroupMeta();
std::set<RsGxsGroupId> grpIds;
getAllGrpIds(grpIds);
if (!getGrpIds().empty()) {
requestIdList();
if (!mId.isNull() && grpIds.find(mId)!=grpIds.end()) {
requestIdDetails();
requestRepList();
}
}
// std::set<RsGxsGroupId> grpIds;
// getAllGrpIds(grpIds);
// if (!getGrpIds().empty()) {
// requestIdList();
//
// if (!mId.isNull() && grpIds.find(mId)!=grpIds.end()) {
// requestIdDetails();
// requestRepList();
// }
// }
}
void IdDialog::addIdentity()
@ -2277,6 +2270,7 @@ void IdDialog::filterIds()
ui->idTreeWidget->filterItems(filterColumn, text);
}
#ifdef TO_REMOVE
void IdDialog::requestRepList()
{
// Removing this for the moment.
@ -2352,6 +2346,7 @@ void IdDialog::loadRequest(const TokenQueue * queue, const TokenRequest &req)
{
switch(req.mUserType)
{
#ifdef TO_REMOVE
case IDDIALOG_IDLIST:
insertIdList(req.mToken);
break;
@ -2376,9 +2371,11 @@ void IdDialog::loadRequest(const TokenQueue * queue, const TokenRequest &req)
std::cerr << "IdDialog::loadRequest() ERROR";
std::cerr << std::endl;
break;
#endif
}
}
#ifdef TO_REMOVE
if(queue == mCircleQueue)
{
#ifdef ID_DEBUG
@ -2389,17 +2386,17 @@ void IdDialog::loadRequest(const TokenQueue * queue, const TokenRequest &req)
/* now switch on req */
switch(req.mUserType)
{
case CIRCLESDIALOG_GROUPMETA:
loadCircleGroupMeta(req.mToken);
break;
// case CIRCLESDIALOG_GROUPMETA:
// loadCircleGroupMeta(req.mToken);
// break;
case CIRCLESDIALOG_GROUPDATA:
loadCircleGroupData(req.mToken);
break;
case CIRCLESDIALOG_GROUPUPDATE:
updateCircleGroup(req.mToken);
break;
// case CIRCLESDIALOG_GROUPDATA:
// loadCircleGroupData(req.mToken);
// break;
//
// case CIRCLESDIALOG_GROUPUPDATE:
// updateCircleGroup(req.mToken);
// break;
default:
std::cerr << "CirclesDialog::loadRequest() ERROR: INVALID TYPE";
@ -2407,7 +2404,9 @@ void IdDialog::loadRequest(const TokenQueue * queue, const TokenRequest &req)
break;
}
}
#endif
}
#endif
void IdDialog::IdListCustomPopupMenu( QPoint )
{
@ -2595,22 +2594,36 @@ void IdDialog::copyRetroshareLink()
if(! rsIdentity->getIdDetails(gxs_id,details))
return ;
if (!mIdQueue)
return;
RsThread::async([gxs_id,details,this]()
{
#ifdef ID_DEBUG
std::cerr << "Retrieving post data for identity " << mThreadId << std::endl;
#endif
std::string radix,errMsg;
mStateHelper->setLoading(IDDIALOG_SERIALIZED_GROUP, true);
if(!rsIdentity->exportIdentityLink( radix, gxs_id, true, std::string(), errMsg))
{
std::cerr << "Cannot retrieve identity data " << mId << " to create a link. Error:" << errMsg << std::endl;
return ;
}
mIdQueue->cancelActiveRequestTokens(IDDIALOG_SERIALIZED_GROUP);
RsQThreadUtils::postToObject( [radix,details,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 */
std::list<RsGxsGroupId> ids ;
ids.push_back(RsGxsGroupId(gxs_id)) ;
QList<RetroShareLink> urls ;
RsTokReqOptions opts;
opts.mReqType = GXS_REQUEST_TYPE_GROUP_SERIALIZED_DATA;
RetroShareLink link = RetroShareLink::createIdentity(details.mId,QString::fromUtf8(details.mNickname.c_str()),QString::fromStdString(radix)) ;
urls.push_back(link);
uint32_t token;
RSLinkClipboard::copyLinks(urls) ;
mIdQueue->requestGroupInfo(token, RS_TOKREQ_ANSTYPE_DATA, opts, ids, IDDIALOG_SERIALIZED_GROUP);
QMessageBox::information(NULL,tr("information"),tr("This identity link was copied to your clipboard. Paste it in a mail, or a message to transmit the identity to someone.")) ;
}, this );
});
}
void IdDialog::chatIdentity()
@ -2739,8 +2752,8 @@ void IdDialog::negativePerson()
rsReputations->setOwnOpinion(RsGxsId(Id), RsOpinion::NEGATIVE);
}
requestIdDetails();
requestIdList();
updateIdentity();
updateIdList();
}
void IdDialog::neutralPerson()
@ -2755,8 +2768,8 @@ void IdDialog::neutralPerson()
rsReputations->setOwnOpinion(RsGxsId(Id), RsOpinion::NEUTRAL);
}
requestIdDetails();
requestIdList();
updateIdentity();
updateIdList();
}
void IdDialog::positivePerson()
{
@ -2770,8 +2783,8 @@ void IdDialog::positivePerson()
rsReputations->setOwnOpinion(RsGxsId(Id), RsOpinion::POSITIVE);
}
requestIdDetails();
requestIdList();
updateIdentity();
updateIdList();
}
void IdDialog::addtoContacts()
@ -2785,7 +2798,7 @@ void IdDialog::addtoContacts()
rsIdentity->setAsRegularContact(RsGxsId(Id),true);
}
requestIdList();
updateIdList();
}
void IdDialog::removefromContacts()
@ -2799,7 +2812,7 @@ QList<QTreeWidgetItem *> selected_items = ui->idTreeWidget->selectedItems();
rsIdentity->setAsRegularContact(RsGxsId(Id),false);
}
requestIdList();
updateIdList();
}
void IdDialog::on_closeInfoFrameButton_clicked()

View File

@ -45,7 +45,7 @@ struct CircleUpdateOrder
uint32_t action ;
};
class IdDialog : public RsGxsUpdateBroadcastPage, public TokenResponse
class IdDialog : public MainPage
{
Q_OBJECT
@ -57,17 +57,19 @@ public:
virtual QString pageName() const { return tr("People") ; } //MainPage
virtual QString helpText() const { return ""; } //MainPage
void loadRequest(const TokenQueue *queue, const TokenRequest &req);
void navigate(const RsGxsId& gxs_id) ; // shows the info about this particular ID
protected:
virtual void updateDisplay(bool complete);
void loadCircleGroupMeta(const uint32_t &token);
void loadCircleGroupData(const uint32_t &token);
void updateCircleGroup(const uint32_t& token);
void updateIdList();
void loadIdentities(const std::map<RsGxsGroupId, RsGxsIdGroup> &ids_set);
void updateIdentity();
void loadIdentity(RsGxsIdGroup id_data);
void updateCircles();
void loadCircles(const std::list<RsGroupMetaData>& circle_metas);
void requestCircleGroupMeta();
//void requestCircleGroupData(const RsGxsCircleId& circle_id);
bool getItemCircleId(QTreeWidgetItem *item,RsGxsCircleId& id) ;
@ -120,10 +122,6 @@ private:
void processSettings(bool load);
QString createUsageString(const RsIdentityUsage& u) const;
void requestIdDetails();
void insertIdDetails(uint32_t token);
void requestIdList();
void requestIdData(std::list<RsGxsGroupId> &ids);
bool fillIdListItem(const RsGxsIdGroup& data, QTreeWidgetItem *&item, const RsPgpId &ownPgpId, int accept);
void insertIdList(uint32_t token);
@ -139,9 +137,6 @@ private:
void clearPerson();
private:
TokenQueue *mIdQueue;
TokenQueue *mCircleQueue;
UIStateHelper *mStateHelper;
QTreeWidgetItem *contactsItem;

View File

@ -25,7 +25,7 @@
#include "gui/msgs/MessageComposer.h"
#include "gui/RetroShareLink.h"
#include "gui/gxs/GxsIdDetails.h"
#include "gui/gxs/RsGxsUpdateBroadcastBase.h"
//#include "gui/gxs/RsGxsUpdateBroadcastBase.h"
#include "gui/Identity/IdDetailsDialog.h"
#include "gui/Identity/IdDialog.h"
#include "gui/MainWindow.h"
@ -53,7 +53,7 @@ const uint32_t PeopleDialog::PD_CIRCLES = 0x0004 ;
/** Constructor */
PeopleDialog::PeopleDialog(QWidget *parent)
: RsGxsUpdateBroadcastPage(rsIdentity, parent)
: MainPage(parent)
{
setupUi(this);
@ -61,8 +61,8 @@ PeopleDialog::PeopleDialog(QWidget *parent)
mIdentityQueue = new TokenQueue(rsIdentity->getTokenService(), this);
mCirclesQueue = new TokenQueue(rsGxsCircles->getTokenService(), this);
// This is used to grab the broadcast of changes from p3GxsCircles, which is discarded by the current dialog, since it expects data for p3Identity only.
mCirclesBroadcastBase = new RsGxsUpdateBroadcastBase(rsGxsCircles, this);
connect(mCirclesBroadcastBase, SIGNAL(fillDisplay(bool)), this, SLOT(updateCirclesDisplay(bool)));
//mCirclesBroadcastBase = new RsGxsUpdateBroadcastBase(rsGxsCircles, this);
//connect(mCirclesBroadcastBase, SIGNAL(fillDisplay(bool)), this, SLOT(updateCirclesDisplay(bool)));
tabWidget->removeTab(1);

View File

@ -33,7 +33,7 @@
#define IMAGE_IDENTITY ":/icons/png/people.png"
class PeopleDialog : public RsGxsUpdateBroadcastPage, public Ui::PeopleDialog, public TokenResponse
class PeopleDialog : public MainPage, public Ui::PeopleDialog, public TokenResponse
{
Q_OBJECT
@ -97,7 +97,7 @@ private:
TokenQueue *mIdentityQueue;
TokenQueue *mCirclesQueue;
RsGxsUpdateBroadcastBase *mCirclesBroadcastBase ;
//RsGxsUpdateBroadcastBase *mCirclesBroadcastBase ;
FlowLayout *_flowLayoutExt;
std::map<RsGxsId,IdentityWidget *> _gxs_identity_widgets ;

View File

@ -60,13 +60,7 @@ void PostedDialog::handleEvent_main_thread(std::shared_ptr<const RsEvent> event)
switch(e->mPostedEventCode)
{
case RsPostedEventCode::NEW_MESSAGE:
updateMessageSummaryList(e->mPostedGroupId);
break;
case RsPostedEventCode::UPDATED_MESSAGE: // [[fallthrough]];
updateDisplay(false);
break;
case RsPostedEventCode::READ_STATUS_CHANGED: // [[fallthrough]];
updateMessageSummaryList(e->mPostedGroupId);
break;

View File

@ -27,6 +27,7 @@
#include "util/qtthreadsutils.h"
#include "gui/gxs/GxsIdDetails.h"
#include "PostedCreatePostDialog.h"
#include "gui/settings/rsharesettings.h"
#include "PostedItem.h"
#include "PostedCardView.h"
#include "gui/common/UIStateHelper.h"
@ -105,9 +106,15 @@ PostedListWidget::PostedListWidget(const RsGxsGroupId &postedId, QWidget *parent
/* load settings */
processSettings(true);
mEventHandlerId = 0;
// Needs to be asynced because this function is likely to be called by another thread!
rsEvents->registerEventsHandler(RsEventType::GXS_POSTED, [this](std::shared_ptr<const RsEvent> event) { RsQThreadUtils::postToObject( [=]() { handleEvent_main_thread(event); }, this ); }, mEventHandlerId );
/* Initialize GUI */
setGroupId(postedId);
}
PostedListWidget::~PostedListWidget()
{
// save settings
@ -116,20 +123,63 @@ PostedListWidget::~PostedListWidget()
delete(ui);
}
void PostedListWidget::handleEvent_main_thread(std::shared_ptr<const RsEvent> event)
{
const RsGxsPostedEvent *e = dynamic_cast<const RsGxsPostedEvent*>(event.get());
if(!e)
return;
switch(e->mPostedEventCode)
{
case RsPostedEventCode::UPDATED_POSTED_GROUP:
case RsPostedEventCode::NEW_POSTED_GROUP:
case RsPostedEventCode::UPDATED_MESSAGE:
case RsPostedEventCode::NEW_MESSAGE:
if(e->mPostedGroupId == groupId())
updateDisplay(true);
break;
default:
break;
}
}
void PostedListWidget::processSettings(bool load)
{
Settings->beginGroup(QString("PostedListWidget"));
if (load) {
if (load)
{
// load settings
/* View mode */
setViewMode(Settings->value("viewMode", VIEW_MODE_CLASSIC).toInt());
} else {
RsGxsId voteId(Settings->value("defaultIdentity",QString()).toString().toStdString());
if(!voteId.isNull())
ui->idChooser->setChosenId(voteId);
}
else
{
// save settings
/* View mode */
Settings->setValue("viewMode", viewMode());
RsGxsId voteId;
switch (ui->idChooser->getChosenId(voteId))
{
case GxsIdChooser::KnowId:
case GxsIdChooser::UnKnowId: Settings->setValue("defaultIdentity",QString::fromStdString(voteId.toStdString()));
break;
default:
case GxsIdChooser::NoId:
case GxsIdChooser::None:
break;
}
}
Settings->endGroup();
@ -283,10 +333,10 @@ void PostedListWidget::submitVote(const RsGxsGrpMsgIdPair &msgId, bool up)
std::cerr << "PostedListWidget::createPost() ERROR GETTING AuthorId!, Vote Failed";
std::cerr << std::endl;
QMessageBox::warning(this, tr("RetroShare"),tr("Please create or choose a Signing Id before Voting"), QMessageBox::Ok, QMessageBox::Ok);
QMessageBox::warning(this, tr("RetroShare"),tr("Please create or choose a default identity to use for voting"), QMessageBox::Ok, QMessageBox::Ok);
return;
}//switch (ui.idChooser->getChosenId(authorId))
}
RsGxsVote vote;
@ -295,11 +345,10 @@ void PostedListWidget::submitVote(const RsGxsGrpMsgIdPair &msgId, bool up)
vote.mMeta.mParentId = msgId.second;
vote.mMeta.mAuthorId = authorId;
if (up) {
if (up)
vote.mVoteType = GXS_VOTE_UP;
} else { //if (up)
else
vote.mVoteType = GXS_VOTE_DOWN;
}//if (up)
#ifdef DEBUG_POSTED_LIST_WIDGET
std::cerr << "PostedListWidget::submitVote()";

View File

@ -57,6 +57,8 @@ public:
virtual void loadRequest(const TokenQueue *queue, const TokenRequest &req);
protected:
void handleEvent_main_thread(std::shared_ptr<const RsEvent> event);
/* GxsMessageFramePostWidget */
virtual bool insertGroupData(const uint32_t &token, RsGroupMetaData &metaData);
virtual void insertAllPosts(const uint32_t &token, GxsMessageFramePostThread *thread);
@ -126,6 +128,7 @@ private:
/* UI - from Designer */
Ui::PostedListWidget *ui;
RsEventsHandlerId_t mEventHandlerId ;
};
#endif

View File

@ -6,8 +6,8 @@
<rect>
<x>0</x>
<y>0</y>
<width>616</width>
<height>595</height>
<width>950</width>
<height>771</height>
</rect>
</property>
<property name="windowTitle">
@ -250,7 +250,11 @@
</widget>
</item>
<item>
<widget class="GxsIdChooser" name="idChooser"/>
<widget class="GxsIdChooser" name="idChooser">
<property name="toolTip">
<string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Default identity used when voting&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
</property>
</widget>
</item>
</layout>
</widget>
@ -508,7 +512,7 @@
<string notr="true">&lt;!DOCTYPE HTML PUBLIC &quot;-//W3C//DTD HTML 4.0//EN&quot; &quot;http://www.w3.org/TR/REC-html40/strict.dtd&quot;&gt;
&lt;html&gt;&lt;head&gt;&lt;meta name=&quot;qrichtext&quot; content=&quot;1&quot; /&gt;&lt;style type=&quot;text/css&quot;&gt;
p, li { white-space: pre-wrap; }
&lt;/style&gt;&lt;/head&gt;&lt;body style=&quot; font-family:'MS Shell Dlg 2'; font-size:8.25pt; font-weight:400; font-style:normal;&quot;&gt;
&lt;/style&gt;&lt;/head&gt;&lt;body style=&quot; font-family:'Sans'; font-size:9pt; font-weight:400; font-style:normal;&quot;&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;&lt;span style=&quot; font-family:'MS Shell Dlg 2'; font-size:8pt;&quot;&gt;Description&lt;/span&gt;&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
</property>
<property name="textInteractionFlags">
@ -613,7 +617,7 @@ p, li { white-space: pre-wrap; }
<rect>
<x>0</x>
<y>0</y>
<width>614</width>
<width>948</width>
<height>16</height>
</rect>
</property>
@ -667,9 +671,9 @@ p, li { white-space: pre-wrap; }
</customwidget>
</customwidgets>
<resources>
<include location="../images.qrc"/>
<include location="../icons.qrc"/>
<include location="Posted_images.qrc"/>
<include location="../images.qrc"/>
</resources>
<connections/>
</ui>

View File

@ -74,19 +74,9 @@ void ElidedLabel::clear()
void ElidedLabel::paintEvent(QPaintEvent *event)
{
QLabel::paintEvent(event);
QList<QPair<QTextLine,QPoint> > lLines;
QString elidedLastLine = "";
QPainter painter(this);
QFontMetrics fontMetrics = painter.fontMetrics();
QRect cr = contentsRect();
cr.adjust(margin(), margin(), -margin(), -margin());
bool didElide = false;
QChar ellipsisChar(0x2026);//= "…"
int lineSpacing = fontMetrics.lineSpacing();
int y = 0;
QString plainText = "";
QString plainText = "";
if (mOnlyPlainText)
{
plainText = mContent;
@ -95,13 +85,38 @@ void ElidedLabel::paintEvent(QPaintEvent *event)
td.setHtml(mContent);
plainText = td.toPlainText();
}
QRect cr(contentsRect());
cr.adjust(margin(), margin(), -margin(), -margin());
bool didElide = paintElidedLine(painter,plainText,cr,alignment(),wordWrap(),true,mRectElision);
//Send signal if changed
if (didElide != mElided)
{
mElided = didElide;
emit elisionChanged(didElide);
}
}
bool ElidedLabel::paintElidedLine(QPainter& painter,QString plainText,const QRect& cr,Qt::Alignment alignment,bool wordWrap,bool drawRoundRect,QRect& rectElision)
{
QList<QPair<QTextLine,QPoint> > lLines;
QString elidedLastLine = "";
QFontMetrics fontMetrics = painter.fontMetrics();
bool didElide = false;
QChar ellipsisChar(0x2026);//= "…"
int lineSpacing = fontMetrics.lineSpacing();
int y = 0;
plainText = plainText.replace("\n",QChar(QChar::LineSeparator));
plainText = plainText.replace("\r",QChar(QChar::LineSeparator));
QTextLayout textLayout(plainText, painter.font());
QTextOption to = textLayout.textOption();
to.setAlignment(alignment());
to.setWrapMode(wordWrap() ? QTextOption::WrapAtWordBoundaryOrAnywhere : QTextOption::NoWrap);
to.setAlignment(alignment);
to.setWrapMode(wordWrap ? QTextOption::WrapAtWordBoundaryOrAnywhere : QTextOption::NoWrap);
textLayout.setTextOption(to);
textLayout.beginLayout();
@ -115,7 +130,7 @@ void ElidedLabel::paintEvent(QPaintEvent *event)
line.setLineWidth(cr.width());
int nextLineY = y + lineSpacing;
if ((cr.height() >= nextLineY + lineSpacing) && wordWrap()) {
if ((cr.height() >= nextLineY + lineSpacing) && wordWrap) {
//Line written normaly, next line will too
lLines.append(QPair<QTextLine, QPoint>(line, QPoint(0, y)));
y = nextLineY;
@ -123,8 +138,7 @@ void ElidedLabel::paintEvent(QPaintEvent *event)
//The next line can't be written.
QString lastLine = plainText.mid(line.textStart()).split(QChar(QChar::LineSeparator)).at(0);
QTextLine lineEnd = textLayout.createLine();
if (!lineEnd.isValid() && (wordWrap()
|| (fontMetrics.width(lastLine) < cr.width()))) {
if (!lineEnd.isValid() && (wordWrap || (fontMetrics.width(lastLine) < cr.width()))) {
//No more text for next line so this one is OK
lLines.append(QPair<QTextLine, QPoint>(line, QPoint(0, y)));
elidedLastLine="";
@ -150,11 +164,11 @@ void ElidedLabel::paintEvent(QPaintEvent *event)
if (didElide) iHeight += lineSpacing;
//Compute lines translation with alignment
if (alignment() & Qt::AlignTop)
if (alignment & Qt::AlignTop)
iTransY = 0;
if (alignment() & Qt::AlignBottom)
if (alignment & Qt::AlignBottom)
iTransY = cr.height() - iHeight;
if (alignment() & Qt::AlignVCenter)
if (alignment & Qt::AlignVCenter)
iTransY = (cr.height() - iHeight) / 2;
QPair<QTextLine,QPoint> pair;
@ -166,7 +180,8 @@ void ElidedLabel::paintEvent(QPaintEvent *event)
}
//Print last elided line
if (didElide) {
if (didElide)
{
int width = fontMetrics.width(elidedLastLine);
if (lastPos.y() == -1){
y = iTransY;// Only one line
@ -175,32 +190,35 @@ void ElidedLabel::paintEvent(QPaintEvent *event)
}
if (width < cr.width()){
//Text don't taking all line (with line break), so align it
if (alignment() & Qt::AlignLeft)
if (alignment & Qt::AlignLeft)
iTransX = 0;
if (alignment() & Qt::AlignRight)
if (alignment & Qt::AlignRight)
iTransX = cr.width() - width;
if (alignment() & Qt::AlignHCenter)
if (alignment & Qt::AlignHCenter)
iTransX = (cr.width() - width) / 2;
if (alignment() & Qt::AlignJustify)
if (alignment & Qt::AlignJustify)
iTransX = 0;
}
painter.drawText(QPoint(iTransX + cr.left(), y + fontMetrics.ascent() + cr.top()), elidedLastLine);
//Draw button to get ToolTip
mRectElision = QRect(iTransX + width - fontMetrics.width(ellipsisChar) + cr.left()
, y + cr.top()
, fontMetrics.width(ellipsisChar)
, fontMetrics.height() - 1);
painter.drawRoundRect(mRectElision);
} else {
mRectElision = QRect();
}
//Send signal if changed
if (didElide != mElided) {
mElided = didElide;
emit elisionChanged(didElide);
if(drawRoundRect)
{
rectElision = QRect(iTransX + width - fontMetrics.width(ellipsisChar) + cr.left()
, y + cr.top()
, fontMetrics.width(ellipsisChar)
, fontMetrics.height() - 1);
painter.drawRoundRect(rectElision);
}
else
rectElision = QRect();
}
else
rectElision = QRect();
return didElide;
}
void ElidedLabel::mousePressEvent(QMouseEvent *ev)

View File

@ -48,6 +48,8 @@ public:
QColor textColor() const { return mTextColor; }
void setTextColor(const QColor &color);
static bool paintElidedLine(QPainter& painter, QString plainText, const QRect &cr, Qt::Alignment alignment, bool wordWrap, bool drawRoundRect, QRect &rectElision);
public slots:
void setText(const QString &text);
void setOnlyPlainText(const bool &value);

View File

@ -80,7 +80,7 @@ static void setSelected(FriendSelectionWidget::Modus modus, QTreeWidgetItem *ite
}
FriendSelectionWidget::FriendSelectionWidget(QWidget *parent)
: RsGxsUpdateBroadcastPage(rsIdentity,parent), ui(new Ui::FriendSelectionWidget)
: QWidget(parent), ui(new Ui::FriendSelectionWidget)
{
ui->setupUi(this);

View File

@ -34,7 +34,7 @@ class FriendSelectionWidget;
class QTreeWidgetItem;
class RSTreeWidgetItemCompareRole;
class FriendSelectionWidget : public RsGxsUpdateBroadcastPage, public TokenResponse
class FriendSelectionWidget : public QWidget, public TokenResponse
{
Q_OBJECT

View File

@ -86,6 +86,7 @@ void GxsFeedItem::copyMessageLink()
}
}
#ifdef TO_REMOVE
void GxsFeedItem::fillDisplay(RsGxsUpdateBroadcastBase *updateBroadcastBase, bool complete)
{
GxsGroupFeedItem::fillDisplay(updateBroadcastBase, complete);
@ -101,6 +102,7 @@ void GxsFeedItem::fillDisplay(RsGxsUpdateBroadcastBase *updateBroadcastBase, boo
requestMessage();
}
}
#endif
void GxsFeedItem::requestMessage()
{

View File

@ -50,7 +50,7 @@ protected:
/* GxsGroupFeedItem */
virtual bool isLoading();
virtual void fillDisplay(RsGxsUpdateBroadcastBase *updateBroadcastBase, bool complete);
//virtual void fillDisplay(RsGxsUpdateBroadcastBase *updateBroadcastBase, bool complete);
/* TokenResponse */
virtual void loadRequest(const TokenQueue *queue, const TokenRequest &req);

View File

@ -51,6 +51,7 @@ GxsGroupFeedItem::GxsGroupFeedItem(FeedHolder *feedHolder, uint32_t feedId, cons
mLoadQueue = NULL;
#ifdef TO_REMOVE
if (mGxsIface && autoUpdate) {
/* Connect to update broadcast */
mUpdateBroadcastBase = new RsGxsUpdateBroadcastBase(mGxsIface);
@ -58,6 +59,7 @@ GxsGroupFeedItem::GxsGroupFeedItem(FeedHolder *feedHolder, uint32_t feedId, cons
} else {
mUpdateBroadcastBase = NULL;
}
#endif
}
GxsGroupFeedItem::~GxsGroupFeedItem()
@ -71,10 +73,12 @@ GxsGroupFeedItem::~GxsGroupFeedItem()
delete mLoadQueue;
}
#ifdef TO_REMOVE
if (mUpdateBroadcastBase)
{
delete(mUpdateBroadcastBase);
}
#endif
}
bool GxsGroupFeedItem::initLoadQueue()
@ -139,9 +143,11 @@ void GxsGroupFeedItem::copyGroupLink()
void GxsGroupFeedItem::fillDisplaySlot(bool complete)
{
fillDisplay(mUpdateBroadcastBase, complete);
requestGroup();
// fillDisplay(mUpdateBroadcastBase, complete);
}
#ifdef TO_REMOVE
void GxsGroupFeedItem::fillDisplay(RsGxsUpdateBroadcastBase *updateBroadcastBase, bool /*complete*/)
{
std::set<RsGxsGroupId> grpIds;
@ -150,6 +156,7 @@ void GxsGroupFeedItem::fillDisplay(RsGxsUpdateBroadcastBase *updateBroadcastBase
if (grpIds.find(groupId()) != grpIds.end())
requestGroup();
}
#endif
/***********************************************************/

View File

@ -56,7 +56,7 @@ protected:
virtual void loadGroup(const uint32_t &token) = 0;
virtual RetroShareLink::enumType getLinkType() = 0;
virtual QString groupName() = 0;
virtual void fillDisplay(RsGxsUpdateBroadcastBase *updateBroadcastBase, bool complete);
//virtual void fillDisplay(RsGxsUpdateBroadcastBase *updateBroadcastBase, bool complete);
/* TokenResponse */
virtual void loadRequest(const TokenQueue *queue, const TokenRequest &req);
@ -77,7 +77,7 @@ private slots:
private:
RsGxsGroupId mGroupId;
RsGxsUpdateBroadcastBase *mUpdateBroadcastBase;
// RsGxsUpdateBroadcastBase *mUpdateBroadcastBase;
uint32_t mNextTokenType;
uint32_t mTokenTypeGroup;
};

View File

@ -68,7 +68,7 @@
/** Constructor */
GxsGroupFrameDialog::GxsGroupFrameDialog(RsGxsIfaceHelper *ifaceImpl, QWidget *parent,bool allow_dist_sync)
: RsGxsUpdateBroadcastPage(ifaceImpl, parent)
: MainPage(parent)
{
/* Invoke the Qt Designer generated object setup routine */
ui = new Ui::GxsGroupFrameDialog();
@ -179,7 +179,9 @@ void GxsGroupFrameDialog::showEvent(QShowEvent *event)
initUi();
}
RsGxsUpdateBroadcastPage::showEvent(event);
updateDisplay(true);
// RsGxsUpdateBroadcastPage::showEvent(event);
}
void GxsGroupFrameDialog::processSettings(bool load)
@ -239,25 +241,15 @@ void GxsGroupFrameDialog::setHideTabBarWithOneTab(bool hideTabBarWithOneTab)
void GxsGroupFrameDialog::updateDisplay(bool complete)
{
if (complete || !getGrpIds().empty() || !getGrpIdsMeta().empty()) {
/* Update group list */
requestGroupSummary();
} else {
/* Update all groups of changed messages */
std::map<RsGxsGroupId, std::set<RsGxsMessageId> > msgIds;
getAllMsgIds(msgIds);
for (auto msgIt = msgIds.begin(); msgIt != msgIds.end(); ++msgIt) {
updateMessageSummaryList(msgIt->first);
}
}
if(complete) // || !getGrpIds().empty() || !getGrpIdsMeta().empty()) {
requestGroupSummary(); /* Update group list */
updateSearchResults() ;
}
void GxsGroupFrameDialog::updateSearchResults()
{
const std::set<TurtleRequestId>& reqs = getSearchResults();
const std::set<TurtleRequestId>& reqs = getSearchRequests();
for(auto it(reqs.begin());it!=reqs.end();++it)
{
@ -448,7 +440,7 @@ void GxsGroupFrameDialog::groupTreeCustomPopupMenu(QPoint point)
actnn = ctxMenu2->addAction(tr(" Indefinitly"),this,SLOT(setStorePostsDelay())) ; actnn->setData(QVariant( 0)) ; if(current_store_time == 0) { actnn->setEnabled(false);actnn->setIcon(QIcon(":/images/start.png"));}
if (shareKeyType()) {
action = contextMnu.addAction(QIcon(IMAGE_SHARE), tr("Share publish permissions"), this, SLOT(sharePublishKey()));
action = contextMnu.addAction(QIcon(IMAGE_SHARE), tr("Share publish permissions..."), this, SLOT(sharePublishKey()));
action->setEnabled(!mGroupId.isNull() && isPublisher);
}

View File

@ -44,7 +44,7 @@ class UIStateHelper;
struct RsGxsCommentService;
class GxsCommentDialog;
class GxsGroupFrameDialog : public RsGxsUpdateBroadcastPage, public TokenResponse
class GxsGroupFrameDialog : public MainPage, public TokenResponse
{
Q_OBJECT
@ -98,6 +98,7 @@ protected:
void updateMessageSummaryList(RsGxsGroupId groupId);
virtual const std::set<TurtleRequestId> getSearchRequests() const { return std::set<TurtleRequestId>(); } // overload this for subclasses that provide distant search
private slots:
void todo();

View File

@ -51,8 +51,8 @@
GxsIdChooser::GxsIdChooser(QWidget *parent)
: QComboBox(parent), mFlags(IDCHOOSER_ANON_DEFAULT)
{
mBase = new RsGxsUpdateBroadcastBase(rsIdentity, this);
connect(mBase, SIGNAL(fillDisplay(bool)), this, SLOT(fillDisplay(bool)));
// mBase = new RsGxsUpdateBroadcastBase(rsIdentity, this);
// connect(mBase, SIGNAL(fillDisplay(bool)), this, SLOT(fillDisplay(bool)));
/* Initialize ui */
setSizeAdjustPolicy(QComboBox::AdjustToContents);
@ -94,7 +94,8 @@ void GxsIdChooser::fillDisplay(bool complete)
void GxsIdChooser::showEvent(QShowEvent *event)
{
mBase->showEvent(event);
// mBase->showEvent(event);
updateDisplay(true);
QComboBox::showEvent(event);
}

View File

@ -86,7 +86,7 @@ private:
uint32_t mAllowedCount ;
std::set<RsGxsId> mConstraintIdsSet ; // leave empty if all allowed
RsGxsUpdateBroadcastBase *mBase;
// RsGxsUpdateBroadcastBase *mBase;
};
#endif

View File

@ -22,35 +22,38 @@
#include "GxsIdDetails.h"
/** Constructor */
GxsIdLabel::GxsIdLabel(QWidget *parent)
: QLabel(parent)
GxsIdLabel::GxsIdLabel(bool show_tooltip,QWidget *parent)
: QLabel(parent),mShowTooltip(show_tooltip)
{
}
static void fillLabelCallback(GxsIdDetailsType type, const RsIdentityDetails &details, QObject *object, const QVariant &/*data*/)
{
QLabel *label = dynamic_cast<QLabel*>(object);
GxsIdLabel *label = dynamic_cast<GxsIdLabel*>(object);
if (!label) {
return;
}
label->setText(GxsIdDetails::getNameForType(type, details));
QString toolTip;
if(label->showTooltip())
{
QString toolTip;
switch (type) {
case GXS_ID_DETAILS_TYPE_EMPTY:
case GXS_ID_DETAILS_TYPE_LOADING:
case GXS_ID_DETAILS_TYPE_FAILED:
case GXS_ID_DETAILS_TYPE_BANNED:
break;
switch (type) {
case GXS_ID_DETAILS_TYPE_EMPTY:
case GXS_ID_DETAILS_TYPE_LOADING:
case GXS_ID_DETAILS_TYPE_FAILED:
case GXS_ID_DETAILS_TYPE_BANNED:
break;
case GXS_ID_DETAILS_TYPE_DONE:
toolTip = GxsIdDetails::getComment(details);
break;
case GXS_ID_DETAILS_TYPE_DONE:
toolTip = GxsIdDetails::getComment(details);
break;
}
label->setToolTip(toolTip);
}
label->setToolTip(toolTip);
}
void GxsIdLabel::setId(const RsGxsId &id)

View File

@ -29,13 +29,16 @@ class GxsIdLabel : public QLabel
Q_OBJECT
public:
GxsIdLabel(QWidget *parent = NULL);
GxsIdLabel(bool show_tooltip=true,QWidget *parent = NULL);
void setId(const RsGxsId &id);
bool getId(RsGxsId &id);
bool showTooltip() const { return mShowTooltip; }
private:
RsGxsId mId;
bool mShowTooltip;
};
#endif

View File

@ -26,8 +26,8 @@
#define BANNED_IMAGE ":/icons/yellow_biohazard64.png"
/** Constructor */
GxsIdRSTreeWidgetItem::GxsIdRSTreeWidgetItem(const RSTreeWidgetItemCompareRole *compareRole, uint32_t icon_mask,QTreeWidget *parent)
: QObject(NULL), RSTreeWidgetItem(compareRole, parent), mColumn(0), mIconTypeMask(icon_mask)
GxsIdRSTreeWidgetItem::GxsIdRSTreeWidgetItem(const RSTreeWidgetItemCompareRole *compareRole, uint32_t icon_mask,bool auto_tooltip,QTreeWidget *parent)
: QObject(NULL), RSTreeWidgetItem(compareRole, parent), mColumn(0), mIconTypeMask(icon_mask),mAutoTooltip(auto_tooltip)
{
init();
}
@ -72,7 +72,9 @@ static void fillGxsIdRSTreeWidgetItemCallback(GxsIdDetailsType type, const RsIde
}
int column = item->idColumn();
item->setToolTip(column, GxsIdDetails::getComment(details));
if(item->autoTooltip())
item->setToolTip(column, GxsIdDetails::getComment(details));
item->setText(column, GxsIdDetails::getNameForType(type, details));
item->setData(column, Qt::UserRole, QString::fromStdString(details.mId.toStdString()));
@ -176,3 +178,104 @@ QVariant GxsIdRSTreeWidgetItem::data(int column, int role) const
return RSTreeWidgetItem::data(column, role);
}
QSize GxsIdTreeItemDelegate::sizeHint(const QStyleOptionViewItem &option, const QModelIndex &index) const
{
RsGxsId id(index.data(Qt::UserRole).toString().toStdString());
if(id.isNull())
return QStyledItemDelegate::sizeHint(option,index);
QStyleOptionViewItemV4 opt = option;
initStyleOption(&opt, index);
// disable default icon
opt.icon = QIcon();
const QRect r = option.rect;
QString str;
QList<QIcon> icons;
QString comment;
QFontMetricsF fm(option.font);
float f = fm.height();
QIcon icon ;
if(!GxsIdDetails::MakeIdDesc(id, true, str, icons, comment,GxsIdDetails::ICON_TYPE_AVATAR))
{
icon = GxsIdDetails::getLoadingIcon(id);
launchAsyncLoading();
}
else
icon = *icons.begin();
QPixmap pix = icon.pixmap(r.size());
return QSize(1.2*(pix.width() + fm.width(str)),std::max(1.1*pix.height(),1.4*fm.height()));
}
void GxsIdTreeItemDelegate::paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex& index) const
{
if(!index.isValid())
{
std::cerr << "(EE) attempt to draw an invalid index." << std::endl;
return ;
}
RsGxsId id(index.data(Qt::UserRole).toString().toStdString());
if(id.isNull())
return QStyledItemDelegate::paint(painter,option,index);
QStyleOptionViewItemV4 opt = option;
initStyleOption(&opt, index);
// disable default icon
opt.icon = QIcon();
// draw default item
QApplication::style()->drawControl(QStyle::CE_ItemViewItem, &opt, painter, 0);
QRect r = option.rect;
QString str;
QString comment;
QFontMetricsF fm(painter->font());
float f = fm.height();
QIcon icon ;
if(id.isNull())
{
str = tr("[Notification]");
icon = QIcon(":/icons/logo_128.png");
}
else if(! computeNameIconAndComment(id,str,icon,comment))
if(mReloadPeriod > 3)
{
str = tr("[Unknown]");
icon = QIcon();
}
else
{
icon = GxsIdDetails::getLoadingIcon(id);
launchAsyncLoading();
}
QPixmap pix = icon.pixmap(r.size());
const QPoint p = QPoint(r.height()/2.0, (r.height() - pix.height())/2);
// draw pixmap at center of item
painter->drawPixmap(r.topLeft() + p, pix);
//painter->drawText(r.topLeft() + QPoint(r.height()+ f/2.0 + f/2.0,f*1.0), str);
//cr.adjust(margin(), margin(), -margin(), -margin());
QRect mRectElision;
r.adjust(pix.height()+f,(r.height()-f)/2.0,0,0);
bool didElide = ElidedLabel::paintElidedLine(*painter,str,r,Qt::AlignLeft,false,false,mRectElision);
}

View File

@ -24,10 +24,11 @@
#include <QPainter>
#include <QTimer>
#include <QApplication>
#include <retroshare/rsidentity.h>
#include <retroshare/rspeers.h>
#include "retroshare/rsidentity.h"
#include "retroshare/rspeers.h"
#include "gui/common/RSTreeWidgetItem.h"
#include "gui/common/ElidedLabel.h"
#include "gui/gxs/GxsIdDetails.h"
/*****
@ -41,7 +42,7 @@ class GxsIdRSTreeWidgetItem : public QObject, public RSTreeWidgetItem
Q_OBJECT
public:
GxsIdRSTreeWidgetItem(const RSTreeWidgetItemCompareRole *compareRole, uint32_t icon_mask,QTreeWidget *parent = NULL);
GxsIdRSTreeWidgetItem(const RSTreeWidgetItemCompareRole *compareRole, uint32_t icon_mask,bool auto_tooltip=true,QTreeWidget *parent = NULL);
void setId(const RsGxsId &id, int column, bool retryWhenFailed);
bool getId(RsGxsId &id);
@ -57,6 +58,7 @@ public:
void setBannedState(bool b) { mBannedState = b; } // does not actually change the state, but used instead by callbacks to leave a trace
void updateBannedState() ; // checks reputation, and update is needed
bool autoTooltip() const { return mAutoTooltip; }
private slots:
void startProcess();
@ -66,8 +68,9 @@ private:
RsGxsId mId;
int mColumn;
bool mIdFound;
bool mBannedState ;
bool mBannedState ;
bool mRetryWhenFailed;
bool mAutoTooltip;
RsReputationLevel mReputationLevel;
uint32_t mIconTypeMask;
RsGxsImage mAvatar;
@ -86,89 +89,8 @@ public:
mReloadPeriod = 0;
}
QSize sizeHint(const QStyleOptionViewItem &option, const QModelIndex &index) const override
{
QStyleOptionViewItemV4 opt = option;
initStyleOption(&opt, index);
// disable default icon
opt.icon = QIcon();
const QRect r = option.rect;
RsGxsId id(index.data(Qt::UserRole).toString().toStdString());
QString str;
QList<QIcon> icons;
QString comment;
QFontMetricsF fm(option.font);
float f = fm.height();
QIcon icon ;
if(!GxsIdDetails::MakeIdDesc(id, true, str, icons, comment,GxsIdDetails::ICON_TYPE_AVATAR))
{
icon = GxsIdDetails::getLoadingIcon(id);
launchAsyncLoading();
}
else
icon = *icons.begin();
QPixmap pix = icon.pixmap(r.size());
return QSize(1.2*(pix.width() + fm.width(str)),std::max(1.1*pix.height(),1.4*fm.height()));
}
virtual void paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex& index) const override
{
if(!index.isValid())
{
std::cerr << "(EE) attempt to draw an invalid index." << std::endl;
return ;
}
QStyleOptionViewItemV4 opt = option;
initStyleOption(&opt, index);
// disable default icon
opt.icon = QIcon();
// draw default item
QApplication::style()->drawControl(QStyle::CE_ItemViewItem, &opt, painter, 0);
const QRect r = option.rect;
RsGxsId id(index.data(Qt::UserRole).toString().toStdString());
QString str;
QString comment;
QFontMetricsF fm(painter->font());
float f = fm.height();
QIcon icon ;
if(id.isNull())
{
str = tr("[Notification]");
icon = QIcon(":/icons/logo_128.png");
}
else if(! computeNameIconAndComment(id,str,icon,comment))
if(mReloadPeriod > 3)
{
str = tr("[Unknown]");
icon = QIcon();
}
else
{
icon = GxsIdDetails::getLoadingIcon(id);
launchAsyncLoading();
}
QPixmap pix = icon.pixmap(r.size());
const QPoint p = QPoint(r.height()/2.0, (r.height() - pix.height())/2);
// draw pixmap at center of item
painter->drawPixmap(r.topLeft() + p, pix);
painter->drawText(r.topLeft() + QPoint(r.height()+ f/2.0 + f/2.0,f*1.0), str);
}
QSize sizeHint(const QStyleOptionViewItem &option, const QModelIndex &index) const override;
void paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex& index) const override;
void launchAsyncLoading() const
{

View File

@ -55,7 +55,7 @@ void GxsMessageFramePostWidget::groupIdChanged()
emit groupChanged(this);
fillComplete();
updateDisplay(true);
}
QString GxsMessageFramePostWidget::groupName(bool /*withUnreadCount*/)
@ -107,6 +107,7 @@ void GxsMessageFramePostWidget::updateDisplay(bool complete)
return;
}
#ifdef TO_REMOVE
bool updateGroup = false;
const std::set<RsGxsGroupId> &grpIdsMeta = getGrpIdsMeta();
@ -133,6 +134,7 @@ void GxsMessageFramePostWidget::updateDisplay(bool complete)
if (updateGroup) {
requestGroupData();
}
#endif
}
void GxsMessageFramePostWidget::fillThreadAddPost(const QVariant &post, bool related, int current, int count)

View File

@ -24,7 +24,7 @@
#include <retroshare/rsgxsifacehelper.h>
GxsMessageFrameWidget::GxsMessageFrameWidget(RsGxsIfaceHelper *ifaceImpl, QWidget *parent)
: RsGxsUpdateBroadcastWidget(ifaceImpl, parent)
: QWidget(parent)
{
mNextTokenType = 0;

View File

@ -27,7 +27,7 @@
struct RsGxsIfaceHelper;
class UIStateHelper;
class GxsMessageFrameWidget : public RsGxsUpdateBroadcastWidget, public TokenResponse
class GxsMessageFrameWidget : public QWidget, public TokenResponse
{
Q_OBJECT

View File

@ -19,7 +19,7 @@
*******************************************************************************/
#include "GxsUserNotify.h"
#include "gui/gxs/RsGxsUpdateBroadcastBase.h"
//#include "gui/gxs/RsGxsUpdateBroadcastBase.h"
#include "retroshare/rsgxsifacehelper.h"
@ -36,8 +36,8 @@ GxsUserNotify::GxsUserNotify(RsGxsIfaceHelper *ifaceImpl, QObject *parent) :
mTokenService = mInterface->getTokenService();
mTokenQueue = new TokenQueue(mInterface->getTokenService(), this);
mBase = new RsGxsUpdateBroadcastBase(ifaceImpl);
connect(mBase, SIGNAL(fillDisplay(bool)), this, SLOT(updateIcon()));
//mBase = new RsGxsUpdateBroadcastBase(ifaceImpl);
//connect(mBase, SIGNAL(fillDisplay(bool)), this, SLOT(updateIcon()));
}
GxsUserNotify::~GxsUserNotify()
@ -45,9 +45,9 @@ GxsUserNotify::~GxsUserNotify()
if (mTokenQueue) {
delete(mTokenQueue);
}
if (mBase) {
delete(mBase);
}
//if (mBase) {
//delete(mBase);
//}
}
void GxsUserNotify::startUpdate()

View File

@ -47,7 +47,7 @@ public:
const std::map<RsGxsGroupId, std::set<RsGxsMessageId> > &getMsgIds() { return mMsgIds; }
const std::map<RsGxsGroupId, std::set<RsGxsMessageId> > &getMsgIdsMeta() { return mMsgIdsMeta; }
void getAllMsgIds(std::map<RsGxsGroupId, std::set<RsGxsMessageId> > &msgIds);
const std::set<TurtleRequestId>& getSearchResults() { return mTurtleResults ; }
const std::set<TurtleRequestId>& getSearchRequests() { return mTurtleResults ; }
protected:
void fillComplete();

View File

@ -52,7 +52,7 @@ public:
const std::map<RsGxsGroupId, std::set<RsGxsMessageId> > &getMsgIdsMeta();
void getAllMsgIds(std::map<RsGxsGroupId, std::set<RsGxsMessageId> > &msgIds);
virtual const std::set<TurtleRequestId> getSearchResults() const { return std::set<TurtleRequestId>(); } // overload this for subclasses that provide distant search
virtual const std::set<TurtleRequestId> getSearchRequests() const { return std::set<TurtleRequestId>(); } // overload this for subclasses that provide distant search
protected:
virtual void showEvent(QShowEvent *event);

View File

@ -49,10 +49,12 @@ const std::set<RsGxsGroupId> &RsGxsUpdateBroadcastWidget::getGrpIds()
return mBase->getGrpIds();
}
#ifdef TO_REMOVE
const std::set<TurtleRequestId>& RsGxsUpdateBroadcastWidget::getSearchResults()
{
return mBase->getSearchResults();
}
#endif
const std::set<RsGxsGroupId> &RsGxsUpdateBroadcastWidget::getGrpIdsMeta()
{
return mBase->getGrpIdsMeta();

View File

@ -51,7 +51,7 @@ public:
const std::map<RsGxsGroupId, std::set<RsGxsMessageId> > &getMsgIds();
const std::map<RsGxsGroupId, std::set<RsGxsMessageId> > &getMsgIdsMeta();
void getAllMsgIds(std::map<RsGxsGroupId, std::set<RsGxsMessageId> > &msgIds);
const std::set<TurtleRequestId>& getSearchResults() ;
const std::set<TurtleRequestId>& getSearchquests() ;
RsGxsIfaceHelper *interfaceHelper() { return mInterfaceHelper; }

View File

@ -65,13 +65,7 @@ void GxsChannelDialog::handleEvent_main_thread(std::shared_ptr<const RsEvent> ev
switch(e->mChannelEventCode)
{
case RsChannelEventCode::NEW_MESSAGE:
updateMessageSummaryList(e->mChannelGroupId);
break;
case RsChannelEventCode::UPDATED_MESSAGE: // [[fallthrough]];
updateDisplay(false);
break;
case RsChannelEventCode::READ_STATUS_CHANGED:
updateMessageSummaryList(e->mChannelGroupId);
break;

View File

@ -48,7 +48,7 @@ protected:
virtual QString getHelpString() const ;
virtual void groupInfoToGroupItemInfo(const RsGroupMetaData &groupInfo, GroupItemInfo &groupItemInfo, const RsUserdata *userdata);
virtual bool getDistantSearchResults(TurtleRequestId id, std::map<RsGxsGroupId,RsGxsGroupSummary>& group_infos);
virtual const std::set<TurtleRequestId> getSearchResults() const override { return mSearchResults ; }
virtual const std::set<TurtleRequestId> getSearchRequests() const override { return mSearchResults ; }
virtual TurtleRequestId distantSearch(const QString& search_string) ;
virtual void checkRequestGroup(const RsGxsGroupId& grpId) ;

View File

@ -311,7 +311,7 @@ GxsForumThreadWidget::GxsForumThreadWidget(const RsGxsGroupId &forumId, QWidget
{
ui->setupUi(this);
setUpdateWhenInvisible(true);
//setUpdateWhenInvisible(true);
//mUpdating = false;
mUnreadCount = 0;
@ -680,6 +680,7 @@ void GxsForumThreadWidget::updateDisplay(bool complete)
complete = true;
}
#ifdef TO_REMOVE
if(!complete)
{
#ifdef DEBUG_FORUMS
@ -725,6 +726,7 @@ void GxsForumThreadWidget::updateDisplay(bool complete)
}
}
}
#endif
if(complete) // need to update the group data, reload the messages etc.
{

View File

@ -60,13 +60,7 @@ void GxsForumsDialog::handleEvent_main_thread(std::shared_ptr<const RsEvent> eve
switch(e->mForumEventCode)
{
case RsForumEventCode::NEW_MESSAGE:
updateMessageSummaryList(e->mForumGroupId);
break;
case RsForumEventCode::UPDATED_MESSAGE: // [[fallthrough]];
updateDisplay(false);
break;
case RsForumEventCode::READ_STATUS_CHANGED:
updateMessageSummaryList(e->mForumGroupId);
break;

View File

@ -78,7 +78,7 @@
//#define DEBUG_GXSTRANS_STATS 1
GxsTransportStatistics::GxsTransportStatistics(QWidget *parent)
: RsGxsUpdateBroadcastPage(rsGxsTrans,parent)
: MainPage(parent)
{
setupUi(this) ;

View File

@ -60,7 +60,7 @@ public:
std::map<RsGxsMessageId,RsMsgMetaData> messages_metas ;
};
class GxsTransportStatistics: public RsGxsUpdateBroadcastPage, public TokenResponse, public Ui::GxsTransportStatistics
class GxsTransportStatistics: public MainPage, public TokenResponse, public Ui::GxsTransportStatistics
{
Q_OBJECT

View File

@ -1418,9 +1418,6 @@ gxsgui {
gui/gxs/GxsMessageFramePostWidget.h \
gui/gxs/GxsGroupFeedItem.h \
gui/gxs/GxsFeedItem.h \
gui/gxs/RsGxsUpdateBroadcastBase.h \
gui/gxs/RsGxsUpdateBroadcastWidget.h \
gui/gxs/RsGxsUpdateBroadcastPage.h \
gui/gxs/GxsGroupShareKey.h \
gui/gxs/GxsUserNotify.h \
gui/gxs/GxsFeedWidget.h \
@ -1455,9 +1452,6 @@ gxsgui {
gui/gxs/GxsMessageFramePostWidget.cpp \
gui/gxs/GxsGroupFeedItem.cpp \
gui/gxs/GxsFeedItem.cpp \
gui/gxs/RsGxsUpdateBroadcastBase.cpp \
gui/gxs/RsGxsUpdateBroadcastWidget.cpp \
gui/gxs/RsGxsUpdateBroadcastPage.cpp \
gui/gxs/GxsUserNotify.cpp \
gui/gxs/GxsFeedWidget.cpp \
util/TokenQueue.cpp \
@ -1467,3 +1461,16 @@ gxsgui {
}
wikipoos {
HEADERS += \
gui/gxs/RsGxsUpdateBroadcastBase.h \
gui/gxs/RsGxsUpdateBroadcastWidget.h \
gui/gxs/RsGxsUpdateBroadcastPage.h
SOURCES += \
gui/gxs/RsGxsUpdateBroadcastBase.cpp \
gui/gxs/RsGxsUpdateBroadcastWidget.cpp \
gui/gxs/RsGxsUpdateBroadcastPage.cpp \
}

View File

@ -82,8 +82,6 @@ void GxsTestService::notifyChanges(std::vector<RsGxsNotify*>& changes)
{
std::cerr << "GxsTestService::notifyChanges() New stuff";
std::cerr << std::endl;
RsGxsIfaceHelper::receiveChanges(changes);
}
/* Specific Service Data */