diff --git a/libretroshare/src/retroshare/rsgxscircles.h b/libretroshare/src/retroshare/rsgxscircles.h index a760c008e..8ce446200 100644 --- a/libretroshare/src/retroshare/rsgxscircles.h +++ b/libretroshare/src/retroshare/rsgxscircles.h @@ -142,6 +142,7 @@ public: /* standard load */ virtual bool getGroupData(const uint32_t &token, std::vector &groups) = 0; + virtual bool getMsgData(const uint32_t &token, std::vector &msgs) = 0; /* make new group */ virtual void createGroup(uint32_t& token, RsGxsCircleGroup &group) = 0; diff --git a/libretroshare/src/retroshare/rsnotify.h b/libretroshare/src/retroshare/rsnotify.h index 8a2dfff8b..d5a208379 100644 --- a/libretroshare/src/retroshare/rsnotify.h +++ b/libretroshare/src/retroshare/rsnotify.h @@ -77,6 +77,7 @@ const uint32_t RS_FEED_TYPE_FILES = 0x0400; const uint32_t RS_FEED_TYPE_SECURITY = 0x0800; const uint32_t RS_FEED_TYPE_POSTED = 0x1000; const uint32_t RS_FEED_TYPE_SECURITY_IP = 0x2000; +const uint32_t RS_FEED_TYPE_CIRCLE = 0x4000; const uint32_t RS_FEED_ITEM_PEER_CONNECT = RS_FEED_TYPE_PEER | 0x0001; const uint32_t RS_FEED_ITEM_PEER_DISCONNECT = RS_FEED_TYPE_PEER | 0x0002; @@ -114,9 +115,12 @@ const uint32_t RS_FEED_ITEM_POSTED_NEW = RS_FEED_TYPE_POSTED | 0x0001; //const uint32_t RS_FEED_ITEM_POSTED_UPDATE = RS_FEED_TYPE_POSTED | 0x0002; const uint32_t RS_FEED_ITEM_POSTED_MSG = RS_FEED_TYPE_POSTED | 0x0003; -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_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_MESSAGE_CONNECT_ATTEMPT = 0x0001; diff --git a/libretroshare/src/rsitems/rsgxscircleitems.cc b/libretroshare/src/rsitems/rsgxscircleitems.cc index 40ae6cf5f..a468f483f 100644 --- a/libretroshare/src/rsitems/rsgxscircleitems.cc +++ b/libretroshare/src/rsitems/rsgxscircleitems.cc @@ -55,7 +55,8 @@ void RsGxsCircleSubscriptionRequestItem::clear() void RsGxsCircleMsgItem::serial_process(RsGenericSerializer::SerializeJob j,RsGenericSerializer::SerializeContext& ctx) { - RsTypeSerializer::serial_process(j,ctx,TLV_TYPE_STR_MSG,msg.stuff,"msg.stuff") ; + //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 RsGxsCircleSubscriptionRequestItem::serial_process(RsGenericSerializer::SerializeJob j,RsGenericSerializer::SerializeContext& ctx) @@ -74,7 +75,7 @@ void RsGxsCircleGroupItem::serial_process(RsGenericSerializer::SerializeJob j,Rs void RsGxsCircleMsgItem::clear() { - msg.stuff.clear(); + mMsg.stuff.clear(); } void RsGxsCircleGroupItem::clear() diff --git a/libretroshare/src/rsitems/rsgxscircleitems.h b/libretroshare/src/rsitems/rsgxscircleitems.h index 5734b34cd..8e57b478c 100644 --- a/libretroshare/src/rsitems/rsgxscircleitems.h +++ b/libretroshare/src/rsitems/rsgxscircleitems.h @@ -78,7 +78,7 @@ public: virtual void serial_process(RsGenericSerializer::SerializeJob j,RsGenericSerializer::SerializeContext& ctx); - RsGxsCircleMsg msg; + RsGxsCircleMsg mMsg; }; class RsGxsCircleSubscriptionRequestItem: public RsGxsMsgItem diff --git a/libretroshare/src/services/p3gxscircles.cc b/libretroshare/src/services/p3gxscircles.cc index 0daa3d24e..2e2796747 100644 --- a/libretroshare/src/services/p3gxscircles.cc +++ b/libretroshare/src/services/p3gxscircles.cc @@ -35,6 +35,7 @@ #include "pgp/pgpauxutils.h" #include "retroshare/rsgxscircles.h" #include "retroshare/rspeers.h" +#include "rsserver/p3face.h" #include #include @@ -194,30 +195,38 @@ void p3GxsCircles::service_tick() void p3GxsCircles::notifyChanges(std::vector &changes) { #ifdef DEBUG_CIRCLES - std::cerr << "p3GxsCircles::notifyChanges()"; - std::cerr << std::endl; + std::cerr << "p3GxsCircles::notifyChanges()"; + std::cerr << std::endl; #endif - std::vector::iterator it; - for(it = changes.begin(); it != changes.end(); ++it) - { - RsGxsGroupChange *groupChange = dynamic_cast(*it); - RsGxsMsgChange *msgChange = dynamic_cast(*it); + p3Notify *notify = RsServer::notify(); + std::vector::iterator it; + for(it = changes.begin(); it != changes.end(); ++it) + { + RsGxsGroupChange *groupChange = dynamic_cast(*it); + RsGxsMsgChange *msgChange = dynamic_cast(*it); + RsGxsNotify *c = *it; - if (msgChange && !msgChange->metaChange()) - { + if (msgChange && !msgChange->metaChange()) + { #ifdef DEBUG_CIRCLES - std::cerr << " Found circle Message Change Notification" << std::endl; + std::cerr << " Found circle Message Change Notification" << std::endl; #endif - for(std::map >::iterator mit = msgChange->msgChangeMap.begin(); mit != msgChange->msgChangeMap.end(); ++mit) - { + for(std::map >::iterator mit = msgChange->msgChangeMap.begin(); mit != msgChange->msgChangeMap.end(); ++mit) + { #ifdef DEBUG_CIRCLES - std::cerr << " Msgs for Group: " << mit->first << std::endl; + std::cerr << " Msgs for Group: " << mit->first << std::endl; #endif - for(std::map >::const_iterator it2(msgChange->msgChangeMap.begin());it2!=msgChange->msgChangeMap.end();++it2) - force_cache_reload(RsGxsCircleId(it2->first)) ; - } - } + force_cache_reload(RsGxsCircleId(mit->first)); + if (notify && (c->getType() == RsGxsNotify::TYPE_RECEIVE) ) + for (std::vector::const_iterator msgIdIt(mit->second.begin()), end(mit->second.end()); msgIdIt != end; ++msgIdIt) + { + const RsGxsMessageId& msgId = *msgIdIt; + notify->AddFeedItem(RS_FEED_ITEM_CIRCLE_MEMB_REQ,RsGxsCircleId(mit->first).toStdString(),msgId.toStdString()); + } + + } + } /* add groups to ExternalIdList (Might get Personal Circles here until NetChecks in place) */ if (groupChange && !groupChange->metaChange()) @@ -245,16 +254,19 @@ void p3GxsCircles::notifyChanges(std::vector &changes) } } - if(groupChange) - for(std::list::const_iterator git(groupChange->mGrpIdList.begin());git!=groupChange->mGrpIdList.end();++git) - { + if(groupChange) + for(std::list::const_iterator git(groupChange->mGrpIdList.begin());git!=groupChange->mGrpIdList.end();++git) + { #ifdef DEBUG_CIRCLES - std::cerr << " forcing cache loading for circle " << *git << " in order to trigger subscribe update." << std::endl; + std::cerr << " forcing cache loading for circle " << *git << " in order to trigger subscribe update." << std::endl; #endif - force_cache_reload(RsGxsCircleId(*git)) ; - } - } - RsGxsIfaceHelper::receiveChanges(changes); // this clear up the vector and delete its elements + force_cache_reload(RsGxsCircleId(*git)) ; + if (notify && (c->getType() == RsGxsNotify::TYPE_RECEIVE) ) + notify->AddFeedItem(RS_FEED_ITEM_CIRCLE_INVIT_REC,RsGxsCircleId(*git).toStdString(),""); + } + + } + RsGxsIfaceHelper::receiveChanges(changes); // this clear up the vector and delete its elements } /********************************************************************************/ @@ -496,6 +508,62 @@ bool p3GxsCircles::getGroupData(const uint32_t &token, std::vector &msgs) +{ + GxsMsgDataMap msgData; + bool ok = RsGenExchange::getMsgData(token, msgData); + + if(ok) + { + GxsMsgDataMap::iterator mit = msgData.begin(); + + for(; mit != msgData.end(); ++mit) + { + std::vector& msgItems = mit->second; + std::vector::iterator vit = msgItems.begin(); + + for(; vit != msgItems.end(); ++vit) + { + RsGxsCircleMsgItem* item = dynamic_cast(*vit); + RsGxsCircleSubscriptionRequestItem* rsItem = dynamic_cast(*vit); + if(item) + { + RsGxsCircleMsg msg = item->mMsg; + msg.mMeta = item->meta; + msgs.push_back(msg); + delete item; + } + else if (rsItem) + { + RsGxsCircleMsg msg ;//= rsItem->mMsg; + msg.mMeta = rsItem->meta; + switch (rsItem->subscription_type) + { + case RsGxsCircleSubscriptionRequestItem::SUBSCRIPTION_REQUEST_UNKNOWN: + msg.stuff.clear(); + break; + case RsGxsCircleSubscriptionRequestItem::SUBSCRIPTION_REQUEST_SUBSCRIBE: + msg.stuff="SUBSCRIPTION_REQUEST_SUBSCRIBE"; + break; + case RsGxsCircleSubscriptionRequestItem::SUBSCRIPTION_REQUEST_UNSUBSCRIBE: + msg.stuff="SUBSCRIPTION_REQUEST_UNSUBSCRIBE"; + break; + } + msgs.push_back(msg); + delete rsItem; + } + else + { + std::cerr << "Not a GxsCircleMsgItem, deleting!" << std::endl; + delete *vit; + } + } + } + } + + return ok; +} + void p3GxsCircles::createGroup(uint32_t& token, RsGxsCircleGroup &group) { #ifdef DEBUG_CIRCLES @@ -2065,21 +2133,3 @@ bool p3GxsCircles::processMembershipRequests(uint32_t token) return true ; } - - - - - - - - - - - - - - - - - - diff --git a/libretroshare/src/services/p3gxscircles.h b/libretroshare/src/services/p3gxscircles.h index 06ddad407..4e011eea0 100644 --- a/libretroshare/src/services/p3gxscircles.h +++ b/libretroshare/src/services/p3gxscircles.h @@ -199,6 +199,7 @@ virtual RsServiceInfo getServiceInfo(); virtual bool getGroupData(const uint32_t &token, std::vector &groups); + virtual bool getMsgData(const uint32_t &token, std::vector &msgs); virtual void createGroup(uint32_t& token, RsGxsCircleGroup &group); virtual void updateGroup(uint32_t &token, RsGxsCircleGroup &group); diff --git a/retroshare-gui/src/gui/NewsFeed.cpp b/retroshare-gui/src/gui/NewsFeed.cpp index 4b08caec9..6051510a5 100644 --- a/retroshare-gui/src/gui/NewsFeed.cpp +++ b/retroshare-gui/src/gui/NewsFeed.cpp @@ -25,45 +25,43 @@ #include "NewsFeed.h" #include "ui_NewsFeed.h" -#include -#include +#include #include #include -#include #include +#include +#include #include -#include - -#include "feeds/GxsChannelGroupItem.h" -#include "feeds/GxsChannelPostItem.h" -#include "feeds/GxsForumGroupItem.h" -#include "feeds/GxsForumMsgItem.h" -#include "feeds/PostedGroupItem.h" -#include "Posted/PostedItem.h" -#include "feeds/GxsForumMsgItem.h" - -#include "settings/rsettingswin.h" +#include +#include "feeds/ChatMsgItem.h" #ifdef BLOGS #include "feeds/BlogNewItem.h" #include "feeds/BlogMsgItem.h" #endif - +#include "feeds/GxsCircleItem.h" +#include "feeds/GxsChannelGroupItem.h" +#include "feeds/GxsChannelPostItem.h" +#include "feeds/GxsForumGroupItem.h" +#include "feeds/GxsForumMsgItem.h" #include "feeds/MsgItem.h" +#include "feeds/NewsFeedUserNotify.h" #include "feeds/PeerItem.h" -#include "feeds/ChatMsgItem.h" +#include "feeds/PostedGroupItem.h" #include "feeds/SecurityItem.h" #include "feeds/SecurityIpItem.h" -#include "feeds/NewsFeedUserNotify.h" +#include "settings/rsettingswin.h" #include "settings/rsharesettings.h" + #include "chat/ChatDialog.h" +#include "Posted/PostedItem.h" #include "msgs/MessageComposer.h" +#include "msgs/MessageInterface.h" + #include "common/FeedNotify.h" #include "notifyqt.h" -#include "gui/msgs/MessageInterface.h" - const uint32_t NEWSFEED_PEERLIST = 0x0001; const uint32_t NEWSFEED_FORUMNEWLIST = 0x0002; @@ -80,6 +78,7 @@ const uint32_t NEWSFEED_CHATMSGLIST = 0x0009; const uint32_t NEWSFEED_SECLIST = 0x000a; const uint32_t NEWSFEED_POSTEDNEWLIST = 0x000b; const uint32_t NEWSFEED_POSTEDMSGLIST = 0x000c; +const uint32_t NEWSFEED_CIRCLELIST = 0x000d; #define ROLE_RECEIVED FEED_TREEWIDGET_SORTROLE @@ -102,6 +101,7 @@ NewsFeed::NewsFeed(QWidget *parent) : ui->setupUi(this); mTokenQueueChannel = NULL; + mTokenQueueCircle = NULL; mTokenQueueForum = NULL; mTokenQueuePosted = NULL; @@ -156,6 +156,9 @@ NewsFeed::~NewsFeed() if (mTokenQueueChannel) { delete(mTokenQueueChannel); } + if (mTokenQueueCircle) { + delete(mTokenQueueCircle); + } if (mTokenQueueForum) { delete(mTokenQueueForum); } @@ -370,6 +373,52 @@ void NewsFeed::updateDisplay() if (flags & RS_FEED_TYPE_FILES) addFeedItemFilesNew(fi); break; + + case RS_FEED_ITEM_CIRCLE_MEMB_REQ: + if (flags & RS_FEED_TYPE_CIRCLE) + { + if (!mTokenQueueCircle) { + mTokenQueueCircle = new TokenQueue(rsGxsCircles->getTokenService(), instance); + } + + RsGxsGroupId grpId(fi.mId1); + RsGxsMessageId msgId(fi.mId2); + if (!grpId.isNull() && !msgId.isNull()) { + RsTokReqOptions opts; + opts.mReqType = GXS_REQUEST_TYPE_MSG_DATA; + + GxsMsgReq msgIds; + std::vector &vect_msgIds = msgIds[grpId]; + vect_msgIds.push_back(msgId); + + uint32_t token; + mTokenQueueCircle->requestMsgInfo(token, RS_TOKREQ_ANSTYPE_DATA, opts, msgIds, TOKEN_TYPE_MESSAGE); + } + } + // addFeedItemCircleMembReq(fi); + break; + case RS_FEED_ITEM_CIRCLE_INVIT_REC: + if (flags & RS_FEED_TYPE_CIRCLE) + { + if (!mTokenQueueCircle) { + mTokenQueueCircle = new TokenQueue(rsGxsCircles->getTokenService(), instance); + } + + RsGxsGroupId grpId(fi.mId1); + if (!grpId.isNull()) { + RsTokReqOptions opts; + opts.mReqType = GXS_REQUEST_TYPE_GROUP_DATA; + + std::list grpIds; + grpIds.push_back(grpId); + + uint32_t token; + mTokenQueueCircle->requestGroupInfo(token, RS_TOKREQ_ANSTYPE_SUMMARY, opts, grpIds, TOKEN_TYPE_GROUP); + } + } + // addFeedItemCircleInvitRec(fi); + break; + default: std::cerr << "(EE) Unknown type " << std::hex << fi.mType << std::dec << " in news feed." << std::endl; break; @@ -534,6 +583,24 @@ void NewsFeed::testFeeds(uint notifyFlags) // not used // instance->addFeedItemFilesNew(fi); break; + + case RS_FEED_TYPE_CIRCLE: + { + if (!instance->mTokenQueueCircle) { + instance->mTokenQueueCircle = new TokenQueue(rsGxsCircles->getTokenService(), instance); + } + + RsTokReqOptions opts; + opts.mReqType = GXS_REQUEST_TYPE_GROUP_DATA; + uint32_t token; + instance->mTokenQueueCircle->requestGroupInfo(token, RS_TOKREQ_ANSTYPE_SUMMARY, opts, TOKEN_TYPE_GROUP); + + break; + } +// instance->addFeedItemCircleMembReq(fi); +// instance->addFeedItemCircleInvitRec(fi); + break; + } } @@ -542,6 +609,78 @@ void NewsFeed::testFeeds(uint notifyFlags) instance->sendNewsFeedChanged(); } +void NewsFeed::loadCircleGroup(const uint32_t &token) +{ + std::vector groups; + if (!rsGxsCircles->getGroupData(token, groups)) { + std::cerr << "NewsFeed::loadCircleGroup() ERROR getting data"; + std::cerr << std::endl; + return; + } + + std::list own_identities; + rsIdentity->getOwnIds(own_identities); + + std::vector::const_iterator circleIt; + for (circleIt = groups.begin(); circleIt != groups.end(); ++circleIt) { + RsGxsCircleGroup group = *(circleIt); + RsGxsCircleDetails details; + if(rsGxsCircles->getCircleDetails(group.mMeta.mCircleId,details)) + { + for(std::list::const_iterator it(own_identities.begin());it!=own_identities.end();++it) { + std::map::const_iterator vit = details.mSubscriptionFlags.find(*it); + uint32_t subscribe_flags = (vit == details.mSubscriptionFlags.end())?0:(vit->second); + + if( !(subscribe_flags & GXS_EXTERNAL_CIRCLE_FLAGS_SUBSCRIBED) + && (subscribe_flags & GXS_EXTERNAL_CIRCLE_FLAGS_IN_ADMIN_LIST) ) { + + RsFeedItem fi; + fi.mId1 = group.mMeta.mGroupId.toStdString(); + fi.mId2 = it->toStdString(); + + instance->addFeedItemCircleInvitRec(fi); + + } + } + } + } +} + +void NewsFeed::loadCircleMessage(const uint32_t &token) +{ + std::vector msgs; + if (!rsGxsCircles->getMsgData(token, msgs)) { + std::cerr << "NewsFeed::loadCircleMessage() ERROR getting data"; + std::cerr << std::endl; + return; + } + + std::list own_identities; + rsIdentity->getOwnIds(own_identities); + + std::vector::iterator msgIt; + for (msgIt = msgs.begin(); msgIt != msgs.end(); ++msgIt) { + RsGxsCircleMsg msg = *(msgIt); + RsGxsCircleDetails details; + if(rsGxsCircles->getCircleDetails(RsGxsCircleId(msg.mMeta.mGroupId),details)) { + //for(std::list::const_iterator it(own_identities.begin());it!=own_identities.end();++it) { + // std::map::const_iterator vit = details.mSubscriptionFlags.find(*it); + // if (vit != details.mSubscriptionFlags.end()) { + RsFeedItem fi; + fi.mId1 = msgIt->mMeta.mGroupId.toStdString(); + fi.mId2 = msgIt->mMeta.mAuthorId.toStdString(); + + if (msgIt->stuff == "SUBSCRIPTION_REQUEST_UNSUBSCRIBE") + instance->remFeedItemCircleMembReq(fi); + else + instance->addFeedItemCircleMembReq(fi); + + //} + //} + } + } +} + void NewsFeed::loadChannelGroup(const uint32_t &token) { std::vector groups; @@ -821,7 +960,24 @@ void NewsFeed::loadRequest(const TokenQueue *queue, const TokenRequest &req) break; default: - std::cerr << "NewsFeed::loadRequest() ERROR: INVALID TYPE"; + std::cerr << "NewsFeed::loadRequest() ERROR: INVALID CHANNEL TYPE"; + std::cerr << std::endl; + break; + } + } + + if (queue == mTokenQueueCircle) { + switch (req.mUserType) { + case TOKEN_TYPE_GROUP: + loadCircleGroup(req.mToken); + break; + + case TOKEN_TYPE_MESSAGE: + loadCircleMessage(req.mToken); + break; + + default: + std::cerr << "NewsFeed::loadRequest() ERROR: INVALID CIRCLE TYPE"; std::cerr << std::endl; break; } @@ -842,7 +998,7 @@ void NewsFeed::loadRequest(const TokenQueue *queue, const TokenRequest &req) break; default: - std::cerr << "NewsFeed::loadRequest() ERROR: INVALID TYPE"; + std::cerr << "NewsFeed::loadRequest() ERROR: INVALID FORUM TYPE"; std::cerr << std::endl; break; } @@ -859,7 +1015,7 @@ void NewsFeed::loadRequest(const TokenQueue *queue, const TokenRequest &req) break; default: - std::cerr << "NewsFeed::loadRequest() ERROR: INVALID TYPE"; + std::cerr << "NewsFeed::loadRequest() ERROR: INVALID POSTED TYPE"; std::cerr << std::endl; break; } @@ -908,18 +1064,24 @@ void NewsFeed::addFeedItem(FeedItem *item) struct AddFeedItemIfUniqueData { - AddFeedItemIfUniqueData(FeedItem *feedItem, int type, const RsPeerId &sslId, const std::string& ipAddr, const std::string& ipAddrReported) - : mType(type), mSslId(sslId), mIpAddr(ipAddr), mIpAddrReported(ipAddrReported) + AddFeedItemIfUniqueData(FeedItem *feedItem, int type + , const std::string& id1, const std::string& id2 + , const std::string& id3, const std::string& id4) + : mType(type), mId1(id1), mId2(id2), mId3(id3), mId4(id4) { + mGxsCircleItem = dynamic_cast(feedItem); mPeerItem = dynamic_cast(feedItem); mSecItem = dynamic_cast(feedItem); mSecurityIpItem = dynamic_cast(feedItem); } int mType; - const RsPeerId &mSslId; - const std::string& mIpAddr; - const std::string& mIpAddrReported; + const std::string& mId1; + const std::string& mId2; + const std::string& mId3; + const std::string& mId4; + + GxsCircleItem *mGxsCircleItem; PeerItem *mPeerItem; SecurityItem *mSecItem; SecurityIpItem *mSecurityIpItem; @@ -928,13 +1090,21 @@ struct AddFeedItemIfUniqueData static bool addFeedItemIfUniqueCallback(FeedItem *feedItem, void *data) { AddFeedItemIfUniqueData *findData = (AddFeedItemIfUniqueData*) data; - if (!findData || findData->mSslId.isNull()) { + if (!findData || findData->mId1.empty()) { + return false; + } + + if (findData->mGxsCircleItem) { + GxsCircleItem *gxsCircleItem = dynamic_cast(feedItem); + if (gxsCircleItem && gxsCircleItem->isSame(RsGxsCircleId(findData->mId1), RsGxsId(findData->mId2), findData->mType)) { + return true; + } return false; } if (findData->mPeerItem) { PeerItem *peerItem = dynamic_cast(feedItem); - if (peerItem && peerItem->isSame(findData->mSslId, findData->mType)) { + if (peerItem && peerItem->isSame(RsPeerId(findData->mId1), findData->mType)) { return true; } return false; @@ -942,7 +1112,7 @@ static bool addFeedItemIfUniqueCallback(FeedItem *feedItem, void *data) if (findData->mSecItem) { SecurityItem *secitem = dynamic_cast(feedItem); - if (secitem && secitem->isSame(findData->mSslId, findData->mType)) { + if (secitem && secitem->isSame(RsPeerId(findData->mId1), findData->mType)) { return true; } return false; @@ -950,7 +1120,7 @@ static bool addFeedItemIfUniqueCallback(FeedItem *feedItem, void *data) if (findData->mSecurityIpItem) { SecurityIpItem *securityIpItem = dynamic_cast(feedItem); - if (securityIpItem && securityIpItem->isSame(findData->mIpAddr, findData->mIpAddrReported, findData->mType)) { + if (securityIpItem && securityIpItem->isSame(findData->mId1, findData->mId2, findData->mType)) { return true; } return false; @@ -959,9 +1129,9 @@ static bool addFeedItemIfUniqueCallback(FeedItem *feedItem, void *data) return false; } -void NewsFeed::addFeedItemIfUnique(FeedItem *item, int itemType, const RsPeerId &sslId, const std::string& ipAddr, const std::string& ipAddrReported, bool replace) +void NewsFeed::addFeedItemIfUnique(FeedItem *item, int itemType, const std::string& id1, const std::string& id2, const std::string& id3, const std::string& id4, bool replace) { - AddFeedItemIfUniqueData data(item, itemType, sslId, ipAddr, ipAddrReported); + AddFeedItemIfUniqueData data(item, itemType, id1, id2, id3, id4); FeedItem *feedItem = ui->feedWidget->findFeedItem(addFeedItemIfUniqueCallback, &data); if (feedItem) { @@ -976,6 +1146,18 @@ void NewsFeed::addFeedItemIfUnique(FeedItem *item, int itemType, const RsPeerId addFeedItem(item); } +void NewsFeed::remUniqueFeedItem(FeedItem *item, int itemType, const std::string &id1, const std::string &id2, const std::string &id3, const std::string &id4) +{ + AddFeedItemIfUniqueData data(item, itemType, id1, id2, id3, id4); + FeedItem *feedItem = ui->feedWidget->findFeedItem(addFeedItemIfUniqueCallback, &data); + + if (feedItem) { + delete item; + + ui->feedWidget->removeFeedItem(feedItem); + } +} + void NewsFeed::addFeedItemPeerConnect(const RsFeedItem &fi) { /* make new widget */ @@ -1038,7 +1220,7 @@ void NewsFeed::addFeedItemPeerOffset(const RsFeedItem &fi) PeerItem *pi = new PeerItem(this, NEWSFEED_PEERLIST, RsPeerId(fi.mId1), PEER_TYPE_OFFSET, false); /* add to layout */ - addFeedItemIfUnique(pi, PEER_TYPE_OFFSET, RsPeerId(fi.mId1), "", "", false); + addFeedItemIfUnique(pi, PEER_TYPE_OFFSET, fi.mId1, fi.mId2, fi.mId3, fi.mId4, false); #ifdef NEWS_DEBUG std::cerr << "NewsFeed::addFeedItemPeerOffset()"; @@ -1052,7 +1234,7 @@ void NewsFeed::addFeedItemSecurityConnectAttempt(const RsFeedItem &fi) SecurityItem *pi = new SecurityItem(this, NEWSFEED_SECLIST, RsPgpId(fi.mId1), RsPeerId(fi.mId2), fi.mId3, fi.mId4, fi.mType, false); /* add to layout */ - addFeedItemIfUnique(pi, fi.mType, RsPeerId(fi.mId2), "", "", false); + addFeedItemIfUnique(pi, fi.mType, fi.mId2, "", "", "", false); #ifdef NEWS_DEBUG std::cerr << "NewsFeed::addFeedItemSecurityConnectAttempt()"; @@ -1066,7 +1248,7 @@ void NewsFeed::addFeedItemSecurityAuthDenied(const RsFeedItem &fi) SecurityItem *pi = new SecurityItem(this, NEWSFEED_SECLIST, RsPgpId(fi.mId1), RsPeerId(fi.mId2), fi.mId3, fi.mId4, fi.mType, false); /* add to layout */ - addFeedItemIfUnique(pi, RS_FEED_ITEM_SEC_AUTH_DENIED, RsPeerId(fi.mId2), "", "", false); + addFeedItemIfUnique(pi, RS_FEED_ITEM_SEC_AUTH_DENIED, fi.mId2, "", "", "", false); #ifdef NEWS_DEBUG std::cerr << "NewsFeed::addFeedItemSecurityAuthDenied()"; @@ -1080,7 +1262,7 @@ void NewsFeed::addFeedItemSecurityUnknownIn(const RsFeedItem &fi) SecurityItem *pi = new SecurityItem(this, NEWSFEED_SECLIST, RsPgpId(fi.mId1), RsPeerId(fi.mId2), fi.mId3, fi.mId4, RS_FEED_ITEM_SEC_UNKNOWN_IN, false); /* add to layout */ - addFeedItemIfUnique(pi, RS_FEED_ITEM_SEC_UNKNOWN_IN, RsPeerId(fi.mId2), "", "", false); + addFeedItemIfUnique(pi, RS_FEED_ITEM_SEC_UNKNOWN_IN, fi.mId2, "", "", "", false); #ifdef NEWS_DEBUG std::cerr << "NewsFeed::addFeedItemSecurityUnknownIn()"; @@ -1094,7 +1276,7 @@ void NewsFeed::addFeedItemSecurityUnknownOut(const RsFeedItem &fi) SecurityItem *pi = new SecurityItem(this, NEWSFEED_SECLIST, RsPgpId(fi.mId1), RsPeerId(fi.mId2), fi.mId3, fi.mId4, RS_FEED_ITEM_SEC_UNKNOWN_OUT, false); /* add to layout */ - addFeedItemIfUnique(pi, RS_FEED_ITEM_SEC_UNKNOWN_OUT, RsPeerId(fi.mId2), "", "", false); + addFeedItemIfUnique(pi, RS_FEED_ITEM_SEC_UNKNOWN_OUT, fi.mId2, "", "", "", false); #ifdef NEWS_DEBUG std::cerr << "NewsFeed::addFeedItemSecurityUnknownOut()"; @@ -1108,7 +1290,7 @@ void NewsFeed::addFeedItemSecurityIpBlacklisted(const RsFeedItem &fi, bool isTes SecurityIpItem *pi = new SecurityIpItem(this, RsPeerId(fi.mId1), fi.mId2, fi.mResult1, RS_FEED_ITEM_SEC_IP_BLACKLISTED, isTest); /* add to layout */ - addFeedItemIfUnique(pi, RS_FEED_ITEM_SEC_IP_BLACKLISTED, RsPeerId(fi.mId1), fi.mId2, "", false); + addFeedItemIfUnique(pi, RS_FEED_ITEM_SEC_IP_BLACKLISTED, fi.mId1, fi.mId2, fi.mId3, fi.mId4, false); #ifdef NEWS_DEBUG std::cerr << "NewsFeed::addFeedItemSecurityIpBlacklisted()"; @@ -1122,7 +1304,7 @@ void NewsFeed::addFeedItemSecurityWrongExternalIpReported(const RsFeedItem &fi, SecurityIpItem *pi = new SecurityIpItem(this, RsPeerId(fi.mId1), fi.mId2, fi.mId3, RS_FEED_ITEM_SEC_IP_WRONG_EXTERNAL_IP_REPORTED, isTest); /* add to layout */ - addFeedItemIfUnique(pi, RS_FEED_ITEM_SEC_IP_WRONG_EXTERNAL_IP_REPORTED, RsPeerId(fi.mId1), fi.mId2, fi.mId3, false); + addFeedItemIfUnique(pi, RS_FEED_ITEM_SEC_IP_WRONG_EXTERNAL_IP_REPORTED, fi.mId1, fi.mId2, fi.mId3, fi.mId4, false); #ifdef NEWS_DEBUG std::cerr << "NewsFeed::addFeedItemSecurityWrongExternalIpReported()"; @@ -1375,6 +1557,66 @@ void NewsFeed::addFeedItemFilesNew(const RsFeedItem &/*fi*/) #endif } +void NewsFeed::addFeedItemCircleMembReq(const RsFeedItem &fi) +{ + RsGxsCircleId circleId(fi.mId1); + RsGxsId gxsId(fi.mId2); + + if (circleId.isNull() || gxsId.isNull()) { + return; + } + + /* make new widget */ + GxsCircleItem *item = new GxsCircleItem(this, NEWSFEED_CIRCLELIST, circleId, gxsId, RS_FEED_ITEM_CIRCLE_MEMB_REQ); + + /* add to layout */ + addFeedItemIfUnique(item, RS_FEED_ITEM_CIRCLE_MEMB_REQ, fi.mId1, fi.mId2, fi.mId3, fi.mId4, false); + +#ifdef NEWS_DEBUG + std::cerr << "NewsFeed::addFeedItemCircleMembReq()" << std::endl; +#endif +} + +void NewsFeed::remFeedItemCircleMembReq(const RsFeedItem &fi) +{ + RsGxsCircleId circleId(fi.mId1); + RsGxsId gxsId(fi.mId2); + + if (circleId.isNull() || gxsId.isNull()) { + return; + } + + /* make new widget */ + GxsCircleItem *item = new GxsCircleItem(this, NEWSFEED_CIRCLELIST, circleId, gxsId, RS_FEED_ITEM_CIRCLE_MEMB_REQ); + + /* add to layout */ + remUniqueFeedItem(item, RS_FEED_ITEM_CIRCLE_MEMB_REQ, fi.mId1, fi.mId2, fi.mId3, fi.mId4); + +#ifdef NEWS_DEBUG + std::cerr << "NewsFeed::remFeedItemCircleMembReq()" << std::endl; +#endif +} + +void NewsFeed::addFeedItemCircleInvitRec(const RsFeedItem &fi) +{ + RsGxsCircleId circleId(fi.mId1); + RsGxsId gxsId(fi.mId2); + + if (circleId.isNull()) { + return; + } + + /* make new widget */ + GxsCircleItem *item = new GxsCircleItem(this, NEWSFEED_CIRCLELIST, circleId, gxsId, RS_FEED_ITEM_CIRCLE_INVIT_REC); + + /* add to layout */ + addFeedItem(item); + +#ifdef NEWS_DEBUG + std::cerr << "NewsFeed::addFeedItemCircleInvitRec()" << std::endl; +#endif +} + /* FeedHolder Functions (for FeedItem functionality) */ QScrollArea *NewsFeed::getScrollArea() { @@ -1403,7 +1645,7 @@ void NewsFeed::openChat(const RsPeerId &peerId) ChatDialog::chatFriend(ChatId(peerId)); } -void NewsFeed::openComments(uint32_t /*type*/, const RsGxsGroupId &/*groupId*/, const QVector& versions,const RsGxsMessageId &/*msgId*/, const QString &/*title*/) +void NewsFeed::openComments(uint32_t /*type*/, const RsGxsGroupId &/*groupId*/, const QVector &/*versions*/,const RsGxsMessageId &/*msgId*/, const QString &/*title*/) { std::cerr << "NewsFeed::openComments() Not Handled Yet"; std::cerr << std::endl; diff --git a/retroshare-gui/src/gui/NewsFeed.h b/retroshare-gui/src/gui/NewsFeed.h index b97476435..9fceaf486 100644 --- a/retroshare-gui/src/gui/NewsFeed.h +++ b/retroshare-gui/src/gui/NewsFeed.h @@ -83,7 +83,8 @@ private slots: private: void addFeedItem(FeedItem *item); - void addFeedItemIfUnique(FeedItem *item, int itemType, const RsPeerId &sslId, const std::string& ipAddr, const std::string& ipAddrReported, bool replace); + void addFeedItemIfUnique(FeedItem *item, int itemType, const std::string& id1, const std::string& id2, const std::string& id3, const std::string& id4, bool replace); + void remUniqueFeedItem(FeedItem *item, int itemType, const std::string& id1, const std::string& id2, const std::string& id3, const std::string& id4); void addFeedItemPeerConnect(const RsFeedItem &fi); void addFeedItemPeerDisconnect(const RsFeedItem &fi); @@ -119,6 +120,10 @@ private: void addFeedItemMessage(const RsFeedItem &fi); void addFeedItemFilesNew(const RsFeedItem &fi); + void addFeedItemCircleMembReq(const RsFeedItem &fi); + void remFeedItemCircleMembReq(const RsFeedItem &fi); + void addFeedItemCircleInvitRec(const RsFeedItem &fi); + virtual void loadChannelGroup(const uint32_t &token); virtual void loadChannelPost(const uint32_t &token); virtual void loadChannelPublishKey(const uint32_t &token); @@ -130,8 +135,12 @@ private: virtual void loadPostedGroup(const uint32_t &token); virtual void loadPostedMessage(const uint32_t &token); + virtual void loadCircleGroup(const uint32_t &token); + virtual void loadCircleMessage(const uint32_t &token); + private: TokenQueue *mTokenQueueChannel; + TokenQueue *mTokenQueueCircle; TokenQueue *mTokenQueueForum; TokenQueue *mTokenQueuePosted; diff --git a/retroshare-gui/src/gui/feeds/GxsCircleItem.cpp b/retroshare-gui/src/gui/feeds/GxsCircleItem.cpp new file mode 100644 index 000000000..b37b72ef1 --- /dev/null +++ b/retroshare-gui/src/gui/feeds/GxsCircleItem.cpp @@ -0,0 +1,284 @@ +/* + * Retroshare Gxs Feed Item + * + * Copyright 2014 RetroShare Team + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License Version 2.1 as published by the Free Software Foundation. + * + * This library 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 + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 + * USA. + * + * Please report all bugs and problems to "retroshare@lunamutt.com". + * + */ + +#include "GxsCircleItem.h" +#include "ui_GxsCircleItem.h" + +#include "FeedHolder.h" +#include "gui/notifyqt.h" +#include "gui/Circles/CreateCircleDialog.h" +#include "gui/gxs/GxsIdDetails.h" + +#include +#include +#include + +#include + +/**** + * #define DEBUG_ITEM 1 + ****/ + +#define COLOR_NORMAL QColor(248, 248, 248) +#define COLOR_NEW QColor(220, 236, 253) + +#define CIRCLESDIALOG_GROUPUPDATE 3 + + +GxsCircleItem::GxsCircleItem(FeedHolder *feedHolder, uint32_t feedId, const RsGxsCircleId &circleId, const RsGxsId &gxsId, const uint32_t type) + :FeedItem(NULL), mFeedHolder(feedHolder), mFeedId(feedId), mType(type), mCircleId(circleId), mGxsId(gxsId) +{ + setup(); +} + + +GxsCircleItem::~GxsCircleItem() +{ + delete(ui); +} + +void GxsCircleItem::setup() +{ + /* Invoke the Qt Designer generated object setup routine */ + ui = new Ui::GxsCircleItem; + ui->setupUi(this); + + setAttribute(Qt::WA_DeleteOnClose, true); + + /* general ones */ + connect(ui->expandButton, SIGNAL(clicked()), this, SLOT(showCircleDetails())); + connect(ui->clearButton, SIGNAL(clicked()), this, SLOT(removeItem())); + + /* update gxs information */ + + RsIdentityDetails idDetails ; + QString idName ; + if(rsIdentity->getIdDetails(mGxsId, idDetails)) + idName = tr("for identity ")+QString::fromUtf8(idDetails.mNickname.c_str()) + " (ID=" + QString::fromStdString(mGxsId.toStdString()) + ")" ; + else + idName = tr("for identity ")+QString::fromStdString(mGxsId.toStdString()) ; + + + /* update circle information */ + + RsGxsCircleDetails circleDetails; + if (rsGxsCircles->getCircleDetails(mCircleId, circleDetails)) + { + + 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->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 if (mType == RS_FEED_ITEM_CIRCLE_INVIT_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->acceptButton->setToolTip(tr("Accept invitation")); + connect(ui->acceptButton, SIGNAL(clicked()), this, SLOT(acceptCircleSubscription())); + ui->revokeButton->setHidden(true); + } + + } + else + { + ui->titleLabel->setText(tr("Received event from unknown Circle:")); + ui->nameLabel->setText(QString::fromStdString(mCircleId.toStdString())); + ui->gxsIdLabel->setText(idName); + } + + /* Setup TokenQueue */ + mCircleQueue = new TokenQueue(rsGxsCircles->getTokenService(), this); + +} + +bool GxsCircleItem::isSame(const RsGxsCircleId &circleId, const RsGxsId &gxsId, uint32_t type) +{ + if ((mCircleId == circleId) && (mGxsId == gxsId) && (mType == type)) + { + return true; + } + return false; + +} + +void GxsCircleItem::removeItem() +{ +#ifdef DEBUG_ITEM + std::cerr << "GxsCircleItem::removeItem()" << std::endl; +#endif + + if (mFeedHolder) + { + mFeedHolder->lockLayout(this, true); + hide(); + mFeedHolder->lockLayout(this, false); + + mFeedHolder->deleteFeedItem(this, mFeedId); + } +} + +void GxsCircleItem::loadRequest(const TokenQueue * queue, const TokenRequest &req) +{ +#ifdef ID_DEBUG + std::cerr << "GxsCircleItem::loadRequest() UserType: " << req.mUserType; + std::cerr << std::endl; +#endif + if(queue == mCircleQueue) + { +#ifdef ID_DEBUG + std::cerr << "CirclesDialog::loadRequest() UserType: " << req.mUserType; + std::cerr << std::endl; +#endif + + /* now switch on req */ + switch(req.mUserType) + { + case CIRCLESDIALOG_GROUPUPDATE: + updateCircleGroup(req.mToken); + break; + + default: + std::cerr << "GxsCircleItem::loadRequest() ERROR: INVALID TYPE"; + std::cerr << std::endl; + break; + } + } +} + + +/*********** SPECIFIC FUNCTIONS ***********************/ + +void GxsCircleItem::showCircleDetails() +{ + CreateCircleDialog dlg; + + dlg.editExistingId(RsGxsGroupId(mCircleId), true, mType != RS_FEED_ITEM_CIRCLE_MEMB_REQ) ; + dlg.exec(); +} + +void GxsCircleItem::acceptCircleSubscription() +{ + if (rsGxsCircles->requestCircleMembership(mGxsId, mCircleId)) + removeItem(); +} + +void GxsCircleItem::grantCircleMembership() +{ + + RsTokReqOptions opts; + opts.mReqType = GXS_REQUEST_TYPE_GROUP_DATA; + + std::list grps ; + grps.push_back(RsGxsGroupId(mCircleId)); + + uint32_t token; + mCircleQueue->requestGroupInfo(token, RS_TOKREQ_ANSTYPE_DATA, opts, grps, CIRCLESDIALOG_GROUPUPDATE); + + CircleUpdateOrder c ; + c.token = token ; + c.gxs_id = mGxsId ; + c.action = CircleUpdateOrder::GRANT_MEMBERSHIP ; + + mCircleUpdates[token] = c ; +} + +void GxsCircleItem::revokeCircleMembership() +{ + + RsTokReqOptions opts; + opts.mReqType = GXS_REQUEST_TYPE_GROUP_DATA; + + std::list grps; + grps.push_back(RsGxsGroupId(mCircleId)); + + uint32_t token; + mCircleQueue->requestGroupInfo(token, RS_TOKREQ_ANSTYPE_DATA, opts, grps, CIRCLESDIALOG_GROUPUPDATE); + + CircleUpdateOrder c; + c.token = token; + c.gxs_id = mGxsId; + c.action = CircleUpdateOrder::REVOKE_MEMBERSHIP; + + mCircleUpdates[token] = c; +} + +void GxsCircleItem::updateCircleGroup(const uint32_t& token) +{ +#ifdef ID_DEBUG + std::cerr << "Loading circle info" << std::endl; +#endif + + std::vector circle_grp_v ; + rsGxsCircles->getGroupData(token, circle_grp_v); + + if (circle_grp_v.empty()) + { + std::cerr << "(EE) unexpected empty result from getGroupData. Cannot process circle now!" << std::endl; + return ; + } + + if (circle_grp_v.size() != 1) + { + std::cerr << "(EE) very weird result from getGroupData. Should get exactly one circle" << std::endl; + return ; + } + + RsGxsCircleGroup cg = circle_grp_v.front(); + + /* now mark all the members */ + + //std::set members = cg.mInvitedMembers; + + std::map::iterator it = mCircleUpdates.find(token) ; + + if(it == mCircleUpdates.end()) + { + std::cerr << "(EE) Cannot find token " << token << " to perform group update!" << std::endl; + return ; + } + + if(it->second.action == CircleUpdateOrder::GRANT_MEMBERSHIP) + cg.mInvitedMembers.insert(it->second.gxs_id) ; + else if(it->second.action == CircleUpdateOrder::REVOKE_MEMBERSHIP) + cg.mInvitedMembers.erase(it->second.gxs_id) ; + else + { + std::cerr << "(EE) unrecognised membership action to perform: " << it->second.action << "!" << std::endl; + return ; + } + + uint32_t token2 ; + rsGxsCircles->updateGroup(token2,cg) ; + + mCircleUpdates.erase(it) ; +} + diff --git a/retroshare-gui/src/gui/feeds/GxsCircleItem.h b/retroshare-gui/src/gui/feeds/GxsCircleItem.h new file mode 100644 index 000000000..760df3db2 --- /dev/null +++ b/retroshare-gui/src/gui/feeds/GxsCircleItem.h @@ -0,0 +1,98 @@ +/* + * Retroshare Gxs Feed Item + * + * Copyright 2014 RetroShare Team + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License Version 2.1 as published by the Free Software Foundation. + * + * This library 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 + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 + * USA. + * + * Please report all bugs and problems to "retroshare@lunamutt.com". + * + */ + +#ifndef _GXSCIRCLEITEM_H +#define _GXSCIRCLEITEM_H + +#include +#include "FeedItem.h" + +#include "util/TokenQueue.h" + +namespace Ui { +class GxsCircleItem; +} + +class FeedHolder; + +struct CircleUpdateOrder +{ + enum { UNKNOWN_ACTION=0x00, GRANT_MEMBERSHIP=0x01, REVOKE_MEMBERSHIP=0x02 }; + + uint32_t token ; + RsGxsId gxs_id ; + uint32_t action ; +}; + + +class GxsCircleItem : public FeedItem, public TokenResponse +{ + Q_OBJECT + +public: + + /** Default Constructor */ + GxsCircleItem(FeedHolder *feedHolder, uint32_t feedId, const RsGxsCircleId &circleId, const RsGxsId &gxsId, const uint32_t type); + virtual ~GxsCircleItem(); + + bool isSame(const RsGxsCircleId &circleId, const RsGxsId &gxsId, uint32_t type); + + void loadRequest(const TokenQueue *queue, const TokenRequest &req); + + +protected: + /* FeedItem */ + virtual void doExpand(bool /*open*/) {} + + void updateCircleGroup(const uint32_t& token); + + + +private slots: + /* default stuff */ + void removeItem(); + + void showCircleDetails(); + void acceptCircleSubscription(); + void grantCircleMembership() ; + void revokeCircleMembership(); + +private: + void setup(); + + FeedHolder *mFeedHolder; + uint32_t mFeedId; + uint32_t mType; + + RsGxsCircleId mCircleId; + RsGxsId mGxsId; + + TokenQueue *mCircleQueue; + std::map mCircleUpdates ; + + + /** Qt Designer generated object */ + Ui::GxsCircleItem *ui; +}; + +#endif diff --git a/retroshare-gui/src/gui/feeds/GxsCircleItem.ui b/retroshare-gui/src/gui/feeds/GxsCircleItem.ui new file mode 100644 index 000000000..141d49e4c --- /dev/null +++ b/retroshare-gui/src/gui/feeds/GxsCircleItem.ui @@ -0,0 +1,298 @@ + + + GxsCircleItem + + + + 0 + 0 + 618 + 96 + + + + + 1 + + + 1 + + + 1 + + + 1 + + + + + + 0 + 0 + + + + + + + + + 215 + 215 + 215 + + + + + + + 215 + 215 + 215 + + + + + + + + + 215 + 215 + 215 + + + + + + + 215 + 215 + 215 + + + + + + + + + 215 + 215 + 215 + + + + + + + 215 + 215 + 215 + + + + + + + + true + + + QFrame::Box + + + QFrame::Sunken + + + + + + + + + 70 + 70 + + + + + 70 + 70 + + + + + + + :/icons/svg/circles.svg + + + true + + + + + + + + + + 0 + 0 + + + + + 75 + true + true + + + + Circle + + + + + + + name + + + true + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + + + + name + + + true + + + + + + + Qt::Horizontal + + + QSizePolicy::Expanding + + + + 254 + 28 + + + + + + + + + 0 + 0 + + + + Qt::NoFocus + + + + :/images/accepted16.png:/images/accepted16.png + + + + + + + + 0 + 0 + + + + Qt::NoFocus + + + + :/images/cancel.png:/images/cancel.png + + + + + + + + 0 + 0 + + + + Qt::NoFocus + + + Details + + + + :/images/edit_add24.png:/images/edit_add24.png + + + + + + + + 0 + 0 + + + + Qt::NoFocus + + + Remove Item + + + + :/images/close_normal.png:/images/close_normal.png + + + + + + + + + + + + + + + + + + diff --git a/retroshare-gui/src/gui/settings/NotifyPage.cpp b/retroshare-gui/src/gui/settings/NotifyPage.cpp index 09f9efbfc..7c0bdd123 100755 --- a/retroshare-gui/src/gui/settings/NotifyPage.cpp +++ b/retroshare-gui/src/gui/settings/NotifyPage.cpp @@ -162,6 +162,7 @@ NotifyPage::NotifyPage(QWidget * parent, Qt::WindowFlags flags) connect(ui.message_ConnectAttempt, SIGNAL(toggled(bool)), this, SLOT(updateMessageFlags())) ; connect(ui.notify_Peers, SIGNAL(toggled(bool)), this, SLOT(updateNewsFeedFlags())); + connect(ui.notify_Circles, SIGNAL(toggled(bool)), this, SLOT(updateNewsFeedFlags())); connect(ui.notify_Channels, SIGNAL(toggled(bool)), this, SLOT(updateNewsFeedFlags())); connect(ui.notify_Forums, SIGNAL(toggled(bool)), this, SLOT(updateNewsFeedFlags())); connect(ui.notify_Posted, SIGNAL(toggled(bool)), this, SLOT(updateNewsFeedFlags())); @@ -195,6 +196,8 @@ uint NotifyPage::getNewsFlags() if (ui.notify_Peers->isChecked()) newsFlags |= RS_FEED_TYPE_PEER; + if (ui.notify_Circles->isChecked()) + newsFlags |= RS_FEED_TYPE_CIRCLE; if (ui.notify_Channels->isChecked()) newsFlags |= RS_FEED_TYPE_CHANNEL; if (ui.notify_Forums->isChecked()) @@ -324,6 +327,7 @@ void NotifyPage::load() whileBlocking(ui.popup_ConnectAttempt)->setChecked(notifyflags & RS_POPUP_CONNECT_ATTEMPT); whileBlocking(ui.notify_Peers)->setChecked(newsflags & RS_FEED_TYPE_PEER); + whileBlocking(ui.notify_Circles)->setChecked(newsflags & RS_FEED_TYPE_CIRCLE); whileBlocking(ui.notify_Channels)->setChecked(newsflags & RS_FEED_TYPE_CHANNEL); whileBlocking(ui.notify_Forums)->setChecked(newsflags & RS_FEED_TYPE_FORUM); whileBlocking(ui.notify_Posted)->setChecked(newsflags & RS_FEED_TYPE_POSTED); diff --git a/retroshare-gui/src/gui/settings/NotifyPage.ui b/retroshare-gui/src/gui/settings/NotifyPage.ui index c0bd95317..0f25f470e 100755 --- a/retroshare-gui/src/gui/settings/NotifyPage.ui +++ b/retroshare-gui/src/gui/settings/NotifyPage.ui @@ -51,6 +51,13 @@ + + + + Circles + + + diff --git a/retroshare-gui/src/retroshare-gui.pro b/retroshare-gui/src/retroshare-gui.pro index c469dcbba..b0280c686 100644 --- a/retroshare-gui/src/retroshare-gui.pro +++ b/retroshare-gui/src/retroshare-gui.pro @@ -551,6 +551,7 @@ HEADERS += rshare.h \ gui/NewsFeed.h \ gui/feeds/FeedItem.h \ gui/feeds/FeedHolder.h \ + gui/feeds/GxsCircleItem.h \ gui/feeds/PeerItem.h \ gui/feeds/MsgItem.h \ gui/feeds/ChatMsgItem.h \ @@ -656,6 +657,7 @@ FORMS += gui/StartDialog.ui \ gui/advsearch/AdvancedSearchDialog.ui \ gui/advsearch/expressionwidget.ui \ gui/NewsFeed.ui \ + gui/feeds/GxsCircleItem.ui \ gui/feeds/PeerItem.ui \ gui/feeds/MsgItem.ui \ gui/feeds/ChatMsgItem.ui \ @@ -685,7 +687,7 @@ FORMS += gui/StartDialog.ui \ gui/statistics/StatisticsWindow.ui \ gui/statistics/BwCtrlWindow.ui \ gui/statistics/RttStatistics.ui \ - gui/GetStartedDialog.ui \ + gui/GetStartedDialog.ui # gui/ForumsDialog.ui \ @@ -900,6 +902,7 @@ SOURCES += main.cpp \ gui/NewsFeed.cpp \ gui/feeds/FeedItem.cpp \ gui/feeds/FeedHolder.cpp \ + gui/feeds/GxsCircleItem.cpp \ gui/feeds/PeerItem.cpp \ gui/feeds/MsgItem.cpp \ gui/feeds/ChatMsgItem.cpp \