mirror of
https://github.com/RetroShare/RetroShare.git
synced 2025-01-13 16:39:43 -05:00
Merge remote-tracking branch 'upstream/master' into pqihandlerOptim
This commit is contained in:
commit
998e1a5de3
@ -1604,6 +1604,12 @@ ChatLobbyId DistributedChatService::createChatLobby(const std::string& lobby_nam
|
||||
#endif
|
||||
ChatLobbyId lobby_id ;
|
||||
{
|
||||
if (!rsIdentity->isOwnId(lobby_identity))
|
||||
{
|
||||
RsErr() << __PRETTY_FUNCTION__ << " lobby_identity RsGxsId id must be own" << std::endl;
|
||||
return 0;
|
||||
}
|
||||
|
||||
RsStackMutex stack(mDistributedChatMtx); /********** STACK LOCKED MTX ******/
|
||||
|
||||
// create a unique id.
|
||||
|
@ -289,7 +289,7 @@ bool GxsSecurity::generateKeyPair(RsTlvPublicRSAKey& public_key,RsTlvPrivateRSAK
|
||||
if(!(private_key.checkKey() && public_key.checkKey()))
|
||||
{
|
||||
std::cerr << "(EE) ERROR while generating keys. Something inconsistent in flags. This is probably a bad sign!" << std::endl;
|
||||
return false ;
|
||||
return false ;
|
||||
}
|
||||
|
||||
return true ;
|
||||
@ -418,13 +418,11 @@ bool GxsSecurity::validateNxsMsg(const RsNxsMsg& msg, const RsTlvKeySignature& s
|
||||
|
||||
/* check signature timeperiod */
|
||||
if ((msgMeta.mPublishTs < key.startTS) || (key.endTS != 0 && msgMeta.mPublishTs > key.endTS))
|
||||
{
|
||||
#ifdef GXS_SECURITY_DEBUG
|
||||
std::cerr << " GxsSecurity::validateNxsMsg() TS out of range";
|
||||
std::cerr << std::endl;
|
||||
#endif
|
||||
return false;
|
||||
}
|
||||
{
|
||||
RsWarn() << __PRETTY_FUNCTION__ << " GxsSecurity::validateNxsMsg() TS out of range for key " << msgMeta.mAuthorId
|
||||
<< " usage is limited to TS=[" << key.startTS << "," << key.endTS << "] and msg publish time is " << msgMeta.mPublishTs << std::endl;
|
||||
return false;
|
||||
}
|
||||
|
||||
/* decode key */
|
||||
const unsigned char *keyptr = (const unsigned char *) key.keyData.bin_data;
|
||||
|
@ -149,7 +149,7 @@ public:
|
||||
bool withMeta = false ) = 0;
|
||||
|
||||
/*!
|
||||
* Retrieves all groups stored
|
||||
* Retrieves all groups stored. Caller owns the memory and is supposed to delete the RsNxsGrp pointers after use.
|
||||
* @param grp retrieved groups
|
||||
* @param withMeta if true the meta handle of nxs grps is intitialised
|
||||
* @param cache whether to store retrieval in mem for faster later retrieval
|
||||
|
@ -236,14 +236,17 @@ void RsGenExchange::tick()
|
||||
|
||||
if (!grpIds.empty())
|
||||
{
|
||||
RsGxsGroupChange* gc = new RsGxsGroupChange(RsGxsNotify::TYPE_PROCESSED, false);
|
||||
gc->mGrpIdList = grpIds;
|
||||
for(auto& groupId:grpIds)
|
||||
{
|
||||
RsGxsGroupChange* gc = new RsGxsGroupChange(RsGxsNotify::TYPE_GROUP_DELETED,groupId, false);
|
||||
|
||||
#ifdef GEN_EXCH_DEBUG
|
||||
std::cerr << " adding the following grp ids to notification: " << std::endl;
|
||||
for(std::list<RsGxsGroupId>::const_iterator it(grpIds.begin());it!=grpIds.end();++it)
|
||||
std::cerr << " " << *it << std::endl;
|
||||
std::cerr << " adding the following grp ids to notification: " << std::endl;
|
||||
for(std::list<RsGxsGroupId>::const_iterator it(grpIds.begin());it!=grpIds.end();++it)
|
||||
std::cerr << " " << *it << std::endl;
|
||||
#endif
|
||||
mNotifications.push_back(gc);
|
||||
mNotifications.push_back(gc);
|
||||
}
|
||||
|
||||
// also notify the network exchange service that these groups no longer exist.
|
||||
|
||||
@ -251,12 +254,12 @@ void RsGenExchange::tick()
|
||||
mNetService->removeGroups(grpIds) ;
|
||||
}
|
||||
|
||||
if (!msgIds.empty())
|
||||
{
|
||||
RsGxsMsgChange* c = new RsGxsMsgChange(RsGxsNotify::TYPE_PROCESSED, false);
|
||||
c->msgChangeMap = msgIds;
|
||||
mNotifications.push_back(c);
|
||||
}
|
||||
for(auto it(msgIds.begin());it!=msgIds.end();++it)
|
||||
for(auto& msgId:it->second)
|
||||
{
|
||||
RsGxsMsgChange* c = new RsGxsMsgChange(RsGxsNotify::TYPE_MESSAGE_DELETED,it->first, msgId, false);
|
||||
mNotifications.push_back(c);
|
||||
}
|
||||
|
||||
delete mIntegrityCheck;
|
||||
mIntegrityCheck = NULL;
|
||||
@ -770,7 +773,7 @@ int RsGenExchange::createMessage(RsNxsMsg* msg)
|
||||
hash.addData(allMsgData, allMsgDataLen);
|
||||
RsFileHash hashId;
|
||||
hash.Complete(hashId);
|
||||
msg->msgId = hashId;
|
||||
msg->msgId = RsGxsMessageId(hashId);
|
||||
|
||||
// assign msg id to msg meta
|
||||
msg->metaData->mMsgId = msg->msgId;
|
||||
@ -934,7 +937,7 @@ int RsGenExchange::validateMsg(RsNxsMsg *msg, const uint32_t& grpFlag, const uin
|
||||
RsReputationLevel::LOCALLY_NEGATIVE )
|
||||
{
|
||||
#ifdef GEN_EXCH_DEBUG
|
||||
std::cerr << "RsGenExchange::validateMsg(): message from " << metaData.mAuthorId << ", rejected because reputation level (" << details.mReputation.mOverallReputationLevel <<") indicate that you banned this ID." << std::endl;
|
||||
std::cerr << "RsGenExchange::validateMsg(): message from " << metaData.mAuthorId << ", rejected because reputation level (" << static_cast<int>(details.mReputation.mOverallReputationLevel) <<") indicate that you banned this ID." << std::endl;
|
||||
#endif
|
||||
idValidate = false ;
|
||||
}
|
||||
@ -1110,6 +1113,7 @@ static void addMessageChanged(std::map<RsGxsGroupId, std::set<RsGxsMessageId> >
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef TO_REMOVE
|
||||
void RsGenExchange::receiveChanges(std::vector<RsGxsNotify*>& changes)
|
||||
{
|
||||
std::cerr << "*********************************** RsGenExchange::receiveChanges()" << std::endl;
|
||||
@ -1155,6 +1159,7 @@ void RsGenExchange::receiveChanges(std::vector<RsGxsNotify*>& changes)
|
||||
|
||||
if(rsEvents) rsEvents->postEvent(std::move(evt));
|
||||
}
|
||||
#endif
|
||||
|
||||
bool RsGenExchange::subscribeToGroup(uint32_t& token, const RsGxsGroupId& grpId, bool subscribe)
|
||||
{
|
||||
@ -1683,8 +1688,7 @@ void RsGenExchange::notifyReceivePublishKey(const RsGxsGroupId &grpId)
|
||||
{
|
||||
RS_STACK_MUTEX(mGenMtx);
|
||||
|
||||
RsGxsGroupChange* gc = new RsGxsGroupChange(RsGxsNotify::TYPE_RECEIVED_PUBLISHKEY, true);
|
||||
gc->mGrpIdList.push_back(grpId);
|
||||
RsGxsGroupChange* gc = new RsGxsGroupChange(RsGxsNotify::TYPE_RECEIVED_PUBLISHKEY,grpId, true);
|
||||
mNotifications.push_back(gc);
|
||||
}
|
||||
|
||||
@ -1692,8 +1696,8 @@ void RsGenExchange::notifyChangedGroupStats(const RsGxsGroupId &grpId)
|
||||
{
|
||||
RS_STACK_MUTEX(mGenMtx);
|
||||
|
||||
RsGxsGroupChange* gc = new RsGxsGroupChange(RsGxsNotify::TYPE_STATISTICS_CHANGED, false);
|
||||
gc->mGrpIdList.push_back(grpId);
|
||||
RsGxsGroupChange* gc = new RsGxsGroupChange(RsGxsNotify::TYPE_STATISTICS_CHANGED,grpId, false);
|
||||
|
||||
mNotifications.push_back(gc);
|
||||
}
|
||||
|
||||
@ -1790,19 +1794,20 @@ void RsGenExchange::publishGroup(uint32_t& token, RsGxsGrpItem *grpItem)
|
||||
|
||||
void RsGenExchange::updateGroup(uint32_t& token, RsGxsGrpItem* grpItem)
|
||||
{
|
||||
if(!checkGroupMetaConsistency(grpItem->meta))
|
||||
{
|
||||
std::cerr << "(EE) Cannot update group. Some information was not supplied." << std::endl;
|
||||
return ;
|
||||
}
|
||||
if(!checkGroupMetaConsistency(grpItem->meta))
|
||||
{
|
||||
std::cerr << "(EE) Cannot update group. Some information was not supplied." << std::endl;
|
||||
delete grpItem;
|
||||
return ;
|
||||
}
|
||||
|
||||
RS_STACK_MUTEX(mGenMtx) ;
|
||||
RS_STACK_MUTEX(mGenMtx) ;
|
||||
token = mDataAccess->generatePublicToken();
|
||||
mGroupUpdatePublish.push_back(GroupUpdatePublish(grpItem, token));
|
||||
mGroupUpdatePublish.push_back(GroupUpdatePublish(grpItem, token));
|
||||
|
||||
#ifdef GEN_EXCH_DEBUG
|
||||
std::cerr << "RsGenExchange::updateGroup() token: " << token;
|
||||
std::cerr << std::endl;
|
||||
std::cerr << "RsGenExchange::updateGroup() token: " << token;
|
||||
std::cerr << std::endl;
|
||||
#endif
|
||||
}
|
||||
|
||||
@ -2049,11 +2054,13 @@ void RsGenExchange::processMsgMetaChanges()
|
||||
}
|
||||
}
|
||||
|
||||
if (!msgIds.empty()) {
|
||||
if (!msgIds.empty())
|
||||
{
|
||||
RS_STACK_MUTEX(mGenMtx);
|
||||
RsGxsMsgChange* c = new RsGxsMsgChange(RsGxsNotify::TYPE_PROCESSED, false);
|
||||
c->msgChangeMap = msgIds;
|
||||
mNotifications.push_back(c);
|
||||
|
||||
for(auto it(msgIds.begin());it!=msgIds.end();++it)
|
||||
for(auto& msg_id:it->second)
|
||||
mNotifications.push_back(new RsGxsMsgChange(RsGxsNotify::TYPE_PROCESSED, it->first, msg_id, false));
|
||||
}
|
||||
}
|
||||
|
||||
@ -2099,17 +2106,11 @@ void RsGenExchange::processGrpMetaChanges()
|
||||
}
|
||||
}
|
||||
|
||||
if(!grpChanged.empty())
|
||||
for(auto& groupId:grpChanged)
|
||||
{
|
||||
RS_STACK_MUTEX(mGenMtx);
|
||||
RsGxsGroupChange* gc = new RsGxsGroupChange(RsGxsNotify::TYPE_PROCESSED, true);
|
||||
gc->mGrpIdList = grpChanged;
|
||||
mNotifications.push_back(gc);
|
||||
#ifdef GEN_EXCH_DEBUG
|
||||
std::cerr << " adding the following grp ids to notification: " << std::endl;
|
||||
for(std::list<RsGxsGroupId>::const_iterator it(grpChanged.begin());it!=grpChanged.end();++it)
|
||||
std::cerr << " " << *it << std::endl;
|
||||
#endif
|
||||
|
||||
mNotifications.push_back(new RsGxsGroupChange(RsGxsNotify::TYPE_PROCESSED,groupId, true));
|
||||
}
|
||||
}
|
||||
|
||||
@ -2186,7 +2187,7 @@ void RsGenExchange::publishMsgs()
|
||||
mMsgsToPublish.insert(std::make_pair(sign_it->first, item.mItem));
|
||||
}
|
||||
|
||||
std::map<RsGxsGroupId, std::set<RsGxsMessageId> > msgChangeMap;
|
||||
std::map<RsGxsGroupId, std::list<RsGxsMsgItem*> > msgChangeMap;
|
||||
std::map<uint32_t, RsGxsMsgItem*>::iterator mit = mMsgsToPublish.begin();
|
||||
|
||||
for(; mit != mMsgsToPublish.end(); ++mit)
|
||||
@ -2315,9 +2316,12 @@ void RsGenExchange::publishMsgs()
|
||||
|
||||
mPublishedMsgs[token] = *msg->metaData;
|
||||
|
||||
RsGxsMsgItem *msg_item = dynamic_cast<RsGxsMsgItem*>(mSerialiser->deserialise(msg->msg.bin_data,&msg->msg.bin_len)) ;
|
||||
msg_item->meta = *msg->metaData;
|
||||
|
||||
delete msg ;
|
||||
|
||||
msgChangeMap[grpId].insert(msgId);
|
||||
msgChangeMap[grpId].push_back(msg_item);
|
||||
|
||||
delete[] metaDataBuff;
|
||||
|
||||
@ -2356,13 +2360,14 @@ void RsGenExchange::publishMsgs()
|
||||
// entries are invalid
|
||||
mMsgsToPublish.clear();
|
||||
|
||||
if(!msgChangeMap.empty())
|
||||
{
|
||||
RsGxsMsgChange* ch = new RsGxsMsgChange(RsGxsNotify::TYPE_PUBLISHED, false);
|
||||
ch->msgChangeMap = msgChangeMap;
|
||||
mNotifications.push_back(ch);
|
||||
}
|
||||
for(auto it(msgChangeMap.begin());it!=msgChangeMap.end();++it)
|
||||
for(auto& msg_item: it->second)
|
||||
{
|
||||
RsGxsMsgChange* ch = new RsGxsMsgChange(RsGxsNotify::TYPE_PUBLISHED,msg_item->meta.mGroupId, msg_item->meta.mMsgId, false);
|
||||
ch->mNewMsgItem = msg_item;
|
||||
|
||||
mNotifications.push_back(ch);
|
||||
}
|
||||
}
|
||||
|
||||
RsGenExchange::ServiceCreate_Return RsGenExchange::service_CreateGroup(RsGxsGrpItem* /* grpItem */,
|
||||
@ -2381,15 +2386,14 @@ RsGenExchange::ServiceCreate_Return RsGenExchange::service_CreateGroup(RsGxsGrpI
|
||||
|
||||
void RsGenExchange::processGroupUpdatePublish()
|
||||
{
|
||||
RS_STACK_MUTEX(mGenMtx) ;
|
||||
RS_STACK_MUTEX(mGenMtx) ;
|
||||
|
||||
// get keys for group update publish
|
||||
|
||||
// first build meta request map for groups to be updated
|
||||
RsGxsGrpMetaTemporaryMap grpMeta;
|
||||
std::vector<GroupUpdatePublish>::iterator vit = mGroupUpdatePublish.begin();
|
||||
|
||||
for(; vit != mGroupUpdatePublish.end(); ++vit)
|
||||
for(auto vit = mGroupUpdatePublish.begin(); vit != mGroupUpdatePublish.end(); ++vit)
|
||||
{
|
||||
GroupUpdatePublish& gup = *vit;
|
||||
const RsGxsGroupId& groupId = gup.grpItem->meta.mGroupId;
|
||||
@ -2402,8 +2406,7 @@ void RsGenExchange::processGroupUpdatePublish()
|
||||
mDataStore->retrieveGxsGrpMetaData(grpMeta);
|
||||
|
||||
// now
|
||||
vit = mGroupUpdatePublish.begin();
|
||||
for(; vit != mGroupUpdatePublish.end(); ++vit)
|
||||
for(auto vit = mGroupUpdatePublish.begin(); vit != mGroupUpdatePublish.end(); ++vit)
|
||||
{
|
||||
GroupUpdatePublish& gup = *vit;
|
||||
const RsGxsGroupId& groupId = gup.grpItem->meta.mGroupId;
|
||||
@ -2421,14 +2424,14 @@ void RsGenExchange::processGroupUpdatePublish()
|
||||
meta = mit->second;
|
||||
|
||||
//gup.grpItem->meta = *meta;
|
||||
GxsGrpPendingSign ggps(gup.grpItem, gup.mToken);
|
||||
GxsGrpPendingSign ggps(gup.grpItem, gup.mToken);
|
||||
|
||||
if(checkKeys(meta->keys))
|
||||
{
|
||||
ggps.mKeys = meta->keys;
|
||||
|
||||
GxsSecurity::createPublicKeysFromPrivateKeys(ggps.mKeys) ;
|
||||
|
||||
|
||||
GxsSecurity::createPublicKeysFromPrivateKeys(ggps.mKeys) ;
|
||||
|
||||
ggps.mHaveKeys = true;
|
||||
ggps.mStartTS = time(NULL);
|
||||
ggps.mLastAttemptTS = 0;
|
||||
@ -2438,8 +2441,8 @@ void RsGenExchange::processGroupUpdatePublish()
|
||||
}
|
||||
else
|
||||
{
|
||||
std::cerr << "(EE) publish group fails because RS cannot find the private publish and author keys" << std::endl;
|
||||
|
||||
std::cerr << "(EE) publish group fails because RS cannot find the private publish and author keys" << std::endl;
|
||||
|
||||
delete gup.grpItem;
|
||||
mDataAccess->updatePublicRequestStatus(gup.mToken, RsTokenService::FAILED);
|
||||
}
|
||||
@ -2494,15 +2497,15 @@ void RsGenExchange::processGroupDelete()
|
||||
grpDeleted.push_back(note.second);
|
||||
}
|
||||
|
||||
if(!grpDeleted.empty())
|
||||
for(auto& groupId:grpDeleted)
|
||||
{
|
||||
RsGxsGroupChange* gc = new RsGxsGroupChange(RsGxsNotify::TYPE_PUBLISHED, false);
|
||||
gc->mGrpIdList = grpDeleted;
|
||||
RsGxsGroupChange* gc = new RsGxsGroupChange(RsGxsNotify::TYPE_GROUP_DELETED, groupId,false);
|
||||
mNotifications.push_back(gc);
|
||||
}
|
||||
|
||||
mGroupDeletePublish.clear();
|
||||
}
|
||||
|
||||
void RsGenExchange::processMessageDelete()
|
||||
{
|
||||
RS_STACK_MUTEX(mGenMtx) ;
|
||||
@ -2521,31 +2524,24 @@ void RsGenExchange::processMessageDelete()
|
||||
mDataStore->removeMsgs( (*vit).mMsgs );
|
||||
}
|
||||
|
||||
// std::list<RsGxsGroupId> grpDeleted;
|
||||
// std::map<uint32_t, GrpNote>::iterator mit = toNotify.begin();
|
||||
// for(; mit != toNotify.end(); ++mit)
|
||||
// {
|
||||
// GrpNote& note = mit->second;
|
||||
// uint8_t status = note.first ? RsTokenService::GXS_REQUEST_V2_STATUS_COMPLETE
|
||||
// : RsTokenService::GXS_REQUEST_V2_STATUS_FAILED;
|
||||
//
|
||||
// mGrpNotify.insert(std::make_pair(mit->first, note.second));
|
||||
// mDataAccess->updatePublicRequestStatus(mit->first, status);
|
||||
//
|
||||
// if(note.first)
|
||||
// grpDeleted.push_back(note.second);
|
||||
// }
|
||||
|
||||
#warning csoler: TODO: notify for deleted messages
|
||||
#ifdef SUSPENDED
|
||||
std::list<RsGxsGroupId> grpDeleted;
|
||||
std::map<uint32_t, GrpNote>::iterator mit = toNotify.begin();
|
||||
for(; mit != toNotify.end(); ++mit)
|
||||
{
|
||||
GrpNote& note = mit->second;
|
||||
uint8_t status = note.first ? RsTokenService::GXS_REQUEST_V2_STATUS_COMPLETE
|
||||
: RsTokenService::GXS_REQUEST_V2_STATUS_FAILED;
|
||||
|
||||
mGrpNotify.insert(std::make_pair(mit->first, note.second));
|
||||
mDataAccess->updatePublicRequestStatus(mit->first, status);
|
||||
|
||||
if(note.first)
|
||||
grpDeleted.push_back(note.second);
|
||||
}
|
||||
|
||||
if(!grpDeleted.empty())
|
||||
{
|
||||
RsGxsGroupChange* gc = new RsGxsGroupChange(RsGxsNotify::TYPE_PUBLISH, false);
|
||||
gc->mGrpIdList = grpDeleted;
|
||||
mNotifications.push_back(gc);
|
||||
}
|
||||
#endif
|
||||
for(uint32_t i=0;i<mMsgDeletePublish.size();++i)
|
||||
for(auto it(mMsgDeletePublish[i].mMsgs.begin());it!=mMsgDeletePublish[i].mMsgs.end();++it)
|
||||
mNotifications.push_back(new RsGxsGroupChange(RsGxsNotify::TYPE_MESSAGE_DELETED,it->first, false));
|
||||
|
||||
mMsgDeletePublish.clear();
|
||||
}
|
||||
@ -2805,17 +2801,8 @@ void RsGenExchange::publishGrps()
|
||||
grpChanged.push_back(note.second);
|
||||
}
|
||||
|
||||
if(!grpChanged.empty())
|
||||
{
|
||||
RsGxsGroupChange* gc = new RsGxsGroupChange(RsGxsNotify::TYPE_RECEIVED_NEW, true);
|
||||
gc->mGrpIdList = grpChanged;
|
||||
mNotifications.push_back(gc);
|
||||
#ifdef GEN_EXCH_DEBUG
|
||||
std::cerr << " adding the following grp ids to notification: " << std::endl;
|
||||
for(std::list<RsGxsGroupId>::const_iterator it(grpChanged.begin());it!=grpChanged.end();++it)
|
||||
std::cerr << " " << *it << std::endl;
|
||||
#endif
|
||||
}
|
||||
for(auto& groupId:grpChanged)
|
||||
mNotifications.push_back(new RsGxsGroupChange(RsGxsNotify::TYPE_RECEIVED_NEW,groupId, true));
|
||||
}
|
||||
|
||||
// This is done off-mutex to avoid possible cross deadlocks with the net service.
|
||||
@ -3072,11 +3059,19 @@ void RsGenExchange::processRecvdMessages()
|
||||
#ifdef GEN_EXCH_DEBUG
|
||||
std::cerr << " storing remaining messages" << std::endl;
|
||||
#endif
|
||||
mDataStore->storeMessage(msgs_to_store);
|
||||
|
||||
RsGxsMsgChange* c = new RsGxsMsgChange(RsGxsNotify::TYPE_RECEIVED_NEW, false);
|
||||
c->msgChangeMap = msgIds;
|
||||
mNotifications.push_back(c);
|
||||
for(auto& nxs_msg: msgs_to_store)
|
||||
{
|
||||
RsGxsMsgItem *item = dynamic_cast<RsGxsMsgItem*>(mSerialiser->deserialise(nxs_msg->msg.bin_data,&nxs_msg->msg.bin_len));
|
||||
item->meta = *nxs_msg->metaData;
|
||||
|
||||
RsGxsMsgChange* c = new RsGxsMsgChange(RsGxsNotify::TYPE_RECEIVED_NEW, item->meta.mGroupId, item->meta.mMsgId,false);
|
||||
c->mNewMsgItem = item;
|
||||
|
||||
mNotifications.push_back(c);
|
||||
}
|
||||
|
||||
mDataStore->storeMessage(msgs_to_store); // we do that late because it destroys the items in msgs_to_store
|
||||
}
|
||||
}
|
||||
|
||||
@ -3205,11 +3200,17 @@ void RsGenExchange::processRecvdGroups()
|
||||
vit = tmp ;
|
||||
}
|
||||
|
||||
if(!grpIds.empty())
|
||||
if(!grps_to_store.empty())
|
||||
{
|
||||
RsGxsGroupChange* c = new RsGxsGroupChange(RsGxsNotify::TYPE_RECEIVED_NEW, false);
|
||||
c->mGrpIdList = grpIds;
|
||||
mNotifications.push_back(c);
|
||||
for(auto Grp:grps_to_store)
|
||||
{
|
||||
RsGxsGroupChange* c = new RsGxsGroupChange(RsGxsNotify::TYPE_RECEIVED_NEW, Grp->grpId, false);
|
||||
|
||||
c->mNewGroupItem = dynamic_cast<RsGxsGrpItem*>(mSerialiser->deserialise(Grp->grp.bin_data,&Grp->grp.bin_len));
|
||||
|
||||
mNotifications.push_back(c);
|
||||
}
|
||||
|
||||
mDataStore->storeGroup(grps_to_store);
|
||||
#ifdef GEN_EXCH_DEBUG
|
||||
std::cerr << " adding the following grp ids to notification: " << std::endl;
|
||||
@ -3230,39 +3231,42 @@ void RsGenExchange::performUpdateValidation()
|
||||
std::cerr << "RsGenExchange::performUpdateValidation() " << std::endl;
|
||||
#endif
|
||||
|
||||
RsGxsGrpMetaTemporaryMap grpMetas;
|
||||
RsNxsGrpDataTemporaryMap grpDatas;
|
||||
|
||||
std::vector<GroupUpdate>::iterator vit = mGroupUpdates.begin();
|
||||
for(; vit != mGroupUpdates.end(); ++vit)
|
||||
grpMetas.insert(std::make_pair(vit->newGrp->grpId, (RsGxsGrpMetaData*)NULL));
|
||||
for(auto vit(mGroupUpdates.begin()); vit != mGroupUpdates.end(); ++vit)
|
||||
grpDatas.insert(std::make_pair(vit->newGrp->grpId, (RsNxsGrp*)NULL));
|
||||
|
||||
if(grpDatas.empty() || !mDataStore->retrieveNxsGrps(grpDatas,true,false))
|
||||
{
|
||||
if(grpDatas.empty())
|
||||
RsErr() << __PRETTY_FUNCTION__ << " Validation of multiple group updates failed: no group in list!" << std::endl;
|
||||
else
|
||||
RsErr() << __PRETTY_FUNCTION__ << " Validation of multiple group updates failed: cannot retrieve froup data for these groups!" << std::endl;
|
||||
|
||||
if(!grpMetas.empty())
|
||||
mDataStore->retrieveGxsGrpMetaData(grpMetas);
|
||||
else
|
||||
return;
|
||||
|
||||
vit = mGroupUpdates.begin();
|
||||
for(; vit != mGroupUpdates.end(); ++vit)
|
||||
{
|
||||
GroupUpdate& gu = *vit;
|
||||
std::map<RsGxsGroupId, RsGxsGrpMetaData*>::iterator mit = grpMetas.find(gu.newGrp->grpId);
|
||||
gu.oldGrpMeta = mit->second;
|
||||
gu.validUpdate = updateValid(*(gu.oldGrpMeta), *(gu.newGrp));
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef GEN_EXCH_DEBUG
|
||||
std::cerr << "RsGenExchange::performUpdateValidation() " << std::endl;
|
||||
#endif
|
||||
|
||||
vit = mGroupUpdates.begin();
|
||||
|
||||
RsNxsGrpDataTemporaryList grps ;
|
||||
|
||||
for(; vit != mGroupUpdates.end(); ++vit)
|
||||
for(auto vit(mGroupUpdates.begin()); vit != mGroupUpdates.end(); ++vit)
|
||||
{
|
||||
GroupUpdate& gu = *vit;
|
||||
|
||||
if(gu.validUpdate)
|
||||
auto mit = grpDatas.find(gu.newGrp->grpId);
|
||||
|
||||
if(mit == grpDatas.end())
|
||||
{
|
||||
RsErr() << __PRETTY_FUNCTION__ << " Validation of group update failed for group " << gu.newGrp->grpId << " because previous grp version cannot be found." << std::endl;
|
||||
continue;
|
||||
}
|
||||
RsGxsGrpMetaData *oldGrpMeta(mit->second->metaData);
|
||||
RsNxsGrp *oldGrp(mit->second);
|
||||
|
||||
if(updateValid(*oldGrpMeta, *gu.newGrp))
|
||||
{
|
||||
if(gu.newGrp->metaData->mCircleType == GXS_CIRCLE_TYPE_YOUR_FRIENDS_ONLY)
|
||||
gu.newGrp->metaData->mOriginator = gu.newGrp->PeerId();
|
||||
@ -3270,42 +3274,39 @@ void RsGenExchange::performUpdateValidation()
|
||||
// Keep subscriptionflag to what it was. This avoids clearing off the flag when updates to group meta information
|
||||
// is received.
|
||||
|
||||
gu.newGrp->metaData->mSubscribeFlags = gu.oldGrpMeta->mSubscribeFlags ;
|
||||
gu.newGrp->metaData->mSubscribeFlags = oldGrpMeta->mSubscribeFlags ;
|
||||
|
||||
// Also keep private keys if present
|
||||
|
||||
if(!gu.newGrp->metaData->keys.private_keys.empty())
|
||||
std::cerr << "(EE) performUpdateValidation() group " <<gu.newGrp->metaData->mGroupId << " has been received with private keys. This is very unexpected!" << std::endl;
|
||||
else
|
||||
gu.newGrp->metaData->keys.private_keys = gu.oldGrpMeta->keys.private_keys ;
|
||||
gu.newGrp->metaData->keys.private_keys = oldGrpMeta->keys.private_keys ;
|
||||
|
||||
// Now prepare notification of the client
|
||||
|
||||
RsGxsGroupChange *c = new RsGxsGroupChange(RsGxsNotify::TYPE_UPDATED,gu.newGrp->metaData->mGroupId,false);
|
||||
|
||||
c->mNewGroupItem = dynamic_cast<RsGxsGrpItem*>(mSerialiser->deserialise(gu.newGrp->grp.bin_data,&gu.newGrp->grp.bin_len));
|
||||
c->mNewGroupItem->meta = *gu.newGrp->metaData; // gu.newGrp will be deleted because mDataStore will destroy it on update
|
||||
|
||||
c->mOldGroupItem = dynamic_cast<RsGxsGrpItem*>(mSerialiser->deserialise(oldGrp->grp.bin_data,&oldGrp->grp.bin_len));
|
||||
c->mOldGroupItem->meta = *oldGrpMeta; // no need to delete mit->second, as it will be deleted automatically in the temporary map
|
||||
|
||||
mNotifications.push_back(c);
|
||||
|
||||
// finally, add the group to the list to send to mDataStore
|
||||
|
||||
grps.push_back(gu.newGrp);
|
||||
}
|
||||
else
|
||||
{
|
||||
delete gu.newGrp;
|
||||
delete gu.newGrp; // delete here because mDataStore will not take care of this one. no need to delete mit->second, as it will be deleted automatically in the temporary map
|
||||
gu.newGrp = NULL ;
|
||||
}
|
||||
|
||||
gu.oldGrpMeta = NULL ;
|
||||
}
|
||||
// notify the client
|
||||
|
||||
RsGxsGroupChange* c = new RsGxsGroupChange(RsGxsNotify::TYPE_RECEIVED_NEW, true);
|
||||
|
||||
for(uint32_t i=0;i<mGroupUpdates.size();++i)
|
||||
if(mGroupUpdates[i].newGrp != NULL)
|
||||
{
|
||||
c->mGrpIdList.push_back(mGroupUpdates[i].newGrp->grpId) ;
|
||||
#ifdef GEN_EXCH_DEBUG
|
||||
std::cerr << " " << mGroupUpdates[i].newGrp->grpId << std::endl;
|
||||
#endif
|
||||
}
|
||||
|
||||
mNotifications.push_back(c);
|
||||
|
||||
// Warning: updateGroup will destroy the objects in grps. Dont use it afterwards!
|
||||
|
||||
mDataStore->updateGroup(grps);
|
||||
|
||||
#ifdef GEN_EXCH_DEBUG
|
||||
|
@ -33,6 +33,7 @@
|
||||
#include "rsnxsobserver.h"
|
||||
#include "retroshare/rsgxsservice.h"
|
||||
#include "rsitems/rsnxsitems.h"
|
||||
#include "gxs/rsgxsnotify.h"
|
||||
#include "rsgxsutil.h"
|
||||
|
||||
template<class GxsItem, typename Identity = std::string>
|
||||
@ -262,12 +263,14 @@ public:
|
||||
*/
|
||||
bool getPublishedMsgMeta(const uint32_t& token,RsMsgMetaData& meta);
|
||||
|
||||
#ifdef TO_REMOVE
|
||||
/*!
|
||||
* Gxs services should call this for automatic handling of
|
||||
* changes, send
|
||||
* @param changes
|
||||
*/
|
||||
virtual void receiveChanges(std::vector<RsGxsNotify*>& changes);
|
||||
#endif
|
||||
|
||||
/*!
|
||||
* \brief acceptNewGroup
|
||||
@ -748,9 +751,6 @@ protected:
|
||||
*/
|
||||
virtual void notifyChanges(std::vector<RsGxsNotify*>& changes) = 0;
|
||||
|
||||
|
||||
|
||||
|
||||
private:
|
||||
|
||||
void processRecvdData();
|
||||
|
@ -1038,7 +1038,7 @@ bool RsGxsDataAccess::getMsgMetaDataList( const GxsMsgReq& msgIds, const RsTokRe
|
||||
// Because msgs are stored in a std::vector we build a map to convert each vector to its position in metaV.
|
||||
|
||||
std::vector<bool> keep(metaV.size(),true); // this vector will tell wether we keep or not a given Meta
|
||||
std::map<RsMessageId,uint32_t> index_in_metaV; // holds the index of each group Id in metaV
|
||||
std::map<RsGxsMessageId,uint32_t> index_in_metaV; // holds the index of each group Id in metaV
|
||||
|
||||
for(uint32_t i=0;i<metaV.size();++i)
|
||||
index_in_metaV[metaV[i]->mMsgId] = i;
|
||||
|
@ -320,9 +320,9 @@ static const uint32_t RS_NXS_ITEM_ENCRYPTION_STATUS_GXS_KEY_MISSING = 0x05 ;
|
||||
|| defined(NXS_NET_DEBUG_4) || defined(NXS_NET_DEBUG_5) || defined(NXS_NET_DEBUG_6) || defined(NXS_NET_DEBUG_7) \
|
||||
|| defined(NXS_NET_DEBUG_8)
|
||||
|
||||
static const RsPeerId peer_to_print = RsPeerId(std::string("")) ;
|
||||
static const RsGxsGroupId group_id_to_print = RsGxsGroupId(std::string("")) ; // use this to allow to this group id only, or "" for all IDs
|
||||
static const uint32_t service_to_print = RS_SERVICE_GXS_TYPE_CHANNELS ; // use this to allow to this service id only, or 0 for all services
|
||||
static const RsPeerId peer_to_print = RsPeerId();//std::string("a97fef0e2dc82ddb19200fb30f9ac575")) ;
|
||||
static const RsGxsGroupId group_id_to_print = RsGxsGroupId(std::string("66052380f5d1d0c5992e2b55dc402ce6")) ; // use this to allow to this group id only, or "" for all IDs
|
||||
static const uint32_t service_to_print = RS_SERVICE_GXS_TYPE_GXSCIRCLE; // use this to allow to this service id only, or 0 for all services
|
||||
// warning. Numbers should be SERVICE IDS (see serialiser/rsserviceids.h. E.g. 0x0215 for forums)
|
||||
|
||||
class nullstream: public std::ostream {};
|
||||
@ -3598,6 +3598,10 @@ void RsGxsNetService::locked_genSendMsgsTransaction(NxsTransaction* tr)
|
||||
msg->count = 1; // only one piece. This is to keep compatibility if we ever implement fragmenting in the future.
|
||||
msg->pos = 0;
|
||||
|
||||
#ifdef NXS_NET_DEBUG_0
|
||||
GXSNETDEBUG_PG(tr->mTransaction->PeerId(),msg->grpId) << " sending msg Id " << msg->msgId << " in Group " << msg->grpId << std::endl;
|
||||
#endif
|
||||
|
||||
newTr->mItems.push_back(msg);
|
||||
msgSize++;
|
||||
#endif
|
||||
|
107
libretroshare/src/gxs/rsgxsnotify.h
Normal file
107
libretroshare/src/gxs/rsgxsnotify.h
Normal file
@ -0,0 +1,107 @@
|
||||
/*******************************************************************************
|
||||
* libretroshare/src/gxs/: rsgxsnotify.h *
|
||||
* *
|
||||
* libretroshare: retroshare core library *
|
||||
* *
|
||||
* Copyright (C) 2015 Retroshare Team <retroshare.project@gmail.com> *
|
||||
* *
|
||||
* This program is free software: you can redistribute it and/or modify *
|
||||
* it under the terms of the GNU Lesser General Public License as *
|
||||
* published by the Free Software Foundation, either version 3 of the *
|
||||
* License, or (at your option) any later version. *
|
||||
* *
|
||||
* This program is distributed in the hope that it will be useful, *
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
|
||||
* GNU Lesser General Public License for more details. *
|
||||
* *
|
||||
* You should have received a copy of the GNU Lesser General Public License *
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>. *
|
||||
* *
|
||||
*******************************************************************************/
|
||||
|
||||
#pragma once
|
||||
|
||||
/*!
|
||||
* The aim of this class is to implement notifications internally to GXS, which are
|
||||
* mostly used by RsGenExchange to send information to specific services. These services
|
||||
* then interpret these changes and turn them into human-readable/processed service-specific changes.
|
||||
*/
|
||||
|
||||
#include "retroshare/rsids.h"
|
||||
|
||||
class RsGxsNotify
|
||||
{
|
||||
public:
|
||||
RsGxsNotify(const RsGxsGroupId& gid): mGroupId(gid){}
|
||||
virtual ~RsGxsNotify()=default;
|
||||
|
||||
enum NotifyType
|
||||
{
|
||||
TYPE_UNKNOWN = 0x00,
|
||||
TYPE_PUBLISHED = 0x01,
|
||||
TYPE_RECEIVED_NEW = 0x02,
|
||||
TYPE_PROCESSED = 0x03,
|
||||
TYPE_RECEIVED_PUBLISHKEY = 0x04,
|
||||
TYPE_RECEIVED_DISTANT_SEARCH_RESULTS = 0x05,
|
||||
TYPE_STATISTICS_CHANGED = 0x06,
|
||||
TYPE_UPDATED = 0x07,
|
||||
TYPE_MESSAGE_DELETED = 0x08,
|
||||
TYPE_GROUP_DELETED = 0x09,
|
||||
};
|
||||
|
||||
virtual NotifyType getType() = 0;
|
||||
|
||||
RsGxsGroupId mGroupId; // Group id of the group we're talking about. When the group is deleted, it's useful to know which group
|
||||
// that was although there is no pointers to the actual group data anymore.
|
||||
};
|
||||
|
||||
/*!
|
||||
* Relevant to group changes
|
||||
*/
|
||||
class RsGxsGroupChange : public RsGxsNotify
|
||||
{
|
||||
public:
|
||||
RsGxsGroupChange(NotifyType type, const RsGxsGroupId& gid,bool metaChange) : RsGxsNotify(gid),mNewGroupItem(nullptr),mOldGroupItem(nullptr), mNotifyType(type), mMetaChange(metaChange) {}
|
||||
virtual ~RsGxsGroupChange() override { delete mOldGroupItem; delete mNewGroupItem ; }
|
||||
|
||||
NotifyType getType() override { return mNotifyType;}
|
||||
bool metaChange() { return mMetaChange; }
|
||||
|
||||
RsGxsGrpItem *mNewGroupItem; // Valid when a group has changed, or a new group is received.
|
||||
RsGxsGrpItem *mOldGroupItem; // only valid when mNotifyType is TYPE_UPDATED
|
||||
|
||||
protected:
|
||||
NotifyType mNotifyType;
|
||||
bool mMetaChange;
|
||||
};
|
||||
|
||||
class RsGxsDistantSearchResultChange: public RsGxsNotify
|
||||
{
|
||||
public:
|
||||
RsGxsDistantSearchResultChange(TurtleRequestId id,const RsGxsGroupId& gid) : RsGxsNotify(gid), mRequestId(id){}
|
||||
|
||||
NotifyType getType() { return TYPE_RECEIVED_DISTANT_SEARCH_RESULTS ; }
|
||||
|
||||
TurtleRequestId mRequestId ;
|
||||
};
|
||||
|
||||
/*!
|
||||
* Relevant to message changes
|
||||
*/
|
||||
class RsGxsMsgChange : public RsGxsNotify
|
||||
{
|
||||
public:
|
||||
RsGxsMsgChange(NotifyType type, const RsGxsGroupId& gid, const RsGxsMessageId& msg_id,bool metaChange)
|
||||
: RsGxsNotify(gid), mMsgId(msg_id), mNewMsgItem(nullptr),NOTIFY_TYPE(type), mMetaChange(metaChange) {}
|
||||
|
||||
RsGxsMessageId mMsgId;
|
||||
RsGxsMsgItem *mNewMsgItem;
|
||||
|
||||
NotifyType getType(){ return NOTIFY_TYPE;}
|
||||
bool metaChange() { return mMetaChange; }
|
||||
private:
|
||||
const NotifyType NOTIFY_TYPE;
|
||||
bool mMetaChange;
|
||||
};
|
||||
|
@ -656,6 +656,9 @@ void p3GxsTrans::notifyChanges(std::vector<RsGxsNotify*>& changes)
|
||||
#ifdef DEBUG_GXSTRANS
|
||||
std::cout << "p3GxsTrans::notifyChanges(...)" << std::endl;
|
||||
#endif
|
||||
std::list<RsGxsGroupId> grps_to_request;
|
||||
GxsMsgReq msgs_to_request;
|
||||
|
||||
for( auto it = changes.begin(); it != changes.end(); ++it )
|
||||
{
|
||||
RsGxsGroupChange* grpChange = dynamic_cast<RsGxsGroupChange *>(*it);
|
||||
@ -666,18 +669,15 @@ void p3GxsTrans::notifyChanges(std::vector<RsGxsNotify*>& changes)
|
||||
#ifdef DEBUG_GXSTRANS
|
||||
std::cout << "p3GxsTrans::notifyChanges(...) grpChange" << std::endl;
|
||||
#endif
|
||||
requestGroupsData(&(grpChange->mGrpIdList));
|
||||
grps_to_request.push_back(grpChange->mGroupId);
|
||||
}
|
||||
else if(msgChange)
|
||||
{
|
||||
#ifdef DEBUG_GXSTRANS
|
||||
std::cout << "p3GxsTrans::notifyChanges(...) msgChange" << std::endl;
|
||||
#endif
|
||||
uint32_t token;
|
||||
RsTokReqOptions opts; opts.mReqType = GXS_REQUEST_TYPE_MSG_DATA;
|
||||
RsGenExchange::getTokenService()->requestMsgInfo( token, 0xcaca,
|
||||
opts, msgChange->msgChangeMap );
|
||||
GxsTokenQueue::queueRequest(token, MAILS_UPDATE);
|
||||
|
||||
msgs_to_request[msgChange->mGroupId].insert(msgChange->mMsgId);
|
||||
|
||||
#ifdef DEBUG_GXSTRANS
|
||||
for( GxsMsgReq::const_iterator it = msgChange->msgChangeMap.begin();
|
||||
@ -698,6 +698,20 @@ void p3GxsTrans::notifyChanges(std::vector<RsGxsNotify*>& changes)
|
||||
}
|
||||
delete *it;
|
||||
}
|
||||
|
||||
if(!msgs_to_request.empty())
|
||||
{
|
||||
uint32_t token;
|
||||
RsTokReqOptions opts;
|
||||
opts.mReqType = GXS_REQUEST_TYPE_MSG_DATA;
|
||||
RsGenExchange::getTokenService()->requestMsgInfo( token, 0xcaca, opts, msgs_to_request);
|
||||
|
||||
GxsTokenQueue::queueRequest(token, MAILS_UPDATE);
|
||||
}
|
||||
|
||||
|
||||
if(!grps_to_request.empty())
|
||||
requestGroupsData(&grps_to_request);
|
||||
}
|
||||
|
||||
uint32_t p3GxsTrans::AuthenPolicy()
|
||||
|
@ -672,6 +672,7 @@ HEADERS += rsitems/rsnxsitems.h \
|
||||
util/rsdbbind.h \
|
||||
util/contentvalue.h \
|
||||
gxs/rsgxsutil.h \
|
||||
gxs/rsgxsnotify.h \
|
||||
gxs/gxssecurity.h \
|
||||
gxs/rsgds.h \
|
||||
gxs/rsgxs.h \
|
||||
|
@ -1113,10 +1113,16 @@ int pqissl::SSL_Connection_Complete()
|
||||
if(rsEvents)
|
||||
{
|
||||
X509 *x509 = SSL_get_peer_certificate(ssl_connection);
|
||||
auto ev = std::make_shared<RsAuthSslConnectionAutenticationEvent>();
|
||||
ev->mSslId = RsX509Cert::getCertSslId(*x509);
|
||||
ev->mErrorCode = RsAuthSslError::PEER_REFUSED_CONNECTION;
|
||||
rsEvents->postEvent(ev);
|
||||
|
||||
if(x509)
|
||||
{
|
||||
auto ev = std::make_shared<RsAuthSslConnectionAutenticationEvent>();
|
||||
ev->mSslId = RsX509Cert::getCertSslId(*x509);
|
||||
ev->mErrorCode = RsAuthSslError::PEER_REFUSED_CONNECTION;
|
||||
|
||||
if(!ev->mSslId.isNull())
|
||||
rsEvents->postEvent(ev);
|
||||
}
|
||||
}
|
||||
|
||||
std::string out;
|
||||
|
@ -314,7 +314,8 @@ public:
|
||||
*/
|
||||
virtual bool getChannelAllContent( const RsGxsGroupId& channelId,
|
||||
std::vector<RsGxsChannelPost>& posts,
|
||||
std::vector<RsGxsComment>& comments ) = 0;
|
||||
std::vector<RsGxsComment>& comments,
|
||||
std::vector<RsGxsVote>& votes ) = 0;
|
||||
|
||||
/**
|
||||
* @brief Get channel messages and comments corresponding to the given IDs.
|
||||
@ -326,12 +327,14 @@ public:
|
||||
* @param[in] contentsIds ids of requested contents
|
||||
* @param[out] posts storage for posts
|
||||
* @param[out] comments storage for the comments
|
||||
* @param[out] votes storage for the votes
|
||||
* @return false if something failed, true otherwhise
|
||||
*/
|
||||
virtual bool getChannelContent( const RsGxsGroupId& channelId,
|
||||
const std::set<RsGxsMessageId>& contentsIds,
|
||||
std::vector<RsGxsChannelPost>& posts,
|
||||
std::vector<RsGxsComment>& comments ) = 0;
|
||||
std::vector<RsGxsComment>& comments,
|
||||
std::vector<RsGxsVote>& votes ) = 0;
|
||||
|
||||
/**
|
||||
* @brief Get channel comments corresponding to the given IDs.
|
||||
@ -571,6 +574,9 @@ public:
|
||||
RS_DEPRECATED_FOR(getChannelsInfo)
|
||||
virtual bool getGroupData(const uint32_t &token, std::vector<RsGxsChannelGroup> &groups) = 0;
|
||||
|
||||
RS_DEPRECATED_FOR(getChannelContent)
|
||||
virtual bool getPostData(const uint32_t &token, std::vector<RsGxsChannelPost> &posts, std::vector<RsGxsComment> &cmts, std::vector<RsGxsVote> &votes) = 0;
|
||||
|
||||
RS_DEPRECATED_FOR(getChannelContent)
|
||||
virtual bool getPostData(const uint32_t &token, std::vector<RsGxsChannelPost> &posts, std::vector<RsGxsComment> &cmts) = 0;
|
||||
|
||||
|
@ -45,25 +45,23 @@ extern RsGxsCircles* rsGxsCircles;
|
||||
|
||||
enum class RsGxsCircleType : uint32_t // 32 bit overkill, just for retrocompat
|
||||
{
|
||||
UNKNOWN = 0, /// Used to detect uninizialized values.
|
||||
PUBLIC = 1, /// Public distribution
|
||||
EXTERNAL = 2, /// Restricted to an external circle
|
||||
UNKNOWN = 0, /// Used to detect uninizialized values.
|
||||
PUBLIC = 1, /// Public distribution, based on GxsIds
|
||||
EXTERNAL = 2, /// Restricted to an external circle, based on GxsIds
|
||||
|
||||
/** Restricted to a group of friend nodes, the administrator of the circle
|
||||
* behave as a hub for them */
|
||||
NODES_GROUP = 3,
|
||||
NODES_GROUP = 3, /// Restricted to a group of friend nodes, the administrator of the circle behave as a hub for them
|
||||
/// Based on PGP nodes ids.
|
||||
|
||||
LOCAL = 4, /// not distributed at all
|
||||
|
||||
/** Self-restricted. Used only at creation time of self-restricted circles
|
||||
* when the circle id isn't known yet. Once the circle id is known the type
|
||||
* is set to EXTERNAL, and the external circle id is set to the id of the
|
||||
* circle itself.
|
||||
* circle itself. Based on GxsIds.
|
||||
*/
|
||||
EXT_SELF = 5,
|
||||
|
||||
/// distributed to nodes signed by your own PGP key only.
|
||||
YOUR_EYES_ONLY = 6
|
||||
YOUR_EYES_ONLY = 6 /// distributed to nodes signed by your own PGP key only.
|
||||
};
|
||||
|
||||
// TODO: convert to enum class
|
||||
@ -98,22 +96,32 @@ struct RsGxsCircleGroup : RsSerializable
|
||||
~RsGxsCircleGroup() override;
|
||||
};
|
||||
|
||||
enum class RsGxsCircleSubscriptionType:uint8_t {
|
||||
UNKNOWN = 0x00,
|
||||
SUBSCRIBE = 0x01,
|
||||
UNSUBSCRIBE = 0x02
|
||||
};
|
||||
|
||||
struct RsGxsCircleMsg : RsSerializable
|
||||
{
|
||||
RsMsgMetaData mMeta;
|
||||
|
||||
#ifdef TO_REMOVE
|
||||
// This item is actually totally unused, so we can change it no problem
|
||||
#ifndef V07_NON_BACKWARD_COMPATIBLE_CHANGE_UNNAMED
|
||||
/* This is horrible and should be changed into yet to be defined something
|
||||
* reasonable in next non-retrocompatible version */
|
||||
std::string stuff;
|
||||
#endif
|
||||
#endif
|
||||
RsGxsCircleSubscriptionType mSubscriptionType;
|
||||
|
||||
/// @see RsSerializable
|
||||
void serial_process( RsGenericSerializer::SerializeJob j,
|
||||
RsGenericSerializer::SerializeContext& ctx) override
|
||||
{
|
||||
RS_SERIAL_PROCESS(mMeta);
|
||||
RS_SERIAL_PROCESS(stuff);
|
||||
RS_SERIAL_PROCESS(mSubscriptionType);
|
||||
}
|
||||
|
||||
~RsGxsCircleMsg() override;
|
||||
@ -121,15 +129,29 @@ struct RsGxsCircleMsg : RsSerializable
|
||||
|
||||
struct RsGxsCircleDetails : RsSerializable
|
||||
{
|
||||
RsGxsCircleDetails() :
|
||||
mCircleType(static_cast<uint32_t>(RsGxsCircleType::EXTERNAL)),
|
||||
mAmIAllowed(false),mAmIAdmin(false) {}
|
||||
RsGxsCircleDetails() : mCircleType(RsGxsCircleType::EXTERNAL), mAmIAllowed(false),mAmIAdmin(false) {}
|
||||
~RsGxsCircleDetails() override;
|
||||
|
||||
// helper functions.
|
||||
bool isIdInCircle(const RsGxsId& id) const { return mAllowedGxsIds.find(id) != mAllowedGxsIds.end(); }
|
||||
bool isIdInInviteeList(const RsGxsId& id) const
|
||||
{
|
||||
auto it = mSubscriptionFlags.find(id);
|
||||
return (it != mSubscriptionFlags.end()) && (it->second & GXS_EXTERNAL_CIRCLE_FLAGS_IN_ADMIN_LIST );
|
||||
}
|
||||
bool isIdRequestingMembership(const RsGxsId& id) const
|
||||
{
|
||||
auto it = mSubscriptionFlags.find(id);
|
||||
return it != mSubscriptionFlags.end() && (it->second & GXS_EXTERNAL_CIRCLE_FLAGS_SUBSCRIBED );
|
||||
}
|
||||
bool isGxsIdBased() const { return mCircleType==RsGxsCircleType::PUBLIC || mCircleType==RsGxsCircleType::EXTERNAL || mCircleType==RsGxsCircleType::EXT_SELF; }
|
||||
|
||||
// Members
|
||||
|
||||
RsGxsCircleId mCircleId;
|
||||
std::string mCircleName;
|
||||
|
||||
uint32_t mCircleType;
|
||||
RsGxsCircleType mCircleType;
|
||||
RsGxsCircleId mRestrictedCircleId;
|
||||
|
||||
/** true when one of load GXS ids belong to the circle allowed list (admin
|
||||
@ -165,32 +187,54 @@ struct RsGxsCircleDetails : RsSerializable
|
||||
|
||||
enum class RsGxsCircleEventCode: uint8_t
|
||||
{
|
||||
// Notifications be only have 4 different possibilities:
|
||||
//
|
||||
// invitee list join/leave and
|
||||
// membership request / leave request
|
||||
//
|
||||
// From there, depending on what the client displays, it is possible to interpret these
|
||||
// as "some user joined the circle", or "membership pending for that Id", etc, depending
|
||||
// on whether the current node owns the circle, or the admin is or is not yours.
|
||||
//
|
||||
// These should be decided in the UI based on what the circle cache is displaying.
|
||||
//
|
||||
UNKNOWN = 0x00,
|
||||
|
||||
/** mCircleId contains the circle id and mGxsId is the id requesting
|
||||
* membership */
|
||||
CIRCLE_MEMBERSHIP_REQUEST = 0x01,
|
||||
/**
|
||||
* Sent when we receive a membership request msg for a particular circle.
|
||||
*
|
||||
* mCircleId contains the circle id and mGxsId is the id requesting membership */
|
||||
CIRCLE_MEMBERSHIP_REQUEST = 0x01,
|
||||
|
||||
/** mCircleId is the circle that invites me, and mGxsId is my own Id that is
|
||||
* invited */
|
||||
CIRCLE_MEMBERSHIP_INVITE = 0x02,
|
||||
/**
|
||||
* Sent when the ID has been added to the circle invitee list.
|
||||
*
|
||||
* mCircleId is the circle that invites me, and mGxsId is my own Id that is invited */
|
||||
CIRCLE_MEMBERSHIP_ID_ADDED_TO_INVITEE_LIST = 0x02,
|
||||
|
||||
/** mCircleId contains the circle id and mGxsId is the id dropping
|
||||
* membership */
|
||||
CIRCLE_MEMBERSHIP_LEAVE = 0x03,
|
||||
/**
|
||||
* Sent when a GxsId annouces its will to not be in the circle.
|
||||
*
|
||||
* mCircleId contains the circle id and mGxsId is the id dropping membership */
|
||||
CIRCLE_MEMBERSHIP_LEAVE = 0x03,
|
||||
|
||||
/// mCircleId contains the circle id and mGxsId is the id of the new member
|
||||
CIRCLE_MEMBERSHIP_JOIN = 0x04,
|
||||
/**
|
||||
* Sent when the Id has been removed from the invitee list.
|
||||
*
|
||||
* mCircleId contains the circle id and mGxsId is the id that was revoqued * by admin */
|
||||
CIRCLE_MEMBERSHIP_ID_REMOVED_FROM_INVITEE_LIST = 0x04,
|
||||
|
||||
/** mCircleId contains the circle id and mGxsId is the id that was revoqued * by admin */
|
||||
CIRCLE_MEMBERSHIP_REVOQUED= 0x05,
|
||||
|
||||
/** 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,
|
||||
/**
|
||||
* Means a new circle has been received.
|
||||
*
|
||||
* mCircleId contains the circle id */
|
||||
NEW_CIRCLE = 0x05,
|
||||
|
||||
/**
|
||||
* Means that the circle cache has updated, and membership status that is displayed should probably be updated to.
|
||||
*
|
||||
* no additional information. Simply means that the info previously from the cache has changed. */
|
||||
CACHE_DATA_UPDATED = 0x06,
|
||||
};
|
||||
|
||||
struct RsGxsCircleEvent: RsEvent
|
||||
|
@ -112,6 +112,7 @@ enum class RsForumEventCode: uint8_t
|
||||
SUBSCRIBE_STATUS_CHANGED = 0x05, /// forum was subscribed or unsubscribed
|
||||
READ_STATUS_CHANGED = 0x06, /// msg was read or marked unread
|
||||
STATISTICS_CHANGED = 0x07, /// suppliers and how many messages they have changed
|
||||
MODERATOR_LIST_CHANGED = 0x08, /// forum moderation list has changed.
|
||||
};
|
||||
|
||||
struct RsGxsForumEvent: RsEvent
|
||||
@ -123,6 +124,8 @@ struct RsGxsForumEvent: RsEvent
|
||||
RsForumEventCode mForumEventCode;
|
||||
RsGxsGroupId mForumGroupId;
|
||||
RsGxsMessageId mForumMsgId;
|
||||
std::list<RsGxsId> mModeratorsAdded;
|
||||
std::list<RsGxsId> mModeratorsRemoved;
|
||||
|
||||
///* @see RsEvent @see RsSerializable
|
||||
void serial_process(
|
||||
@ -133,6 +136,9 @@ struct RsGxsForumEvent: RsEvent
|
||||
RS_SERIAL_PROCESS(mForumEventCode);
|
||||
RS_SERIAL_PROCESS(mForumGroupId);
|
||||
RS_SERIAL_PROCESS(mForumMsgId);
|
||||
RS_SERIAL_PROCESS(mForumMsgId);
|
||||
RS_SERIAL_PROCESS(mModeratorsAdded);
|
||||
RS_SERIAL_PROCESS(mModeratorsRemoved);
|
||||
}
|
||||
|
||||
~RsGxsForumEvent() override;
|
||||
|
@ -116,12 +116,14 @@ struct RsGxsIface
|
||||
*/
|
||||
virtual uint16_t serviceType() const =0;
|
||||
|
||||
#ifdef TO_REMOVE
|
||||
/*!
|
||||
* Gxs services should call this for automatic handling of
|
||||
* changes, send
|
||||
* @param changes
|
||||
*/
|
||||
virtual void receiveChanges(std::vector<RsGxsNotify*>& changes) = 0;
|
||||
#endif
|
||||
|
||||
/*!
|
||||
* @return handle to token service for this GXS service
|
||||
|
@ -72,6 +72,7 @@ public:
|
||||
|
||||
~RsGxsIfaceHelper() = default;
|
||||
|
||||
#ifdef TO_REMOVE
|
||||
/*!
|
||||
* Gxs services should call this for automatic handling of
|
||||
* changes, send
|
||||
@ -81,6 +82,7 @@ public:
|
||||
{
|
||||
mGxs.receiveChanges(changes);
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Generic Lists */
|
||||
|
||||
|
@ -34,8 +34,6 @@
|
||||
#include "serialiser/rstypeserializer.h"
|
||||
#include "util/rstime.h"
|
||||
|
||||
typedef Sha1CheckSum RsGxsMessageId;
|
||||
|
||||
typedef std::map<RsGxsGroupId, std::set<RsGxsMessageId> > GxsMsgIdResult;
|
||||
typedef std::pair<RsGxsGroupId, RsGxsMessageId> RsGxsGrpMsgIdPair;
|
||||
typedef std::map<RsGxsGrpMsgIdPair, std::set<RsGxsMessageId> > MsgRelatedIdResult;
|
||||
|
@ -32,69 +32,6 @@ typedef uint32_t TurtleRequestId;
|
||||
typedef std::map<RsGxsGroupId, std::vector<RsMsgMetaData> > GxsMsgMetaMap;
|
||||
typedef std::map<RsGxsGrpMsgIdPair, std::vector<RsMsgMetaData> > GxsMsgRelatedMetaMap;
|
||||
|
||||
/*!
|
||||
* The aim of this class is to abstract how changes are represented so they can
|
||||
* be determined outside the client API without explcitly enumerating all
|
||||
* possible changes at the interface
|
||||
*/
|
||||
struct RsGxsNotify
|
||||
{
|
||||
enum NotifyType
|
||||
{
|
||||
TYPE_UNKNOWN = 0x00,
|
||||
TYPE_PUBLISHED = 0x01,
|
||||
TYPE_RECEIVED_NEW = 0x02,
|
||||
TYPE_PROCESSED = 0x03,
|
||||
TYPE_RECEIVED_PUBLISHKEY = 0x04,
|
||||
TYPE_RECEIVED_DISTANT_SEARCH_RESULTS = 0x05,
|
||||
TYPE_STATISTICS_CHANGED = 0x06
|
||||
};
|
||||
|
||||
virtual ~RsGxsNotify() {}
|
||||
virtual NotifyType getType() = 0;
|
||||
};
|
||||
|
||||
/*!
|
||||
* Relevant to group changes
|
||||
*/
|
||||
class RsGxsGroupChange : public RsGxsNotify
|
||||
{
|
||||
public:
|
||||
RsGxsGroupChange(NotifyType type, bool metaChange) : NOTIFY_TYPE(type), mMetaChange(metaChange) {}
|
||||
std::list<RsGxsGroupId> mGrpIdList;
|
||||
NotifyType getType(){ return NOTIFY_TYPE;}
|
||||
bool metaChange() { return mMetaChange; }
|
||||
private:
|
||||
const NotifyType NOTIFY_TYPE;
|
||||
bool mMetaChange;
|
||||
};
|
||||
|
||||
class RsGxsDistantSearchResultChange: public RsGxsNotify
|
||||
{
|
||||
public:
|
||||
RsGxsDistantSearchResultChange(TurtleRequestId id,const RsGxsGroupId& group_id) : mRequestId(id),mGroupId(group_id){}
|
||||
|
||||
NotifyType getType() { return TYPE_RECEIVED_DISTANT_SEARCH_RESULTS ; }
|
||||
|
||||
TurtleRequestId mRequestId ;
|
||||
RsGxsGroupId mGroupId;
|
||||
};
|
||||
|
||||
/*!
|
||||
* Relevant to message changes
|
||||
*/
|
||||
class RsGxsMsgChange : public RsGxsNotify
|
||||
{
|
||||
public:
|
||||
RsGxsMsgChange(NotifyType type, bool metaChange) : NOTIFY_TYPE(type), mMetaChange(metaChange) {}
|
||||
std::map<RsGxsGroupId, std::set<RsGxsMessageId> > msgChangeMap;
|
||||
NotifyType getType(){ return NOTIFY_TYPE;}
|
||||
bool metaChange() { return mMetaChange; }
|
||||
private:
|
||||
const NotifyType NOTIFY_TYPE;
|
||||
bool mMetaChange;
|
||||
};
|
||||
|
||||
|
||||
|
||||
#endif // RSGXSSERVICE_H
|
||||
|
@ -328,6 +328,7 @@ using Sha256CheckSum = t_RsGenericIdType<_RsIdSize::SHA256 , false, R
|
||||
using RsPgpFingerprint = t_RsGenericIdType<_RsIdSize::PGP_FINGERPRINT, true, RsGenericIdType::PGP_FINGERPRINT>;
|
||||
using Bias20Bytes = t_RsGenericIdType<_RsIdSize::SHA1 , true, RsGenericIdType::BIAS_20_BYTES >;
|
||||
using RsGxsGroupId = t_RsGenericIdType<_RsIdSize::CERT_SIGN , false, RsGenericIdType::GXS_GROUP >;
|
||||
using RsGxsMessageId = t_RsGenericIdType<_RsIdSize::SHA1 , false, RsGenericIdType::GXS_MSG >;
|
||||
using RsGxsId = t_RsGenericIdType<_RsIdSize::CERT_SIGN , false, RsGenericIdType::GXS_ID >;
|
||||
using RsGxsCircleId = t_RsGenericIdType<_RsIdSize::CERT_SIGN , false, RsGenericIdType::GXS_CIRCLE >;
|
||||
using RsGxsTunnelId = t_RsGenericIdType<_RsIdSize::SSL_ID , false, RsGenericIdType::GXS_TUNNEL >;
|
||||
|
@ -62,6 +62,7 @@
|
||||
#define RS_MSG_SIGNED 0x004000 /* message was signed and signature didn't check */
|
||||
#define RS_MSG_LOAD_EMBEDDED_IMAGES 0x008000 /* load embedded images */
|
||||
#define RS_MSG_PUBLISH_KEY 0x020000 /* publish key */
|
||||
#define RS_MSG_SPAM 0x040000 /* Message is marked as spam */
|
||||
|
||||
#define RS_MSG_SYSTEM (RS_MSG_USER_REQUEST | RS_MSG_FRIEND_RECOMMENDATION | RS_MSG_PUBLISH_KEY)
|
||||
|
||||
@ -703,6 +704,15 @@ public:
|
||||
*/
|
||||
virtual bool MessageStar(const std::string &msgId, bool mark) = 0;
|
||||
|
||||
/**
|
||||
* @brief MessageJunk
|
||||
* @jsonapi{development}
|
||||
* @param[in] msgId
|
||||
* @param[in] mark
|
||||
* @return true on success
|
||||
*/
|
||||
virtual bool MessageJunk(const std::string &msgId, bool mark) = 0;
|
||||
|
||||
/**
|
||||
* @brief MessageLoadEmbeddedImages
|
||||
* @jsonapi{development}
|
||||
|
@ -115,11 +115,13 @@ const uint32_t RS_FEED_ITEM_CHAT_NEW = RS_FEED_TYPE_CHAT | 0x0001;
|
||||
const uint32_t RS_FEED_ITEM_MESSAGE = RS_FEED_TYPE_MSG | 0x0001;
|
||||
const uint32_t RS_FEED_ITEM_FILES_NEW = RS_FEED_TYPE_FILES | 0x0001;
|
||||
|
||||
const uint32_t RS_FEED_ITEM_CIRCLE_MEMB_REQ = RS_FEED_TYPE_CIRCLE | 0x0001;
|
||||
const uint32_t RS_FEED_ITEM_CIRCLE_INVIT_REC = RS_FEED_TYPE_CIRCLE | 0x0002;
|
||||
const uint32_t RS_FEED_ITEM_CIRCLE_MEMB_LEAVE = RS_FEED_TYPE_CIRCLE | 0x0003;
|
||||
const uint32_t RS_FEED_ITEM_CIRCLE_MEMB_JOIN = RS_FEED_TYPE_CIRCLE | 0x0004;
|
||||
const uint32_t RS_FEED_ITEM_CIRCLE_MEMB_REVOQUED = RS_FEED_TYPE_CIRCLE | 0x0005;
|
||||
const uint32_t RS_FEED_ITEM_CIRCLE_MEMB_REQ = RS_FEED_TYPE_CIRCLE | 0x0001;
|
||||
const uint32_t RS_FEED_ITEM_CIRCLE_INVITE_REC = RS_FEED_TYPE_CIRCLE | 0x0002;
|
||||
const uint32_t RS_FEED_ITEM_CIRCLE_MEMB_LEAVE = RS_FEED_TYPE_CIRCLE | 0x0003;
|
||||
const uint32_t RS_FEED_ITEM_CIRCLE_MEMB_JOIN = RS_FEED_TYPE_CIRCLE | 0x0004;
|
||||
const uint32_t RS_FEED_ITEM_CIRCLE_MEMB_ACCEPTED = RS_FEED_TYPE_CIRCLE | 0x0005;
|
||||
const uint32_t RS_FEED_ITEM_CIRCLE_MEMB_REVOKED = RS_FEED_TYPE_CIRCLE | 0x0006;
|
||||
const uint32_t RS_FEED_ITEM_CIRCLE_INVITE_CANCELLED= RS_FEED_TYPE_CIRCLE | 0x0007;
|
||||
|
||||
const uint32_t RS_MESSAGE_CONNECT_ATTEMPT = 0x0001;
|
||||
|
||||
|
@ -154,13 +154,15 @@ public:
|
||||
virtual bool getBoardAllContent(
|
||||
const RsGxsGroupId& boardId,
|
||||
std::vector<RsPostedPost>& posts,
|
||||
std::vector<RsGxsComment>& comments ) = 0;
|
||||
std::vector<RsGxsComment>& comments,
|
||||
std::vector<RsGxsVote>& votes ) = 0;
|
||||
|
||||
virtual bool getBoardContent(
|
||||
const RsGxsGroupId& boardId,
|
||||
const std::set<RsGxsMessageId>& contentsIds,
|
||||
std::vector<RsPostedPost>& posts,
|
||||
std::vector<RsGxsComment>& comments ) = 0;
|
||||
std::vector<RsGxsComment>& comments,
|
||||
std::vector<RsGxsVote>& votes ) = 0;
|
||||
|
||||
virtual bool editBoard(RsPostedGroup& board) =0;
|
||||
|
||||
@ -176,6 +178,11 @@ public:
|
||||
virtual bool getGroupData( const uint32_t& token,
|
||||
std::vector<RsPostedGroup> &groups ) = 0;
|
||||
|
||||
RS_DEPRECATED_FOR(getBoardsContent)
|
||||
virtual bool getPostData(
|
||||
const uint32_t& token, std::vector<RsPostedPost>& posts,
|
||||
std::vector<RsGxsComment>& cmts, std::vector<RsGxsVote>& vots) = 0;
|
||||
|
||||
RS_DEPRECATED_FOR(getBoardsContent)
|
||||
virtual bool getPostData(
|
||||
const uint32_t& token, std::vector<RsPostedPost>& posts,
|
||||
|
@ -38,7 +38,6 @@
|
||||
#define USE_NEW_CHUNK_CHECKING_CODE
|
||||
|
||||
typedef Sha1CheckSum RsFileHash ;
|
||||
typedef Sha1CheckSum RsMessageId ;
|
||||
|
||||
const uint32_t FT_STATE_FAILED = 0x0000 ;
|
||||
const uint32_t FT_STATE_OKAY = 0x0001 ;
|
||||
|
@ -35,7 +35,9 @@ RsItem *RsGxsCircleSerialiser::create_item(uint16_t service, uint8_t item_sub_id
|
||||
switch(item_sub_id)
|
||||
{
|
||||
case RS_PKT_SUBTYPE_GXSCIRCLE_GROUP_ITEM: return new RsGxsCircleGroupItem();
|
||||
#ifdef TO_REMOVE
|
||||
case RS_PKT_SUBTYPE_GXSCIRCLE_MSG_ITEM: return new RsGxsCircleMsgItem();
|
||||
#endif
|
||||
case RS_PKT_SUBTYPE_GXSCIRCLE_SUBSCRIPTION_REQUEST_ITEM: return new RsGxsCircleSubscriptionRequestItem();
|
||||
default:
|
||||
return NULL ;
|
||||
@ -46,20 +48,27 @@ void RsGxsCircleSubscriptionRequestItem::clear()
|
||||
{
|
||||
time_stamp = 0 ;
|
||||
time_out = 0 ;
|
||||
subscription_type = SUBSCRIPTION_REQUEST_UNKNOWN;
|
||||
subscription_type = RsGxsCircleSubscriptionType::UNKNOWN;
|
||||
}
|
||||
|
||||
#ifdef TO_REMOVE
|
||||
void RsGxsCircleMsgItem::serial_process(RsGenericSerializer::SerializeJob j,RsGenericSerializer::SerializeContext& ctx)
|
||||
{
|
||||
//RsTypeSerializer::serial_process(j,ctx,TLV_TYPE_STR_MSG,mMsg.stuff,"mMsg.stuff") ;//Should be this but not retrocompatible...
|
||||
RsTypeSerializer::serial_process(j,ctx,TLV_TYPE_STR_MSG,mMsg.stuff,"msg.stuff") ;
|
||||
}
|
||||
|
||||
void RsGxsCircleMsgItem::clear()
|
||||
{
|
||||
mMsg.stuff.clear();
|
||||
}
|
||||
#endif
|
||||
|
||||
void RsGxsCircleSubscriptionRequestItem::serial_process(RsGenericSerializer::SerializeJob j,RsGenericSerializer::SerializeContext& ctx)
|
||||
{
|
||||
RsTypeSerializer::serial_process<uint32_t>(j,ctx,time_stamp,"time_stamp") ;
|
||||
RsTypeSerializer::serial_process<uint32_t>(j,ctx,time_out ,"time_out") ;
|
||||
RsTypeSerializer::serial_process<uint8_t> (j,ctx,subscription_type ,"subscription_type") ;
|
||||
RsTypeSerializer::serial_process<RsGxsCircleSubscriptionType> (j,ctx,subscription_type ,"subscription_type") ;
|
||||
}
|
||||
|
||||
void RsGxsCircleGroupItem::serial_process(RsGenericSerializer::SerializeJob j,RsGenericSerializer::SerializeContext& ctx)
|
||||
@ -69,11 +78,6 @@ void RsGxsCircleGroupItem::serial_process(RsGenericSerializer::SerializeJob j,Rs
|
||||
RsTypeSerializer::serial_process<RsTlvItem>(j,ctx,subCircleSet,"subCircleSet") ;
|
||||
}
|
||||
|
||||
void RsGxsCircleMsgItem::clear()
|
||||
{
|
||||
mMsg.stuff.clear();
|
||||
}
|
||||
|
||||
void RsGxsCircleGroupItem::clear()
|
||||
{
|
||||
pgpIdSet.TlvClear();
|
||||
|
@ -64,6 +64,7 @@ public:
|
||||
RsTlvGxsCircleIdSet subCircleSet;
|
||||
};
|
||||
|
||||
#ifdef TO_REMOVE
|
||||
class RsGxsCircleMsgItem : public RsGxsMsgItem
|
||||
{
|
||||
public:
|
||||
@ -76,6 +77,7 @@ public:
|
||||
|
||||
RsGxsCircleMsg mMsg;
|
||||
};
|
||||
#endif
|
||||
|
||||
class RsGxsCircleSubscriptionRequestItem: public RsGxsMsgItem
|
||||
{
|
||||
@ -86,17 +88,11 @@ public:
|
||||
|
||||
void clear();
|
||||
|
||||
enum {
|
||||
SUBSCRIPTION_REQUEST_UNKNOWN = 0x00,
|
||||
SUBSCRIPTION_REQUEST_SUBSCRIBE = 0x01,
|
||||
SUBSCRIPTION_REQUEST_UNSUBSCRIBE = 0x02
|
||||
};
|
||||
|
||||
virtual void serial_process(RsGenericSerializer::SerializeJob j,RsGenericSerializer::SerializeContext& ctx);
|
||||
|
||||
uint32_t time_stamp ;
|
||||
uint32_t time_out ;
|
||||
uint8_t subscription_type ;
|
||||
RsGxsCircleSubscriptionType subscription_type ;
|
||||
};
|
||||
|
||||
class RsGxsCircleSerialiser : public RsServiceSerializer
|
||||
|
@ -83,19 +83,19 @@ void RsMsgTagType::serial_process(RsGenericSerializer::SerializeJob j,RsGenericS
|
||||
|
||||
void RsMsgTags::serial_process(RsGenericSerializer::SerializeJob j,RsGenericSerializer::SerializeContext& ctx)
|
||||
{
|
||||
RsTypeSerializer::serial_process<uint32_t>(j,ctx,msgId,"msgId") ;
|
||||
RsTypeSerializer::serial_process<uint32_t>(j,ctx,msgId,"msgId") ;
|
||||
|
||||
#warning this is not the correct way to serialise here. We should directly call serial_process<std::vector<uint32_t> >() but for backward compatibility, we cannot
|
||||
|
||||
if(j == RsGenericSerializer::DESERIALIZE)
|
||||
while(ctx.mOffset < ctx.mSize)
|
||||
{
|
||||
uint32_t n ;
|
||||
if(j == RsGenericSerializer::DESERIALIZE)
|
||||
while(ctx.mOffset < ctx.mSize)
|
||||
{
|
||||
uint32_t n = 0;// No real need to initialize but otherwise the compiler complains.
|
||||
RsTypeSerializer::serial_process<uint32_t>(j,ctx,n,"tagIds element") ;
|
||||
tagIds.push_back(n) ;
|
||||
}
|
||||
else
|
||||
for(std::list<uint32_t>::iterator it(tagIds.begin());it!=tagIds.end();++it)
|
||||
}
|
||||
else
|
||||
for(std::list<uint32_t>::iterator it(tagIds.begin());it!=tagIds.end();++it)
|
||||
RsTypeSerializer::serial_process<uint32_t>(j,ctx,*it,"tagIds element") ;
|
||||
}
|
||||
|
||||
|
@ -68,6 +68,7 @@ const uint32_t RS_MSG_FLAGS_LOAD_EMBEDDED_IMAGES = 0x00040000;
|
||||
const uint32_t RS_MSG_FLAGS_DECRYPTED = 0x00080000;
|
||||
const uint32_t RS_MSG_FLAGS_ROUTED = 0x00100000;
|
||||
const uint32_t RS_MSG_FLAGS_PUBLISH_KEY = 0x00200000;
|
||||
const uint32_t RS_MSG_FLAGS_SPAM = 0x00400000;
|
||||
|
||||
const uint32_t RS_MSG_FLAGS_SYSTEM = RS_MSG_FLAGS_USER_REQUEST | RS_MSG_FLAGS_FRIEND_RECOMMENDATION | RS_MSG_FLAGS_PUBLISH_KEY;
|
||||
|
||||
|
@ -376,11 +376,15 @@ bool p3Msgs::getMessageTagTypes(MsgTagType& tags)
|
||||
}
|
||||
|
||||
bool p3Msgs::MessageStar(const std::string &mid, bool star)
|
||||
|
||||
{
|
||||
return mMsgSrv->setMsgFlag(mid, star ? RS_MSG_FLAGS_STAR : 0, RS_MSG_FLAGS_STAR);
|
||||
}
|
||||
|
||||
bool p3Msgs::MessageJunk(const std::string &mid, bool junk)
|
||||
{
|
||||
return mMsgSrv->setMsgFlag(mid, junk ? RS_MSG_FLAGS_SPAM : 0, RS_MSG_FLAGS_SPAM);
|
||||
}
|
||||
|
||||
bool p3Msgs::setMessageTagType(uint32_t tagId, std::string& text, uint32_t rgb_color)
|
||||
{
|
||||
return mMsgSrv->setMessageTagType(tagId, text, rgb_color);
|
||||
|
@ -78,6 +78,7 @@ public:
|
||||
virtual bool MessageReplied(const std::string &mid, bool replied);
|
||||
virtual bool MessageForwarded(const std::string &mid, bool forwarded);
|
||||
virtual bool MessageStar(const std::string &mid, bool star);
|
||||
virtual bool MessageJunk(const std::string &mid, bool junk);
|
||||
virtual bool MessageLoadEmbeddedImages(const std::string &mid, bool load);
|
||||
virtual bool getMsgParentId(const std::string &msgId, std::string &msgParentId);
|
||||
|
||||
|
@ -92,11 +92,15 @@ template<class ID_CLASS,uint32_t TLV_TYPE> class RS_DEPRECATED_FOR(std::set<>) t
|
||||
ids.insert(id) ;
|
||||
}
|
||||
if(*offset != tlvend)
|
||||
{
|
||||
std::cerr << "(EE) deserialisaiton error in " << __PRETTY_FUNCTION__ << std::endl;
|
||||
else if(!ok)
|
||||
ok = false;
|
||||
}
|
||||
|
||||
if(!ok)
|
||||
std::cerr << "(WW) something wrong in ID_CLASS.deserialise in " << __PRETTY_FUNCTION__ << std::endl;
|
||||
|
||||
return *offset == tlvend ;
|
||||
return ok;
|
||||
}
|
||||
virtual std::ostream &print(std::ostream &out, uint16_t /* indent */) const
|
||||
{
|
||||
|
@ -599,7 +599,8 @@ void RsTypeSerializer::RawMemoryWrapper::serial_process(
|
||||
RsBase64::encode(first, second, encodedValue, true, false);
|
||||
ctx.mJson.SetString(
|
||||
encodedValue.data(),
|
||||
static_cast<rapidjson::SizeType>(encodedValue.length()) );
|
||||
static_cast<rapidjson::SizeType>(encodedValue.length()),
|
||||
ctx.mJson.GetAllocator());
|
||||
break;
|
||||
}
|
||||
case RsGenericSerializer::FROM_JSON:
|
||||
|
@ -239,7 +239,7 @@ void p3GxsChannels::notifyChanges(std::vector<RsGxsNotify *> &changes)
|
||||
#endif
|
||||
|
||||
/* iterate through and grab any new messages */
|
||||
std::list<RsGxsGroupId> unprocessedGroups;
|
||||
std::set<RsGxsGroupId> unprocessedGroups;
|
||||
|
||||
std::vector<RsGxsNotify *>::iterator it;
|
||||
for(it = changes.begin(); it != changes.end(); ++it)
|
||||
@ -253,16 +253,12 @@ void p3GxsChannels::notifyChanges(std::vector<RsGxsNotify *> &changes)
|
||||
/* message received */
|
||||
if (rsEvents)
|
||||
{
|
||||
std::map<RsGxsGroupId, std::set<RsGxsMessageId> > &msgChangeMap = msgChange->msgChangeMap;
|
||||
for (auto mit = msgChangeMap.begin(); mit != msgChangeMap.end(); ++mit)
|
||||
for (auto mit1 = mit->second.begin(); mit1 != mit->second.end(); ++mit1)
|
||||
{
|
||||
auto ev = std::make_shared<RsGxsChannelEvent>();
|
||||
ev->mChannelMsgId = *mit1;
|
||||
ev->mChannelGroupId = mit->first;
|
||||
ev->mChannelEventCode = RsChannelEventCode::NEW_MESSAGE;
|
||||
rsEvents->postEvent(ev);
|
||||
}
|
||||
auto ev = std::make_shared<RsGxsChannelEvent>();
|
||||
|
||||
ev->mChannelMsgId = msgChange->mMsgId;
|
||||
ev->mChannelGroupId = msgChange->mGroupId;
|
||||
ev->mChannelEventCode = RsChannelEventCode::NEW_MESSAGE;
|
||||
rsEvents->postEvent(ev);
|
||||
}
|
||||
}
|
||||
|
||||
@ -273,25 +269,21 @@ void p3GxsChannels::notifyChanges(std::vector<RsGxsNotify *> &changes)
|
||||
std::cerr << std::endl;
|
||||
#endif
|
||||
|
||||
std::map<RsGxsGroupId, std::set<RsGxsMessageId> > &msgChangeMap = msgChange->msgChangeMap;
|
||||
for(auto mit = msgChangeMap.begin(); mit != msgChangeMap.end(); ++mit)
|
||||
#ifdef GXSCHANNELS_DEBUG
|
||||
std::cerr << "p3GxsChannels::notifyChanges() Msgs for Group: " << mit->first;
|
||||
std::cerr << std::endl;
|
||||
#endif
|
||||
{
|
||||
#ifdef GXSCHANNELS_DEBUG
|
||||
std::cerr << "p3GxsChannels::notifyChanges() Msgs for Group: " << mit->first;
|
||||
std::cerr << "p3GxsChannels::notifyChanges() AutoDownload for Group: " << mit->first;
|
||||
std::cerr << std::endl;
|
||||
#endif
|
||||
bool enabled = false;
|
||||
if (autoDownloadEnabled(mit->first, enabled) && enabled)
|
||||
{
|
||||
#ifdef GXSCHANNELS_DEBUG
|
||||
std::cerr << "p3GxsChannels::notifyChanges() AutoDownload for Group: " << mit->first;
|
||||
std::cerr << std::endl;
|
||||
#endif
|
||||
|
||||
/* problem is most of these will be comments and votes,
|
||||
* should make it occasional - every 5mins / 10minutes TODO */
|
||||
unprocessedGroups.push_back(mit->first);
|
||||
}
|
||||
/* problem is most of these will be comments and votes, should make it occasional - every 5mins / 10minutes TODO */
|
||||
// We do not call if(autoDownLoadEnabled()) here, because it would be too costly when
|
||||
// many msgs are received from the same group. We back the groupIds and then request one by one.
|
||||
|
||||
unprocessedGroups.insert(msgChange->mGroupId);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -304,71 +296,52 @@ void p3GxsChannels::notifyChanges(std::vector<RsGxsNotify *> &changes)
|
||||
{
|
||||
case RsGxsNotify::TYPE_PROCESSED: // happens when the group is subscribed
|
||||
{
|
||||
std::list<RsGxsGroupId> &grpList = grpChange->mGrpIdList;
|
||||
std::list<RsGxsGroupId>::iterator git;
|
||||
for (git = grpList.begin(); git != grpList.end(); ++git)
|
||||
{
|
||||
auto ev = std::make_shared<RsGxsChannelEvent>();
|
||||
ev->mChannelGroupId = *git;
|
||||
ev->mChannelEventCode = RsChannelEventCode::SUBSCRIBE_STATUS_CHANGED;
|
||||
rsEvents->postEvent(ev);
|
||||
}
|
||||
|
||||
auto ev = std::make_shared<RsGxsChannelEvent>();
|
||||
ev->mChannelGroupId = grpChange->mGroupId;
|
||||
ev->mChannelEventCode = RsChannelEventCode::SUBSCRIBE_STATUS_CHANGED;
|
||||
rsEvents->postEvent(ev);
|
||||
}
|
||||
break;
|
||||
|
||||
case RsGxsNotify::TYPE_STATISTICS_CHANGED:
|
||||
{
|
||||
std::list<RsGxsGroupId> &grpList = grpChange->mGrpIdList;
|
||||
std::list<RsGxsGroupId>::iterator git;
|
||||
for (git = grpList.begin(); git != grpList.end(); ++git)
|
||||
{
|
||||
auto ev = std::make_shared<RsGxsChannelEvent>();
|
||||
ev->mChannelGroupId = *git;
|
||||
ev->mChannelEventCode = RsChannelEventCode::STATISTICS_CHANGED;
|
||||
rsEvents->postEvent(ev);
|
||||
}
|
||||
}
|
||||
{
|
||||
auto ev = std::make_shared<RsGxsChannelEvent>();
|
||||
ev->mChannelGroupId = grpChange->mGroupId;
|
||||
ev->mChannelEventCode = RsChannelEventCode::STATISTICS_CHANGED;
|
||||
rsEvents->postEvent(ev);
|
||||
}
|
||||
break;
|
||||
|
||||
case RsGxsNotify::TYPE_PUBLISHED:
|
||||
case RsGxsNotify::TYPE_RECEIVED_NEW:
|
||||
{
|
||||
/* group received */
|
||||
std::list<RsGxsGroupId> &grpList = grpChange->mGrpIdList;
|
||||
std::list<RsGxsGroupId>::iterator git;
|
||||
RS_STACK_MUTEX(mKnownChannelsMutex);
|
||||
for (git = grpList.begin(); git != grpList.end(); ++git)
|
||||
{
|
||||
if(mKnownChannels.find(*git) == mKnownChannels.end())
|
||||
{
|
||||
mKnownChannels.insert(std::make_pair(*git,time(NULL))) ;
|
||||
IndicateConfigChanged();
|
||||
|
||||
auto ev = std::make_shared<RsGxsChannelEvent>();
|
||||
ev->mChannelGroupId = *git;
|
||||
ev->mChannelEventCode = RsChannelEventCode::NEW_CHANNEL;
|
||||
rsEvents->postEvent(ev);
|
||||
}
|
||||
else
|
||||
std::cerr << "(II) Not notifying already known channel " << *git << std::endl;
|
||||
RS_STACK_MUTEX(mKnownChannelsMutex);
|
||||
|
||||
if(mKnownChannels.find(grpChange->mGroupId) == mKnownChannels.end())
|
||||
{
|
||||
mKnownChannels.insert(std::make_pair(grpChange->mGroupId,time(NULL))) ;
|
||||
IndicateConfigChanged();
|
||||
|
||||
auto ev = std::make_shared<RsGxsChannelEvent>();
|
||||
ev->mChannelGroupId = grpChange->mGroupId;
|
||||
ev->mChannelEventCode = RsChannelEventCode::NEW_CHANNEL;
|
||||
rsEvents->postEvent(ev);
|
||||
}
|
||||
break;
|
||||
else
|
||||
std::cerr << "(II) Not notifying already known channel " << grpChange->mGroupId << std::endl;
|
||||
}
|
||||
break;
|
||||
|
||||
case RsGxsNotify::TYPE_RECEIVED_PUBLISHKEY:
|
||||
{
|
||||
/* group received */
|
||||
std::list<RsGxsGroupId> &grpList = grpChange->mGrpIdList;
|
||||
std::list<RsGxsGroupId>::iterator git;
|
||||
for (git = grpList.begin(); git != grpList.end(); ++git)
|
||||
{
|
||||
auto ev = std::make_shared<RsGxsChannelEvent>();
|
||||
ev->mChannelGroupId = *git;
|
||||
ev->mChannelEventCode = RsChannelEventCode::RECEIVED_PUBLISH_KEY;
|
||||
auto ev = std::make_shared<RsGxsChannelEvent>();
|
||||
ev->mChannelGroupId = grpChange->mGroupId;
|
||||
ev->mChannelEventCode = RsChannelEventCode::RECEIVED_PUBLISH_KEY;
|
||||
|
||||
rsEvents->postEvent(ev);
|
||||
}
|
||||
rsEvents->postEvent(ev);
|
||||
}
|
||||
break;
|
||||
|
||||
@ -395,8 +368,16 @@ void p3GxsChannels::notifyChanges(std::vector<RsGxsNotify *> &changes)
|
||||
delete *it;
|
||||
}
|
||||
|
||||
if(!unprocessedGroups.empty())
|
||||
request_SpecificSubscribedGroups(unprocessedGroups);
|
||||
std::list<RsGxsGroupId> grps;
|
||||
for(auto& grp_id:unprocessedGroups)
|
||||
{
|
||||
bool enabled = false;
|
||||
if (autoDownloadEnabled(grp_id, enabled) && enabled) // costly call, that's why it's packed down here.
|
||||
grps.push_back(grp_id);
|
||||
}
|
||||
|
||||
if(!grps.empty())
|
||||
request_SpecificSubscribedGroups(grps);
|
||||
}
|
||||
|
||||
void p3GxsChannels::service_tick()
|
||||
@ -471,22 +452,23 @@ bool p3GxsChannels::groupShareKeys(
|
||||
|
||||
bool p3GxsChannels::getPostData(
|
||||
const uint32_t &token, std::vector<RsGxsChannelPost> &msgs,
|
||||
std::vector<RsGxsComment> &cmts )
|
||||
std::vector<RsGxsComment> &cmts,
|
||||
std::vector<RsGxsVote> &vots)
|
||||
{
|
||||
#ifdef GXSCHANNELS_DEBUG
|
||||
std::cerr << __PRETTY_FUNCTION__ << std::cerr << std::endl;
|
||||
RsDbg() << __PRETTY_FUNCTION__ << std::endl;
|
||||
#endif
|
||||
|
||||
GxsMsgDataMap msgData;
|
||||
if(!RsGenExchange::getMsgData(token, msgData))
|
||||
{
|
||||
std::cerr << __PRETTY_FUNCTION__ <<" ERROR in request" << std::endl;
|
||||
RsErr() << __PRETTY_FUNCTION__ << " ERROR in request" << std::endl;
|
||||
return false;
|
||||
}
|
||||
|
||||
GxsMsgDataMap::iterator mit = msgData.begin();
|
||||
|
||||
for(; mit != msgData.end(); ++mit)
|
||||
for(; mit != msgData.end(); ++mit)
|
||||
{
|
||||
std::vector<RsGxsMsgItem*>& msgItems = mit->second;
|
||||
std::vector<RsGxsMsgItem*>::iterator vit = msgItems.begin();
|
||||
@ -514,7 +496,7 @@ bool p3GxsChannels::getPostData(
|
||||
cmt = cmtItem->mMsg;
|
||||
cmt.mMeta = mi->meta;
|
||||
#ifdef GXSCOMMENT_DEBUG
|
||||
std::cerr << "p3GxsChannels::getPostData Found Comment:" << std::endl;
|
||||
RsDbg() << __PRETTY_FUNCTION__ << " Found Comment:" << std::endl;
|
||||
cmt.print(std::cerr," ", "cmt");
|
||||
#endif
|
||||
cmts.push_back(cmt);
|
||||
@ -522,18 +504,33 @@ bool p3GxsChannels::getPostData(
|
||||
}
|
||||
else
|
||||
{
|
||||
RsGxsMsgItem* msg = (*vit);
|
||||
//const uint16_t RS_SERVICE_GXS_TYPE_CHANNELS = 0x0217;
|
||||
//const uint8_t RS_PKT_SUBTYPE_GXSCHANNEL_POST_ITEM = 0x03;
|
||||
//const uint8_t RS_PKT_SUBTYPE_GXSCOMMENT_COMMENT_ITEM = 0xf1;
|
||||
std::cerr << __PRETTY_FUNCTION__
|
||||
<< " Not a GxsChannelPostItem neither a "
|
||||
<< "RsGxsCommentItem PacketService=" << std::hex
|
||||
<< (int)msg->PacketService() << std::dec
|
||||
<< " PacketSubType=" << std::hex
|
||||
<< (int)msg->PacketSubType() << std::dec
|
||||
<< " , deleting!" << std::endl;
|
||||
delete *vit;
|
||||
RsGxsVoteItem* votItem =
|
||||
dynamic_cast<RsGxsVoteItem*>(*vit);
|
||||
if(votItem)
|
||||
{
|
||||
RsGxsVote vot;
|
||||
RsGxsMsgItem *mi = (*vit);
|
||||
vot = votItem->mMsg;
|
||||
vot.mMeta = mi->meta;
|
||||
vots.push_back(vot);
|
||||
delete votItem;
|
||||
}
|
||||
else
|
||||
{
|
||||
RsGxsMsgItem* msg = (*vit);
|
||||
//const uint16_t RS_SERVICE_GXS_TYPE_CHANNELS = 0x0217;
|
||||
//const uint8_t RS_PKT_SUBTYPE_GXSCHANNEL_POST_ITEM = 0x03;
|
||||
//const uint8_t RS_PKT_SUBTYPE_GXSCOMMENT_COMMENT_ITEM = 0xf1;
|
||||
//const uint8_t RS_PKT_SUBTYPE_GXSCOMMENT_VOTE_ITEM = 0xf2;
|
||||
RsErr() << __PRETTY_FUNCTION__
|
||||
<< " Not a GxsChannelPostItem neither a "
|
||||
<< "RsGxsCommentItem neither a RsGxsVoteItem"
|
||||
<< " PacketService=" << std::hex << (int)msg->PacketService() << std::dec
|
||||
<< " PacketSubType=" << std::hex << (int)msg->PacketSubType() << std::dec
|
||||
<< " type name =" << typeid(*msg).name()
|
||||
<< " , deleting!" << std::endl;
|
||||
delete *vit;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -542,11 +539,19 @@ bool p3GxsChannels::getPostData(
|
||||
return true;
|
||||
}
|
||||
|
||||
bool p3GxsChannels::getPostData(
|
||||
const uint32_t& token, std::vector<RsGxsChannelPost>& posts, std::vector<RsGxsComment>& cmts )
|
||||
{
|
||||
std::vector<RsGxsVote> vots;
|
||||
return getPostData(token, posts, cmts, vots);
|
||||
}
|
||||
|
||||
bool p3GxsChannels::getPostData(
|
||||
const uint32_t& token, std::vector<RsGxsChannelPost>& posts )
|
||||
{
|
||||
std::vector<RsGxsComment> cmts;
|
||||
return getPostData(token, posts, cmts);
|
||||
std::vector<RsGxsVote> vots;
|
||||
return getPostData(token, posts, cmts, vots);
|
||||
}
|
||||
|
||||
//Not currently used
|
||||
@ -724,8 +729,7 @@ void p3GxsChannels::request_AllSubscribedGroups()
|
||||
}
|
||||
|
||||
|
||||
void p3GxsChannels::request_SpecificSubscribedGroups(
|
||||
const std::list<RsGxsGroupId> &groups )
|
||||
void p3GxsChannels::request_SpecificSubscribedGroups( const std::list<RsGxsGroupId> &groups )
|
||||
{
|
||||
#ifdef GXSCHANNELS_DEBUG
|
||||
std::cerr << "p3GxsChannels::request_SpecificSubscribedGroups()";
|
||||
@ -738,8 +742,7 @@ void p3GxsChannels::request_SpecificSubscribedGroups(
|
||||
|
||||
uint32_t token = 0;
|
||||
|
||||
if(!RsGenExchange::getTokenService()->
|
||||
requestGroupInfo(token, ansType, opts, groups))
|
||||
if(!RsGenExchange::getTokenService()-> requestGroupInfo(token, ansType, opts, groups))
|
||||
{
|
||||
std::cerr << __PRETTY_FUNCTION__ << " Failed requesting groups info!"
|
||||
<< std::endl;
|
||||
@ -1112,22 +1115,24 @@ bool p3GxsChannels::getContentSummaries(
|
||||
|
||||
bool p3GxsChannels::getChannelAllContent( const RsGxsGroupId& channelId,
|
||||
std::vector<RsGxsChannelPost>& posts,
|
||||
std::vector<RsGxsComment>& comments )
|
||||
std::vector<RsGxsComment>& comments,
|
||||
std::vector<RsGxsVote>& votes )
|
||||
{
|
||||
uint32_t token;
|
||||
RsTokReqOptions opts;
|
||||
opts.mReqType = GXS_REQUEST_TYPE_MSG_DATA;
|
||||
|
||||
if( !requestMsgInfo(token, opts,std::list<RsGxsGroupId>({channelId})) || waitToken(token) != RsTokenService::COMPLETE )
|
||||
return false;
|
||||
if( !requestMsgInfo(token, opts,std::list<RsGxsGroupId>({channelId})) || waitToken(token) != RsTokenService::COMPLETE )
|
||||
return false;
|
||||
|
||||
return getPostData(token, posts, comments);
|
||||
return getPostData(token, posts, comments,votes);
|
||||
}
|
||||
|
||||
bool p3GxsChannels::getChannelContent( const RsGxsGroupId& channelId,
|
||||
const std::set<RsGxsMessageId>& contentIds,
|
||||
std::vector<RsGxsChannelPost>& posts,
|
||||
std::vector<RsGxsComment>& comments )
|
||||
std::vector<RsGxsComment>& comments,
|
||||
std::vector<RsGxsVote>& votes )
|
||||
{
|
||||
uint32_t token;
|
||||
RsTokReqOptions opts;
|
||||
@ -1139,7 +1144,7 @@ bool p3GxsChannels::getChannelContent( const RsGxsGroupId& channelId,
|
||||
if( !requestMsgInfo(token, opts, msgIds) || waitToken(token) != RsTokenService::COMPLETE )
|
||||
return false;
|
||||
|
||||
return getPostData(token, posts, comments);
|
||||
return getPostData(token, posts, comments, votes);
|
||||
}
|
||||
|
||||
bool p3GxsChannels::getChannelComments(const RsGxsGroupId &channelId,
|
||||
@ -1314,8 +1319,9 @@ bool p3GxsChannels::createVoteV2(
|
||||
std::set<RsGxsMessageId> s({commentId});
|
||||
std::vector<RsGxsChannelPost> posts;
|
||||
std::vector<RsGxsComment> comments;
|
||||
std::vector<RsGxsVote> votes;
|
||||
|
||||
if(!getChannelContent(channelId, s, posts, comments))
|
||||
if(!getChannelContent(channelId, s, posts, comments, votes))
|
||||
{
|
||||
errorMessage = "You cannot vote on comment "
|
||||
+ commentId.toStdString() + " of channel with Id "
|
||||
@ -1475,8 +1481,9 @@ bool p3GxsChannels::createPostV2(
|
||||
std::set<RsGxsMessageId> s({origPostId});
|
||||
std::vector<RsGxsChannelPost> posts;
|
||||
std::vector<RsGxsComment> comments;
|
||||
std::vector<RsGxsVote> votes;
|
||||
|
||||
if(!getChannelContent(channelId,s,posts,comments))
|
||||
if(!getChannelContent(channelId,s,posts,comments,votes))
|
||||
{
|
||||
errorMessage = "You cannot edit post " + origPostId.toStdString()
|
||||
+ " of channel with Id " + channelId.toStdString()
|
||||
@ -1546,9 +1553,11 @@ bool p3GxsChannels::createCommentV2(
|
||||
|
||||
std::vector<RsGxsChannelPost> posts;
|
||||
std::vector<RsGxsComment> comments;
|
||||
std::vector<RsGxsVote> votes;
|
||||
|
||||
if(!getChannelContent( // does the post thread exist?
|
||||
channelId,std::set<RsGxsMessageId>({threadId}), posts, comments ))
|
||||
channelId, std::set<RsGxsMessageId>({threadId}),
|
||||
posts, comments, votes) )
|
||||
return failure( "You cannot comment post " + threadId.toStdString() +
|
||||
" of channel with Id " + channelId.toStdString() +
|
||||
": this post does not exists locally!" );
|
||||
@ -1560,19 +1569,18 @@ bool p3GxsChannels::createCommentV2(
|
||||
": supplied threadId is not a thread, or parentMsgId is"
|
||||
" not a comment!");
|
||||
|
||||
if(!getChannelContent( // does the post thread exist?
|
||||
if(!getChannelContent( // does the post parent exist?
|
||||
channelId, std::set<RsGxsMessageId>({parentId}),
|
||||
posts, comments ))
|
||||
posts, comments, votes) )
|
||||
return failure( "You cannot comment post " + parentId.toStdString() +
|
||||
": supplied parent doesn't exists locally!" );
|
||||
|
||||
if(!origCommentId.isNull())
|
||||
{
|
||||
std::set<RsGxsMessageId> s({origCommentId});
|
||||
std::vector<RsGxsChannelPost> posts;
|
||||
std::vector<RsGxsComment> comments;
|
||||
std::vector<RsGxsComment> cmts;
|
||||
|
||||
if( !getChannelContent(channelId, s, posts, comments) ||
|
||||
if( !getChannelContent(channelId, s, posts, cmts, votes) ||
|
||||
comments.size() != 1 )
|
||||
return failure( "You cannot edit comment " +
|
||||
origCommentId.toStdString() +
|
||||
|
@ -82,9 +82,10 @@ virtual void handle_event(uint32_t event_type, const std::string &elabel);
|
||||
|
||||
public:
|
||||
|
||||
virtual bool getGroupData(const uint32_t &token, std::vector<RsGxsChannelGroup> &groups);
|
||||
virtual bool getPostData(const uint32_t &token, std::vector<RsGxsChannelPost> &posts, std::vector<RsGxsComment> &cmts);
|
||||
virtual bool getPostData(const uint32_t &token, std::vector<RsGxsChannelPost> &posts);
|
||||
virtual bool getGroupData(const uint32_t &token, std::vector<RsGxsChannelGroup> &groups ) override;
|
||||
virtual bool getPostData(const uint32_t &token, std::vector<RsGxsChannelPost> &posts, std::vector<RsGxsComment> &cmts, std::vector<RsGxsVote> &vots) override;
|
||||
virtual bool getPostData(const uint32_t &token, std::vector<RsGxsChannelPost> &posts, std::vector<RsGxsComment> &cmts) override;
|
||||
virtual bool getPostData(const uint32_t &token, std::vector<RsGxsChannelPost> &posts) override;
|
||||
//Not currently used
|
||||
//virtual bool getRelatedPosts(const uint32_t &token, std::vector<RsGxsChannelPost> &posts);
|
||||
|
||||
@ -187,14 +188,16 @@ virtual bool ExtraFileRemove(const RsFileHash &hash);
|
||||
|
||||
/// Implementation of @see RsGxsChannels::getChannelAllMessages
|
||||
bool getChannelAllContent(const RsGxsGroupId& channelId,
|
||||
std::vector<RsGxsChannelPost>& posts,
|
||||
std::vector<RsGxsComment>& comments ) override;
|
||||
std::vector<RsGxsChannelPost>& posts,
|
||||
std::vector<RsGxsComment>& comments,
|
||||
std::vector<RsGxsVote>& votes ) override;
|
||||
|
||||
/// Implementation of @see RsGxsChannels::getChannelMessages
|
||||
bool getChannelContent(const RsGxsGroupId& channelId,
|
||||
const std::set<RsGxsMessageId>& contentIds,
|
||||
std::vector<RsGxsChannelPost>& posts,
|
||||
std::vector<RsGxsComment>& comments ) override;
|
||||
std::vector<RsGxsComment>& comments,
|
||||
std::vector<RsGxsVote>& votes ) override;
|
||||
|
||||
/// Implementation of @see RsGxsChannels::getChannelComments
|
||||
virtual bool getChannelComments(const RsGxsGroupId &channelId,
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -128,11 +128,20 @@ public:
|
||||
uint32_t subscription_flags ; // combination of GXS_EXTERNAL_CIRCLE_FLAGS_IN_ADMIN_LIST and GXS_EXTERNAL_CIRCLE_FLAGS_SUBSCRIBED
|
||||
};
|
||||
|
||||
enum CircleEntryCacheStatus: uint8_t {
|
||||
UNKNOWN = 0x00, // Used to detect uninitialized memory
|
||||
NO_DATA_YET = 0x01, // Used in the constuctor
|
||||
LOADING = 0x02, // When the token request to load cache has been sent and no data is present
|
||||
UPDATING = 0x03, // Starting from this level the cache entry can be used
|
||||
CHECKING_MEMBERSHIP = 0x04, // Means we're actually looking into msgs to update membership status
|
||||
UP_TO_DATE = 0x05 // Everything should be loaded here.
|
||||
};
|
||||
|
||||
class RsGxsCircleCache
|
||||
{
|
||||
public:
|
||||
|
||||
public:
|
||||
RsGxsCircleCache();
|
||||
|
||||
bool loadBaseCircle(const RsGxsCircleGroup &circle);
|
||||
bool loadSubCircle(const RsGxsCircleCache &subcircle);
|
||||
|
||||
@ -142,33 +151,62 @@ class RsGxsCircleCache
|
||||
bool addAllowedPeer(const RsPgpId &pgpid);
|
||||
bool addLocalFriend(const RsPgpId &pgpid);
|
||||
|
||||
// Cache related data
|
||||
|
||||
rstime_t mLastUpdatedMembershipTS ; // Last time the subscribe messages have been requested. Should be reset when new messages arrive.
|
||||
rstime_t mLastUpdateTime; // Last time the cache entry was loaded
|
||||
CircleEntryCacheStatus mStatus; // Overall state of the cache entry
|
||||
bool mAllIdsHere ; // True when all ids are knwon and available.
|
||||
|
||||
// GxsCircle related data
|
||||
|
||||
RsGxsCircleId mCircleId;
|
||||
std::string mCircleName;
|
||||
|
||||
uint32_t mCircleType;
|
||||
RsGxsCircleType mCircleType;
|
||||
bool mIsExternal;
|
||||
RsGxsCircleId mRestrictedCircleId ; // circle ID that circle is restricted to.
|
||||
RsGxsCircleId mRestrictedCircleId ; // circle ID that circle is restricted to.
|
||||
|
||||
uint32_t mGroupStatus;
|
||||
uint32_t mGroupSubscribeFlags;
|
||||
|
||||
rstime_t mUpdateTime;
|
||||
#ifdef SUBSCIRCLES
|
||||
std::set<RsGxsCircleId> mUnprocessedCircles;
|
||||
std::set<RsGxsCircleId> mProcessedCircles;
|
||||
#endif
|
||||
std::map<RsGxsId,RsGxsCircleMembershipStatus> mMembershipStatus;
|
||||
rstime_t mLastUpdatedMembershipTS ; // last time the subscribe messages have been requested. Should be reset when new messages arrive.
|
||||
|
||||
|
||||
std::set<RsGxsId> mAllowedGxsIds; // IDs that are allowed in the circle and have requested membership. This is the official members list.
|
||||
std::set<RsPgpId> mAllowedNodes;
|
||||
|
||||
RsPeerId mOriginator ; // peer who sent the data, in case we need to ask for ids
|
||||
|
||||
RsPeerId mOriginator ; // peer who sent the data, in case we need to ask for ids
|
||||
};
|
||||
|
||||
|
||||
class PgpAuxUtils;
|
||||
|
||||
class RsCirclesMemCache : public std::map<RsGxsCircleId,RsGxsCircleCache>
|
||||
{
|
||||
public:
|
||||
RsCirclesMemCache() : std::map<RsGxsCircleId,RsGxsCircleCache>(){}
|
||||
|
||||
bool is_cached(const RsGxsCircleId& id) { return end() != find(id) ; }
|
||||
RsGxsCircleCache& ref(const RsGxsCircleId& id) { return operator[](id) ; }
|
||||
|
||||
void printStats() { std::cerr << "CircleMemCache: " << size() << " elements." << std::endl; }
|
||||
|
||||
template<class ClientClass> void applyToAllCachedEntries(ClientClass& c,bool (ClientClass::*method)(RsGxsCircleCache&))
|
||||
{
|
||||
for(auto& it:*this)
|
||||
(c.*method)(it.second);
|
||||
}
|
||||
template<class ClientClass> void applyToAllCachedEntries(ClientClass& c,bool (ClientClass::*method)(const RsGxsCircleCache&))
|
||||
{
|
||||
for(const auto& it:*this)
|
||||
(c.*method)(it.second);
|
||||
}
|
||||
};
|
||||
|
||||
class p3GxsCircles: public RsGxsCircleExchange, public RsGxsCircles,
|
||||
public GxsTokenQueue, public RsTickEvent
|
||||
{
|
||||
@ -264,7 +302,7 @@ public:
|
||||
|
||||
protected:
|
||||
|
||||
bool pushCircleMembershipRequest(const RsGxsId& own_gxsid,const RsGxsCircleId& circle_id,uint32_t request_type) ;
|
||||
bool pushCircleMembershipRequest(const RsGxsId& own_gxsid, const RsGxsCircleId& circle_id, RsGxsCircleSubscriptionType request_type) ;
|
||||
static uint32_t circleAuthenPolicy();
|
||||
|
||||
/** Notifications **/
|
||||
@ -319,20 +357,18 @@ public:
|
||||
std::list<RsGxsCircleId> mCirclePersonalIdList;
|
||||
|
||||
/***** Caching Circle Info, *****/
|
||||
// initial load queue
|
||||
std::list<RsGxsCircleId> mCacheLoad_ToCache;
|
||||
|
||||
// waiting for subcircle to load. (first is part of each of the second list)
|
||||
// TODO.
|
||||
//std::map<RsGxsCircleId, std::list<RsGxsCircleId> > mCacheLoad_SubCircle;
|
||||
|
||||
// Circles that are being loaded.
|
||||
std::map<RsGxsCircleId, RsGxsCircleCache> mLoadingCache;
|
||||
std::set<RsGxsCircleId> mCirclesToLoad; // list of circles to update/load, so that we can treat them by groups.
|
||||
RsCirclesMemCache mCircleCache;
|
||||
//RsMemCache<RsGxsCircleId, RsGxsCircleCache> mCircleCache; // actual cache data
|
||||
|
||||
// actual cache.
|
||||
RsMemCache<RsGxsCircleId, RsGxsCircleCache> mCircleCache;
|
||||
|
||||
private:
|
||||
void debug_dumpCache(); // debug method to overview what's going on
|
||||
bool debug_dumpCacheEntry(RsGxsCircleCache &cache);
|
||||
private:
|
||||
|
||||
std::string genRandomId();
|
||||
|
||||
@ -345,8 +381,9 @@ public:
|
||||
uint32_t mDummyIdToken;
|
||||
std::list<RsGxsId> mDummyPgpLinkedIds;
|
||||
std::list<RsGxsId> mDummyOwnIds;
|
||||
bool mCacheUpdated ;
|
||||
bool mShouldSendCacheUpdateNotification ;
|
||||
rstime_t mLastCacheUpdateEvent;
|
||||
rstime_t mLastDebugPrintTS;
|
||||
|
||||
RS_SET_CONTEXT_DEBUG_LEVEL(2)
|
||||
};
|
||||
|
@ -189,21 +189,17 @@ void p3GxsForums::notifyChanges(std::vector<RsGxsNotify *> &changes)
|
||||
for(it = changes.begin(); it != changes.end(); ++it)
|
||||
{
|
||||
RsGxsMsgChange *msgChange = dynamic_cast<RsGxsMsgChange *>(*it);
|
||||
|
||||
if (msgChange)
|
||||
{
|
||||
if (msgChange->getType() == RsGxsNotify::TYPE_RECEIVED_NEW || msgChange->getType() == RsGxsNotify::TYPE_PUBLISHED) /* message received */
|
||||
if (rsEvents)
|
||||
{
|
||||
std::map<RsGxsGroupId, std::set<RsGxsMessageId> >& msgChangeMap = msgChange->msgChangeMap;
|
||||
for (auto mit = msgChangeMap.begin(); mit != msgChangeMap.end(); ++mit)
|
||||
for (auto mit1 = mit->second.begin(); mit1 != mit->second.end(); ++mit1)
|
||||
{
|
||||
auto ev = std::make_shared<RsGxsForumEvent>();
|
||||
ev->mForumMsgId = *mit1;
|
||||
ev->mForumGroupId = mit->first;
|
||||
ev->mForumEventCode = RsForumEventCode::NEW_MESSAGE;
|
||||
rsEvents->postEvent(ev);
|
||||
}
|
||||
auto ev = std::make_shared<RsGxsForumEvent>();
|
||||
ev->mForumMsgId = msgChange->mMsgId;
|
||||
ev->mForumGroupId = msgChange->mGroupId;
|
||||
ev->mForumEventCode = RsForumEventCode::NEW_MESSAGE;
|
||||
rsEvents->postEvent(ev);
|
||||
}
|
||||
|
||||
#ifdef NOT_USED_YET
|
||||
@ -248,16 +244,10 @@ void p3GxsForums::notifyChanges(std::vector<RsGxsNotify *> &changes)
|
||||
{
|
||||
case RsGxsNotify::TYPE_PROCESSED: // happens when the group is subscribed
|
||||
{
|
||||
std::list<RsGxsGroupId> &grpList = grpChange->mGrpIdList;
|
||||
std::list<RsGxsGroupId>::iterator git;
|
||||
for (git = grpList.begin(); git != grpList.end(); ++git)
|
||||
{
|
||||
auto ev = std::make_shared<RsGxsForumEvent>();
|
||||
ev->mForumGroupId = *git;
|
||||
ev->mForumGroupId = grpChange->mGroupId;
|
||||
ev->mForumEventCode = RsForumEventCode::SUBSCRIBE_STATUS_CHANGED;
|
||||
rsEvents->postEvent(ev);
|
||||
}
|
||||
|
||||
}
|
||||
break;
|
||||
|
||||
@ -265,67 +255,79 @@ void p3GxsForums::notifyChanges(std::vector<RsGxsNotify *> &changes)
|
||||
case RsGxsNotify::TYPE_RECEIVED_NEW:
|
||||
{
|
||||
/* group received */
|
||||
std::list<RsGxsGroupId> &grpList = grpChange->mGrpIdList;
|
||||
std::list<RsGxsGroupId>::iterator git;
|
||||
|
||||
RS_STACK_MUTEX(mKnownForumsMutex);
|
||||
for (git = grpList.begin(); git != grpList.end(); ++git)
|
||||
{
|
||||
if(mKnownForums.find(*git) == mKnownForums.end())
|
||||
{
|
||||
mKnownForums.insert(
|
||||
std::make_pair(*git, time(nullptr)));
|
||||
IndicateConfigChanged();
|
||||
|
||||
auto ev = std::make_shared<RsGxsForumEvent>();
|
||||
ev->mForumGroupId = *git;
|
||||
ev->mForumEventCode = RsForumEventCode::NEW_FORUM;
|
||||
rsEvents->postEvent(ev);
|
||||
}
|
||||
else
|
||||
RsInfo() << __PRETTY_FUNCTION__
|
||||
<< " Not notifying already known forum "
|
||||
<< *git << std::endl;
|
||||
if(mKnownForums.find(grpChange->mGroupId) == mKnownForums.end())
|
||||
{
|
||||
mKnownForums.insert( std::make_pair(grpChange->mGroupId, time(nullptr)));
|
||||
IndicateConfigChanged();
|
||||
|
||||
auto ev = std::make_shared<RsGxsForumEvent>();
|
||||
ev->mForumGroupId = grpChange->mGroupId;
|
||||
ev->mForumEventCode = RsForumEventCode::NEW_FORUM;
|
||||
rsEvents->postEvent(ev);
|
||||
}
|
||||
else
|
||||
RsInfo() << __PRETTY_FUNCTION__
|
||||
<< " Not notifying already known forum "
|
||||
<< grpChange->mGroupId << std::endl;
|
||||
}
|
||||
break;
|
||||
|
||||
case RsGxsNotify::TYPE_STATISTICS_CHANGED:
|
||||
{
|
||||
std::list<RsGxsGroupId> &grpList = grpChange->mGrpIdList;
|
||||
std::list<RsGxsGroupId>::iterator git;
|
||||
for (git = grpList.begin(); git != grpList.end(); ++git)
|
||||
auto ev = std::make_shared<RsGxsForumEvent>();
|
||||
ev->mForumGroupId = grpChange->mGroupId;
|
||||
ev->mForumEventCode = RsForumEventCode::STATISTICS_CHANGED;
|
||||
rsEvents->postEvent(ev);
|
||||
}
|
||||
break;
|
||||
|
||||
case RsGxsNotify::TYPE_UPDATED:
|
||||
{
|
||||
// Happens when the group data has changed. In this case we need to analyse the old and new group in order to detect possible notifications for clients
|
||||
|
||||
RsGxsForumGroupItem *old_forum_grp_item = dynamic_cast<RsGxsForumGroupItem*>(grpChange->mOldGroupItem);
|
||||
RsGxsForumGroupItem *new_forum_grp_item = dynamic_cast<RsGxsForumGroupItem*>(grpChange->mNewGroupItem);
|
||||
|
||||
if(old_forum_grp_item == nullptr || new_forum_grp_item == nullptr)
|
||||
{
|
||||
RsErr() << __PRETTY_FUNCTION__ << " received GxsGroupUpdate item with mOldGroup and mNewGroup not of type RsGxsForumGroupItem. This is inconsistent!" << std::endl;
|
||||
delete grpChange;
|
||||
continue;
|
||||
}
|
||||
|
||||
// First of all, we check if there is a difference between the old and new list of moderators
|
||||
|
||||
std::list<RsGxsId> added_mods, removed_mods;
|
||||
|
||||
for(auto& gxs_id: new_forum_grp_item->mGroup.mAdminList.ids)
|
||||
if(old_forum_grp_item->mGroup.mAdminList.ids.find(gxs_id) == old_forum_grp_item->mGroup.mAdminList.ids.end())
|
||||
added_mods.push_back(gxs_id);
|
||||
|
||||
for(auto& gxs_id: old_forum_grp_item->mGroup.mAdminList.ids)
|
||||
if(new_forum_grp_item->mGroup.mAdminList.ids.find(gxs_id) == new_forum_grp_item->mGroup.mAdminList.ids.end())
|
||||
removed_mods.push_back(gxs_id);
|
||||
|
||||
if(!added_mods.empty() || !removed_mods.empty())
|
||||
{
|
||||
auto ev = std::make_shared<RsGxsForumEvent>();
|
||||
ev->mForumGroupId = *git;
|
||||
ev->mForumEventCode = RsForumEventCode::STATISTICS_CHANGED;
|
||||
|
||||
ev->mForumGroupId = new_forum_grp_item->meta.mGroupId;
|
||||
ev->mModeratorsAdded = added_mods;
|
||||
ev->mModeratorsRemoved = removed_mods;
|
||||
ev->mForumEventCode = RsForumEventCode::MODERATOR_LIST_CHANGED;
|
||||
|
||||
rsEvents->postEvent(ev);
|
||||
}
|
||||
}
|
||||
break;
|
||||
break;
|
||||
|
||||
|
||||
default:
|
||||
RsErr() << " Got a GXS event of type " << grpChange->getType() << " Currently not handled." << std::endl;
|
||||
break;
|
||||
|
||||
|
||||
#ifdef NOT_USED_YET
|
||||
case RsGxsNotify::TYPE_RECEIVED_PUBLISHKEY:
|
||||
{
|
||||
/* group received */
|
||||
std::list<RsGxsGroupId> &grpList = grpChange->mGrpIdList;
|
||||
std::list<RsGxsGroupId>::iterator git;
|
||||
for (git = grpList.begin(); git != grpList.end(); ++git)
|
||||
{
|
||||
auto ev = std::make_shared<RsGxsChannelEvent>();
|
||||
|
||||
ev->mChannelGroupId = *git;
|
||||
ev->mChannelEventCode = RsGxsChannelEvent::RECEIVED_PUBLISH_KEY;
|
||||
|
||||
rsEvents->sendEvent(ev);
|
||||
}
|
||||
}
|
||||
break;
|
||||
#endif
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -606,22 +606,7 @@ void p3IdService::notifyChanges(std::vector<RsGxsNotify *> &changes)
|
||||
RsGxsMsgChange *msgChange = dynamic_cast<RsGxsMsgChange *>(changes[i]);
|
||||
|
||||
if (msgChange && !msgChange->metaChange())
|
||||
{
|
||||
#ifdef DEBUG_IDS
|
||||
std::cerr << "p3IdService::notifyChanges() Found Message Change Notification";
|
||||
std::cerr << std::endl;
|
||||
#endif
|
||||
|
||||
std::map<RsGxsGroupId, std::set<RsGxsMessageId> > &msgChangeMap = msgChange->msgChangeMap;
|
||||
|
||||
for(auto mit = msgChangeMap.begin(); mit != msgChangeMap.end(); ++mit)
|
||||
{
|
||||
#ifdef DEBUG_IDS
|
||||
std::cerr << "p3IdService::notifyChanges() Msgs for Group: " << mit->first;
|
||||
std::cerr << std::endl;
|
||||
#endif
|
||||
}
|
||||
}
|
||||
RsWarn() << __PRETTY_FUNCTION__ << " Found a Msg data change in p3IdService. This is quite unexpected." << std::endl;
|
||||
|
||||
RsGxsGroupChange *groupChange = dynamic_cast<RsGxsGroupChange *>(changes[i]);
|
||||
|
||||
@ -631,16 +616,13 @@ void p3IdService::notifyChanges(std::vector<RsGxsNotify *> &changes)
|
||||
std::cerr << "p3IdService::notifyChanges() Found Group Change Notification";
|
||||
std::cerr << std::endl;
|
||||
#endif
|
||||
std::list<RsGxsGroupId> &groupList = groupChange->mGrpIdList;
|
||||
|
||||
for(auto git = groupList.begin(); git != groupList.end();++git)
|
||||
{
|
||||
#ifdef DEBUG_IDS
|
||||
std::cerr << "p3IdService::notifyChanges() Auto Subscribe to Incoming Groups: " << *git;
|
||||
std::cerr << std::endl;
|
||||
#endif
|
||||
const RsGxsGroupId& gid(groupChange->mGroupId);
|
||||
|
||||
if(!rsReputations->isIdentityBanned(RsGxsId(*git)))
|
||||
if(!rsReputations->isIdentityBanned(RsGxsId(gid)))
|
||||
{
|
||||
// notify that a new identity is received, if needed
|
||||
|
||||
@ -654,12 +636,12 @@ void p3IdService::notifyChanges(std::vector<RsGxsNotify *> &changes)
|
||||
case RsGxsNotify::TYPE_PUBLISHED:
|
||||
{
|
||||
auto ev = std::make_shared<RsGxsIdentityEvent>();
|
||||
ev->mIdentityId = *git;
|
||||
ev->mIdentityId = gid;
|
||||
ev->mIdentityEventCode = RsGxsIdentityEventCode::UPDATED_IDENTITY;
|
||||
rsEvents->postEvent(ev);
|
||||
|
||||
// also time_stamp the key that this group represents
|
||||
timeStampKey(RsGxsId(*git),RsIdentityUsage(serviceType(),RsIdentityUsage::IDENTITY_DATA_UPDATE)) ;
|
||||
timeStampKey(RsGxsId(gid),RsIdentityUsage(serviceType(),RsIdentityUsage::IDENTITY_DATA_UPDATE)) ;
|
||||
should_subscribe = true;
|
||||
}
|
||||
break;
|
||||
@ -667,12 +649,12 @@ void p3IdService::notifyChanges(std::vector<RsGxsNotify *> &changes)
|
||||
case RsGxsNotify::TYPE_RECEIVED_NEW:
|
||||
{
|
||||
auto ev = std::make_shared<RsGxsIdentityEvent>();
|
||||
ev->mIdentityId = *git;
|
||||
ev->mIdentityId = gid;
|
||||
ev->mIdentityEventCode = RsGxsIdentityEventCode::NEW_IDENTITY;
|
||||
rsEvents->postEvent(ev);
|
||||
|
||||
// also time_stamp the key that this group represents
|
||||
timeStampKey(RsGxsId(*git),RsIdentityUsage(serviceType(),RsIdentityUsage::IDENTITY_DATA_UPDATE)) ;
|
||||
timeStampKey(RsGxsId(gid),RsIdentityUsage(serviceType(),RsIdentityUsage::IDENTITY_DATA_UPDATE)) ;
|
||||
should_subscribe = true;
|
||||
}
|
||||
break;
|
||||
@ -684,11 +666,10 @@ void p3IdService::notifyChanges(std::vector<RsGxsNotify *> &changes)
|
||||
if(should_subscribe)
|
||||
{
|
||||
uint32_t token;
|
||||
RsGenExchange::subscribeToGroup(token, *git, true);
|
||||
RsGenExchange::subscribeToGroup(token, gid, true);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
delete changes[i];
|
||||
|
@ -1737,6 +1737,7 @@ void p3MsgService::initRsMI(RsMsgItem *msg, MessageInfo &mi)
|
||||
if (msg->msgFlags & RS_MSG_FLAGS_REPLIED) mi.msgflags |= RS_MSG_REPLIED;
|
||||
if (msg->msgFlags & RS_MSG_FLAGS_FORWARDED) mi.msgflags |= RS_MSG_FORWARDED;
|
||||
if (msg->msgFlags & RS_MSG_FLAGS_STAR) mi.msgflags |= RS_MSG_STAR;
|
||||
if (msg->msgFlags & RS_MSG_FLAGS_SPAM) mi.msgflags |= RS_MSG_SPAM;
|
||||
if (msg->msgFlags & RS_MSG_FLAGS_USER_REQUEST) mi.msgflags |= RS_MSG_USER_REQUEST;
|
||||
if (msg->msgFlags & RS_MSG_FLAGS_FRIEND_RECOMMENDATION) mi.msgflags |= RS_MSG_FRIEND_RECOMMENDATION;
|
||||
if (msg->msgFlags & RS_MSG_FLAGS_PUBLISH_KEY) mi.msgflags |= RS_MSG_PUBLISH_KEY;
|
||||
@ -1831,6 +1832,10 @@ void p3MsgService::initRsMIS(RsMsgItem *msg, MsgInfoSummary &mis)
|
||||
{
|
||||
mis.msgflags |= RS_MSG_STAR;
|
||||
}
|
||||
if (msg->msgFlags & RS_MSG_FLAGS_SPAM)
|
||||
{
|
||||
mis.msgflags |= RS_MSG_SPAM;
|
||||
}
|
||||
if (msg->msgFlags & RS_MSG_FLAGS_USER_REQUEST)
|
||||
{
|
||||
mis.msgflags |= RS_MSG_USER_REQUEST;
|
||||
|
@ -98,27 +98,22 @@ void p3PostBase::notifyChanges(std::vector<RsGxsNotify *> &changes)
|
||||
std::cerr << std::endl;
|
||||
#endif
|
||||
|
||||
std::map<RsGxsGroupId, std::set<RsGxsMessageId> > &msgChangeMap = msgChange->msgChangeMap;
|
||||
for(auto mit = msgChangeMap.begin(); mit != msgChangeMap.end(); ++mit)
|
||||
{
|
||||
#ifdef POSTBASE_DEBUG
|
||||
std::cerr << "p3PostBase::notifyChanges() Msgs for Group: " << mit->first;
|
||||
std::cerr << std::endl;
|
||||
std::cerr << "p3PostBase::notifyChanges() Msgs for Group: " << mit->first;
|
||||
std::cerr << std::endl;
|
||||
#endif
|
||||
// To start with we are just going to trigger updates on these groups.
|
||||
// FUTURE OPTIMISATION.
|
||||
// It could be taken a step further and directly request these msgs for an update.
|
||||
addGroupForProcessing(mit->first);
|
||||
// To start with we are just going to trigger updates on these groups.
|
||||
// FUTURE OPTIMISATION.
|
||||
// It could be taken a step further and directly request these msgs for an update.
|
||||
addGroupForProcessing(msgChange->mGroupId);
|
||||
|
||||
if (rsEvents && (msgChange->getType() == RsGxsNotify::TYPE_RECEIVED_NEW || msgChange->getType() == RsGxsNotify::TYPE_PUBLISHED))
|
||||
for (auto mit1 = mit->second.begin(); mit1 != mit->second.end(); ++mit1)
|
||||
{
|
||||
auto ev = std::make_shared<RsGxsPostedEvent>();
|
||||
ev->mPostedMsgId = *mit1;
|
||||
ev->mPostedGroupId = mit->first;
|
||||
ev->mPostedEventCode = RsPostedEventCode::NEW_MESSAGE;
|
||||
rsEvents->postEvent(ev);
|
||||
}
|
||||
if (rsEvents && (msgChange->getType() == RsGxsNotify::TYPE_RECEIVED_NEW || msgChange->getType() == RsGxsNotify::TYPE_PUBLISHED))
|
||||
{
|
||||
auto ev = std::make_shared<RsGxsPostedEvent>();
|
||||
ev->mPostedMsgId = msgChange->mMsgId;
|
||||
ev->mPostedGroupId = msgChange->mGroupId;
|
||||
ev->mPostedEventCode = RsPostedEventCode::NEW_MESSAGE;
|
||||
rsEvents->postEvent(ev);
|
||||
}
|
||||
}
|
||||
|
||||
@ -131,36 +126,25 @@ void p3PostBase::notifyChanges(std::vector<RsGxsNotify *> &changes)
|
||||
std::cerr << "p3PostBase::notifyChanges() Found Group Change Notification";
|
||||
std::cerr << std::endl;
|
||||
#endif
|
||||
const RsGxsGroupId& group_id(grpChange->mGroupId);
|
||||
|
||||
switch(grpChange->getType())
|
||||
{
|
||||
case RsGxsNotify::TYPE_PROCESSED: // happens when the group is subscribed
|
||||
{
|
||||
std::list<RsGxsGroupId> &grpList = grpChange->mGrpIdList;
|
||||
std::list<RsGxsGroupId>::iterator git;
|
||||
for (git = grpList.begin(); git != grpList.end(); ++git)
|
||||
{
|
||||
auto ev = std::make_shared<RsGxsPostedEvent>();
|
||||
ev->mPostedGroupId = *git;
|
||||
ev->mPostedEventCode = RsPostedEventCode::SUBSCRIBE_STATUS_CHANGED;
|
||||
rsEvents->postEvent(ev);
|
||||
}
|
||||
|
||||
auto ev = std::make_shared<RsGxsPostedEvent>();
|
||||
ev->mPostedGroupId = group_id;
|
||||
ev->mPostedEventCode = RsPostedEventCode::SUBSCRIBE_STATUS_CHANGED;
|
||||
rsEvents->postEvent(ev);
|
||||
}
|
||||
break;
|
||||
|
||||
case RsGxsNotify::TYPE_STATISTICS_CHANGED:
|
||||
{
|
||||
std::list<RsGxsGroupId> &grpList = grpChange->mGrpIdList;
|
||||
std::list<RsGxsGroupId>::iterator git;
|
||||
|
||||
for (git = grpList.begin(); git != grpList.end(); ++git)
|
||||
{
|
||||
auto ev = std::make_shared<RsGxsPostedEvent>();
|
||||
ev->mPostedGroupId = *git;
|
||||
ev->mPostedEventCode = RsPostedEventCode::STATISTICS_CHANGED;
|
||||
rsEvents->postEvent(ev);
|
||||
}
|
||||
auto ev = std::make_shared<RsGxsPostedEvent>();
|
||||
ev->mPostedGroupId = group_id;
|
||||
ev->mPostedEventCode = RsPostedEventCode::STATISTICS_CHANGED;
|
||||
rsEvents->postEvent(ev);
|
||||
}
|
||||
break;
|
||||
|
||||
@ -168,30 +152,26 @@ void p3PostBase::notifyChanges(std::vector<RsGxsNotify *> &changes)
|
||||
case RsGxsNotify::TYPE_RECEIVED_NEW:
|
||||
{
|
||||
/* group received */
|
||||
const std::list<RsGxsGroupId>& grpList = grpChange->mGrpIdList;
|
||||
|
||||
for (auto git = grpList.begin(); git != grpList.end(); ++git)
|
||||
if(mKnownPosted.find(group_id) == mKnownPosted.end())
|
||||
{
|
||||
if(mKnownPosted.find(*git) == mKnownPosted.end())
|
||||
{
|
||||
mKnownPosted.insert(std::make_pair(*git, time(nullptr)));
|
||||
IndicateConfigChanged();
|
||||
mKnownPosted.insert(std::make_pair(group_id, time(nullptr)));
|
||||
IndicateConfigChanged();
|
||||
|
||||
auto ev = std::make_shared<RsGxsPostedEvent>();
|
||||
ev->mPostedGroupId = *git;
|
||||
ev->mPostedEventCode = RsPostedEventCode::NEW_POSTED_GROUP;
|
||||
rsEvents->postEvent(ev);
|
||||
auto ev = std::make_shared<RsGxsPostedEvent>();
|
||||
ev->mPostedGroupId = group_id;
|
||||
ev->mPostedEventCode = RsPostedEventCode::NEW_POSTED_GROUP;
|
||||
rsEvents->postEvent(ev);
|
||||
|
||||
#ifdef POSTBASE_DEBUG
|
||||
std::cerr << "p3PostBase::notifyChanges() Incoming Group: " << *git;
|
||||
std::cerr << std::endl;
|
||||
std::cerr << "p3PostBase::notifyChanges() Incoming Group: " << group_id;
|
||||
std::cerr << std::endl;
|
||||
#endif
|
||||
}
|
||||
else
|
||||
RsInfo() << __PRETTY_FUNCTION__
|
||||
<< " Not notifying already known forum "
|
||||
<< *git << std::endl;
|
||||
}
|
||||
else
|
||||
RsInfo() << __PRETTY_FUNCTION__
|
||||
<< " Not notifying already known forum "
|
||||
<< group_id << std::endl;
|
||||
}
|
||||
break;
|
||||
|
||||
@ -351,11 +331,7 @@ void p3PostBase::addGroupForProcessing(RsGxsGroupId grpId)
|
||||
{
|
||||
RsStackMutex stack(mPostBaseMtx); /********** STACK LOCKED MTX ******/
|
||||
// no point having multiple lookups queued.
|
||||
if (mBgGroupList.end() == std::find(mBgGroupList.begin(),
|
||||
mBgGroupList.end(), grpId))
|
||||
{
|
||||
mBgGroupList.push_back(grpId);
|
||||
}
|
||||
mBgGroupList.insert(grpId);
|
||||
}
|
||||
}
|
||||
|
||||
@ -388,8 +364,8 @@ void p3PostBase::background_requestUnprocessedGroup()
|
||||
return;
|
||||
}
|
||||
|
||||
grpId = mBgGroupList.front();
|
||||
mBgGroupList.pop_front();
|
||||
grpId = *mBgGroupList.begin();
|
||||
mBgGroupList.erase(grpId);
|
||||
mBgProcessing = true;
|
||||
}
|
||||
|
||||
@ -483,8 +459,6 @@ void p3PostBase::background_loadMsgs(const uint32_t &token, bool unprocessed)
|
||||
|
||||
// generate vector of changes to push to the GUI.
|
||||
std::vector<RsGxsNotify *> changes;
|
||||
RsGxsMsgChange *msgChanges = new RsGxsMsgChange(RsGxsNotify::TYPE_PROCESSED, false);
|
||||
|
||||
|
||||
RsGxsGroupId groupId;
|
||||
std::map<RsGxsGroupId, std::vector<RsGxsMsgItem*> >::iterator mit;
|
||||
@ -535,7 +509,7 @@ void p3PostBase::background_loadMsgs(const uint32_t &token, bool unprocessed)
|
||||
#endif
|
||||
|
||||
/* but we need to notify GUI about them */
|
||||
msgChanges->msgChangeMap[mit->first].insert((*vit)->meta.mMsgId);
|
||||
changes.push_back(new RsGxsMsgChange(RsGxsNotify::TYPE_PROCESSED, mit->first,(*vit)->meta.mMsgId, false));
|
||||
}
|
||||
else if (NULL != (commentItem = dynamic_cast<RsGxsCommentItem *>(*vit)))
|
||||
{
|
||||
@ -631,22 +605,7 @@ void p3PostBase::background_loadMsgs(const uint32_t &token, bool unprocessed)
|
||||
}
|
||||
|
||||
/* push updates of new Posts */
|
||||
if (msgChanges->msgChangeMap.size() > 0)
|
||||
{
|
||||
#ifdef POSTBASE_DEBUG
|
||||
std::cerr << "p3PostBase::background_processNewMessages() -> receiveChanges()";
|
||||
std::cerr << std::endl;
|
||||
#endif
|
||||
|
||||
changes.push_back(msgChanges);
|
||||
//receiveHelperChanges(changes);
|
||||
|
||||
notifyChanges(changes);
|
||||
}
|
||||
else
|
||||
{
|
||||
delete(msgChanges);
|
||||
}
|
||||
notifyChanges(changes);
|
||||
|
||||
/* request the summary info from the parents */
|
||||
uint32_t token_b;
|
||||
@ -711,7 +670,6 @@ void p3PostBase::background_updateVoteCounts(const uint32_t &token)
|
||||
|
||||
// generate vector of changes to push to the GUI.
|
||||
std::vector<RsGxsNotify *> changes;
|
||||
RsGxsMsgChange *msgChanges = new RsGxsMsgChange(RsGxsNotify::TYPE_PROCESSED, false);
|
||||
|
||||
for(mit = parentMsgList.begin(); mit != parentMsgList.end(); ++mit)
|
||||
{
|
||||
@ -754,7 +712,8 @@ void p3PostBase::background_updateVoteCounts(const uint32_t &token)
|
||||
#endif
|
||||
|
||||
stats.increment(it->second);
|
||||
msgChanges->msgChangeMap[mit->first].insert(vit->mMsgId);
|
||||
|
||||
changes.push_back(new RsGxsMsgChange(RsGxsNotify::TYPE_PROCESSED,mit->first,vit->mMsgId, false));
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -786,21 +745,7 @@ void p3PostBase::background_updateVoteCounts(const uint32_t &token)
|
||||
}
|
||||
}
|
||||
|
||||
if (msgChanges->msgChangeMap.size() > 0)
|
||||
{
|
||||
#ifdef POSTBASE_DEBUG
|
||||
std::cerr << "p3PostBase::background_updateVoteCounts() -> receiveChanges()";
|
||||
std::cerr << std::endl;
|
||||
#endif
|
||||
|
||||
changes.push_back(msgChanges);
|
||||
//receiveHelperChanges(changes);
|
||||
notifyChanges(changes);
|
||||
}
|
||||
else
|
||||
{
|
||||
delete(msgChanges);
|
||||
}
|
||||
notifyChanges(changes);
|
||||
|
||||
// DONE!.
|
||||
background_cleanup();
|
||||
|
@ -125,7 +125,7 @@ private:
|
||||
|
||||
bool mBgProcessing;
|
||||
bool mBgIncremental;
|
||||
std::list<RsGxsGroupId> mBgGroupList;
|
||||
std::set<RsGxsGroupId> mBgGroupList;
|
||||
std::map<RsGxsMessageId, PostStats> mBgStatsMap;
|
||||
|
||||
std::map<RsGxsGroupId,rstime_t> mKnownPosted;
|
||||
|
@ -94,55 +94,75 @@ bool p3Posted::getGroupData(const uint32_t &token, std::vector<RsPostedGroup> &g
|
||||
return ok;
|
||||
}
|
||||
|
||||
bool p3Posted::getPostData(const uint32_t &token, std::vector<RsPostedPost> &msgs, std::vector<RsGxsComment> &cmts)
|
||||
bool p3Posted::getPostData(
|
||||
const uint32_t &token, std::vector<RsPostedPost> &msgs,
|
||||
std::vector<RsGxsComment> &cmts,
|
||||
std::vector<RsGxsVote> &vots)
|
||||
{
|
||||
#ifdef POSTED_DEBUG
|
||||
std::cerr << "p3Posted::getPostData()";
|
||||
std::cerr << std::endl;
|
||||
RsDbg() << __PRETTY_FUNCTION__ << std::endl;
|
||||
#endif
|
||||
|
||||
GxsMsgDataMap msgData;
|
||||
bool ok = RsGenExchange::getMsgData(token, msgData);
|
||||
rstime_t now = time(NULL);
|
||||
|
||||
if(ok)
|
||||
if(!RsGenExchange::getMsgData(token, msgData))
|
||||
{
|
||||
GxsMsgDataMap::iterator mit = msgData.begin();
|
||||
|
||||
for(; mit != msgData.end(); ++mit)
|
||||
RsErr() << __PRETTY_FUNCTION__ << " ERROR in request" << std::endl;
|
||||
return false;
|
||||
}
|
||||
|
||||
GxsMsgDataMap::iterator mit = msgData.begin();
|
||||
|
||||
for(; mit != msgData.end(); ++mit)
|
||||
{
|
||||
std::vector<RsGxsMsgItem*>& msgItems = mit->second;
|
||||
std::vector<RsGxsMsgItem*>::iterator vit = msgItems.begin();
|
||||
|
||||
for(; vit != msgItems.end(); ++vit)
|
||||
{
|
||||
std::vector<RsGxsMsgItem*>& msgItems = mit->second;
|
||||
std::vector<RsGxsMsgItem*>::iterator vit = msgItems.begin();
|
||||
|
||||
for(; vit != msgItems.end(); ++vit)
|
||||
RsGxsPostedPostItem* postItem =
|
||||
dynamic_cast<RsGxsPostedPostItem*>(*vit);
|
||||
|
||||
if(postItem)
|
||||
{
|
||||
RsGxsPostedPostItem* postItem = dynamic_cast<RsGxsPostedPostItem*>(*vit);
|
||||
// TODO Really needed all of these lines?
|
||||
RsPostedPost msg = postItem->mPost;
|
||||
msg.mMeta = postItem->meta;
|
||||
postItem->toPostedPost(msg, true);
|
||||
msg.calculateScores(now);
|
||||
|
||||
if(postItem)
|
||||
msgs.push_back(msg);
|
||||
delete postItem;
|
||||
}
|
||||
else
|
||||
{
|
||||
RsGxsCommentItem* cmtItem =
|
||||
dynamic_cast<RsGxsCommentItem*>(*vit);
|
||||
if(cmtItem)
|
||||
{
|
||||
RsPostedPost msg = postItem->mPost;
|
||||
msg.mMeta = postItem->meta;
|
||||
postItem->toPostedPost(msg, true);
|
||||
msg.calculateScores(now);
|
||||
|
||||
msgs.push_back(msg);
|
||||
delete postItem;
|
||||
RsGxsComment cmt;
|
||||
RsGxsMsgItem *mi = (*vit);
|
||||
cmt = cmtItem->mMsg;
|
||||
cmt.mMeta = mi->meta;
|
||||
#ifdef GXSCOMMENT_DEBUG
|
||||
RsDbg() << __PRETTY_FUNCTION__ << " Found Comment:" << std::endl;
|
||||
cmt.print(std::cerr," ", "cmt");
|
||||
#endif
|
||||
cmts.push_back(cmt);
|
||||
delete cmtItem;
|
||||
}
|
||||
else
|
||||
{
|
||||
RsGxsCommentItem* cmtItem = dynamic_cast<RsGxsCommentItem*>(*vit);
|
||||
if(cmtItem)
|
||||
RsGxsVoteItem* votItem =
|
||||
dynamic_cast<RsGxsVoteItem*>(*vit);
|
||||
if(votItem)
|
||||
{
|
||||
RsGxsComment cmt;
|
||||
RsGxsVote vot;
|
||||
RsGxsMsgItem *mi = (*vit);
|
||||
cmt = cmtItem->mMsg;
|
||||
cmt.mMeta = mi->meta;
|
||||
#ifdef GXSCOMMENT_DEBUG
|
||||
std::cerr << "p3Posted::getPostData Found Comment:" << std::endl;
|
||||
cmt.print(std::cerr," ", "cmt");
|
||||
#endif
|
||||
cmts.push_back(cmt);
|
||||
delete cmtItem;
|
||||
vot = votItem->mMsg;
|
||||
vot.mMeta = mi->meta;
|
||||
vots.push_back(vot);
|
||||
delete votItem;
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -150,24 +170,37 @@ bool p3Posted::getPostData(const uint32_t &token, std::vector<RsPostedPost> &msg
|
||||
//const uint16_t RS_SERVICE_GXS_TYPE_CHANNELS = 0x0217;
|
||||
//const uint8_t RS_PKT_SUBTYPE_GXSCHANNEL_POST_ITEM = 0x03;
|
||||
//const uint8_t RS_PKT_SUBTYPE_GXSCOMMENT_COMMENT_ITEM = 0xf1;
|
||||
std::cerr << "Not a PostedPostItem neither a RsGxsCommentItem"
|
||||
<< " PacketService=" << std::hex << (int)msg->PacketService() << std::dec
|
||||
<< " PacketSubType=" << std::hex << (int)msg->PacketSubType() << std::dec
|
||||
<< " type name =" << typeid(*msg).name()
|
||||
<< " , deleting!" << std::endl;
|
||||
//const uint8_t RS_PKT_SUBTYPE_GXSCOMMENT_VOTE_ITEM = 0xf2;
|
||||
RsErr() << __PRETTY_FUNCTION__
|
||||
<< "Not a PostedPostItem neither a "
|
||||
<< "RsGxsCommentItem neither a RsGxsVoteItem"
|
||||
<< " PacketService=" << std::hex << (int)msg->PacketService() << std::dec
|
||||
<< " PacketSubType=" << std::hex << (int)msg->PacketSubType() << std::dec
|
||||
<< " type name =" << typeid(*msg).name()
|
||||
<< " , deleting!" << std::endl;
|
||||
delete *vit;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
std::cerr << "p3GxsChannels::getPostData() ERROR in request";
|
||||
std::cerr << std::endl;
|
||||
}
|
||||
|
||||
return ok;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool p3Posted::getPostData(
|
||||
const uint32_t &token, std::vector<RsPostedPost> &posts, std::vector<RsGxsComment> &cmts)
|
||||
{
|
||||
std::vector<RsGxsVote> vots;
|
||||
return getPostData( token, posts, cmts, vots);
|
||||
}
|
||||
|
||||
bool p3Posted::getPostData(
|
||||
const uint32_t &token, std::vector<RsPostedPost> &posts)
|
||||
{
|
||||
std::vector<RsGxsComment> cmts;
|
||||
std::vector<RsGxsVote> vots;
|
||||
return getPostData( token, posts, cmts, vots);
|
||||
}
|
||||
|
||||
//Not currently used
|
||||
@ -323,23 +356,25 @@ bool p3Posted::getBoardsInfo(
|
||||
}
|
||||
|
||||
bool p3Posted::getBoardAllContent( const RsGxsGroupId& groupId,
|
||||
std::vector<RsPostedPost>& posts,
|
||||
std::vector<RsGxsComment>& comments )
|
||||
std::vector<RsPostedPost>& posts,
|
||||
std::vector<RsGxsComment>& comments,
|
||||
std::vector<RsGxsVote>& votes )
|
||||
{
|
||||
uint32_t token;
|
||||
RsTokReqOptions opts;
|
||||
opts.mReqType = GXS_REQUEST_TYPE_MSG_DATA;
|
||||
|
||||
if( !requestMsgInfo(token, opts, std::list<RsGxsGroupId>({groupId})) || waitToken(token) != RsTokenService::COMPLETE )
|
||||
return false;
|
||||
if( !requestMsgInfo(token, opts, std::list<RsGxsGroupId>({groupId})) || waitToken(token) != RsTokenService::COMPLETE )
|
||||
return false;
|
||||
|
||||
return getPostData(token, posts, comments);
|
||||
return getPostData(token, posts, comments, votes);
|
||||
}
|
||||
|
||||
bool p3Posted::getBoardContent( const RsGxsGroupId& groupId,
|
||||
const std::set<RsGxsMessageId>& contentsIds,
|
||||
std::vector<RsPostedPost>& posts,
|
||||
std::vector<RsGxsComment>& comments )
|
||||
const std::set<RsGxsMessageId>& contentsIds,
|
||||
std::vector<RsPostedPost>& posts,
|
||||
std::vector<RsGxsComment>& comments,
|
||||
std::vector<RsGxsVote>& votes )
|
||||
{
|
||||
uint32_t token;
|
||||
RsTokReqOptions opts;
|
||||
@ -351,7 +386,7 @@ bool p3Posted::getBoardContent( const RsGxsGroupId& groupId,
|
||||
if( !requestMsgInfo(token, opts, msgIds) ||
|
||||
waitToken(token) != RsTokenService::COMPLETE ) return false;
|
||||
|
||||
return getPostData(token, posts, comments);
|
||||
return getPostData(token, posts, comments, votes);
|
||||
}
|
||||
|
||||
bool p3Posted::getBoardsSummaries(std::list<RsGroupMetaData>& boards )
|
||||
|
@ -53,22 +53,26 @@ virtual void notifyChanges(std::vector<RsGxsNotify*>& changes)
|
||||
|
||||
public:
|
||||
|
||||
#ifdef TO_REMOVE
|
||||
virtual void receiveHelperChanges(std::vector<RsGxsNotify*>& changes)
|
||||
{
|
||||
return RsGxsIfaceHelper::receiveChanges(changes);
|
||||
}
|
||||
#endif
|
||||
|
||||
bool getBoardsInfo(const std::list<RsGxsGroupId>& boardsIds,
|
||||
std::vector<RsPostedGroup>& groupsInfo ) override;
|
||||
|
||||
bool getBoardAllContent(const RsGxsGroupId& groupId,
|
||||
std::vector<RsPostedPost>& posts,
|
||||
std::vector<RsGxsComment>& comments ) override;
|
||||
std::vector<RsPostedPost>& posts,
|
||||
std::vector<RsGxsComment>& comments,
|
||||
std::vector<RsGxsVote>& votes ) override;
|
||||
|
||||
bool getBoardContent(const RsGxsGroupId& groupId,
|
||||
const std::set<RsGxsMessageId>& contentsIds,
|
||||
std::vector<RsPostedPost>& posts,
|
||||
std::vector<RsGxsComment>& comments ) override;
|
||||
const std::set<RsGxsMessageId>& contentsIds,
|
||||
std::vector<RsPostedPost>& posts,
|
||||
std::vector<RsGxsComment>& comments,
|
||||
std::vector<RsGxsVote>& votes ) override;
|
||||
|
||||
bool getBoardsSummaries(std::list<RsGroupMetaData>& groupInfo) override;
|
||||
|
||||
@ -80,9 +84,10 @@ virtual void receiveHelperChanges(std::vector<RsGxsNotify*>& changes)
|
||||
|
||||
bool createBoard(RsPostedGroup& board) override;
|
||||
|
||||
virtual bool getGroupData(const uint32_t &token, std::vector<RsPostedGroup> &groups);
|
||||
virtual bool getPostData(const uint32_t &token, std::vector<RsPostedPost> &posts, std::vector<RsGxsComment> &cmts);
|
||||
virtual bool getPostData(const uint32_t &token, std::vector<RsPostedPost> &posts) { std::vector<RsGxsComment> cmts; return getPostData( token, posts, cmts);}
|
||||
virtual bool getGroupData(const uint32_t &token, std::vector<RsPostedGroup> &groups) override;
|
||||
virtual bool getPostData(const uint32_t &token, std::vector<RsPostedPost> &posts, std::vector<RsGxsComment> &cmts, std::vector<RsGxsVote> &vots) override;
|
||||
virtual bool getPostData(const uint32_t &token, std::vector<RsPostedPost> &posts, std::vector<RsGxsComment> &cmts) override;
|
||||
virtual bool getPostData(const uint32_t &token, std::vector<RsPostedPost> &posts) override;
|
||||
//Not currently used
|
||||
//virtual bool getRelatedPosts(const uint32_t &token, std::vector<RsPostedPost> &posts);
|
||||
|
||||
|
@ -60,7 +60,12 @@ public:
|
||||
|
||||
bool is_cached(const Key &key) const;
|
||||
bool fetch(const Key &key, Value &data);
|
||||
Value &ref(const Key &key); // like map[] installs empty one if non-existent.
|
||||
|
||||
// Like map[] installs empty one if non-existent.
|
||||
|
||||
Value& ref(const Key &key);
|
||||
Value& operator[](const Key& key) { return ref(key); }
|
||||
|
||||
bool store(const Key &key, const Value &data);
|
||||
bool erase(const Key &key); // clean up cache.
|
||||
|
||||
@ -70,7 +75,8 @@ public:
|
||||
|
||||
template<class ClientClass> bool applyToAllCachedEntries(ClientClass& c,bool (ClientClass::*method)(Value&));
|
||||
|
||||
uint32_t size() const { return mDataMap.size() ; }
|
||||
uint32_t size() const { return mDataMap.size() ; }
|
||||
void printStats(std::ostream& out);
|
||||
private:
|
||||
|
||||
bool update_lrumap(const Key &key, rstime_t old_ts, rstime_t new_ts);
|
||||
@ -96,7 +102,6 @@ private:
|
||||
std::string mName;
|
||||
|
||||
// some statistics.
|
||||
void printStats(std::ostream &out);
|
||||
void clearStats();
|
||||
|
||||
mutable uint32_t mStats_inserted;
|
||||
|
@ -452,7 +452,7 @@ void FeedReaderDialog::calculateFeedItem(QTreeWidgetItem *item, uint32_t &unread
|
||||
font.setBold(unreadCountItem != 0);
|
||||
item->setFont(i, font);
|
||||
|
||||
item->setTextColor(COLUMN_FEED_NAME, deactivated ? colorDeactivated : colorActivated);
|
||||
item->setData(COLUMN_FEED_NAME, Qt::ForegroundRole, deactivated ? colorDeactivated : colorActivated);
|
||||
}
|
||||
|
||||
QIcon icon = item->data(COLUMN_FEED_DATA, ROLE_FEED_ICON).value<QIcon>();
|
||||
|
@ -27,6 +27,7 @@
|
||||
#include "chat/ChatTabWidget.h"
|
||||
#include "chat/CreateLobbyDialog.h"
|
||||
#include "common/RSTreeWidgetItem.h"
|
||||
#include "common/RSElidedItemDelegate.h"
|
||||
#include "gui/RetroShareLink.h"
|
||||
#include "gui/gxs/GxsIdDetails.h"
|
||||
#include "gui/Identity/IdEditDialog.h"
|
||||
@ -157,6 +158,7 @@ ChatLobbyWidget::ChatLobbyWidget(QWidget *parent, Qt::WindowFlags flags)
|
||||
ui.lobbyTreeWidget->setColumnHidden(COLUMN_USER_COUNT,true) ;
|
||||
ui.lobbyTreeWidget->setColumnHidden(COLUMN_TOPIC,true) ;
|
||||
ui.lobbyTreeWidget->setSortingEnabled(true) ;
|
||||
ui.lobbyTreeWidget->setItemDelegateForColumn(COLUMN_NAME, new RSElidedItemDelegate());
|
||||
|
||||
float fact = QFontMetricsF(font()).height()/14.0f;
|
||||
|
||||
@ -386,6 +388,8 @@ static void updateItem(QTreeWidget *treeWidget, QTreeWidgetItem *item, ChatLobby
|
||||
item->setData(COLUMN_DATA, ROLE_FLAGS, lobby_flags.toUInt32());
|
||||
item->setData(COLUMN_DATA, ROLE_AUTOSUBSCRIBE, autoSubscribe);
|
||||
|
||||
//TODO (Phenom): Add qproperty for these text colors in stylesheets
|
||||
// As palette is not updated by stylesheet
|
||||
QColor color = treeWidget->palette().color(QPalette::Active, QPalette::Text);
|
||||
|
||||
if (!subscribed) {
|
||||
@ -395,7 +399,7 @@ static void updateItem(QTreeWidget *treeWidget, QTreeWidgetItem *item, ChatLobby
|
||||
}
|
||||
|
||||
for (int column = 0; column < COLUMN_COUNT; ++column) {
|
||||
item->setTextColor(column, color);
|
||||
item->setData(column, Qt::ForegroundRole, color);
|
||||
}
|
||||
QString tooltipstr = QObject::tr("Subject:")+" "+item->text(COLUMN_TOPIC)+"\n"
|
||||
+QObject::tr("Participants:")+" "+QString::number(count)+"\n"
|
||||
@ -407,7 +411,7 @@ static void updateItem(QTreeWidget *treeWidget, QTreeWidgetItem *item, ChatLobby
|
||||
tooltipstr += QObject::tr("\nSecurity: no anonymous IDs") ;
|
||||
QColor foreground = QColor(0, 128, 0); // green
|
||||
for (int column = 0; column < COLUMN_COUNT; ++column)
|
||||
item->setTextColor(column, foreground);
|
||||
item->setData(column, Qt::ForegroundRole, foreground);
|
||||
}
|
||||
item->setToolTip(0,tooltipstr) ;
|
||||
}
|
||||
|
@ -415,9 +415,8 @@ void SearchDialog::download()
|
||||
std::cout << *it << "-" << std::endl;
|
||||
|
||||
QColor foreground = textColorDownloading();
|
||||
QBrush brush(foreground);
|
||||
for (int i = 0; i < item->columnCount(); ++i)
|
||||
item->setForeground(i, brush);
|
||||
item->setData(i, Qt::ForegroundRole, foreground );
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1269,10 +1268,9 @@ void SearchDialog::insertFile(qulonglong searchId, const FileDetail& file, int s
|
||||
foreground = textColorHighSources();
|
||||
}
|
||||
|
||||
QBrush brush(foreground);
|
||||
for (int i = 0; i < item->columnCount(); ++i)
|
||||
{
|
||||
item->setForeground(i, brush);
|
||||
item->setData(i, Qt::ForegroundRole, foreground);
|
||||
}
|
||||
}
|
||||
|
||||
@ -1355,10 +1353,9 @@ void SearchDialog::insertFile(qulonglong searchId, const FileDetail& file, int s
|
||||
}
|
||||
|
||||
if (setForeground) {
|
||||
QBrush brush(foreground);
|
||||
for (int i = 0; i < item->columnCount(); ++i)
|
||||
{
|
||||
item->setForeground(i, brush);
|
||||
item->setData(i, Qt::ForegroundRole, foreground);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -970,70 +970,82 @@ void SharedFilesDialog::recursExpandAll(const QModelIndex& index)
|
||||
}
|
||||
}
|
||||
|
||||
void SharedFilesDialog::recursSaveExpandedItems(const QModelIndex& index,const std::string& path,std::set<std::string>& exp,
|
||||
std::set<std::string>& vis,
|
||||
void SharedFilesDialog::recursSaveExpandedItems(const QModelIndex& index,const std::string& path,
|
||||
std::set<std::string>& exp,
|
||||
std::set<std::string>& hid,
|
||||
std::set<std::string>& sel
|
||||
)
|
||||
{
|
||||
std::string local_path = path+"/"+index.data(Qt::DisplayRole).toString().toStdString();
|
||||
std::string local_path = path+"/"+index.data(Qt::DisplayRole).toString().toStdString();
|
||||
#ifdef DEBUG_SHARED_FILES_DIALOG
|
||||
std::cerr << "at index " << index.row() << ". data[1]=" << local_path << std::endl;
|
||||
std::cerr << "at index " << index.row() << ". data[1]=" << local_path << std::endl;
|
||||
#endif
|
||||
|
||||
if(ui.dirTreeView->selectionModel()->selection().contains(index))
|
||||
sel.insert(local_path) ;
|
||||
if(ui.dirTreeView->selectionModel()->selection().contains(index))
|
||||
sel.insert(local_path) ;
|
||||
|
||||
if(ui.dirTreeView->isRowHidden(index.row(),index.parent()))
|
||||
{
|
||||
vis.insert(local_path) ;
|
||||
return ;
|
||||
}
|
||||
// Disable hidden check as we don't use it and Qt bug: https://bugreports.qt.io/browse/QTBUG-11438
|
||||
/*if(ui.dirTreeView->isRowHidden(index.row(),index.parent()))
|
||||
{
|
||||
hid.insert(local_path) ;
|
||||
return ;
|
||||
}*/
|
||||
|
||||
if(ui.dirTreeView->isExpanded(index))
|
||||
{
|
||||
if(ui.dirTreeView->isExpanded(index))
|
||||
{
|
||||
#ifdef DEBUG_SHARED_FILES_DIALOG
|
||||
std::cerr << "Index " << local_path << " is expanded." << std::endl;
|
||||
std::cerr << "Index " << local_path << " is expanded." << std::endl;
|
||||
#endif
|
||||
if(index.isValid())
|
||||
exp.insert(local_path) ;
|
||||
if(index.isValid())
|
||||
exp.insert(local_path) ;
|
||||
|
||||
for(int row=0;row<ui.dirTreeView->model()->rowCount(index);++row)
|
||||
recursSaveExpandedItems(index.child(row,0),local_path,exp,vis,sel) ;
|
||||
}
|
||||
for(int row=0;row<ui.dirTreeView->model()->rowCount(index);++row)
|
||||
#if QT_VERSION >= QT_VERSION_CHECK(5, 8, 0)
|
||||
recursSaveExpandedItems(ui.dirTreeView->model()->index(row,0,index),local_path,exp,hid,sel) ;
|
||||
#else
|
||||
recursSaveExpandedItems(index.child(row,0),local_path,exp,hid,sel) ;
|
||||
#endif
|
||||
}
|
||||
#ifdef DEBUG_SHARED_FILES_DIALOG
|
||||
else
|
||||
std::cerr << "Index is not expanded." << std::endl;
|
||||
else
|
||||
std::cerr << "Index is not expanded." << std::endl;
|
||||
#endif
|
||||
}
|
||||
|
||||
void SharedFilesDialog::recursRestoreExpandedItems(const QModelIndex& index, const std::string &path,
|
||||
const std::set<std::string>& exp,
|
||||
const std::set<std::string>& vis,
|
||||
const std::set<std::string>& hid,
|
||||
const std::set<std::string> &sel)
|
||||
{
|
||||
std::string local_path = path+"/"+index.data(Qt::DisplayRole).toString().toStdString();
|
||||
std::string local_path = path+"/"+index.data(Qt::DisplayRole).toString().toStdString();
|
||||
#ifdef DEBUG_SHARED_FILES_DIALOG
|
||||
std::cerr << "at index " << index.row() << ". data[1]=" << local_path << std::endl;
|
||||
std::cerr << "at index " << index.row() << ". data[1]=" << local_path << std::endl;
|
||||
#endif
|
||||
if(sel.find(local_path) != sel.end())
|
||||
ui.dirTreeView->selectionModel()->select(index, QItemSelectionModel::Select | QItemSelectionModel::Rows);
|
||||
|
||||
bool invisible = vis.find(local_path) != vis.end();
|
||||
ui.dirTreeView->setRowHidden(index.row(),index.parent(),invisible ) ;
|
||||
if(sel.find(local_path) != sel.end())
|
||||
ui.dirTreeView->selectionModel()->select(index, QItemSelectionModel::Select | QItemSelectionModel::Rows);
|
||||
|
||||
// if(invisible)
|
||||
// mHiddenIndexes.push_back(proxyModel->mapToSource(index));
|
||||
// Disable hidden check as we don't use it and Qt bug: https://bugreports.qt.io/browse/QTBUG-11438
|
||||
/*bool invisible = hid.find(local_path) != hid.end();
|
||||
ui.dirTreeView->setRowHidden(index.row(),index.parent(),invisible ) ;*/
|
||||
|
||||
if(!invisible && exp.find(local_path) != exp.end())
|
||||
{
|
||||
// if(invisible)
|
||||
// mHiddenIndexes.push_back(proxyModel->mapToSource(index));
|
||||
|
||||
if(/*!invisible &&*/ exp.find(local_path) != exp.end())
|
||||
{
|
||||
#ifdef DEBUG_SHARED_FILES_DIALOG
|
||||
std::cerr << "re expanding index " << local_path << std::endl;
|
||||
std::cerr << "re expanding index " << local_path << std::endl;
|
||||
#endif
|
||||
ui.dirTreeView->setExpanded(index,true) ;
|
||||
ui.dirTreeView->setExpanded(index,true) ;
|
||||
|
||||
for(int row=0;row<ui.dirTreeView->model()->rowCount(index);++row)
|
||||
recursRestoreExpandedItems(index.child(row,0),local_path,exp,vis,sel) ;
|
||||
}
|
||||
for(int row=0;row<ui.dirTreeView->model()->rowCount(index);++row)
|
||||
#if QT_VERSION >= QT_VERSION_CHECK(5, 8, 0)
|
||||
recursRestoreExpandedItems(ui.dirTreeView->model()->index(row,0,index),local_path,exp,hid,sel) ;
|
||||
#else
|
||||
recursRestoreExpandedItems(index.child(row,0),local_path,exp,hid,sel) ;
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
@ -31,6 +31,7 @@ public:
|
||||
TransferUserNotify(QObject *parent = 0);
|
||||
|
||||
virtual bool hasSetting(QString *name, QString *group);
|
||||
virtual QString textInfo() const override { return tr("completed transfer(s)"); }
|
||||
|
||||
private:
|
||||
virtual QIcon getIcon();
|
||||
|
@ -322,13 +322,13 @@ void IdDetailsDialog::modifyReputation()
|
||||
case 2: op = RsOpinion::POSITIVE; break;
|
||||
default:
|
||||
std::cerr << "Wrong value from opinion combobox. Bug??" << std::endl;
|
||||
break;
|
||||
return;
|
||||
}
|
||||
rsReputations->setOwnOpinion(id,op);
|
||||
|
||||
// trigger refresh when finished.
|
||||
// basic / anstype are not needed.
|
||||
loadIdentity();
|
||||
loadIdentity();
|
||||
|
||||
return;
|
||||
}
|
||||
|
@ -181,8 +181,9 @@ IdDialog::IdDialog(QWidget *parent) : MainPage(parent), ui(new Ui::IdDialog)
|
||||
ui->treeWidget_membership->clear();
|
||||
ui->treeWidget_membership->setItemDelegateForColumn(CIRCLEGROUP_CIRCLE_COL_GROUPNAME,new GxsIdTreeItemDelegate());
|
||||
|
||||
mExternalOtherCircleItem = NULL ;
|
||||
mExternalBelongingCircleItem = NULL ;
|
||||
mExternalOtherCircleItem = NULL ;
|
||||
mExternalBelongingCircleItem = NULL ;
|
||||
mMyCircleItem = NULL ;
|
||||
|
||||
/* Setup UI helper */
|
||||
mStateHelper = new UIStateHelper(this);
|
||||
@ -437,12 +438,11 @@ void IdDialog::handleEvent_main_thread(std::shared_ptr<const RsEvent> event)
|
||||
|
||||
switch(e->mCircleEventType)
|
||||
{
|
||||
case RsGxsCircleEventCode::NEW_CIRCLE:
|
||||
case RsGxsCircleEventCode::CIRCLE_MEMBERSHIP_REQUEST:
|
||||
case RsGxsCircleEventCode::CIRCLE_MEMBERSHIP_INVITE:
|
||||
case RsGxsCircleEventCode::CIRCLE_MEMBERSHIP_ID_ADDED_TO_INVITEE_LIST:
|
||||
case RsGxsCircleEventCode::CIRCLE_MEMBERSHIP_LEAVE:
|
||||
case RsGxsCircleEventCode::CIRCLE_MEMBERSHIP_JOIN:
|
||||
case RsGxsCircleEventCode::CIRCLE_MEMBERSHIP_REVOQUED:
|
||||
case RsGxsCircleEventCode::CIRCLE_MEMBERSHIP_ID_REMOVED_FROM_INVITEE_LIST:
|
||||
case RsGxsCircleEventCode::NEW_CIRCLE:
|
||||
case RsGxsCircleEventCode::CACHE_DATA_UPDATED:
|
||||
|
||||
updateCircles();
|
||||
@ -598,6 +598,10 @@ void IdDialog::loadCircles(const std::list<RsGroupMetaData>& groupInfo)
|
||||
|
||||
mStateHelper->setActive(CIRCLESDIALOG_GROUPMETA, true);
|
||||
|
||||
std::vector<bool> expanded_top_level_items;
|
||||
std::set<RsGxsCircleId> expanded_circle_items;
|
||||
saveExpandedCircleItems(expanded_top_level_items,expanded_circle_items);
|
||||
|
||||
#ifdef QT_BUG_CRASH_IN_TAKECHILD_WORKAROUND
|
||||
// These 3 lines are normally not needed. But apparently a bug (in Qt ??) causes Qt to crash when takeChild() is called. If we remove everything from the
|
||||
// tree widget before updating it, takeChild() is never called, but the all tree is filled again from scratch. This is less efficient obviously, and
|
||||
@ -858,6 +862,7 @@ void IdDialog::loadCircles(const std::list<RsGroupMetaData>& groupInfo)
|
||||
else
|
||||
item->setIcon(CIRCLEGROUP_CIRCLE_COL_GROUPNAME,FilesDefs::getIconFromQtResourcePath(IMAGE_UNKNOWN)) ;
|
||||
}
|
||||
restoreExpandedCircleItems(expanded_top_level_items,expanded_circle_items);
|
||||
}
|
||||
|
||||
//static void mark_matching_tree(QTreeWidget *w, const std::set<RsGxsId>& members, int col)
|
||||
@ -936,14 +941,26 @@ void IdDialog::revokeCircleMembership()
|
||||
if(!getItemCircleId(ui->treeWidget_membership->currentItem(),circle_id))
|
||||
return;
|
||||
|
||||
if(circle_id.isNull())
|
||||
{
|
||||
RsErr() << __PRETTY_FUNCTION__ << " : got a null circle ID. Cannot revoke an identity from that circle!" << std::endl;
|
||||
return ;
|
||||
}
|
||||
|
||||
RsGxsId gxs_id_to_revoke(qobject_cast<QAction*>(sender())->data().toString().toStdString());
|
||||
|
||||
RsThread::async([circle_id,gxs_id_to_revoke]()
|
||||
{
|
||||
// 1 - get message data from p3GxsForums
|
||||
if(gxs_id_to_revoke.isNull())
|
||||
RsErr() << __PRETTY_FUNCTION__ << " : got a null ID. Cannot revoke it from circle " << circle_id << "!" << std::endl;
|
||||
else
|
||||
RsThread::async([circle_id,gxs_id_to_revoke]()
|
||||
{
|
||||
// 1 - get message data from p3GxsForums
|
||||
|
||||
rsGxsCircles->revokeIdsFromCircle(std::set<RsGxsId>( { gxs_id_to_revoke } ),circle_id);
|
||||
});
|
||||
std::set<RsGxsId> ids;
|
||||
ids.insert(gxs_id_to_revoke);
|
||||
|
||||
rsGxsCircles->revokeIdsFromCircle(ids,circle_id);
|
||||
});
|
||||
}
|
||||
|
||||
void IdDialog::acceptCircleSubscription()
|
||||
@ -1369,23 +1386,24 @@ bool IdDialog::fillIdListItem(const RsGxsIdGroup& data, QTreeWidgetItem *&item,
|
||||
item->setData(RSID_COL_NICKNAME, Qt::UserRole, QString::fromStdString(data.mMeta.mGroupId.toStdString()));
|
||||
item->setText(RSID_COL_KEYID, QString::fromStdString(data.mMeta.mGroupId.toStdString()));
|
||||
|
||||
if(isBanned)
|
||||
{
|
||||
item->setForeground(RSID_COL_NICKNAME,QBrush(Qt::red));
|
||||
item->setForeground(RSID_COL_KEYID,QBrush(Qt::red));
|
||||
item->setForeground(RSID_COL_IDTYPE,QBrush(Qt::red));
|
||||
item->setForeground(RSID_COL_VOTES,QBrush(Qt::red));
|
||||
}
|
||||
else
|
||||
{
|
||||
item->setForeground(RSID_COL_NICKNAME,QBrush(Qt::black));
|
||||
item->setForeground(RSID_COL_KEYID,QBrush(Qt::black));
|
||||
item->setForeground(RSID_COL_IDTYPE,QBrush(Qt::black));
|
||||
item->setForeground(RSID_COL_VOTES,QBrush(Qt::black));
|
||||
}
|
||||
if(isBanned)
|
||||
{
|
||||
//TODO (Phenom): Add qproperty for these text colors in stylesheets
|
||||
item->setData(RSID_COL_NICKNAME, Qt::ForegroundRole, QColor(Qt::red));
|
||||
item->setData(RSID_COL_KEYID , Qt::ForegroundRole, QColor(Qt::red));
|
||||
item->setData(RSID_COL_IDTYPE , Qt::ForegroundRole, QColor(Qt::red));
|
||||
item->setData(RSID_COL_VOTES , Qt::ForegroundRole, QColor(Qt::red));
|
||||
}
|
||||
else
|
||||
{
|
||||
item->setData(RSID_COL_NICKNAME, Qt::ForegroundRole, QVariant());
|
||||
item->setData(RSID_COL_KEYID , Qt::ForegroundRole, QVariant());
|
||||
item->setData(RSID_COL_IDTYPE , Qt::ForegroundRole, QVariant());
|
||||
item->setData(RSID_COL_VOTES , Qt::ForegroundRole, QVariant());
|
||||
}
|
||||
|
||||
item->setData(RSID_COL_KEYID, Qt::UserRole,QVariant(item_flags)) ;
|
||||
item->setTextAlignment(RSID_COL_VOTES, Qt::AlignRight | Qt::AlignVCenter);
|
||||
item->setData(RSID_COL_KEYID, Qt::UserRole,QVariant(item_flags)) ;
|
||||
item->setTextAlignment(RSID_COL_VOTES, Qt::AlignRight | Qt::AlignVCenter);
|
||||
item->setData(
|
||||
RSID_COL_VOTES,Qt::DecorationRole,
|
||||
static_cast<uint32_t>(idd.mReputation.mOverallReputationLevel));
|
||||
@ -1404,14 +1422,15 @@ bool IdDialog::fillIdListItem(const RsGxsIdGroup& data, QTreeWidgetItem *&item,
|
||||
|
||||
QString tooltip = tr("This identity is owned by you");
|
||||
|
||||
if(idd.mFlags & RS_IDENTITY_FLAGS_IS_DEPRECATED)
|
||||
{
|
||||
item->setForeground(RSID_COL_NICKNAME,QBrush(Qt::red));
|
||||
item->setForeground(RSID_COL_KEYID,QBrush(Qt::red));
|
||||
item->setForeground(RSID_COL_IDTYPE,QBrush(Qt::red));
|
||||
if(idd.mFlags & RS_IDENTITY_FLAGS_IS_DEPRECATED)
|
||||
{
|
||||
//TODO (Phenom): Add qproperty for these text colors in stylesheets
|
||||
item->setData(RSID_COL_NICKNAME, Qt::ForegroundRole, QColor(Qt::red));
|
||||
item->setData(RSID_COL_KEYID , Qt::ForegroundRole, QColor(Qt::red));
|
||||
item->setData(RSID_COL_IDTYPE , Qt::ForegroundRole, QColor(Qt::red));
|
||||
|
||||
tooltip += tr("\nThis identity has a unsecure fingerprint (It's probably quite old).\nYou should get rid of it now and use a new one.\nThese identities will soon be not supported anymore.") ;
|
||||
}
|
||||
tooltip += tr("\nThis identity has a unsecure fingerprint (It's probably quite old).\nYou should get rid of it now and use a new one.\nThese identities will soon be not supported anymore.") ;
|
||||
}
|
||||
|
||||
item->setToolTip(RSID_COL_NICKNAME, tooltip) ;
|
||||
item->setToolTip(RSID_COL_KEYID, tooltip) ;
|
||||
@ -2450,3 +2469,53 @@ void IdDialog::on_closeInfoFrameButton_clicked()
|
||||
{
|
||||
ui->inviteFrame->setVisible(false);
|
||||
}
|
||||
|
||||
// We need to use indexes here because saving items is not possible since they can be re-created.
|
||||
|
||||
void IdDialog::saveExpandedCircleItems(std::vector<bool>& expanded_root_items, std::set<RsGxsCircleId>& expanded_circle_items) const
|
||||
{
|
||||
expanded_root_items.clear();
|
||||
expanded_root_items.resize(3,false);
|
||||
expanded_circle_items.clear();
|
||||
|
||||
auto saveTopLevel = [&](const QTreeWidgetItem* top_level_item,uint32_t index){
|
||||
if(!top_level_item)
|
||||
return;
|
||||
|
||||
if(top_level_item->isExpanded())
|
||||
{
|
||||
expanded_root_items[index] = true;
|
||||
|
||||
for(int row=0;row<top_level_item->childCount();++row)
|
||||
if(top_level_item->child(row)->isExpanded())
|
||||
expanded_circle_items.insert(RsGxsCircleId(top_level_item->child(row)->data(CIRCLEGROUP_CIRCLE_COL_GROUPID,Qt::UserRole).toString().toStdString()));
|
||||
}
|
||||
};
|
||||
|
||||
saveTopLevel(mExternalBelongingCircleItem,0);
|
||||
saveTopLevel(mExternalOtherCircleItem,1);
|
||||
saveTopLevel(mMyCircleItem,2);
|
||||
}
|
||||
|
||||
void IdDialog::restoreExpandedCircleItems(const std::vector<bool>& expanded_root_items,const std::set<RsGxsCircleId>& expanded_circle_items)
|
||||
{
|
||||
auto restoreTopLevel = [=](QTreeWidgetItem* top_level_item,uint32_t index){
|
||||
if(!top_level_item)
|
||||
return;
|
||||
|
||||
top_level_item->setExpanded(expanded_root_items[index]);
|
||||
|
||||
for(int row=0;row<top_level_item->childCount();++row)
|
||||
{
|
||||
RsGxsCircleId circle_id(RsGxsCircleId(top_level_item->child(row)->data(CIRCLEGROUP_CIRCLE_COL_GROUPID,Qt::UserRole).toString().toStdString()));
|
||||
bool expanded = expanded_circle_items.find(circle_id) != expanded_circle_items.end();
|
||||
|
||||
top_level_item->child(row)->setExpanded(expanded_circle_items.find(circle_id) != expanded_circle_items.end());
|
||||
}
|
||||
};
|
||||
|
||||
restoreTopLevel(mExternalBelongingCircleItem,0);
|
||||
restoreTopLevel(mExternalOtherCircleItem,1);
|
||||
restoreTopLevel(mMyCircleItem,2);
|
||||
}
|
||||
|
||||
|
@ -145,6 +145,9 @@ private:
|
||||
QTreeWidgetItem *mMyCircleItem;
|
||||
RsGxsUpdateBroadcastBase *mCirclesBroadcastBase ;
|
||||
|
||||
void saveExpandedCircleItems(std::vector<bool> &expanded_root_items, std::set<RsGxsCircleId>& expanded_circle_items) const;
|
||||
void restoreExpandedCircleItems(const std::vector<bool>& expanded_root_items,const std::set<RsGxsCircleId>& expanded_circle_items);
|
||||
|
||||
std::map<uint32_t, CircleUpdateOrder> mCircleUpdates ;
|
||||
|
||||
RsGxsGroupId mId;
|
||||
|
@ -120,7 +120,7 @@
|
||||
<enum>Qt::NoFocus</enum>
|
||||
</property>
|
||||
<property name="icon">
|
||||
<iconset resource="../images.qrc">
|
||||
<iconset resource="../icons.qrc">
|
||||
<normaloff>:/icons/help_64.png</normaloff>:/icons/help_64.png</iconset>
|
||||
</property>
|
||||
<property name="checkable">
|
||||
@ -268,7 +268,7 @@
|
||||
</widget>
|
||||
<widget class="QTabWidget" name="rightTabWidget">
|
||||
<property name="currentIndex">
|
||||
<number>0</number>
|
||||
<number>1</number>
|
||||
</property>
|
||||
<widget class="QWidget" name="personTab">
|
||||
<attribute name="icon">
|
||||
@ -289,8 +289,8 @@
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>634</width>
|
||||
<height>523</height>
|
||||
<width>1372</width>
|
||||
<height>719</height>
|
||||
</rect>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="scrollAreaWidgetContentsVLayout">
|
||||
@ -1052,7 +1052,7 @@ border-image: url(:/images/closepressed.png)
|
||||
</action>
|
||||
<action name="chatIdentity">
|
||||
<property name="icon">
|
||||
<iconset resource="../images.qrc">
|
||||
<iconset>
|
||||
<normaloff>:/images/toaster/chat.png</normaloff>:/images/toaster/chat.png</iconset>
|
||||
</property>
|
||||
<property name="text">
|
||||
@ -1094,8 +1094,8 @@ border-image: url(:/images/closepressed.png)
|
||||
<tabstop>idTreeWidget</tabstop>
|
||||
</tabstops>
|
||||
<resources>
|
||||
<include location="../images.qrc"/>
|
||||
<include location="../icons.qrc"/>
|
||||
<include location="../images.qrc"/>
|
||||
</resources>
|
||||
<connections/>
|
||||
</ui>
|
||||
|
@ -486,7 +486,7 @@ void MainWindow::initStackedPage()
|
||||
for (notifyIt = notify.begin(); notifyIt != notify.end(); ++notifyIt) {
|
||||
UserNotify *userNotify = notifyIt->first->getUserNotify();
|
||||
if (userNotify) {
|
||||
userNotify->initialize(ui->toolBarPage, notifyIt->second.first, notifyIt->second.second);
|
||||
userNotify->initialize(ui->toolBarPage, notifyIt->second.first, notifyIt->second.second,userNotify->textInfo());
|
||||
connect(userNotify, SIGNAL(countChanged()), this, SLOT(updateTrayCombine()));
|
||||
userNotifyList.push_back(userNotify);
|
||||
}
|
||||
|
@ -251,14 +251,20 @@ void NewsFeed::handleForumEvent(std::shared_ptr<const RsEvent> event)
|
||||
|
||||
switch(pe->mForumEventCode)
|
||||
{
|
||||
case RsForumEventCode::MODERATOR_LIST_CHANGED:
|
||||
addFeedItem(new GxsForumGroupItem(this, NEWSFEED_UPDATED_FORUM, pe->mForumGroupId,pe->mModeratorsAdded,pe->mModeratorsRemoved, false, true));
|
||||
break;
|
||||
|
||||
case RsForumEventCode::UPDATED_FORUM:
|
||||
case RsForumEventCode::NEW_FORUM:
|
||||
addFeedItem(new GxsForumGroupItem(this, NEWSFEED_FORUMNEWLIST, pe->mForumGroupId, false, true));
|
||||
addFeedItem(new GxsForumGroupItem(this, NEWSFEED_NEW_FORUM, pe->mForumGroupId, false, true));
|
||||
break;
|
||||
|
||||
case RsForumEventCode::UPDATED_MESSAGE:
|
||||
case RsForumEventCode::NEW_MESSAGE:
|
||||
addFeedItem(new GxsForumMsgItem(this, NEWSFEED_FORUMNEWLIST, pe->mForumGroupId, pe->mForumMsgId, false, true));
|
||||
addFeedItem(new GxsForumMsgItem(this, NEWSFEED_NEW_FORUM, pe->mForumGroupId, pe->mForumMsgId, false, true));
|
||||
break;
|
||||
|
||||
default: break;
|
||||
}
|
||||
}
|
||||
@ -288,47 +294,120 @@ void NewsFeed::handleChannelEvent(std::shared_ptr<const RsEvent> event)
|
||||
|
||||
void NewsFeed::handleCircleEvent(std::shared_ptr<const RsEvent> event)
|
||||
{
|
||||
const RsGxsCircleEvent *pe = dynamic_cast<const RsGxsCircleEvent*>(event.get());
|
||||
if(!pe)
|
||||
return;
|
||||
// Gives the backend a few secs to load the cache data while not blocking the UI. This is not so nice, but there's no proper
|
||||
// other way to do that.
|
||||
|
||||
RsGxsCircleDetails details;
|
||||
|
||||
if(pe->mCircleId.isNull()) // probably an item for cache update
|
||||
return ;
|
||||
|
||||
if(!rsGxsCircles->getCircleDetails(pe->mCircleId,details))
|
||||
RsThread::async( [event,this]()
|
||||
{
|
||||
std::cerr << "(EE) Cannot get information about circle " << pe->mCircleId << ". Not in cache?" << std::endl;
|
||||
return;
|
||||
}
|
||||
const RsGxsCircleEvent *pe = dynamic_cast<const RsGxsCircleEvent*>(event.get());
|
||||
if(!pe)
|
||||
return;
|
||||
|
||||
// Check if the circle is one of which we belong to. If so, then notify in the GUI about other members leaving/subscribing
|
||||
if(pe->mCircleId.isNull()) // probably an item for cache update
|
||||
return ;
|
||||
|
||||
if(details.mAmIAllowed || details.mAmIAdmin)
|
||||
RsGxsCircleDetails details;
|
||||
bool loaded = false;
|
||||
|
||||
for(int i=0;i<5 && !loaded;++i)
|
||||
if(rsGxsCircles->getCircleDetails(pe->mCircleId,details))
|
||||
{
|
||||
std::cerr << "Cache item loaded for circle " << pe->mCircleId << std::endl;
|
||||
loaded = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
std::cerr << "Cache item for circle " << pe->mCircleId << " not loaded. Waiting " << i << "s" << std::endl;
|
||||
rstime::rs_usleep(1000*1000);
|
||||
}
|
||||
|
||||
if(!loaded)
|
||||
{
|
||||
std::cerr << "(EE) Cannot get information about circle " << pe->mCircleId << ". Not in cache?" << std::endl;
|
||||
return;
|
||||
}
|
||||
|
||||
if(!details.isGxsIdBased()) // not handled yet.
|
||||
return;
|
||||
|
||||
// Check if the circle is one of which we belong to or we are an admin of.
|
||||
// If so, then notify in the GUI about other members leaving/subscribing, according
|
||||
// to the following rules. The names correspond to the RS_FEED_CIRCLE_* variables:
|
||||
//
|
||||
// Message-based notifications:
|
||||
//
|
||||
// +---------------------------+----------------------------+
|
||||
// | Membership request | Membership cancellation |
|
||||
// +-------------+-------------+-------------+--------------+
|
||||
// | Admin | Not admin | Admin | Not admin |
|
||||
// +--------------------+-------------+-------------+----------------------------+
|
||||
// | in invitee list | MEMB_JOIN | MEMB_JOIN | MEMB_LEAVE | MEMB_LEAVE |
|
||||
// +--------------------+-------------+-------------+-------------+--------------+
|
||||
// |not in invitee list | MEMB_REQ | X | X | X |
|
||||
// +--------------------+-------------+-------------+-------------+--------------+
|
||||
//
|
||||
// Note: in this case, the GxsId never belongs to you, since you dont need to handle
|
||||
// notifications for actions you took yourself (leave/join a circle)
|
||||
//
|
||||
// GroupData-based notifications, the GxsId belongs to you:
|
||||
//
|
||||
// +---------------------------+----------------------------+
|
||||
// | GxsId joins invitee list | GxsId leaves invitee list |
|
||||
// +-------------+-------------+-------------+--------------+
|
||||
// | Id is yours| Id is not | Id is yours | Id is not |
|
||||
// +--------------------+-------------+-------------+-------------+--------------+
|
||||
// | Has Member request | MEMB_ACCEPT | (MEMB_JOIN) | MEMB_REVOKED| (MEMB_LEAVE) |
|
||||
// +--------------------+-------------+-------------+-------------+--------------+
|
||||
// | No Member request | INVITE_REC | X | INVITE_REM | X |
|
||||
// +--------------------+-------------+-------------+-------------+--------------+
|
||||
//
|
||||
// Note: In this case you're never an admin of the circle, since these notification
|
||||
// would be a direct consequence of your own actions.
|
||||
|
||||
RsQThreadUtils::postToObject( [event,details,this]()
|
||||
{
|
||||
const RsGxsCircleEvent *pe = static_cast<const RsGxsCircleEvent*>(event.get());
|
||||
|
||||
switch(pe->mCircleEventType)
|
||||
{
|
||||
case RsGxsCircleEventCode::CIRCLE_MEMBERSHIP_REQUEST:
|
||||
// only show membership requests if we're an admin of that circle
|
||||
if(details.mAmIAdmin)
|
||||
if(details.isIdInInviteeList(pe->mGxsId))
|
||||
addFeedItemIfUnique(new GxsCircleItem(this, NEWSFEED_CIRCLELIST, pe->mCircleId, pe->mGxsId, RS_FEED_ITEM_CIRCLE_MEMB_JOIN),true);
|
||||
else if(details.mAmIAdmin)
|
||||
addFeedItemIfUnique(new GxsCircleItem(this, NEWSFEED_CIRCLELIST, pe->mCircleId, pe->mGxsId, RS_FEED_ITEM_CIRCLE_MEMB_REQ),true);
|
||||
|
||||
break;
|
||||
case RsGxsCircleEventCode::CIRCLE_MEMBERSHIP_JOIN:
|
||||
addFeedItemIfUnique(new GxsCircleItem(this, NEWSFEED_CIRCLELIST, pe->mCircleId, pe->mGxsId, RS_FEED_ITEM_CIRCLE_MEMB_JOIN),true);
|
||||
break;
|
||||
|
||||
case RsGxsCircleEventCode::CIRCLE_MEMBERSHIP_LEAVE:
|
||||
addFeedItemIfUnique(new GxsCircleItem(this, NEWSFEED_CIRCLELIST, pe->mCircleId, pe->mGxsId, RS_FEED_ITEM_CIRCLE_MEMB_LEAVE),true);
|
||||
|
||||
if(details.isIdInInviteeList(pe->mGxsId))
|
||||
addFeedItemIfUnique(new GxsCircleItem(this, NEWSFEED_CIRCLELIST, pe->mCircleId, pe->mGxsId, RS_FEED_ITEM_CIRCLE_MEMB_LEAVE),true);
|
||||
break;
|
||||
case RsGxsCircleEventCode::CIRCLE_MEMBERSHIP_INVITE:
|
||||
addFeedItemIfUnique(new GxsCircleItem(this, NEWSFEED_CIRCLELIST, pe->mCircleId, pe->mGxsId, RS_FEED_ITEM_CIRCLE_INVIT_REC),true);
|
||||
|
||||
case RsGxsCircleEventCode::CIRCLE_MEMBERSHIP_ID_ADDED_TO_INVITEE_LIST:
|
||||
if(rsIdentity->isOwnId(pe->mGxsId))
|
||||
{
|
||||
if(details.isIdRequestingMembership(pe->mGxsId))
|
||||
addFeedItemIfUnique(new GxsCircleItem(this, NEWSFEED_CIRCLELIST, pe->mCircleId, pe->mGxsId, RS_FEED_ITEM_CIRCLE_MEMB_ACCEPTED),true);
|
||||
else
|
||||
addFeedItemIfUnique(new GxsCircleItem(this, NEWSFEED_CIRCLELIST, pe->mCircleId, pe->mGxsId, RS_FEED_ITEM_CIRCLE_INVITE_REC),true);
|
||||
}
|
||||
break;
|
||||
case RsGxsCircleEventCode::CIRCLE_MEMBERSHIP_REVOQUED:
|
||||
addFeedItemIfUnique(new GxsCircleItem(this, NEWSFEED_CIRCLELIST, pe->mCircleId, pe->mGxsId, RS_FEED_ITEM_CIRCLE_MEMB_REVOQUED),true);
|
||||
|
||||
case RsGxsCircleEventCode::CIRCLE_MEMBERSHIP_ID_REMOVED_FROM_INVITEE_LIST:
|
||||
if(rsIdentity->isOwnId(pe->mGxsId))
|
||||
{
|
||||
if(details.isIdRequestingMembership(pe->mGxsId))
|
||||
addFeedItemIfUnique(new GxsCircleItem(this, NEWSFEED_CIRCLELIST, pe->mCircleId, pe->mGxsId, RS_FEED_ITEM_CIRCLE_MEMB_REVOKED),true);
|
||||
else
|
||||
addFeedItemIfUnique(new GxsCircleItem(this, NEWSFEED_CIRCLELIST, pe->mCircleId, pe->mGxsId, RS_FEED_ITEM_CIRCLE_INVITE_CANCELLED),true);
|
||||
}
|
||||
break;
|
||||
|
||||
default: break;
|
||||
}
|
||||
}
|
||||
}, this ); }); // damn!
|
||||
}
|
||||
|
||||
void NewsFeed::handleConnectionEvent(std::shared_ptr<const RsEvent> event)
|
||||
|
@ -31,8 +31,10 @@
|
||||
|
||||
const uint32_t NEWSFEED_PEERLIST = 0x0001;
|
||||
|
||||
const uint32_t NEWSFEED_FORUMNEWLIST = 0x0002;
|
||||
const uint32_t NEWSFEED_FORUMMSGLIST = 0x0003;
|
||||
const uint32_t NEWSFEED_NEW_FORUM = 0x0002;
|
||||
const uint32_t NEWSFEED_NEW_FORUM_MSG = 0x0003;
|
||||
const uint32_t NEWSFEED_UPDATED_FORUM = 0x000f;
|
||||
|
||||
const uint32_t NEWSFEED_CHANNELNEWLIST = 0x0004;
|
||||
//const uint32_t NEWSFEED_CHANNELMSGLIST = 0x0005;
|
||||
#if 0
|
||||
|
@ -271,25 +271,29 @@ void PeopleDialog::insertCircles(uint32_t token)
|
||||
std::list<RsGroupMetaData> gSummaryList;
|
||||
std::list<RsGroupMetaData>::iterator gsIt;
|
||||
|
||||
if (!rsGxsCircles->getGroupSummary(token,gSummaryList)) {
|
||||
if (!rsGxsCircles->getGroupSummary(token,gSummaryList))
|
||||
{
|
||||
std::cerr << "PeopleDialog::insertExtCircles() Error getting GroupSummary";
|
||||
std::cerr << std::endl;
|
||||
|
||||
return;
|
||||
}//if (!rsGxsCircles->getGroupSummary(token,gSummaryList))
|
||||
}
|
||||
|
||||
for(gsIt = gSummaryList.begin(); gsIt != gSummaryList.end(); ++gsIt) {
|
||||
RsGroupMetaData gsItem = (*gsIt);
|
||||
|
||||
RsGxsCircleDetails details ;
|
||||
if(!rsGxsCircles->getCircleDetails(RsGxsCircleId(gsItem.mGroupId), details)){
|
||||
if(!rsGxsCircles->getCircleDetails(RsGxsCircleId(gsItem.mGroupId), details))
|
||||
{
|
||||
std::cerr << "(EE) Cannot get details for circle id " << gsItem.mGroupId << ". Circle item is not created!" << std::endl;
|
||||
continue ;
|
||||
}//if(!rsGxsCircles->getCircleDetails(RsGxsCircleId(git->mGroupId), details))
|
||||
}
|
||||
|
||||
if (details.mCircleType != GXS_CIRCLE_TYPE_EXTERNAL){
|
||||
if (details.mCircleType != RsGxsCircleType::EXTERNAL)
|
||||
{
|
||||
std::map<RsGxsGroupId, CircleWidget*>::iterator itFound;
|
||||
if((itFound=_int_circles_widgets.find(gsItem.mGroupId)) == _int_circles_widgets.end()) {
|
||||
if((itFound=_int_circles_widgets.find(gsItem.mGroupId)) == _int_circles_widgets.end())
|
||||
{
|
||||
std::cerr << "PeopleDialog::insertExtCircles() add new Internal GroupId: " << gsItem.mGroupId;
|
||||
std::cerr << " GroupName: " << gsItem.mGroupName;
|
||||
std::cerr << std::endl;
|
||||
@ -307,7 +311,9 @@ void PeopleDialog::insertCircles(uint32_t token)
|
||||
QPixmap pixmap = gitem->getImage();
|
||||
pictureFlowWidgetInternal->addSlide( pixmap );
|
||||
_intListCir << gitem;
|
||||
} else {//if((itFound=_int_circles_widgets.find(gsItem.mGroupId)) == _int_circles_widgets.end())
|
||||
}
|
||||
else
|
||||
{
|
||||
std::cerr << "PeopleDialog::insertExtCircles() Update GroupId: " << gsItem.mGroupId;
|
||||
std::cerr << " GroupName: " << gsItem.mGroupName;
|
||||
std::cerr << std::endl;
|
||||
@ -318,8 +324,10 @@ void PeopleDialog::insertCircles(uint32_t token)
|
||||
//int index = _intListCir.indexOf(cirWidget);
|
||||
//QPixmap pixmap = cirWidget->getImage();
|
||||
//pictureFlowWidgetInternal->setSlide(index, pixmap);
|
||||
}//if((item=_int_circles_widgets.find(gsItem.mGroupId)) == _int_circles_widgets.end())
|
||||
} else {//if (!details.mIsExternal)
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
std::map<RsGxsGroupId, CircleWidget*>::iterator itFound;
|
||||
if((itFound=_ext_circles_widgets.find(gsItem.mGroupId)) == _ext_circles_widgets.end()) {
|
||||
std::cerr << "PeopleDialog::insertExtCircles() add new GroupId: " << gsItem.mGroupId;
|
||||
@ -339,7 +347,9 @@ void PeopleDialog::insertCircles(uint32_t token)
|
||||
QPixmap pixmap = gitem->getImage();
|
||||
pictureFlowWidgetExternal->addSlide( pixmap );
|
||||
_extListCir << gitem;
|
||||
} else {//if((itFound=_circles_widgets.find(gsItem.mGroupId)) == _circles_widgets.end())
|
||||
}
|
||||
else
|
||||
{
|
||||
std::cerr << "PeopleDialog::insertExtCircles() Update GroupId: " << gsItem.mGroupId;
|
||||
std::cerr << " GroupName: " << gsItem.mGroupName;
|
||||
std::cerr << std::endl;
|
||||
@ -350,9 +360,9 @@ void PeopleDialog::insertCircles(uint32_t token)
|
||||
//int index = _extListCir.indexOf(cirWidget);
|
||||
//QPixmap pixmap = cirWidget->getImage();
|
||||
//pictureFlowWidgetExternal->setSlide(index, pixmap);
|
||||
}//if((item=_circles_items.find(gsItem.mGroupId)) == _circles_items.end())
|
||||
}//else (!details.mIsExternal)
|
||||
}//for(gsIt = gSummaryList.begin(); gsIt != gSummaryList.end(); ++gsIt)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void PeopleDialog::requestIdList()
|
||||
|
@ -167,8 +167,9 @@ void BasePostedItem::loadMessage()
|
||||
|
||||
std::vector<RsPostedPost> posts;
|
||||
std::vector<RsGxsComment> comments;
|
||||
std::vector<RsGxsVote> votes;
|
||||
|
||||
if(! rsPosted->getBoardContent( groupId(), std::set<RsGxsMessageId>( { messageId() } ),posts,comments))
|
||||
if(! rsPosted->getBoardContent( groupId(), std::set<RsGxsMessageId>( { messageId() } ),posts,comments,votes))
|
||||
{
|
||||
RsErr() << "BasePostedItem::loadMessage() ERROR getting data" << std::endl;
|
||||
mIsLoadingMessage = false;
|
||||
@ -227,8 +228,9 @@ void BasePostedItem::loadComment()
|
||||
|
||||
std::vector<RsPostedPost> posts;
|
||||
std::vector<RsGxsComment> comments;
|
||||
std::vector<RsGxsVote> votes;
|
||||
|
||||
if(! rsPosted->getBoardContent( groupId(),msgIds,posts,comments))
|
||||
if(! rsPosted->getBoardContent( groupId(),msgIds,posts,comments,votes))
|
||||
{
|
||||
RsErr() << "BasePostedItem::loadGroup() ERROR getting data" << std::endl;
|
||||
mIsLoadingComment = false;
|
||||
|
@ -106,14 +106,16 @@ public:
|
||||
protected:
|
||||
void setup() override;
|
||||
void fill() override;
|
||||
void doExpand(bool open) override;
|
||||
void setComment(const RsGxsComment&) override;
|
||||
void setReadStatus(bool isNew, bool isUnread) override;
|
||||
void toggle() override ;
|
||||
void setCommentsSize(int comNb) override;
|
||||
void makeUpVote() override;
|
||||
void makeDownVote() override;
|
||||
void toggleNotes() override;
|
||||
|
||||
private slots:
|
||||
void doExpand(bool open);
|
||||
void toggle();
|
||||
void makeUpVote();
|
||||
void makeDownVote();
|
||||
void toggleNotes() ;
|
||||
|
||||
private:
|
||||
/** Qt Designer generated object */
|
||||
|
@ -1033,8 +1033,9 @@ void PostedListWidget::getMsgData(const std::set<RsGxsMessageId>& msgIds,std::ve
|
||||
{
|
||||
std::vector<RsPostedPost> posts;
|
||||
std::vector<RsGxsComment> comments;
|
||||
std::vector<RsGxsVote> votes;
|
||||
|
||||
rsPosted->getBoardContent( groupId(),msgIds,posts,comments );
|
||||
rsPosted->getBoardContent( groupId(),msgIds,posts,comments,votes );
|
||||
|
||||
psts.clear();
|
||||
|
||||
@ -1046,8 +1047,9 @@ void PostedListWidget::getAllMsgData(std::vector<RsGxsGenericMsgData*>& psts)
|
||||
{
|
||||
std::vector<RsPostedPost> posts;
|
||||
std::vector<RsGxsComment> comments;
|
||||
std::vector<RsGxsVote> votes;
|
||||
|
||||
rsPosted->getBoardAllContent( groupId(),posts,comments );
|
||||
rsPosted->getBoardAllContent( groupId(),posts,comments,votes );
|
||||
|
||||
psts.clear();
|
||||
|
||||
|
@ -21,6 +21,7 @@
|
||||
#include "retroshare/rsposted.h"
|
||||
#include "PostedUserNotify.h"
|
||||
#include "gui/MainWindow.h"
|
||||
#include "gui/common/FilesDefs.h"
|
||||
|
||||
PostedUserNotify::PostedUserNotify(RsGxsIfaceHelper *ifaceImpl, const GxsGroupFrameDialog *g, QObject *parent) :
|
||||
GxsUserNotify(ifaceImpl, g, parent)
|
||||
@ -37,12 +38,12 @@ bool PostedUserNotify::hasSetting(QString *name, QString *group)
|
||||
|
||||
QIcon PostedUserNotify::getIcon()
|
||||
{
|
||||
return QIcon(":/icons/png/posted.png");
|
||||
return FilesDefs::getIconFromQtResourcePath(":/icons/png/posted.png");
|
||||
}
|
||||
|
||||
QIcon PostedUserNotify::getMainIcon(bool hasNew)
|
||||
{
|
||||
return hasNew ? QIcon(":/icons/png/posted-notify.png") : QIcon(":/icons/png/posted.png");
|
||||
return hasNew ? FilesDefs::getIconFromQtResourcePath(":/icons/png/posted-notify.png") : FilesDefs::getIconFromQtResourcePath(":/icons/png/posted.png");
|
||||
}
|
||||
|
||||
void PostedUserNotify::iconClicked()
|
||||
|
@ -31,6 +31,7 @@ public:
|
||||
PostedUserNotify(RsGxsIfaceHelper *ifaceImpl, const GxsGroupFrameDialog *g, QObject *parent = 0);
|
||||
|
||||
virtual bool hasSetting(QString *name, QString *group);
|
||||
virtual QString textInfo() const override { return tr("new board post(s)"); }
|
||||
|
||||
private:
|
||||
virtual QIcon getIcon();
|
||||
|
@ -335,12 +335,13 @@ QString RetroshareDirModel::getAgeIndicatorString(const DirDetails &details) con
|
||||
const QIcon& RetroshareDirModel::getFlagsIcon(FileStorageFlags flags)
|
||||
{
|
||||
static QIcon *static_icons[8] = {NULL};
|
||||
if(static_icons[0] == NULL)
|
||||
static_icons[0] = new QIcon();
|
||||
|
||||
int n=0;
|
||||
if(flags & DIR_FLAGS_ANONYMOUS_DOWNLOAD) n += 1 ;
|
||||
if(flags & DIR_FLAGS_ANONYMOUS_SEARCH ) n += 2 ;
|
||||
if(flags & DIR_FLAGS_BROWSABLE ) n += 4 ;
|
||||
n-= 1;
|
||||
|
||||
if(static_icons[n] == NULL)
|
||||
{
|
||||
|
@ -250,21 +250,23 @@ void ShareManager::load()
|
||||
|
||||
listWidget->item(row,COLUMN_GROUPS)->setText(getGroupString(mDirInfos[row].parent_groups));
|
||||
|
||||
QFont font = listWidget->item(row,COLUMN_GROUPS)->font();
|
||||
font.setBold(mDirInfos[row].shareflags & DIR_FLAGS_BROWSABLE) ;
|
||||
listWidget->item(row,COLUMN_GROUPS)->setTextColor( (mDirInfos[row].shareflags & DIR_FLAGS_BROWSABLE)? (Qt::black):(Qt::lightGray)) ;
|
||||
listWidget->item(row,COLUMN_GROUPS)->setFont(font);
|
||||
//TODO (Phenom): Add qproperty for these text colors in stylesheets
|
||||
// As palette is not updated by stylesheet
|
||||
QFont font = listWidget->item(row,COLUMN_GROUPS)->font();
|
||||
font.setBold(mDirInfos[row].shareflags & DIR_FLAGS_BROWSABLE) ;
|
||||
listWidget->item(row,COLUMN_GROUPS)->setData(Qt::ForegroundRole, QColor((mDirInfos[row].shareflags & DIR_FLAGS_BROWSABLE) ? (Qt::black):(Qt::lightGray)) );
|
||||
listWidget->item(row,COLUMN_GROUPS)->setFont(font);
|
||||
|
||||
if(QDir(QString::fromUtf8(mDirInfos[row].filename.c_str())).exists())
|
||||
{
|
||||
listWidget->item(row,COLUMN_PATH)->setTextColor(Qt::black);
|
||||
if(QDir(QString::fromUtf8(mDirInfos[row].filename.c_str())).exists())
|
||||
{
|
||||
listWidget->item(row,COLUMN_PATH)->setData(Qt::ForegroundRole, QColor(Qt::black));
|
||||
listWidget->item(row,COLUMN_PATH)->setToolTip(tr("Double click to change shared directory path")) ;
|
||||
}
|
||||
else
|
||||
{
|
||||
listWidget->item(row,COLUMN_PATH)->setTextColor(Qt::lightGray);
|
||||
}
|
||||
else
|
||||
{
|
||||
listWidget->item(row,COLUMN_PATH)->setData(Qt::ForegroundRole, QColor(Qt::lightGray));
|
||||
listWidget->item(row,COLUMN_PATH)->setToolTip(tr("Directory does not exist! Double click to change shared directory path")) ;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
listWidget->setColumnWidth(COLUMN_SHARE_FLAGS,132 * QFontMetricsF(font()).height()/14.0) ;
|
||||
|
@ -59,12 +59,14 @@
|
||||
#define ROLE_SORT Qt::UserRole + 1
|
||||
|
||||
const static uint32_t timeToInactivity = 60 * 10; // in seconds
|
||||
const static uint32_t timeToInactivity2 = 60 * 5; // in seconds
|
||||
|
||||
/** Default constructor */
|
||||
ChatLobbyDialog::ChatLobbyDialog(const ChatLobbyId& lid, QWidget *parent, Qt::WindowFlags flags)
|
||||
: ChatDialog(parent, flags), lobbyId(lid), mWindowedSetted(false), mPCWindow(nullptr),
|
||||
bullet_red_128(":/icons/bullet_red_128.png"), bullet_grey_128(":/icons/bullet_grey_128.png"),
|
||||
bullet_green_128(":/icons/bullet_green_128.png"), bullet_yellow_128(":/icons/bullet_yellow_128.png")
|
||||
bullet_green_128(":/icons/bullet_green_128.png"), bullet_yellow_128(":/icons/bullet_yellow_128.png"),
|
||||
bullet_blue_128(":/icons/bullet_blue_128.png")
|
||||
{
|
||||
/* Invoke Qt Designer generated QObject setup routine */
|
||||
ui.setupUi(this);
|
||||
@ -614,10 +616,12 @@ void ChatLobbyDialog::updateParticipantsList()
|
||||
else
|
||||
widgetitem = dynamic_cast<GxsIdRSTreeWidgetItem*>(qlFoundParticipants.at(0));
|
||||
|
||||
//TODO (Phenom): Add qproperty for these text colors in stylesheets
|
||||
// As palette is not updated by stylesheet
|
||||
if (isParticipantMuted(it2->first)) {
|
||||
widgetitem->setTextColor(COLUMN_NAME,QColor(255,0,0));
|
||||
widgetitem->setData(COLUMN_NAME, Qt::ForegroundRole, QColor(255,0,0));
|
||||
} else {
|
||||
widgetitem->setTextColor(COLUMN_NAME,ui.participantsList->palette().color(QPalette::Active, QPalette::Text));
|
||||
widgetitem->setData(COLUMN_NAME, Qt::ForegroundRole, QVariant());
|
||||
}
|
||||
|
||||
time_t tLastAct=widgetitem->text(COLUMN_ACTIVITY).toInt();
|
||||
@ -630,13 +634,15 @@ void ChatLobbyDialog::updateParticipantsList()
|
||||
widgetitem->setIcon(COLUMN_ICON, bullet_red_128);
|
||||
else if (tLastAct + timeToInactivity < now)
|
||||
widgetitem->setIcon(COLUMN_ICON, bullet_grey_128);
|
||||
else if (tLastAct + timeToInactivity2 < now)
|
||||
widgetitem->setIcon(COLUMN_ICON, bullet_yellow_128);
|
||||
else
|
||||
widgetitem->setIcon(COLUMN_ICON, bullet_green_128);
|
||||
|
||||
RsGxsId gxs_id;
|
||||
rsMsgs->getIdentityForChatLobby(lobbyId, gxs_id);
|
||||
|
||||
if (RsGxsId(participant.toStdString()) == gxs_id) widgetitem->setIcon(COLUMN_ICON, bullet_yellow_128);
|
||||
if (RsGxsId(participant.toStdString()) == gxs_id) widgetitem->setIcon(COLUMN_ICON, bullet_blue_128);
|
||||
|
||||
widgetitem->updateBannedState();
|
||||
|
||||
|
@ -134,7 +134,7 @@ private:
|
||||
|
||||
GxsIdChooser *ownIdChooser ;
|
||||
//icons cache
|
||||
QIcon bullet_red_128, bullet_grey_128, bullet_green_128, bullet_yellow_128;
|
||||
QIcon bullet_red_128, bullet_grey_128, bullet_green_128, bullet_yellow_128, bullet_blue_128;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
@ -63,6 +63,7 @@ public:
|
||||
QString textToNotify() { return _textToNotify.join("\n");}
|
||||
void setTextCaseSensitive(bool value);
|
||||
bool isTextCaseSensitive() {return _bTextCaseSensitive;}
|
||||
virtual QString textInfo() const override { return tr("mention(s)"); }
|
||||
|
||||
signals:
|
||||
void countChanged(ChatLobbyId id, unsigned int count);
|
||||
|
@ -41,6 +41,7 @@ public:
|
||||
~ChatUserNotify();
|
||||
|
||||
virtual bool hasSetting(QString *name, QString *group);
|
||||
virtual QString textInfo() const override { return tr("mention(s)"); }
|
||||
|
||||
private slots:
|
||||
void chatMessageReceived(ChatMessage msg);
|
||||
|
@ -239,7 +239,10 @@ bool ElidedLabel::paintElidedLine( QPainter* painter, QString plainText
|
||||
*rectElision = mRectElision;
|
||||
|
||||
if(drawRoundedRect)
|
||||
if (painter) painter->drawRoundedRect(mRectElision, 2 , 2);
|
||||
if (painter) {
|
||||
painter->setBrush(QBrush(Qt::transparent));
|
||||
painter->drawRoundedRect(mRectElision, 2 , 2);
|
||||
}
|
||||
}
|
||||
|
||||
if (painter) painter->restore();
|
||||
|
@ -717,7 +717,7 @@ void FriendList::insertPeers()
|
||||
groupItem->setChildIndicatorPolicy(QTreeWidgetItem::DontShowIndicatorWhenChildless);
|
||||
groupItem->setTextAlignment(COLUMN_NAME, Qt::AlignLeft | Qt::AlignVCenter);
|
||||
groupItem->setIcon(COLUMN_NAME, QIcon(IMAGE_GROUP24));
|
||||
groupItem->setForeground(COLUMN_NAME, QBrush(textColorGroup()));
|
||||
groupItem->setData(COLUMN_NAME, Qt::ForegroundRole, textColorGroup());
|
||||
|
||||
/* used to find back the item */
|
||||
QString strID = QString::fromStdString(groupInfo->id.toStdString());
|
||||
@ -1110,8 +1110,8 @@ void FriendList::insertPeers()
|
||||
for (int i = 0; i < columnCount; ++i) {
|
||||
sslItem->setData(i, ROLE_SORT_STATE, peerState);
|
||||
|
||||
sslItem->setTextColor(i, sslColor);
|
||||
sslItem->setFont(i, sslFont);
|
||||
sslItem->setData(i, Qt::ForegroundRole, sslColor);
|
||||
sslItem->setData(i, Qt::FontRole, sslFont);
|
||||
}
|
||||
}
|
||||
|
||||
@ -1222,8 +1222,8 @@ void FriendList::insertPeers()
|
||||
for (int i = 0; i < columnCount; ++i) {
|
||||
gpgItem->setData(i, ROLE_SORT_STATE, bestPeerState);
|
||||
|
||||
gpgItem->setTextColor(i, gpgColor);
|
||||
gpgItem->setFont(i, gpgFont);
|
||||
gpgItem->setData(i, Qt::ForegroundRole, gpgColor);
|
||||
gpgItem->setData(i, Qt::FontRole, gpgFont);
|
||||
}
|
||||
|
||||
if (openPeers.find(gpgId) != openPeers.end()) {
|
||||
|
@ -617,100 +617,104 @@ public:
|
||||
QVariant RsFriendListModel::displayRole(const EntryIndex& e, int col) const
|
||||
{
|
||||
#ifdef DEBUG_MODEL_INDEX
|
||||
std::cerr << " Display role " << e.type << ", (" << (int)e.group_index << ","<< (int)e.profile_index << ","<< (int)e.node_index << ") col="<< col<<": ";
|
||||
AutoEndel x;
|
||||
std::cerr << " Display role " << e.type << ", (" << (int)e.group_index << ","<< (int)e.profile_index << ","<< (int)e.node_index << ") col="<< col<<": ";
|
||||
AutoEndel x;
|
||||
#endif
|
||||
|
||||
switch(e.type)
|
||||
switch(e.type)
|
||||
{
|
||||
case ENTRY_TYPE_GROUP:
|
||||
{
|
||||
const HierarchicalGroupInformation *group = getGroupInfo(e);
|
||||
case ENTRY_TYPE_GROUP:
|
||||
{
|
||||
const HierarchicalGroupInformation *group = getGroupInfo(e);
|
||||
|
||||
if(!group)
|
||||
return QVariant();
|
||||
if(!group)
|
||||
return QVariant();
|
||||
|
||||
uint32_t nb_online = 0;
|
||||
uint32_t nb_online = 0;
|
||||
|
||||
for(uint32_t i=0;i<group->child_profile_indices.size();++i)
|
||||
for(uint32_t j=0;j<mProfiles[group->child_profile_indices[i]].child_node_indices.size();++j)
|
||||
if(mLocations[mProfiles[group->child_profile_indices[i]].child_node_indices[j]].node_info.state & RS_PEER_STATE_CONNECTED)
|
||||
{
|
||||
nb_online++;
|
||||
break;// only breaks the inner loop, on purpose.
|
||||
}
|
||||
for(uint32_t i=0;i<group->child_profile_indices.size();++i)
|
||||
for(uint32_t j=0;j<mProfiles[group->child_profile_indices[i]].child_node_indices.size();++j)
|
||||
if(mLocations[mProfiles[group->child_profile_indices[i]].child_node_indices[j]].node_info.state & RS_PEER_STATE_CONNECTED)
|
||||
{
|
||||
nb_online++;
|
||||
break;// only breaks the inner loop, on purpose.
|
||||
}
|
||||
|
||||
switch(col)
|
||||
{
|
||||
case COLUMN_THREAD_NAME:
|
||||
case COLUMN_THREAD_NAME:
|
||||
#ifdef DEBUG_MODEL_INDEX
|
||||
std::cerr << group->group_info.name.c_str() ;
|
||||
std::cerr << group->group_info.name.c_str() ;
|
||||
#endif
|
||||
|
||||
if(!group->child_profile_indices.empty())
|
||||
return QVariant(QString::fromUtf8(group->group_info.name.c_str())+" (" + QString::number(nb_online) + "/" + QString::number(group->child_profile_indices.size()) + ")");
|
||||
else
|
||||
return QVariant(QString::fromUtf8(group->group_info.name.c_str()));
|
||||
if(!group->child_profile_indices.empty())
|
||||
return QVariant(QString::fromUtf8(group->group_info.name.c_str())+" (" + QString::number(nb_online) + "/" + QString::number(group->child_profile_indices.size()) + ")");
|
||||
else
|
||||
return QVariant(QString::fromUtf8(group->group_info.name.c_str()));
|
||||
|
||||
case COLUMN_THREAD_ID: return QVariant(QString::fromStdString(group->group_info.id.toStdString()));
|
||||
default:
|
||||
case COLUMN_THREAD_ID: return QVariant(QString::fromStdString(group->group_info.id.toStdString()));
|
||||
default:
|
||||
return QVariant();
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
break;
|
||||
|
||||
case ENTRY_TYPE_PROFILE:
|
||||
case ENTRY_TYPE_PROFILE:
|
||||
{
|
||||
const HierarchicalProfileInformation *profile = getProfileInfo(e);
|
||||
const HierarchicalProfileInformation *profile = getProfileInfo(e);
|
||||
|
||||
if(!profile)
|
||||
return QVariant();
|
||||
if(!profile)
|
||||
return QVariant();
|
||||
|
||||
#ifdef DEBUG_MODEL_INDEX
|
||||
std::cerr << profile->profile_info.name.c_str() ;
|
||||
std::cerr << profile->profile_info.name.c_str() ;
|
||||
#endif
|
||||
switch(col)
|
||||
{
|
||||
case COLUMN_THREAD_NAME: return QVariant(QString::fromUtf8(profile->profile_info.name.c_str()));
|
||||
case COLUMN_THREAD_ID: return QVariant(QString::fromStdString(profile->profile_info.gpg_id.toStdString()) );
|
||||
case COLUMN_THREAD_NAME: return QVariant(QString::fromUtf8(profile->profile_info.name.c_str()));
|
||||
case COLUMN_THREAD_ID: return QVariant(QString::fromStdString(profile->profile_info.gpg_id.toStdString()) );
|
||||
|
||||
default:
|
||||
default:
|
||||
return QVariant();
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
break;
|
||||
|
||||
case ENTRY_TYPE_NODE:
|
||||
const HierarchicalNodeInformation *node = getNodeInfo(e);
|
||||
case ENTRY_TYPE_NODE:
|
||||
{
|
||||
const HierarchicalNodeInformation *node = getNodeInfo(e);
|
||||
|
||||
if(!node)
|
||||
return QVariant();
|
||||
if(!node)
|
||||
return QVariant();
|
||||
|
||||
#ifdef DEBUG_MODEL_INDEX
|
||||
std::cerr << node->node_info.location.c_str() ;
|
||||
std::cerr << node->node_info.location.c_str() ;
|
||||
#endif
|
||||
switch(col)
|
||||
{
|
||||
case COLUMN_THREAD_NAME: if(node->node_info.location.empty())
|
||||
return QVariant(QString::fromStdString(node->node_info.id.toStdString()));
|
||||
switch(col)
|
||||
{
|
||||
case COLUMN_THREAD_NAME: if(node->node_info.location.empty())
|
||||
return QVariant(QString::fromStdString(node->node_info.id.toStdString()));
|
||||
|
||||
{
|
||||
std::string css = rsMsgs->getCustomStateString(node->node_info.id);
|
||||
{
|
||||
std::string css = rsMsgs->getCustomStateString(node->node_info.id);
|
||||
|
||||
if(!css.empty() && mDisplayStatusString)
|
||||
return QVariant(QString::fromUtf8(node->node_info.location.c_str())+"\n"+QString::fromUtf8(css.c_str()));
|
||||
else
|
||||
return QVariant(QString::fromUtf8(node->node_info.location.c_str()));
|
||||
}
|
||||
if(!css.empty() && mDisplayStatusString)
|
||||
return QVariant(QString::fromUtf8(node->node_info.location.c_str())+"\n"+QString::fromUtf8(css.c_str()));
|
||||
else
|
||||
return QVariant(QString::fromUtf8(node->node_info.location.c_str()));
|
||||
}
|
||||
|
||||
case COLUMN_THREAD_LAST_CONTACT: return QVariant(QDateTime::fromTime_t(node->node_info.lastConnect).toString());
|
||||
case COLUMN_THREAD_IP: return QVariant( (node->node_info.state & RS_PEER_STATE_CONNECTED) ? StatusDefs::connectStateIpString(node->node_info) : QString("---"));
|
||||
case COLUMN_THREAD_ID: return QVariant( QString::fromStdString(node->node_info.id.toStdString()) );
|
||||
case COLUMN_THREAD_LAST_CONTACT: return QVariant(QDateTime::fromTime_t(node->node_info.lastConnect).toString());
|
||||
case COLUMN_THREAD_IP: return QVariant( (node->node_info.state & RS_PEER_STATE_CONNECTED) ? StatusDefs::connectStateIpString(node->node_info) : QString("---"));
|
||||
case COLUMN_THREAD_ID: return QVariant( QString::fromStdString(node->node_info.id.toStdString()) );
|
||||
|
||||
default:
|
||||
return QVariant();
|
||||
} break;
|
||||
default:
|
||||
return QVariant();
|
||||
} break;
|
||||
}
|
||||
break;
|
||||
|
||||
default: //ENTRY_TYPE
|
||||
return QVariant();
|
||||
}
|
||||
}
|
||||
|
@ -100,7 +100,7 @@ FriendSelectionDialog::FriendSelectionDialog(QWidget *parent,const QString& head
|
||||
friends_widget->setModus(modus) ;
|
||||
friends_widget->setShowType(show_type) ;
|
||||
friends_widget->start() ;
|
||||
friends_widget->setSelectedIds(pre_selected_id_type, pre_selected_ids, false);
|
||||
friends_widget->setSelectedIdsFromString(pre_selected_id_type, pre_selected_ids, false);
|
||||
|
||||
QLayout *l = new QVBoxLayout ;
|
||||
setLayout(l) ;
|
||||
|
@ -215,7 +215,7 @@ static void initSslItem(QTreeWidgetItem *item, const RsPeerDetails &detail, cons
|
||||
}
|
||||
|
||||
if (state != (int) RS_STATUS_OFFLINE) {
|
||||
item->setTextColor(COLUMN_NAME, textColorOnline);
|
||||
item->setData(COLUMN_NAME, Qt::ForegroundRole, textColorOnline);
|
||||
}
|
||||
|
||||
item->setIcon(COLUMN_NAME, QIcon(StatusDefs::imageUser(state)));
|
||||
@ -278,18 +278,35 @@ void FriendSelectionWidget::secured_fillList()
|
||||
|
||||
// get selected items
|
||||
std::set<RsPeerId> sslIdsSelected;
|
||||
if (mShowTypes & SHOW_SSL) {
|
||||
if (mShowTypes & SHOW_SSL)
|
||||
{
|
||||
if(!ui->friendList->topLevelItemCount()) // if not loaded yet, use the existing list.
|
||||
for(auto& s:mPreSelectedIds)
|
||||
sslIdsSelected.insert(RsPeerId(s));
|
||||
|
||||
selectedIds<RsPeerId,IDTYPE_SSL>(sslIdsSelected,true);
|
||||
}
|
||||
|
||||
std::set<RsNodeGroupId> groupIdsSelected;
|
||||
if (mShowTypes & SHOW_GROUP) {
|
||||
|
||||
if (mShowTypes & SHOW_GROUP)
|
||||
{
|
||||
selectedIds<RsNodeGroupId,IDTYPE_GROUP>(groupIdsSelected,true);
|
||||
|
||||
if(!ui->friendList->topLevelItemCount()) // if not loaded yet, use the existing list.
|
||||
for(auto& s:mPreSelectedIds)
|
||||
groupIdsSelected.insert(RsNodeGroupId(s));
|
||||
}
|
||||
|
||||
std::set<RsPgpId> gpgIdsSelected;
|
||||
if (mShowTypes & (SHOW_GPG | SHOW_NON_FRIEND_GPG)) {
|
||||
|
||||
if (mShowTypes & (SHOW_GPG | SHOW_NON_FRIEND_GPG))
|
||||
{
|
||||
selectedIds<RsPgpId,IDTYPE_GPG>(gpgIdsSelected,true);
|
||||
|
||||
if(!ui->friendList->topLevelItemCount()) // if not loaded yet, use the existing list.
|
||||
for(auto& s:mPreSelectedIds)
|
||||
gpgIdsSelected.insert(RsPgpId(s));
|
||||
}
|
||||
|
||||
std::set<RsGxsId> gxsIdsSelected;
|
||||
@ -299,7 +316,8 @@ void FriendSelectionWidget::secured_fillList()
|
||||
selectedIds<RsGxsId,IDTYPE_GXS>(gxsIdsSelected,true);
|
||||
|
||||
if(!ui->friendList->topLevelItemCount()) // if not loaded yet, use the existing list.
|
||||
gxsIdsSelected = mPreSelectedGxsIds;
|
||||
for(auto& s:mPreSelectedIds)
|
||||
gxsIdsSelected.insert(RsGxsId(s));
|
||||
}
|
||||
|
||||
std::set<RsGxsId> gxsIdsSelected2;
|
||||
@ -434,7 +452,7 @@ void FriendSelectionWidget::secured_fillList()
|
||||
}
|
||||
|
||||
if (state != (int) RS_STATUS_OFFLINE) {
|
||||
gpgItem->setTextColor(COLUMN_NAME, textColorOnline());
|
||||
gpgItem->setData(COLUMN_NAME, Qt::ForegroundRole, textColorOnline());
|
||||
}
|
||||
|
||||
gpgItem->setFlags(Qt::ItemIsUserCheckable | gpgItem->flags());
|
||||
@ -571,7 +589,7 @@ void FriendSelectionWidget::secured_fillList()
|
||||
QString name = QString::fromUtf8(detail.mNickname.c_str());
|
||||
gxsItem->setText(COLUMN_NAME, name + " ("+QString::fromStdString( (*gxsIt).toStdString() )+")");
|
||||
|
||||
//gxsItem->setTextColor(COLUMN_NAME, textColorOnline());
|
||||
//gxsItem->setData(COLUMN_NAME, Qt::ForegroundRole, textColorOnline());
|
||||
gxsItem->setFlags(Qt::ItemIsUserCheckable | gxsItem->flags());
|
||||
gxsItem->setIcon(COLUMN_NAME, identicon);
|
||||
gxsItem->setData(COLUMN_DATA, ROLE_ID, QString::fromStdString(detail.mId.toStdString()));
|
||||
@ -625,7 +643,7 @@ void FriendSelectionWidget::secured_fillList()
|
||||
QString name = QString::fromUtf8(detail.mNickname.c_str());
|
||||
gxsItem->setText(COLUMN_NAME, name + " ("+QString::fromStdString( (*gxsIt).toStdString() )+")");
|
||||
|
||||
//gxsItem->setTextColor(COLUMN_NAME, textColorOnline());
|
||||
//gxsItem->setData(COLUMN_NAME, Qt::ForegroundRole, textColorOnline());
|
||||
gxsItem->setFlags(Qt::ItemIsUserCheckable | gxsItem->flags());
|
||||
gxsItem->setIcon(COLUMN_NAME, identicon);
|
||||
gxsItem->setData(COLUMN_DATA, ROLE_ID, QString::fromStdString(detail.mId.toStdString()));
|
||||
@ -678,7 +696,12 @@ void FriendSelectionWidget::updateDisplay(bool)
|
||||
// This call is inlined so that there's no linking conflict with MinGW on Windows
|
||||
template<> inline void FriendSelectionWidget::setSelectedIds<RsGxsId,FriendSelectionWidget::IDTYPE_GXS>(const std::set<RsGxsId>& ids, bool add)
|
||||
{
|
||||
mPreSelectedGxsIds = ids ;
|
||||
if(!add)
|
||||
mPreSelectedIds.clear();
|
||||
|
||||
for(auto& gxsId:ids)
|
||||
mPreSelectedIds.insert(gxsId.toStdString());
|
||||
|
||||
loadIdentities();
|
||||
}
|
||||
|
||||
@ -746,14 +769,12 @@ void FriendSelectionWidget::peerStatusChanged(const QString& peerId, int status)
|
||||
case IDTYPE_GPG:
|
||||
{
|
||||
if (item->data(COLUMN_DATA, ROLE_ID).toString() == gpgId) {
|
||||
QColor color;
|
||||
if (status != (int) RS_STATUS_OFFLINE) {
|
||||
color = textColorOnline();
|
||||
item->setData(COLUMN_NAME, Qt::ForegroundRole, textColorOnline());
|
||||
} else {
|
||||
color = ui->friendList->palette().color(QPalette::Text);
|
||||
item->setData(COLUMN_NAME, Qt::ForegroundRole, QVariant());
|
||||
}
|
||||
|
||||
item->setTextColor(COLUMN_NAME, color);
|
||||
item->setIcon(COLUMN_NAME, QIcon(StatusDefs::imageUser(gpgStatus)));
|
||||
|
||||
item->setData(COLUMN_NAME, ROLE_SORT_STATE, gpgStatus);
|
||||
@ -765,14 +786,12 @@ void FriendSelectionWidget::peerStatusChanged(const QString& peerId, int status)
|
||||
case IDTYPE_SSL:
|
||||
{
|
||||
if (item->data(COLUMN_DATA, ROLE_ID).toString() == peerId) {
|
||||
QColor color;
|
||||
if (status != (int) RS_STATUS_OFFLINE) {
|
||||
color = textColorOnline();
|
||||
item->setData(COLUMN_NAME, Qt::ForegroundRole, textColorOnline());
|
||||
} else {
|
||||
color = ui->friendList->palette().color(QPalette::Text);
|
||||
item->setData(COLUMN_NAME, Qt::ForegroundRole, QVariant());
|
||||
}
|
||||
|
||||
item->setTextColor(COLUMN_NAME, color);
|
||||
item->setIcon(COLUMN_NAME, QIcon(StatusDefs::imageUser(status)));
|
||||
|
||||
item->setData(COLUMN_NAME, ROLE_SORT_STATE, status);
|
||||
@ -981,7 +1000,7 @@ std::string FriendSelectionWidget::selectedId(IdType &idType)
|
||||
return idFromItem(item);
|
||||
}
|
||||
|
||||
void FriendSelectionWidget::selectedIds(IdType idType, std::set<std::string> &ids, bool onlyDirectSelected)
|
||||
void FriendSelectionWidget::selectedIds_internal(IdType idType, std::set<std::string> &ids, bool onlyDirectSelected)
|
||||
{
|
||||
QTreeWidgetItemIterator itemIterator(ui->friendList);
|
||||
QTreeWidgetItem *item;
|
||||
@ -1055,11 +1074,21 @@ void FriendSelectionWidget::selectAll()
|
||||
setSelected(mListModus, *itemIterator, true);
|
||||
}
|
||||
|
||||
void FriendSelectionWidget::setSelectedIds(IdType idType, const std::set<std::string> &ids, bool add)
|
||||
void FriendSelectionWidget::setSelectedIdsFromString(IdType type, const std::set<std::string>& ids, bool add)
|
||||
{
|
||||
setSelectedIds_internal(type,ids,add);
|
||||
}
|
||||
|
||||
void FriendSelectionWidget::setSelectedIds_internal(IdType idType, const std::set<std::string> &ids, bool add)
|
||||
{
|
||||
mPreSelectedIds = ids;
|
||||
|
||||
// if items are already loaded, check them
|
||||
|
||||
QTreeWidgetItemIterator itemIterator(ui->friendList);
|
||||
QTreeWidgetItem *item;
|
||||
while ((item = *itemIterator) != NULL) {
|
||||
while ((item = *itemIterator) != NULL)
|
||||
{
|
||||
++itemIterator;
|
||||
|
||||
std::string id = idFromItem(item);
|
||||
|
@ -85,10 +85,12 @@ public:
|
||||
int selectedItemCount();
|
||||
std::string selectedId(IdType &idType);
|
||||
|
||||
void setSelectedIdsFromString(IdType type,const std::set<std::string>& ids,bool add);
|
||||
|
||||
template<class ID_CLASS,FriendSelectionWidget::IdType TYPE> void selectedIds(std::set<ID_CLASS>& ids, bool onlyDirectSelected)
|
||||
{
|
||||
std::set<std::string> tmpids ;
|
||||
selectedIds(TYPE, tmpids, onlyDirectSelected);
|
||||
selectedIds_internal(TYPE, tmpids, onlyDirectSelected);
|
||||
ids.clear() ;
|
||||
for(std::set<std::string>::const_iterator it(tmpids.begin());it!=tmpids.end();++it)
|
||||
ids.insert(ID_CLASS(*it)) ;
|
||||
@ -98,7 +100,7 @@ public:
|
||||
std::set<std::string> tmpids ;
|
||||
for(typename std::set<ID_CLASS>::const_iterator it(ids.begin());it!=ids.end();++it)
|
||||
tmpids.insert((*it).toStdString()) ;
|
||||
setSelectedIds(TYPE, tmpids, add);
|
||||
setSelectedIds_internal(TYPE, tmpids, add);
|
||||
}
|
||||
|
||||
void itemsFromId(IdType idType, const std::string &id, QList<QTreeWidgetItem*> &items);
|
||||
@ -145,8 +147,8 @@ private:
|
||||
void fillList();
|
||||
void secured_fillList();
|
||||
|
||||
void selectedIds(IdType idType, std::set<std::string> &ids, bool onlyDirectSelected);
|
||||
void setSelectedIds(IdType idType, const std::set<std::string> &ids, bool add);
|
||||
void selectedIds_internal(IdType idType, std::set<std::string> &ids, bool onlyDirectSelected);
|
||||
void setSelectedIds_internal(IdType idType, const std::set<std::string> &ids, bool add);
|
||||
|
||||
private:
|
||||
bool mStarted;
|
||||
@ -170,7 +172,7 @@ private:
|
||||
std::vector<RsGxsGroupId> gxsIds ;
|
||||
QList<QAction*> mContextMenuActions;
|
||||
|
||||
std::set<RsGxsId> mPreSelectedGxsIds; // because loading of GxsIds is asynchroneous we keep selected Ids from the client in a list here and use it to initialize after loading them.
|
||||
std::set<std::string> mPreSelectedIds; // because loading of GxsIds is asynchroneous we keep selected Ids from the client in a list here and use it to initialize after loading them.
|
||||
};
|
||||
|
||||
Q_DECLARE_OPERATORS_FOR_FLAGS(FriendSelectionWidget::ShowTypes)
|
||||
|
@ -287,9 +287,6 @@ void GroupTreeWidget::initDisplayMenu(QToolButton *toolButton)
|
||||
|
||||
void GroupTreeWidget::updateColors()
|
||||
{
|
||||
QBrush brush;
|
||||
QBrush standardBrush = ui->treeWidget->palette().color(QPalette::Text);
|
||||
|
||||
QTreeWidgetItemIterator itemIterator(ui->treeWidget);
|
||||
QTreeWidgetItem *item;
|
||||
while ((item = *itemIterator) != NULL) {
|
||||
@ -297,12 +294,11 @@ void GroupTreeWidget::updateColors()
|
||||
|
||||
int color = item->data(COLUMN_DATA, ROLE_COLOR).toInt();
|
||||
if (color >= 0) {
|
||||
brush = QBrush(mTextColor[color]);
|
||||
item->setData(COLUMN_NAME, Qt::TextColorRole, mTextColor[color]);
|
||||
} else {
|
||||
brush = standardBrush;
|
||||
item->setData(COLUMN_NAME, Qt::TextColorRole, QVariant());
|
||||
}
|
||||
|
||||
item->setForeground(COLUMN_NAME, brush);
|
||||
}
|
||||
}
|
||||
|
||||
@ -356,7 +352,7 @@ QTreeWidgetItem *GroupTreeWidget::addCategoryItem(const QString &name, const QIc
|
||||
int S = QFontMetricsF(font).height();
|
||||
|
||||
item->setSizeHint(COLUMN_NAME, QSize(S*1.9, S*1.9));
|
||||
item->setForeground(COLUMN_NAME, QBrush(textColorCategory()));
|
||||
item->setData(COLUMN_NAME, Qt::TextColorRole, textColorCategory());
|
||||
item->setData(COLUMN_DATA, ROLE_COLOR, GROUPTREEWIDGET_COLOR_CATEGORY);
|
||||
|
||||
item->setExpanded(expand);
|
||||
@ -513,15 +509,14 @@ void GroupTreeWidget::fillGroupItems(QTreeWidgetItem *categoryItem, const QList<
|
||||
item->setData(COLUMN_DATA, ROLE_SUBSCRIBE_FLAGS, itemInfo.subscribeFlags);
|
||||
|
||||
/* Set color */
|
||||
QBrush brush;
|
||||
if (itemInfo.publishKey) {
|
||||
brush = QBrush(textColorPrivateKey());
|
||||
item->setData(COLUMN_DATA, ROLE_COLOR, GROUPTREEWIDGET_COLOR_PRIVATEKEY);
|
||||
item->setData(COLUMN_NAME, Qt::ForegroundRole, QBrush(textColorPrivateKey()));
|
||||
} else {
|
||||
brush = ui->treeWidget->palette().color(QPalette::Text);
|
||||
// Let StyleSheet color
|
||||
item->setData(COLUMN_DATA, ROLE_COLOR, GROUPTREEWIDGET_COLOR_STANDARD);
|
||||
item->setData(COLUMN_NAME, Qt::BackgroundRole, QVariant());
|
||||
}
|
||||
item->setForeground(COLUMN_NAME, brush);
|
||||
|
||||
/* Calculate score */
|
||||
calculateScore(item, filterText);
|
||||
|
@ -36,6 +36,36 @@
|
||||
#include <cmath>
|
||||
#include <chrono>
|
||||
|
||||
//#define DEBUG_EID_PAINT 1
|
||||
|
||||
/* To test it you can make an empty.qss file with:
|
||||
QTreeView::item, QTreeWidget::item{
|
||||
color: #AB0000;
|
||||
background-color: #00DC00;
|
||||
}
|
||||
QTreeView::item:selected, QTreeWidget::item:selected{
|
||||
color: #00CD00;
|
||||
background-color: #0000BA;
|
||||
}
|
||||
QTreeView::item:hover, QTreeWidget::item:hover{
|
||||
color: #0000EF;
|
||||
background-color: #FEDCBA;
|
||||
}
|
||||
QQTreeView::item:selected:hover, TreeWidget::item:selected:hover{
|
||||
color: #ABCDEF;
|
||||
background-color: #FE0000;
|
||||
}
|
||||
|
||||
ForumsDialog, GxsForumThreadWidget
|
||||
{
|
||||
qproperty-textColorRead: darkgray;
|
||||
qproperty-textColorUnread: white;
|
||||
qproperty-textColorUnreadChildren: red;
|
||||
qproperty-textColorNotSubscribed: white;
|
||||
qproperty-textColorMissing: darkred;
|
||||
}
|
||||
*/
|
||||
|
||||
RSElidedItemDelegate::RSElidedItemDelegate(QObject *parent)
|
||||
: RSStyledItemDelegate(parent)
|
||||
, mOnlyPlainText(false), mPaintRoundedRect(true)
|
||||
@ -63,6 +93,18 @@ QSize RSElidedItemDelegate::sizeHint(const QStyleOptionViewItem &option, const Q
|
||||
return contSize;
|
||||
}
|
||||
|
||||
inline QColor getImagePixelColor(QImage img, int x, int y)
|
||||
{
|
||||
#if QT_VERSION >= QT_VERSION_CHECK(5,6,0)
|
||||
#ifdef DEBUG_EID_PAINT
|
||||
// RsDbg() << " RSEID: Found Color " << img.pixelColor(x,y).name(QColor::HexArgb).toStdString() << " at " << x << "," << y << std::endl;
|
||||
#endif
|
||||
return img.pixelColor(x,y);
|
||||
#else
|
||||
return img.pixel(x,y);
|
||||
#endif
|
||||
}
|
||||
|
||||
void RSElidedItemDelegate::paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const
|
||||
{
|
||||
if(!index.isValid())
|
||||
@ -71,15 +113,16 @@ void RSElidedItemDelegate::paint(QPainter *painter, const QStyleOptionViewItem &
|
||||
return ;
|
||||
}
|
||||
painter->save();
|
||||
// To draw with default for debug purpose
|
||||
//QStyledItemDelegate::paint(painter, option, index);
|
||||
|
||||
QStyleOptionViewItem ownOption (option);
|
||||
initStyleOption(&ownOption, index);
|
||||
//Prefer use icon from option
|
||||
if (!option.icon.isNull())
|
||||
ownOption.icon = option.icon;
|
||||
|
||||
#ifdef DEBUG_EID_PAINT
|
||||
RsDbg() << __PRETTY_FUNCTION__ << std::endl << " RSEID: Enter for item with text:" << ownOption.text.toStdString() << std::endl;
|
||||
#endif
|
||||
|
||||
const QWidget* widget = option.widget;
|
||||
QStyle* ownStyle = widget ? widget->style() : QApplication::style();
|
||||
|
||||
@ -89,28 +132,180 @@ void RSElidedItemDelegate::paint(QPainter *painter, const QStyleOptionViewItem &
|
||||
td.setHtml(ownOption.text);
|
||||
ownOption.text = td.toPlainText();
|
||||
}
|
||||
//Get Font as option.font is not accurate
|
||||
// Get Font as option.font is not accurate
|
||||
if (index.data(Qt::FontRole).type() == QVariant::Font) {
|
||||
QFont font = index.data(Qt::FontRole).value<QFont>();
|
||||
ownOption.font = font;
|
||||
ownOption.fontMetrics = QFontMetrics(font);
|
||||
#ifdef DEBUG_EID_PAINT
|
||||
QFontInfo info(font);
|
||||
RsDbg() << " RSEID: Found font in model:" << info.family().toStdString() << std::endl;
|
||||
#endif
|
||||
}
|
||||
// Get Text color from model if one exists
|
||||
QColor textColor;
|
||||
if (index.data(Qt::TextColorRole).canConvert(QMetaType::QColor)) {
|
||||
textColor = QColor(index.data(Qt::TextColorRole).toString());//Needs to pass from string else loose RBG format.
|
||||
if (index.data(Qt::TextColorRole).isValid()) {
|
||||
//textColor = QColor(index.data(Qt::TextColorRole).toString());//Needs to pass from string else loose RBG format.
|
||||
textColor = index.data(Qt::TextColorRole).value<QColor>();
|
||||
#ifdef DEBUG_EID_PAINT
|
||||
RsDbg() << " RSEID: Found text color in model:" << textColor.name().toStdString() << std::endl;
|
||||
#endif
|
||||
}
|
||||
if (index.data(Qt::BackgroundRole).canConvert(QMetaType::QBrush)) {
|
||||
QBrush brush(index.data(Qt::BackgroundRole).convert(QMetaType::QBrush));
|
||||
ownOption.backgroundBrush = brush;
|
||||
// Get Brush from model if one exists
|
||||
QBrush bgBrush;
|
||||
bgBrush.setColor(QColor());// To get color().spec()==QColor::Invalid)
|
||||
if (index.data(Qt::BackgroundRole).isValid()) {
|
||||
bgBrush = index.data(Qt::BackgroundRole).value<QBrush>();
|
||||
#ifdef DEBUG_EID_PAINT
|
||||
RsDbg() << " RSEID: Found bg brush in model:" << bgBrush.color().name().toStdString() << std::endl;
|
||||
#endif
|
||||
}
|
||||
|
||||
//Code from: https://code.woboq.org/qt5/qtbase/src/widgets/styles/qcommonstyle.cpp.html#2271
|
||||
// If we get text and bg color from model, no need to retrieve it from base
|
||||
if ( (bgBrush.color().spec()==QColor::Invalid) || (textColor.spec()!=QColor::Invalid) )
|
||||
{
|
||||
#ifdef DEBUG_EID_PAINT
|
||||
RsDbg() << " RSEID:"
|
||||
<< ((bgBrush.color().spec()==QColor::Invalid) ? " Brush not defined" : "")
|
||||
<< ((textColor.spec()==QColor::Invalid) ? " Text Color not defined" : "")
|
||||
<< " so get it from base image." << std::endl;
|
||||
#endif
|
||||
// QPalette is not updated by StyleSheet all occurs in internal class. (QRenderRule)
|
||||
// https://code.woboq.org/qt5/qtbase/src/widgets/styles/qstylesheetstyle.cpp.html#4138
|
||||
// void QStyleSheetStyle::drawControl(ControlElement ce, const QStyleOption *opt, QPainter *p, const QWidget *w) const
|
||||
// case CE_ItemViewItem:
|
||||
// So we have to print it in Image to get colors by pixel
|
||||
QSize moSize=sizeHint(option,index);
|
||||
if (moSize.width() <= 20)
|
||||
moSize.setWidth(20);
|
||||
#ifdef DEBUG_EID_PAINT
|
||||
RsDbg() << " RSEID: for item size = " << moSize.width() << "x" << moSize.height() << std::endl;
|
||||
#endif
|
||||
|
||||
QImage moImg(moSize,QImage::Format_ARGB32);
|
||||
QPainter moPnt;
|
||||
moPnt.begin(&moImg);
|
||||
moPnt.setCompositionMode (QPainter::CompositionMode_Source);
|
||||
moPnt.fillRect(moImg.rect(), Qt::transparent);
|
||||
moPnt.setCompositionMode (QPainter::CompositionMode_SourceOver);
|
||||
|
||||
QStyleOptionViewItem moOption (option);
|
||||
// Define option to get only what we want
|
||||
{
|
||||
moOption.rect = QRect(QPoint(0,0),moSize);
|
||||
moOption.state = ownOption.state;
|
||||
moOption.text = " ████████████████";//Add a blank char to get BackGround Color at top left
|
||||
// Remove unwanted info. Yes it can draw without that all public data ...
|
||||
moOption.backgroundBrush = QBrush();
|
||||
moOption.checkState = Qt::Unchecked;
|
||||
moOption.decorationAlignment = Qt::AlignLeft;
|
||||
moOption.decorationPosition = QStyleOptionViewItem::Left;
|
||||
moOption.decorationSize = QSize();
|
||||
moOption.displayAlignment = Qt::AlignLeft | Qt::AlignTop;
|
||||
moOption.features=0;
|
||||
moOption.font = QFont();
|
||||
moOption.icon = QIcon();
|
||||
moOption.index = QModelIndex();
|
||||
moOption.locale = QLocale();
|
||||
moOption.showDecorationSelected = false;
|
||||
moOption.textElideMode = Qt::ElideNone;
|
||||
moOption.viewItemPosition = QStyleOptionViewItem::Middle;
|
||||
//moOption.widget = nullptr; //Needed.
|
||||
|
||||
moOption.direction = Qt::LayoutDirectionAuto;
|
||||
moOption.fontMetrics = QFontMetrics(QFont());
|
||||
moOption.palette = QPalette();
|
||||
moOption.styleObject = nullptr;
|
||||
}
|
||||
QStyledItemDelegate::paint(&moPnt, moOption, QModelIndex());
|
||||
|
||||
//// But these lines doesn't works.
|
||||
{
|
||||
//QStyleOptionViewItem moOptionsState;
|
||||
//moOptionsState.initFrom(moOption.widget);
|
||||
//moOptionsState.rect = QRect(QPoint(0,0),moSize);
|
||||
//moOptionsState.state = QStyle::State_MouseOver | QStyle::State_Enabled | QStyle::State_Sibling;
|
||||
//moOptionsState.text = "████████";
|
||||
//moOptionsState.widget = option.widget;
|
||||
//QStyledItemDelegate::paint(&moPnt, moOptionsState, QModelIndex());
|
||||
}
|
||||
|
||||
moPnt.end();
|
||||
#ifdef DEBUG_EID_PAINT
|
||||
// To save what it paint in application path
|
||||
moImg.save("image.png");
|
||||
#endif
|
||||
// Get Color in this rect.
|
||||
{
|
||||
QColor moColor;
|
||||
QColor moBGColor=getImagePixelColor(moImg,1,1); // BackGround may be paint.
|
||||
QColor moColorBorder;// To avoid Border pixel
|
||||
int moWidth = moImg.size().width(), moHeight = moImg.size().height();
|
||||
for (int x = 0; (x<moWidth) && (moColor.spec() == QColor::Invalid); x++)
|
||||
for (int y = 0; (y<moHeight) && (moColor.spec() == QColor::Invalid); y++)
|
||||
if (getImagePixelColor(moImg,x,y) != moBGColor)
|
||||
{
|
||||
if (getImagePixelColor(moImg,x,y) == moColorBorder)
|
||||
moColor = getImagePixelColor(moImg,x,y);
|
||||
else
|
||||
{
|
||||
if (moColorBorder.spec() == QColor::Invalid)
|
||||
{
|
||||
// First pixel border move inside
|
||||
x+=5;
|
||||
y+=5;
|
||||
}
|
||||
moColorBorder = getImagePixelColor(moImg,x,y);
|
||||
}
|
||||
}
|
||||
|
||||
// If not found color is same as BackGround.
|
||||
if (moColor.spec() == QColor::Invalid)
|
||||
moColor = moBGColor;
|
||||
|
||||
if (bgBrush.color().spec()==QColor::Invalid)
|
||||
{
|
||||
bgBrush = QBrush(moBGColor);
|
||||
#ifdef DEBUG_EID_PAINT
|
||||
RsDbg() << " RSEID: bg brush setted to " << moBGColor.name(QColor::HexArgb).toStdString() << std::endl;
|
||||
#endif
|
||||
}
|
||||
if (textColor.spec()==QColor::Invalid)
|
||||
{
|
||||
textColor = moColor;
|
||||
#ifdef DEBUG_EID_PAINT
|
||||
RsDbg() << " RSEID: text color setted to " << moColor.name(QColor::HexArgb).toStdString() << std::endl;
|
||||
#endif
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
painter->setPen(textColor);
|
||||
painter->setBrush(bgBrush);
|
||||
ownOption.backgroundBrush = bgBrush;
|
||||
|
||||
// Code from: https://code.woboq.org/qt5/qtbase/src/widgets/styles/qcommonstyle.cpp.html#2271
|
||||
QRect checkRect = ownStyle->subElementRect(QStyle::SE_ItemViewItemCheckIndicator, &ownOption, widget);
|
||||
QRect iconRect = ownStyle->subElementRect(QStyle::SE_ItemViewItemDecoration, &ownOption, widget);
|
||||
QRect textRect = ownStyle->subElementRect(QStyle::SE_ItemViewItemText, &ownOption, widget);
|
||||
|
||||
// draw the background
|
||||
ownStyle->drawPrimitive(QStyle::PE_PanelItemViewItem, &option, painter, widget);
|
||||
// Draw the background
|
||||
if (bgBrush.color().alpha() == 0)
|
||||
// No BackGround Color found, use default delegate to draw it.
|
||||
ownStyle->proxy()->drawPrimitive(QStyle::PE_PanelItemViewItem, &option, painter, widget);// This prefer draw StyleSheet bg than item one.
|
||||
else
|
||||
painter->fillRect(ownOption.rect,bgBrush);
|
||||
|
||||
#ifdef DEBUG_EID_PAINT
|
||||
{
|
||||
QStyleOptionViewItem tstOption = option;
|
||||
// Reduce rect to get this item bg color external and base internal
|
||||
tstOption.rect.adjust(3,3,-6,-6);
|
||||
// To draw with base for debug purpose
|
||||
QStyledItemDelegate::paint(painter, tstOption, index);
|
||||
}
|
||||
#endif
|
||||
|
||||
// draw the check mark
|
||||
if (ownOption.features & QStyleOptionViewItem::HasCheckIndicator) {
|
||||
QStyleOptionViewItem option(*&ownOption);
|
||||
@ -162,133 +357,34 @@ void RSElidedItemDelegate::paint(QPainter *painter, const QStyleOptionViewItem &
|
||||
int duration = 3;// Time (s) to make a revolution.
|
||||
auto time = (s%duration)*1000 + ms;
|
||||
qreal angle = 360.0*(time/(duration*1000.0));
|
||||
qreal add = 120*(time/(duration*1000.0))*abs(sin(qDegreesToRadians(angle/2)));
|
||||
qreal add = 120*(time/(duration*1000.0))*std::abs(sin(qDegreesToRadians(angle/2)));
|
||||
painter->setPen(QPen(QBrush(ownOption.palette.color(QPalette::Normal, QPalette::WindowText)),diag/10,Qt::DotLine,Qt::RoundCap));
|
||||
painter->drawEllipse( iconRect.x()+iconRect.width() /2 + (diag/4)*cos(qDegreesToRadians(angle ))
|
||||
, iconRect.y()+iconRect.height()/2 + (diag/4)*sin(qDegreesToRadians(angle )), 1, 1);
|
||||
, iconRect.y()+iconRect.height()/2 + (diag/4)*sin(qDegreesToRadians(angle )), 1, 1);
|
||||
painter->setPen(QPen(QBrush(ownOption.palette.color(QPalette::Normal, QPalette::Midlight)),diag/10,Qt::DotLine,Qt::RoundCap));
|
||||
painter->drawEllipse( iconRect.x()+iconRect.width() /2 + (diag/4)*cos(qDegreesToRadians(angle- add))
|
||||
, iconRect.y()+iconRect.height()/2 + (diag/4)*sin(qDegreesToRadians(angle- add)), 1, 1);
|
||||
, iconRect.y()+iconRect.height()/2 + (diag/4)*sin(qDegreesToRadians(angle- add)), 1, 1);
|
||||
painter->setPen(QPen(QBrush(ownOption.palette.color(QPalette::Normal, QPalette::Window)),diag/10,Qt::DotLine,Qt::RoundCap));
|
||||
painter->drawEllipse( iconRect.x()+iconRect.width() /2 + (diag/4)*cos(qDegreesToRadians(angle-2*add))
|
||||
, iconRect.y()+iconRect.height()/2 + (diag/4)*sin(qDegreesToRadians(angle-2*add)), 1, 1);
|
||||
, iconRect.y()+iconRect.height()/2 + (diag/4)*sin(qDegreesToRadians(angle-2*add)), 1, 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
// draw the text
|
||||
if (!ownOption.text.isEmpty()) {
|
||||
QPalette::ColorGroup cg = ownOption.state & QStyle::State_Enabled
|
||||
? QPalette::Normal : QPalette::Disabled;
|
||||
if (cg == QPalette::Normal && !(ownOption.state & QStyle::State_Active))
|
||||
cg = QPalette::Inactive;
|
||||
if (ownOption.state & QStyle::State_Selected) {
|
||||
painter->setPen(ownOption.palette.color(cg, QPalette::HighlightedText));
|
||||
} else {
|
||||
#if QT_VERSION >= QT_VERSION_CHECK(5,6,0)
|
||||
if (ownOption.state & QStyle::State_MouseOver) {
|
||||
//TODO: Manage to get palette with HOVER css pseudoclass
|
||||
// For now this is hidden by Qt: https://code.woboq.org/qt5/qtbase/src/widgets/styles/qstylesheetstyle.cpp.html#6103
|
||||
// So we print default in image and get it's color...
|
||||
QSize moSize=sizeHint(option,index);
|
||||
QImage moImg(moSize,QImage::Format_ARGB32);
|
||||
QPainter moPnt;
|
||||
moPnt.begin(&moImg);
|
||||
moPnt.setPen(Qt::black);//Fill Image with Black
|
||||
moPnt.setBrush(Qt::black);
|
||||
moPnt.drawRect(moImg.rect());
|
||||
|
||||
QStyleOptionViewItem moOption (option);
|
||||
// Define option to get only what we want
|
||||
{
|
||||
moOption.rect = QRect(QPoint(0,0),moSize);
|
||||
moOption.state = QStyle::State_MouseOver | QStyle::State_Enabled | QStyle::State_Sibling;
|
||||
moOption.text = " ████████████████";//Add a blank char to get BackGround Color at top left
|
||||
// Remove unwanted info. Yes it can draw without that all public data ...
|
||||
moOption.backgroundBrush = QBrush();
|
||||
moOption.checkState = Qt::Unchecked;
|
||||
moOption.decorationAlignment = Qt::AlignLeft;
|
||||
moOption.decorationPosition = QStyleOptionViewItem::Left;
|
||||
moOption.decorationSize = QSize();
|
||||
moOption.displayAlignment = Qt::AlignLeft | Qt::AlignTop;
|
||||
moOption.features=0;
|
||||
moOption.font = QFont();
|
||||
moOption.icon = QIcon();
|
||||
moOption.index = QModelIndex();
|
||||
moOption.locale = QLocale();
|
||||
moOption.showDecorationSelected = false;
|
||||
moOption.textElideMode = Qt::ElideNone;
|
||||
moOption.viewItemPosition = QStyleOptionViewItem::Middle;
|
||||
//moOption.widget = nullptr; //Needed.
|
||||
|
||||
moOption.direction = Qt::LayoutDirectionAuto;
|
||||
moOption.fontMetrics = QFontMetrics(QFont());
|
||||
moOption.palette = QPalette();
|
||||
moOption.styleObject = nullptr;
|
||||
}
|
||||
QStyledItemDelegate::paint(&moPnt, moOption, QModelIndex());
|
||||
|
||||
//// But these lines doesn't works.
|
||||
{
|
||||
//QStyleOptionViewItem moOptionsState;
|
||||
//moOptionsState.initFrom(moOption.widget);
|
||||
//moOptionsState.rect = QRect(QPoint(0,0),moSize);
|
||||
//moOptionsState.state = QStyle::State_MouseOver | QStyle::State_Enabled | QStyle::State_Sibling;
|
||||
//moOptionsState.text = "████████";
|
||||
//moOptionsState.widget = option.widget;
|
||||
//QStyledItemDelegate::paint(&moPnt, moOptionsState, QModelIndex());
|
||||
}
|
||||
|
||||
moPnt.end();
|
||||
// To save what it paint
|
||||
//moImg.save("image.bmp");
|
||||
|
||||
// Get Color in this black rect.
|
||||
QColor moColor;
|
||||
QColor moBGColor=moImg.pixelColor(1,1); //BackGround may be paint.
|
||||
QColor moColorBorder;// To avoid Border pixel
|
||||
int moWidth = moImg.size().width(), moHeight = moImg.size().height();
|
||||
for (int x = 0; (x<moWidth) && (moColor.spec() == QColor::Invalid); x++)
|
||||
for (int y = 0; (y<moHeight) && (moColor.spec() == QColor::Invalid); y++)
|
||||
if (moImg.pixelColor(x,y) != moBGColor)
|
||||
{
|
||||
if (moImg.pixelColor(x,y) == moColorBorder)
|
||||
moColor = QColor(moImg.pixelColor(x,y).name());
|
||||
else
|
||||
{
|
||||
if (moColorBorder.spec() == QColor::Invalid)
|
||||
{
|
||||
// First pixel border move inside
|
||||
x+=5;
|
||||
y+=5;
|
||||
}
|
||||
moColorBorder = QColor(moImg.pixelColor(x,y).name());
|
||||
}
|
||||
}
|
||||
|
||||
// If not found color is same as BackGround.
|
||||
if (moColor.spec() == QColor::Invalid)
|
||||
moColor = moBGColor;
|
||||
|
||||
painter->setPen(moColor);
|
||||
}
|
||||
else
|
||||
#ifdef DEBUG_EID_PAINT
|
||||
// To draw text near base one.
|
||||
ownOption.text = ownOption.text.prepend("__");
|
||||
#endif
|
||||
if (textColor.spec()==QColor::Invalid) {
|
||||
painter->setPen(ownOption.palette.color(cg, QPalette::Text));
|
||||
} else { //Only get color from index for unselected(as Qt does)
|
||||
painter->setPen(textColor);
|
||||
}
|
||||
}
|
||||
if (ownOption.state & QStyle::State_Editing) {
|
||||
painter->setPen(ownOption.palette.color(cg, QPalette::Text));
|
||||
painter->drawRect(textRect.adjusted(0, 0, -1, -1));
|
||||
}
|
||||
//d->viewItemDrawText(p, &ownOption, textRect);
|
||||
|
||||
QTextLayout textLayout(ownOption.text, painter->font());
|
||||
QTextOption to = textLayout.textOption();
|
||||
StyledElidedLabel::paintElidedLine(painter,ownOption.text,textRect,ownOption.font,ownOption.displayAlignment,to.wrapMode()&QTextOption::WordWrap,mPaintRoundedRect);
|
||||
}
|
||||
painter->restore();
|
||||
#ifdef DEBUG_EID_PAINT
|
||||
RsDbg() << " RSEID: Finished" << std::endl;
|
||||
#endif
|
||||
}
|
||||
|
||||
bool RSElidedItemDelegate::editorEvent(QEvent *event, QAbstractItemModel *model, const QStyleOptionViewItem &option, const QModelIndex &index)
|
||||
|
@ -537,8 +537,9 @@ bool RsCollectionDialog::addChild(QTreeWidgetItem* parent, const std::vector<Col
|
||||
|
||||
if (colFileInfo.filename_has_wrong_characters)
|
||||
{
|
||||
//TODO (Phenom): Add qproperty for these text colors in stylesheets
|
||||
wrong_chars = true ;
|
||||
item->setTextColor(COLUMN_FILE, QColor(255,80,120)) ;
|
||||
item->setData(COLUMN_FILE, Qt::ForegroundRole, QColor(255,80,120)) ;
|
||||
}
|
||||
|
||||
if (parentsFounds.empty()) {
|
||||
|
@ -88,11 +88,12 @@ void UserNotify::setNotifyEnabled(bool enabled, bool combined, bool blink)
|
||||
Settings->endGroup();
|
||||
}
|
||||
|
||||
void UserNotify::initialize(QToolBar *mainToolBar, QAction *mainAction, QListWidgetItem *listItem)
|
||||
void UserNotify::initialize(QToolBar *mainToolBar, QAction *mainAction, QListWidgetItem *listItem,const QString& subtext)
|
||||
{
|
||||
mMainAction = mainAction;
|
||||
if (mMainAction) {
|
||||
mButtonText = mMainAction->text();
|
||||
mButtonText2 = subtext;
|
||||
if (mainToolBar) {
|
||||
mMainToolButton = dynamic_cast<QToolButton*>(mainToolBar->widgetForAction(mMainAction));
|
||||
}
|
||||
@ -165,7 +166,18 @@ void UserNotify::update()
|
||||
|
||||
if (mMainAction) {
|
||||
mMainAction->setIcon(getMainIcon(count > 0));
|
||||
mMainAction->setText((count > 0) ? QString("%1 (%2)").arg(mButtonText).arg(count) : mButtonText);
|
||||
|
||||
if(count > 0)
|
||||
{
|
||||
if(!mButtonText2.isNull())
|
||||
mMainAction->setToolTip(QString("%1 (%2 %3)").arg(mButtonText).arg(count).arg(mButtonText2));
|
||||
else
|
||||
mMainAction->setToolTip(QString("%1 (%2)").arg(mButtonText).arg(count));
|
||||
|
||||
mMainAction->setText(QString("%1 (%2)").arg(mButtonText).arg(count));
|
||||
}
|
||||
else
|
||||
mMainAction->setText(mButtonText);
|
||||
|
||||
QFont font = mMainAction->font();
|
||||
font.setBold(count > 0);
|
||||
|
@ -37,12 +37,17 @@ public:
|
||||
UserNotify(QObject *parent = 0);
|
||||
virtual ~UserNotify();
|
||||
|
||||
void initialize(QToolBar *mainToolBar, QAction *mainAction, QListWidgetItem *listItem);
|
||||
void initialize(QToolBar *mainToolBar, QAction *mainAction, QListWidgetItem *listItem,const QString& subtext);
|
||||
void createIcons(QMenu *notifyMenu);
|
||||
QSystemTrayIcon* getTrayIcon(){ return mTrayIcon;}
|
||||
QAction* getNotifyIcon(){ return mNotifyIcon;}
|
||||
|
||||
virtual bool hasSetting(QString */*name*/, QString */*group*/) { return false; }
|
||||
|
||||
// UserNotify is used to display tooltips when some services have no messages and so on, in the format of "Name (43242 new messages)"
|
||||
// This method is used to pass the string that comes after the number.
|
||||
virtual QString textInfo() const { return QString() ; }
|
||||
|
||||
bool notifyEnabled();
|
||||
bool notifyCombined();
|
||||
bool notifyBlink();
|
||||
@ -82,6 +87,7 @@ private:
|
||||
QAction *mNotifyIcon;
|
||||
unsigned int mNewCount;
|
||||
QString mButtonText;
|
||||
QString mButtonText2;
|
||||
bool mLastBlinking;
|
||||
};
|
||||
|
||||
|
@ -319,8 +319,9 @@ void GxsChannelPostItem::loadMessage()
|
||||
|
||||
std::vector<RsGxsChannelPost> posts;
|
||||
std::vector<RsGxsComment> comments;
|
||||
std::vector<RsGxsVote> votes;
|
||||
|
||||
if(! rsGxsChannels->getChannelContent( groupId(), std::set<RsGxsMessageId>( { messageId() } ),posts,comments))
|
||||
if(! rsGxsChannels->getChannelContent( groupId(), std::set<RsGxsMessageId>( { messageId() } ),posts,comments,votes))
|
||||
{
|
||||
RsErr() << "GxsGxsChannelGroupItem::loadGroup() ERROR getting data" << std::endl;
|
||||
return;
|
||||
|
@ -77,80 +77,101 @@ void GxsCircleItem::setup()
|
||||
|
||||
/* update circle information */
|
||||
|
||||
ui->membershipButton->setToolTip(tr("Grant membership request"));
|
||||
ui->inviteeButton->setToolTip(tr("Revoke membership"));
|
||||
|
||||
connect(ui->membershipButton, SIGNAL(clicked()), this, SLOT(toggleCircleMembership()));
|
||||
connect(ui->inviteeButton, SIGNAL(clicked()), this, SLOT(toggleCircleInvite()));
|
||||
|
||||
RsGxsCircleDetails circleDetails;
|
||||
|
||||
if (rsGxsCircles->getCircleDetails(mCircleId, circleDetails))
|
||||
{
|
||||
ui->nameLabel->setText(QString::fromUtf8(circleDetails.mCircleName.c_str()) + " (ID: " + QString::fromStdString(circleDetails.mCircleId.toStdString()) + ")");
|
||||
|
||||
// from here we can figure out if we already have requested membership or not
|
||||
|
||||
if (mType == RS_FEED_ITEM_CIRCLE_MEMB_REQ)
|
||||
{
|
||||
ui->titleLabel->setText(tr("You received a membership request for circle:"));
|
||||
ui->nameLabel->setText(QString::fromUtf8(circleDetails.mCircleName.c_str()));
|
||||
ui->gxsIdLabel->setText(idName);
|
||||
ui->titleLabel->setText(tr("You received a membership request a circle you're administrating:"));
|
||||
ui->iconLabel->setPixmap(pixmap);
|
||||
ui->gxsIdLabel->setId(mGxsId);
|
||||
|
||||
if(circleDetails.mAmIAdmin)
|
||||
{
|
||||
ui->acceptButton->setToolTip(tr("Grant membership request"));
|
||||
ui->revokeButton->setToolTip(tr("Revoke membership request"));
|
||||
connect(ui->acceptButton, SIGNAL(clicked()), this, SLOT(grantCircleMembership()));
|
||||
connect(ui->revokeButton, SIGNAL(clicked()), this, SLOT(revokeCircleMembership()));
|
||||
}
|
||||
else
|
||||
{
|
||||
ui->acceptButton->setEnabled(false);
|
||||
ui->revokeButton->setEnabled(false);
|
||||
}
|
||||
ui->inviteeButton->setHidden(false);
|
||||
ui->inviteeButton->setText(tr("Grant membership"));
|
||||
ui->inviteeButton->setToolTip(tr("Grant membership to this circle, for this identity"));
|
||||
|
||||
ui->membershipButton->setHidden(true);
|
||||
}
|
||||
else if (mType == RS_FEED_ITEM_CIRCLE_INVIT_REC)
|
||||
else if (mType == RS_FEED_ITEM_CIRCLE_INVITE_REC)
|
||||
{
|
||||
ui->titleLabel->setText(tr("You received an invitation for circle:"));
|
||||
ui->nameLabel->setText(QString::fromUtf8(circleDetails.mCircleName.c_str()));
|
||||
ui->gxsIdLabel->setText(idName);
|
||||
ui->titleLabel->setText(tr("You received an invitation to join this circle:"));
|
||||
ui->iconLabel->setPixmap(pixmap);
|
||||
ui->gxsIdLabel->setId(mGxsId);
|
||||
|
||||
ui->acceptButton->setToolTip(tr("Accept invitation"));
|
||||
connect(ui->acceptButton, SIGNAL(clicked()), this, SLOT(acceptCircleSubscription()));
|
||||
ui->revokeButton->setHidden(true);
|
||||
ui->membershipButton->setText(tr("Accept"));
|
||||
ui->membershipButton->setToolTip(tr("Accept invitation"));
|
||||
ui->membershipButton->setHidden(false);
|
||||
|
||||
connect(ui->membershipButton, SIGNAL(clicked()), this, SLOT(requestCircleSubscription()));
|
||||
ui->inviteeButton->setHidden(true);
|
||||
}
|
||||
else if (mType == RS_FEED_ITEM_CIRCLE_MEMB_LEAVE)
|
||||
{
|
||||
ui->titleLabel->setText(idName + tr(" has left this circle you belong to."));
|
||||
ui->nameLabel->setText(QString::fromUtf8(circleDetails.mCircleName.c_str()));
|
||||
ui->gxsIdLabel->setText(idName);
|
||||
ui->titleLabel->setText(idName + tr(" has left this circle."));
|
||||
ui->iconLabel->setPixmap(pixmap);
|
||||
ui->gxsIdLabel->setId(mGxsId);
|
||||
|
||||
ui->acceptButton->setHidden(true);
|
||||
ui->revokeButton->setHidden(true);
|
||||
ui->membershipButton->setHidden(true);
|
||||
ui->inviteeButton->setHidden(true);
|
||||
}
|
||||
else if (mType == RS_FEED_ITEM_CIRCLE_MEMB_JOIN)
|
||||
{
|
||||
ui->titleLabel->setText(idName + tr(" has join this circle you also belong to."));
|
||||
ui->nameLabel->setText(QString::fromUtf8(circleDetails.mCircleName.c_str()));
|
||||
ui->gxsIdLabel->setText(idName);
|
||||
ui->iconLabel->setPixmap(pixmap);
|
||||
ui->gxsIdLabel->setId(mGxsId);
|
||||
|
||||
ui->acceptButton->setHidden(true);
|
||||
ui->revokeButton->setHidden(true);
|
||||
}
|
||||
else if (mType == RS_FEED_ITEM_CIRCLE_MEMB_REVOQUED)
|
||||
{
|
||||
if(rsIdentity->isOwnId(mGxsId))
|
||||
ui->titleLabel->setText(tr("Your identity %1 has been revoqued from this circle.").arg(idName));
|
||||
if(circleDetails.mAmIAdmin)
|
||||
{
|
||||
ui->titleLabel->setText(idName + tr(" which you invited, has join this circle you're administrating."));
|
||||
ui->inviteeButton->setHidden(false);
|
||||
ui->inviteeButton->setText(tr("Revoke membership"));
|
||||
ui->inviteeButton->setToolTip(tr("Revoke membership for that identity"));
|
||||
}
|
||||
else
|
||||
ui->titleLabel->setText(tr("Identity %1 has been revoqued from this circle you belong to.").arg(idName));
|
||||
{
|
||||
ui->inviteeButton->setHidden(true);
|
||||
ui->titleLabel->setText(idName + tr(" has join this circle."));
|
||||
}
|
||||
|
||||
ui->nameLabel->setText(QString::fromUtf8(circleDetails.mCircleName.c_str()));
|
||||
ui->gxsIdLabel->setText(idName);
|
||||
ui->iconLabel->setPixmap(pixmap);
|
||||
ui->gxsIdLabel->setId(mGxsId);
|
||||
|
||||
ui->acceptButton->setHidden(true);
|
||||
ui->revokeButton->setHidden(true);
|
||||
ui->membershipButton->setHidden(true);
|
||||
}
|
||||
else if (mType == RS_FEED_ITEM_CIRCLE_MEMB_REVOKED)
|
||||
{
|
||||
ui->titleLabel->setText(tr("Your identity %1 has been revoked from this circle.").arg(idName));
|
||||
|
||||
ui->iconLabel->setPixmap(pixmap);
|
||||
ui->gxsIdLabel->setId(mGxsId);
|
||||
|
||||
ui->membershipButton->setHidden(false);
|
||||
ui->membershipButton->setText(tr("Cancel membership request"));
|
||||
ui->membershipButton->setToolTip(tr("Cancel your membership request from that circle"));
|
||||
|
||||
ui->inviteeButton->setHidden(true);
|
||||
}
|
||||
else if (mType == RS_FEED_ITEM_CIRCLE_MEMB_ACCEPTED)
|
||||
{
|
||||
ui->titleLabel->setText(tr("Your identity %1 as been accepted in this circle.").arg(idName));
|
||||
|
||||
ui->iconLabel->setPixmap(pixmap);
|
||||
ui->gxsIdLabel->setId(mGxsId);
|
||||
|
||||
ui->membershipButton->setHidden(false);
|
||||
ui->membershipButton->setText(tr("Cancel membership"));
|
||||
ui->membershipButton->setToolTip(tr("Cancel your membership from that circle"));
|
||||
|
||||
ui->inviteeButton->setHidden(true);
|
||||
}
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -163,7 +184,7 @@ void GxsCircleItem::setup()
|
||||
|
||||
uint64_t GxsCircleItem::uniqueIdentifier() const
|
||||
{
|
||||
return hash_64bits("GxsCircle " + mCircleId.toStdString() + " " + mGxsId.toStdString() + " " + QString::number(mType).toStdString());
|
||||
return hash_64bits("GxsCircle " + mCircleId.toStdString() + " " + mGxsId.toStdString());
|
||||
}
|
||||
|
||||
/*********** SPECIFIC FUNCTIONS ***********************/
|
||||
@ -176,25 +197,40 @@ void GxsCircleItem::showCircleDetails()
|
||||
dlg.exec();
|
||||
}
|
||||
|
||||
void GxsCircleItem::acceptCircleSubscription()
|
||||
void GxsCircleItem::requestCircleSubscription()
|
||||
{
|
||||
if (rsGxsCircles->requestCircleMembership(mGxsId, mCircleId))
|
||||
removeItem();
|
||||
rsGxsCircles->requestCircleMembership(mGxsId, mCircleId);
|
||||
}
|
||||
|
||||
void GxsCircleItem::grantCircleMembership()
|
||||
void GxsCircleItem::toggleCircleMembership()
|
||||
{
|
||||
RsThread::async([this]()
|
||||
{
|
||||
rsGxsCircles->inviteIdsToCircle(std::set<RsGxsId>( { mGxsId } ),mCircleId);
|
||||
});
|
||||
if(!rsIdentity->isOwnId(mGxsId))
|
||||
{
|
||||
RsErr() << __PRETTY_FUNCTION__ << ": inconsistent call: identity " << mGxsId << " doesn't belong to you" << std::endl;
|
||||
return;
|
||||
}
|
||||
|
||||
if(mType == RS_FEED_ITEM_CIRCLE_INVITE_REC)
|
||||
rsGxsCircles->requestCircleMembership(mGxsId,mCircleId);
|
||||
else if(mType == RS_FEED_ITEM_CIRCLE_MEMB_REVOKED)
|
||||
rsGxsCircles->cancelCircleMembership(mGxsId,mCircleId);
|
||||
else
|
||||
RsErr() << __PRETTY_FUNCTION__ << ": inconsistent call. mType is " << mType << std::endl;
|
||||
}
|
||||
|
||||
void GxsCircleItem::revokeCircleMembership()
|
||||
void GxsCircleItem::toggleCircleInvite()
|
||||
{
|
||||
RsThread::async([this]()
|
||||
{
|
||||
rsGxsCircles->revokeIdsFromCircle(std::set<RsGxsId>( { mGxsId } ),mCircleId);
|
||||
});
|
||||
if(mType == RS_FEED_ITEM_CIRCLE_MEMB_JOIN)
|
||||
RsThread::async([this]()
|
||||
{
|
||||
rsGxsCircles->revokeIdsFromCircle(std::set<RsGxsId>( { mGxsId } ),mCircleId);
|
||||
});
|
||||
else if(mType == RS_FEED_ITEM_CIRCLE_MEMB_REQ)
|
||||
RsThread::async([this]()
|
||||
{
|
||||
rsGxsCircles->inviteIdsToCircle(std::set<RsGxsId>( { mGxsId } ),mCircleId);
|
||||
});
|
||||
else
|
||||
RsErr() << __PRETTY_FUNCTION__ << ": inconsistent call. mType is " << mType << std::endl;
|
||||
}
|
||||
|
||||
|
@ -65,9 +65,9 @@ protected:
|
||||
|
||||
private slots:
|
||||
void showCircleDetails();
|
||||
void acceptCircleSubscription();
|
||||
void grantCircleMembership() ;
|
||||
void revokeCircleMembership();
|
||||
void requestCircleSubscription();
|
||||
void toggleCircleMembership() ;
|
||||
void toggleCircleInvite();
|
||||
|
||||
private:
|
||||
void setup();
|
||||
|
@ -7,7 +7,7 @@
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>618</width>
|
||||
<height>104</height>
|
||||
<height>217</height>
|
||||
</rect>
|
||||
</property>
|
||||
<layout class="QGridLayout" name="GxsCircleItemGLayout">
|
||||
@ -104,8 +104,8 @@
|
||||
<property name="frameShadow">
|
||||
<enum>QFrame::Sunken</enum>
|
||||
</property>
|
||||
<layout class="QGridLayout" name="gridLayout">
|
||||
<item row="0" column="0" rowspan="3">
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_3">
|
||||
<item>
|
||||
<widget class="QLabel" name="logoLabel">
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
@ -130,154 +130,8 @@
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="1" colspan="5">
|
||||
<layout class="QHBoxLayout" name="horizontalLayout">
|
||||
<item>
|
||||
<widget class="QLabel" name="forLabel">
|
||||
<property name="text">
|
||||
<string>for identity</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLabel" name="iconLabel">
|
||||
<property name="maximumSize">
|
||||
<size>
|
||||
<width>20</width>
|
||||
<height>20</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>TextLabel</string>
|
||||
</property>
|
||||
<property name="scaledContents">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="GxsIdLabel" name="gxsIdLabel">
|
||||
<property name="text">
|
||||
<string notr="true">name</string>
|
||||
</property>
|
||||
<property name="openExternalLinks">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<spacer name="horizontalSpacer">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>358</width>
|
||||
<height>20</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item row="2" column="1">
|
||||
<widget class="QPushButton" name="acceptButton">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Fixed" vsizetype="Fixed">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="focusPolicy">
|
||||
<enum>Qt::NoFocus</enum>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Accept</string>
|
||||
</property>
|
||||
<property name="icon">
|
||||
<iconset resource="../images.qrc">
|
||||
<normaloff>:/images/accepted16.png</normaloff>:/images/accepted16.png</iconset>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="2">
|
||||
<widget class="QPushButton" name="revokeButton">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Fixed" vsizetype="Fixed">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="focusPolicy">
|
||||
<enum>Qt::NoFocus</enum>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Revoke</string>
|
||||
</property>
|
||||
<property name="icon">
|
||||
<iconset resource="../images.qrc">
|
||||
<normaloff>:/images/cancel.png</normaloff>:/images/cancel.png</iconset>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="3">
|
||||
<widget class="QPushButton" name="expandButton">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Fixed" vsizetype="Fixed">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="focusPolicy">
|
||||
<enum>Qt::NoFocus</enum>
|
||||
</property>
|
||||
<property name="toolTip">
|
||||
<string>Details</string>
|
||||
</property>
|
||||
<property name="icon">
|
||||
<iconset resource="../images.qrc">
|
||||
<normaloff>:/images/informations_24x24.png</normaloff>:/images/informations_24x24.png</iconset>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="4">
|
||||
<spacer name="tollbarHSpacer">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="sizeType">
|
||||
<enum>QSizePolicy::Expanding</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>285</width>
|
||||
<height>18</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
<item row="2" column="5">
|
||||
<widget class="QPushButton" name="clearButton">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Fixed" vsizetype="Fixed">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="focusPolicy">
|
||||
<enum>Qt::NoFocus</enum>
|
||||
</property>
|
||||
<property name="toolTip">
|
||||
<string>Remove Item</string>
|
||||
</property>
|
||||
<property name="icon">
|
||||
<iconset resource="../icons.qrc">
|
||||
<normaloff>:/icons/png/exit2.png</normaloff>:/icons/png/exit2.png</iconset>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="1" colspan="5">
|
||||
<layout class="QHBoxLayout" name="nameHLayout">
|
||||
<item>
|
||||
<layout class="QVBoxLayout" name="verticalLayout">
|
||||
<item>
|
||||
<widget class="QLabel" name="titleLabel">
|
||||
<property name="sizePolicy">
|
||||
@ -294,32 +148,193 @@
|
||||
</font>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string notr="true">Circle</string>
|
||||
<string notr="true">Circle msg</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLabel" name="nameLabel">
|
||||
<property name="text">
|
||||
<string notr="true">name</string>
|
||||
</property>
|
||||
<property name="openExternalLinks">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
<layout class="QHBoxLayout" name="nameHLayout">
|
||||
<item>
|
||||
<widget class="QLabel" name="label">
|
||||
<property name="text">
|
||||
<string>Circle name:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLabel" name="nameLabel">
|
||||
<property name="text">
|
||||
<string notr="true">name</string>
|
||||
</property>
|
||||
<property name="openExternalLinks">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<spacer name="nameHSpacer">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>40</width>
|
||||
<height>20</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item>
|
||||
<spacer name="nameHSpacer">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>40</width>
|
||||
<height>20</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout">
|
||||
<item>
|
||||
<widget class="QLabel" name="forLabel">
|
||||
<property name="text">
|
||||
<string>Identity:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLabel" name="iconLabel">
|
||||
<property name="maximumSize">
|
||||
<size>
|
||||
<width>20</width>
|
||||
<height>20</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>TextLabel</string>
|
||||
</property>
|
||||
<property name="scaledContents">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="GxsIdLabel" name="gxsIdLabel">
|
||||
<property name="text">
|
||||
<string notr="true">name</string>
|
||||
</property>
|
||||
<property name="openExternalLinks">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<spacer name="horizontalSpacer">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>358</width>
|
||||
<height>20</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_2">
|
||||
<item>
|
||||
<widget class="QPushButton" name="membershipButton">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Fixed" vsizetype="Fixed">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="focusPolicy">
|
||||
<enum>Qt::NoFocus</enum>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Accept</string>
|
||||
</property>
|
||||
<property name="icon">
|
||||
<iconset resource="../images.qrc">
|
||||
<normaloff>:/images/accepted16.png</normaloff>:/images/accepted16.png</iconset>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QPushButton" name="inviteeButton">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Fixed" vsizetype="Fixed">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="focusPolicy">
|
||||
<enum>Qt::NoFocus</enum>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Revoke</string>
|
||||
</property>
|
||||
<property name="icon">
|
||||
<iconset resource="../images.qrc">
|
||||
<normaloff>:/images/cancel.png</normaloff>:/images/cancel.png</iconset>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QPushButton" name="expandButton">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Fixed" vsizetype="Fixed">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="focusPolicy">
|
||||
<enum>Qt::NoFocus</enum>
|
||||
</property>
|
||||
<property name="toolTip">
|
||||
<string>Details</string>
|
||||
</property>
|
||||
<property name="icon">
|
||||
<iconset resource="../images.qrc">
|
||||
<normaloff>:/images/informations_24x24.png</normaloff>:/images/informations_24x24.png</iconset>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<spacer name="tollbarHSpacer">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="sizeType">
|
||||
<enum>QSizePolicy::Expanding</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>285</width>
|
||||
<height>18</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QPushButton" name="clearButton">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Fixed" vsizetype="Fixed">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="focusPolicy">
|
||||
<enum>Qt::NoFocus</enum>
|
||||
</property>
|
||||
<property name="toolTip">
|
||||
<string>Remove Item</string>
|
||||
</property>
|
||||
<property name="icon">
|
||||
<iconset resource="../icons.qrc">
|
||||
<normaloff>:/icons/png/exit2.png</normaloff>:/icons/png/exit2.png</iconset>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
@ -336,8 +351,8 @@
|
||||
</customwidget>
|
||||
</customwidgets>
|
||||
<resources>
|
||||
<include location="../images.qrc"/>
|
||||
<include location="../icons.qrc"/>
|
||||
<include location="../images.qrc"/>
|
||||
</resources>
|
||||
<connections/>
|
||||
</ui>
|
||||
|
@ -20,6 +20,7 @@
|
||||
|
||||
#include "GxsForumGroupItem.h"
|
||||
#include "ui_GxsForumGroupItem.h"
|
||||
#include "gui/NewsFeed.h"
|
||||
|
||||
#include "FeedHolder.h"
|
||||
#include "gui/RetroShareLink.h"
|
||||
@ -37,6 +38,16 @@ GxsForumGroupItem::GxsForumGroupItem(FeedHolder *feedHolder, uint32_t feedId, co
|
||||
requestGroup();
|
||||
}
|
||||
|
||||
GxsForumGroupItem::GxsForumGroupItem(FeedHolder *feedHolder, uint32_t feedId, const RsGxsGroupId &groupId, const std::list<RsGxsId>& added_moderators,const std::list<RsGxsId>& removed_moderators,bool isHome, bool autoUpdate):
|
||||
GxsGroupFeedItem(feedHolder, feedId, groupId, isHome, rsGxsForums, autoUpdate),
|
||||
mAddedModerators(added_moderators),
|
||||
mRemovedModerators(removed_moderators)
|
||||
{
|
||||
setup();
|
||||
|
||||
requestGroup();
|
||||
}
|
||||
|
||||
GxsForumGroupItem::GxsForumGroupItem(FeedHolder *feedHolder, uint32_t feedId, const RsGxsForumGroup &group, bool isHome, bool autoUpdate) :
|
||||
GxsGroupFeedItem(feedHolder, feedId, group.mMeta.mGroupId, isHome, rsGxsForums, autoUpdate)
|
||||
{
|
||||
@ -158,10 +169,62 @@ void GxsForumGroupItem::fill()
|
||||
ui->subscribeButton->setEnabled(true);
|
||||
}
|
||||
|
||||
// if (mIsNew)
|
||||
// {
|
||||
if(feedId() == NEWSFEED_UPDATED_FORUM)
|
||||
{
|
||||
if(!mAddedModerators.empty() || !mRemovedModerators.empty())
|
||||
{
|
||||
ui->titleLabel->setText(tr("Moderator list changed"));
|
||||
ui->moderatorList_GB->show();
|
||||
|
||||
QString msg;
|
||||
|
||||
if(!mAddedModerators.empty())
|
||||
{
|
||||
msg += "<b>Added moderators:</b>" ;
|
||||
msg += "<p>";
|
||||
for(auto& gxsid: mAddedModerators)
|
||||
{
|
||||
RsIdentityDetails det;
|
||||
if(rsIdentity->getIdDetails(gxsid,det))
|
||||
msg += QString::fromUtf8(det.mNickname.c_str())+" ("+QString::fromStdString(gxsid.toStdString())+"), ";
|
||||
else
|
||||
msg += QString("[Unknown name]") + " ("+QString::fromStdString(gxsid.toStdString())+"), ";
|
||||
}
|
||||
msg.resize(msg.size()-2);
|
||||
msg += "</p>";
|
||||
}
|
||||
if(!mRemovedModerators.empty())
|
||||
{
|
||||
msg += "<b>Removed moderators:</b>" ;
|
||||
msg += "<p>";
|
||||
for(auto& gxsid: mRemovedModerators)
|
||||
{
|
||||
RsIdentityDetails det;
|
||||
|
||||
if( rsIdentity->getIdDetails(gxsid,det))
|
||||
msg += QString::fromUtf8(det.mNickname.c_str())+" ("+QString::fromStdString(gxsid.toStdString())+"), ";
|
||||
else
|
||||
msg += QString("[Unknown name]") + " ("+QString::fromStdString(gxsid.toStdString())+"), ";
|
||||
}
|
||||
msg.resize(msg.size()-2);
|
||||
msg += "</p>";
|
||||
}
|
||||
ui->moderatorList_TE->setText(msg);
|
||||
}
|
||||
else
|
||||
{
|
||||
ui->moderatorList_GB->hide();
|
||||
|
||||
ui->titleLabel->setText(tr("Forum updated"));
|
||||
ui->moderatorList_GB->hide();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
ui->titleLabel->setText(tr("New Forum"));
|
||||
// }
|
||||
ui->moderatorList_GB->hide();
|
||||
}
|
||||
|
||||
// else
|
||||
// {
|
||||
// ui->titleLabel->setText(tr("Updated Forum"));
|
||||
|
@ -37,6 +37,7 @@ class GxsForumGroupItem : public GxsGroupFeedItem
|
||||
public:
|
||||
/** Default Constructor */
|
||||
GxsForumGroupItem(FeedHolder *feedHolder, uint32_t feedId, const RsGxsGroupId &groupId, bool isHome, bool autoUpdate);
|
||||
GxsForumGroupItem(FeedHolder *feedHolder, uint32_t feedId, const RsGxsGroupId &groupId, const std::list<RsGxsId>& added_moderators,const std::list<RsGxsId>& removed_moderators,bool isHome, bool autoUpdate);
|
||||
GxsForumGroupItem(FeedHolder *feedHolder, uint32_t feedId, const RsGxsForumGroup &group, bool isHome, bool autoUpdate);
|
||||
~GxsForumGroupItem();
|
||||
|
||||
@ -65,6 +66,9 @@ private:
|
||||
|
||||
/** Qt Designer generated object */
|
||||
Ui::GxsForumGroupItem *ui;
|
||||
|
||||
std::list<RsGxsId> mAddedModerators;
|
||||
std::list<RsGxsId> mRemovedModerators;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
@ -6,8 +6,8 @@
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>618</width>
|
||||
<height>161</height>
|
||||
<width>784</width>
|
||||
<height>464</height>
|
||||
</rect>
|
||||
</property>
|
||||
<layout class="QGridLayout">
|
||||
@ -104,8 +104,8 @@
|
||||
<property name="frameShadow">
|
||||
<enum>QFrame::Sunken</enum>
|
||||
</property>
|
||||
<layout class="QGridLayout">
|
||||
<item row="0" column="0">
|
||||
<layout class="QVBoxLayout" name="verticalLayout">
|
||||
<item>
|
||||
<layout class="QGridLayout">
|
||||
<item row="0" column="0" rowspan="2">
|
||||
<widget class="QLabel" name="forumlogo_label">
|
||||
@ -280,7 +280,7 @@
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item row="1" column="0">
|
||||
<item>
|
||||
<widget class="QFrame" name="expandFrame">
|
||||
<layout class="QVBoxLayout">
|
||||
<property name="spacing">
|
||||
@ -334,6 +334,33 @@
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QGroupBox" name="moderatorList_GB">
|
||||
<property name="title">
|
||||
<string>Moderator list</string>
|
||||
</property>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_3">
|
||||
<property name="spacing">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="leftMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="topMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="rightMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="bottomMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<item>
|
||||
<widget class="QTextEdit" name="moderatorList_TE"/>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
|
@ -29,6 +29,7 @@ class NewsFeedUserNotify : public UserNotify
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
virtual QString textInfo() const override { return tr("logged event(s)"); }
|
||||
public:
|
||||
NewsFeedUserNotify(NewsFeed *newsFeed, QObject *parent = 0);
|
||||
|
||||
|
@ -892,6 +892,10 @@ void GxsGroupDialog::getSelectedModerators(std::set<RsGxsId>& ids)
|
||||
|
||||
void GxsGroupDialog::setSelectedModerators(const std::set<RsGxsId>& ids)
|
||||
{
|
||||
ui.addAdmins_cb->setChecked(true);
|
||||
ui.adminsList->show();
|
||||
ui.filtercomboBox->show();
|
||||
|
||||
ui.adminsList->setSelectedIds<RsGxsId,FriendSelectionWidget::IDTYPE_GXS>(ids, false);
|
||||
|
||||
QString moderatorsListString ;
|
||||
|
@ -6,8 +6,8 @@
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>600</width>
|
||||
<height>563</height>
|
||||
<width>1231</width>
|
||||
<height>967</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="windowTitle">
|
||||
@ -223,14 +223,14 @@
|
||||
<item>
|
||||
<widget class="QRadioButton" name="publish_required">
|
||||
<property name="text">
|
||||
<string>Required</string>
|
||||
<string>Re&quired</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QRadioButton" name="publish_encrypt">
|
||||
<property name="text">
|
||||
<string>Encrypted Msgs</string>
|
||||
<string>Encrypted &Msgs</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
@ -856,7 +856,6 @@
|
||||
</customwidgets>
|
||||
<resources>
|
||||
<include location="../icons.qrc"/>
|
||||
<include location="../images.qrc"/>
|
||||
</resources>
|
||||
<connections/>
|
||||
</ui>
|
||||
|
@ -738,14 +738,15 @@ void CreateGxsChannelMsg::loadOriginalChannelPostInfo()
|
||||
{
|
||||
std::vector<RsGxsChannelPost> posts;
|
||||
std::vector<RsGxsComment> comments;
|
||||
std::vector<RsGxsVote> votes;
|
||||
|
||||
if( !rsGxsChannels->getChannelContent(mChannelId,std::set<RsGxsMessageId>({mOrigPostId}),posts,comments) || posts.size() != 1)
|
||||
{
|
||||
std::cerr << "Cannot get channel post data for channel " << mChannelId << " and post " << mOrigPostId << std::endl;
|
||||
return;
|
||||
}
|
||||
if( !rsGxsChannels->getChannelContent(mChannelId,std::set<RsGxsMessageId>({mOrigPostId}),posts,comments,votes) || posts.size() != 1)
|
||||
{
|
||||
std::cerr << "Cannot get channel post data for channel " << mChannelId << " and post " << mOrigPostId << std::endl;
|
||||
return;
|
||||
}
|
||||
|
||||
RsQThreadUtils::postToObject( [posts,this]()
|
||||
RsQThreadUtils::postToObject( [posts,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
|
||||
|
@ -46,6 +46,8 @@
|
||||
#define ROLE_FILE_HASH Qt::UserRole + 3
|
||||
#define ROLE_MSG Qt::UserRole + 4
|
||||
|
||||
Q_DECLARE_METATYPE(Sha1CheckSum)
|
||||
|
||||
GxsChannelFilesWidget::GxsChannelFilesWidget(QWidget *parent) :
|
||||
QWidget(parent), ui(new Ui::GxsChannelFilesWidget)
|
||||
{
|
||||
|
@ -694,7 +694,7 @@ void GxsChannelPostsWidget::insertChannelPosts(std::vector<RsGxsChannelPost>& po
|
||||
break;
|
||||
|
||||
if (thread)
|
||||
thread->emitAddPost(qVariantFromValue(*it), related, ++pos, count);
|
||||
thread->emitAddPost(QVariant::fromValue(*it), related, ++pos, count);
|
||||
else
|
||||
createPostItem(*it, related);
|
||||
}
|
||||
@ -812,8 +812,9 @@ void GxsChannelPostsWidget::getMsgData(const std::set<RsGxsMessageId>& msgIds,st
|
||||
{
|
||||
std::vector<RsGxsChannelPost> posts;
|
||||
std::vector<RsGxsComment> comments;
|
||||
std::vector<RsGxsVote> votes;
|
||||
|
||||
rsGxsChannels->getChannelContent( groupId(),msgIds,posts,comments );
|
||||
rsGxsChannels->getChannelContent( groupId(),msgIds,posts,comments,votes );
|
||||
|
||||
psts.clear();
|
||||
|
||||
@ -825,8 +826,9 @@ void GxsChannelPostsWidget::getAllMsgData(std::vector<RsGxsGenericMsgData*>& pst
|
||||
{
|
||||
std::vector<RsGxsChannelPost> posts;
|
||||
std::vector<RsGxsComment> comments;
|
||||
std::vector<RsGxsVote> votes;
|
||||
|
||||
rsGxsChannels->getChannelAllContent( groupId(),posts,comments );
|
||||
rsGxsChannels->getChannelAllContent( groupId(),posts,comments,votes );
|
||||
|
||||
psts.clear();
|
||||
|
||||
|
@ -21,6 +21,7 @@
|
||||
#include "retroshare/rsgxschannels.h"
|
||||
#include "GxsChannelUserNotify.h"
|
||||
#include "gui/MainWindow.h"
|
||||
#include "gui/common/FilesDefs.h"
|
||||
|
||||
GxsChannelUserNotify::GxsChannelUserNotify(RsGxsIfaceHelper *ifaceImpl, const GxsGroupFrameDialog *g, QObject *parent) :
|
||||
GxsUserNotify(ifaceImpl, g, parent)
|
||||
@ -37,12 +38,12 @@ bool GxsChannelUserNotify::hasSetting(QString *name, QString *group)
|
||||
|
||||
QIcon GxsChannelUserNotify::getIcon()
|
||||
{
|
||||
return QIcon(":/icons/png/channel.png");
|
||||
return FilesDefs::getIconFromQtResourcePath(":/icons/png/channel.png");
|
||||
}
|
||||
|
||||
QIcon GxsChannelUserNotify::getMainIcon(bool hasNew)
|
||||
{
|
||||
return hasNew ? QIcon(":/icons/png/channels-notify.png") : QIcon(":/icons/png/channel.png");
|
||||
return hasNew ? FilesDefs::getIconFromQtResourcePath(":/icons/png/channels-notify.png") : FilesDefs::getIconFromQtResourcePath(":/icons/png/channel.png");
|
||||
}
|
||||
|
||||
void GxsChannelUserNotify::iconClicked()
|
||||
|
@ -32,6 +32,7 @@ public:
|
||||
GxsChannelUserNotify(RsGxsIfaceHelper *ifaceImpl, const GxsGroupFrameDialog *g, QObject *parent = 0);
|
||||
|
||||
virtual bool hasSetting(QString *name, QString *group);
|
||||
virtual QString textInfo() const override { return tr("new message(s)"); }
|
||||
|
||||
private:
|
||||
virtual QIcon getIcon();
|
||||
|
@ -1225,7 +1225,7 @@ void RsGxsForumModel::setMsgReadStatus(const QModelIndex& i,bool read_status,boo
|
||||
if(!i.isValid())
|
||||
return ;
|
||||
|
||||
// no need to call preMods()/postMods() here because we'renot changing the model
|
||||
// no need to call preMods()/postMods() here because we'renot changing the model
|
||||
|
||||
void *ref = i.internalPointer();
|
||||
uint32_t entry = 0;
|
||||
@ -1233,18 +1233,10 @@ void RsGxsForumModel::setMsgReadStatus(const QModelIndex& i,bool read_status,boo
|
||||
if(!convertRefPointerToTabEntry(ref,entry) || entry >= mPosts.size())
|
||||
return ;
|
||||
|
||||
bool has_unread_below,has_read_below;
|
||||
recursSetMsgReadStatus(entry,read_status,with_children) ;
|
||||
bool has_unread_below, has_read_below;
|
||||
recursSetMsgReadStatus(entry,read_status,with_children) ;
|
||||
recursUpdateReadStatusAndTimes(0,has_unread_below,has_read_below);
|
||||
|
||||
// Normally we should only update the parents up to the top of the tree, but it's complicated and the update here doesn't really cost,
|
||||
// so we blindly update the whole widget.
|
||||
|
||||
if(mTreeMode == TREE_MODE_FLAT)
|
||||
emit dataChanged(createIndex(0,0,(void*)NULL), createIndex(mPosts.size(),COLUMN_THREAD_NB_COLUMNS-1,(void*)NULL));
|
||||
else
|
||||
emit dataChanged(createIndex(0,0,(void*)NULL), createIndex(mPosts[0].mChildren.size(),COLUMN_THREAD_NB_COLUMNS-1,(void*)NULL));
|
||||
|
||||
}
|
||||
|
||||
void RsGxsForumModel::recursSetMsgReadStatus(ForumModelIndex i,bool read_status,bool with_children)
|
||||
@ -1270,6 +1262,9 @@ void RsGxsForumModel::recursSetMsgReadStatus(ForumModelIndex i,bool read_status,
|
||||
}
|
||||
else
|
||||
rsGxsForums->setMessageReadStatus(token,std::make_pair( mForumGroup.mMeta.mGroupId, mPosts[i].mMsgId ), read_status);
|
||||
|
||||
QModelIndex itemIndex = createIndex(i - 1, 0, &mPosts[i]);
|
||||
emit dataChanged(itemIndex, itemIndex);
|
||||
}
|
||||
|
||||
if(!with_children)
|
||||
|
@ -1151,22 +1151,29 @@ void GxsForumThreadWidget::insertMessageData(const RsGxsForumMsg &msg)
|
||||
ui->by_label->show();
|
||||
ui->threadTreeWidget->setFocus();
|
||||
|
||||
if(redacted)
|
||||
{
|
||||
if(redacted) {
|
||||
QString extraTxt = tr( "<p><font color=\"#ff0000\"><b>The author of this message (with ID %1) is banned.</b>").arg(QString::fromStdString(msg.mMeta.mAuthorId.toStdString())) ;
|
||||
extraTxt += tr( "<UL><li><b><font color=\"#ff0000\">Messages from this author are not forwarded. </font></b></li>") ;
|
||||
extraTxt += tr( "<li><b><font color=\"#ff0000\">Messages from this author are replaced by this text. </font></b></li></ul>") ;
|
||||
extraTxt += tr( "<p><b><font color=\"#ff0000\">You can force the visibility and forwarding of messages by setting a different opinion for that Id in People's tab.</font></b></p>") ;
|
||||
|
||||
ui->postText->setHtml(extraTxt) ;
|
||||
}
|
||||
else
|
||||
{
|
||||
uint32_t flags = RSHTML_FORMATTEXT_EMBED_LINKS;
|
||||
if(Settings->getForumLoadEmoticons())
|
||||
flags |= RSHTML_FORMATTEXT_EMBED_SMILEYS ;
|
||||
} else {
|
||||
uint32_t flags = RSHTML_FORMATTEXT_EMBED_LINKS;
|
||||
if(Settings->getForumLoadEmoticons())
|
||||
flags |= RSHTML_FORMATTEXT_EMBED_SMILEYS ;
|
||||
flags |= RSHTML_OPTIMIZEHTML_MASK;
|
||||
|
||||
QString extraTxt = RsHtml().formatText(ui->postText->document(), QString::fromUtf8(msg.mMsg.c_str()),flags);
|
||||
QColor backgroundColor = ui->postText->palette().base().color();
|
||||
qreal desiredContrast = Settings->valueFromGroup("Forum",
|
||||
"MinimumContrast", 4.5).toDouble();
|
||||
int desiredMinimumFontSize = Settings->valueFromGroup("Forum",
|
||||
"MinimumFontSize", 10).toInt();
|
||||
|
||||
QString extraTxt = RsHtml().formatText(ui->postText->document(),
|
||||
QString::fromUtf8(msg.mMsg.c_str()), flags
|
||||
, backgroundColor, desiredContrast, desiredMinimumFontSize
|
||||
);
|
||||
ui->postText->setHtml(extraTxt);
|
||||
}
|
||||
|
||||
|
@ -506,6 +506,11 @@
|
||||
<verstretch>10</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="font">
|
||||
<font>
|
||||
<family>MS Sans Serif</family>
|
||||
</font>
|
||||
</property>
|
||||
<property name="contextMenuPolicy">
|
||||
<enum>Qt::CustomContextMenu</enum>
|
||||
</property>
|
||||
|
@ -19,6 +19,7 @@
|
||||
*******************************************************************************/
|
||||
|
||||
#include "retroshare/rsgxsforums.h"
|
||||
#include "gui/common/FilesDefs.h"
|
||||
#include "GxsForumUserNotify.h"
|
||||
#include "gui/MainWindow.h"
|
||||
|
||||
@ -38,12 +39,12 @@ bool GxsForumUserNotify::hasSetting(QString *name, QString *group)
|
||||
|
||||
QIcon GxsForumUserNotify::getIcon()
|
||||
{
|
||||
return QIcon(":/icons/png/forums.png");
|
||||
return FilesDefs::getIconFromQtResourcePath(":/icons/png/forums.png");
|
||||
}
|
||||
|
||||
QIcon GxsForumUserNotify::getMainIcon(bool hasNew)
|
||||
{
|
||||
return hasNew ? QIcon(":/icons/png/forums-notify.png") : QIcon(":/icons/png/forums.png");
|
||||
return hasNew ? FilesDefs::getIconFromQtResourcePath(":/icons/png/forums-notify.png") : FilesDefs::getIconFromQtResourcePath(":/icons/png/forums.png");
|
||||
}
|
||||
|
||||
void GxsForumUserNotify::iconClicked()
|
||||
|
@ -31,6 +31,7 @@ public:
|
||||
GxsForumUserNotify(RsGxsIfaceHelper *ifaceImpl, const GxsGroupFrameDialog *g, QObject *parent = 0);
|
||||
|
||||
virtual bool hasSetting(QString *name, QString *group);
|
||||
virtual QString textInfo() const override { return tr("new message(s)"); }
|
||||
|
||||
private:
|
||||
virtual QIcon getIcon();
|
||||
|
@ -311,6 +311,7 @@
|
||||
<file>icons/mail/foward.png</file>
|
||||
<file>icons/mail/reply.png</file>
|
||||
<file>icons/mail/reply-all.png</file>
|
||||
<file>icons/mail/attach16.png</file>
|
||||
<file>icons/mail/attach24.png</file>
|
||||
<file>icons/mail/write-mail.png</file>
|
||||
<file>icons/textedit/align.png</file>
|
||||
|
BIN
retroshare-gui/src/gui/icons/mail/attach16.png
Normal file
BIN
retroshare-gui/src/gui/icons/mail/attach16.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 628 B |
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user