diff --git a/libretroshare/src/gxs/rsgxsnetservice.cc b/libretroshare/src/gxs/rsgxsnetservice.cc index 5cebfbfb3..ba2e287ad 100644 --- a/libretroshare/src/gxs/rsgxsnetservice.cc +++ b/libretroshare/src/gxs/rsgxsnetservice.cc @@ -4412,7 +4412,7 @@ void RsGxsNetService::handleRecvSyncMessage(RsNxsSyncMsgReqItem *item,bool item_ if(details.mReputation.mOverallReputationLevel < minReputationForForwardingMessages(grpMeta->mSignFlags, details.mFlags)) { #ifdef NXS_NET_DEBUG_0 - GXSNETDEBUG_PG(item->PeerId(),item->grpId) << " not sending item ID " << (*vit)->mMsgId << ", because the author is flags " << std::hex << details.mFlags << std::dec << " and reputation level " << details.mReputation.mOverallReputationLevel << std::endl; + GXSNETDEBUG_PG(item->PeerId(),item->grpId) << " not sending item ID " << (*vit)->mMsgId << ", because the author is flags " << std::hex << details.mFlags << std::dec << " and reputation level " << (int) details.mReputation.mOverallReputationLevel << std::endl; #endif continue ; } diff --git a/libretroshare/src/rsserver/rsinit.cc b/libretroshare/src/rsserver/rsinit.cc index a4e652c4c..25391fcbe 100644 --- a/libretroshare/src/rsserver/rsinit.cc +++ b/libretroshare/src/rsserver/rsinit.cc @@ -1376,6 +1376,8 @@ int RsServer::StartupRetroShare() mPhoto, mPhoto->getServiceInfo(), mReputations, mGxsCircles,mGxsIdService, pgpAuxUtils); + + mPhoto->setNetworkExchangeService(photo_ns); #endif #ifdef RS_USE_WIRE @@ -1391,6 +1393,8 @@ int RsServer::StartupRetroShare() mWire, mWire->getServiceInfo(), mReputations, mGxsCircles,mGxsIdService, pgpAuxUtils); + + mWire->setNetworkExchangeService(wire_ns); #endif // now add to p3service pqih->addService(gxsid_ns, true); diff --git a/libretroshare/src/services/p3wire.cc b/libretroshare/src/services/p3wire.cc index 18119c9a3..d61691f07 100644 --- a/libretroshare/src/services/p3wire.cc +++ b/libretroshare/src/services/p3wire.cc @@ -64,11 +64,14 @@ uint32_t p3Wire::wireAuthenPolicy() // Edits generally need an authors signature. + // Wire requires all TopLevel (Orig/Reply) msgs to be signed with both PUBLISH & AUTHOR. + // Reply References need to be signed by Author. flag = GXS_SERV::MSG_AUTHEN_ROOT_PUBLISH_SIGN | GXS_SERV::MSG_AUTHEN_CHILD_AUTHOR_SIGN; + flag |= GXS_SERV::MSG_AUTHEN_ROOT_AUTHOR_SIGN; RsGenExchange::setAuthenPolicyFlag(flag, policy, RsGenExchange::PUBLIC_GRP_BITS); - flag |= GXS_SERV::MSG_AUTHEN_ROOT_AUTHOR_SIGN; - flag |= GXS_SERV::MSG_AUTHEN_CHILD_PUBLISH_SIGN; + // expect the requirements to be the same for RESTRICTED / PRIVATE groups too. + // This needs to be worked through / fully evaluated. RsGenExchange::setAuthenPolicyFlag(flag, policy, RsGenExchange::RESTRICTED_GRP_BITS); RsGenExchange::setAuthenPolicyFlag(flag, policy, RsGenExchange::PRIVATE_GRP_BITS); diff --git a/retroshare-gui/src/gui/TheWire/PulseAddDialog.cpp b/retroshare-gui/src/gui/TheWire/PulseAddDialog.cpp index 1e0d58ea6..a23af7f54 100644 --- a/retroshare-gui/src/gui/TheWire/PulseAddDialog.cpp +++ b/retroshare-gui/src/gui/TheWire/PulseAddDialog.cpp @@ -54,7 +54,8 @@ void PulseAddDialog::setReplyTo(RsWirePulse &pulse, std::string &groupName) mReplyGroupName = groupName; { - PulseDetails *details = new PulseDetails(NULL, pulse, groupName, true); + std::map replies; + PulseDetails *details = new PulseDetails(NULL, &pulse, groupName, replies); // add extra widget into layout. QVBoxLayout *vbox = new QVBoxLayout(); vbox->addWidget(details); diff --git a/retroshare-gui/src/gui/TheWire/PulseDetails.cpp b/retroshare-gui/src/gui/TheWire/PulseDetails.cpp index 7bb1f2615..067b1e99e 100644 --- a/retroshare-gui/src/gui/TheWire/PulseDetails.cpp +++ b/retroshare-gui/src/gui/TheWire/PulseDetails.cpp @@ -31,12 +31,14 @@ #include /** Constructor */ -PulseDetails::PulseDetails(PulseHolder *actions, RsWirePulse &pulse, std::string &groupName, bool is_original) -:QWidget(NULL), mActions(actions), mPulse(pulse), mGroupName(groupName), mIsOriginal(is_original) +PulseDetails::PulseDetails(PulseHolder *actions, RsWirePulse *pulse, std::string &groupName, + std::map replies) +:QWidget(NULL), mActions(actions), mPulse(*pulse), mGroupName(groupName) { setupUi(this); setAttribute ( Qt::WA_DeleteOnClose, true ); setup(); + addReplies(replies); } PulseDetails::PulseDetails(PulseHolder *actions, @@ -46,7 +48,7 @@ PulseDetails::PulseDetails(PulseHolder *actions, RsGxsId &parentAuthorId, rstime_t &parentPublishTs, std::string &parentPulseText) -:QWidget(NULL), mActions(actions), mPulse(), mGroupName(parentGroupName), mIsOriginal(false) +:QWidget(NULL), mActions(actions), mPulse(), mGroupName(parentGroupName) { setupUi(this); setAttribute ( Qt::WA_DeleteOnClose, true ); @@ -60,6 +62,15 @@ PulseDetails::PulseDetails(PulseHolder *actions, setup(); } +void PulseDetails::setBackground(QString color) +{ + QWidget *tocolor = this; + QPalette p = tocolor->palette(); + p.setColor(tocolor->backgroundRole(), QColor(color)); + tocolor->setPalette(p); + tocolor->setAutoFillBackground(true); +} + void PulseDetails::setup() { connect(toolButton_expand, SIGNAL(clicked()), this, SLOT(toggle())); @@ -77,6 +88,47 @@ void PulseDetails::setup() // label_icon->setText(); textBrowser->setPlainText(QString::fromStdString(mPulse.mPulseText)); frame_expand->setVisible(false); + + label_replies->setText(""); + frame_replies->setVisible(false); + mHasReplies = false; +} + +void PulseDetails::addReplies(std::map replies) +{ + if (replies.size() == 0) + { + // do nothing. + return; + } + else if (replies.size() == 1) + { + label_replies->setText("1 reply"); + } + else if (replies.size() > 1) + { + label_replies->setText(QString("%1 replies").arg(replies.size())); + } + + // add extra widgets into layout. + QLayout *vbox = frame_replies->layout(); + mHasReplies = true; + + std::map emptyReplies; + std::map::reverse_iterator it; + for (it = replies.rbegin(); it != replies.rend(); it++) + { + // add Ref as child reply. + PulseDetails *pd = new PulseDetails(mActions, + it->second->mRefGroupId, + it->second->mRefGroupName, + it->second->mRefOrigMsgId, + it->second->mRefAuthorId, + it->second->mRefPublishTs, + it->second->mRefPulseText); + pd->setBackground("goldenrod"); + vbox->addWidget(pd); + } } @@ -86,10 +138,14 @@ void PulseDetails::toggle() // switch to minimal view. label_summary->setVisible(true); frame_expand->setVisible(false); + frame_replies->setVisible(false); } else { // switch to expanded view. label_summary->setVisible(false); frame_expand->setVisible(true); + if (mHasReplies) { + frame_replies->setVisible(true); + } } } diff --git a/retroshare-gui/src/gui/TheWire/PulseDetails.h b/retroshare-gui/src/gui/TheWire/PulseDetails.h index 6b063eab9..b6a623f73 100644 --- a/retroshare-gui/src/gui/TheWire/PulseDetails.h +++ b/retroshare-gui/src/gui/TheWire/PulseDetails.h @@ -31,7 +31,8 @@ class PulseDetails : public QWidget, private Ui::PulseDetails Q_OBJECT public: - PulseDetails(PulseHolder *actions, RsWirePulse &pulse, std::string &groupName, bool is_original); + PulseDetails(PulseHolder *actions, RsWirePulse *pulse, std::string &groupName, + std::map replies); // when Reply parent.... PulseDetails(PulseHolder *actions, @@ -44,6 +45,8 @@ public: void setup(); + void setBackground(QString color); + private slots: void toggle(); void follow(); @@ -51,12 +54,13 @@ private slots: void reply(); private: + void addReplies(std::map replies); QString getSummary(); PulseHolder *mActions; RsWirePulse mPulse; std::string mGroupName; - bool mIsOriginal; + bool mHasReplies; }; #endif diff --git a/retroshare-gui/src/gui/TheWire/PulseDetails.ui b/retroshare-gui/src/gui/TheWire/PulseDetails.ui index 3739dd0da..f5f7f7f31 100644 --- a/retroshare-gui/src/gui/TheWire/PulseDetails.ui +++ b/retroshare-gui/src/gui/TheWire/PulseDetails.ui @@ -6,14 +6,14 @@ 0 0 - 750 - 166 + 807 + 231 Form - + @@ -47,9 +47,9 @@ - + - idLabel + # replies @@ -69,7 +69,7 @@ - Summary Text/ date + Summary Text @@ -92,7 +92,7 @@ - TextLabel + DateTime 02/02/20 @@ -134,6 +134,13 @@ + + + + idLabel + + + @@ -171,6 +178,57 @@ + + + + + + Qt::Horizontal + + + QSizePolicy::Preferred + + + + 30 + 0 + + + + + + + + + 0 + 0 + + + + QFrame::StyledPanel + + + QFrame::Raised + + + + + + + 75 + true + + + + Replies + + + + + + + + diff --git a/retroshare-gui/src/gui/TheWire/PulseItem.cpp b/retroshare-gui/src/gui/TheWire/PulseItem.cpp index 3b452ffdf..1e73b3364 100644 --- a/retroshare-gui/src/gui/TheWire/PulseItem.cpp +++ b/retroshare-gui/src/gui/TheWire/PulseItem.cpp @@ -44,40 +44,42 @@ PulseItem::PulseItem(PulseHolder *holder, std::string path) } -PulseItem::PulseItem(PulseHolder *holder, RsWirePulse &pulse, RsWireGroup &group) -:QWidget(NULL), mHolder(holder), mType(0) +PulseItem::PulseItem(PulseHolder *holder, RsWirePulse *pulse_ptr, RsWireGroup *group_ptr, std::map replies) +:QWidget(NULL), mHolder(holder), mPulse(*pulse_ptr), mType(0) { setupUi(this); setAttribute ( Qt::WA_DeleteOnClose, true ); QWidget *pulse_widget = widget_parent; // default msg goes into widget_parent. /* if it is a reply */ - if (pulse.mPulseType & WIRE_PULSE_TYPE_REPLY_MSG) { + if (mPulse.mPulseType & WIRE_PULSE_TYPE_REPLY_MSG) { std::cerr << "Installing Reply Msg"; std::cerr << std::endl; - std::cerr << "GroupID: " << pulse.mRefGroupId; + std::cerr << "GroupID: " << mPulse.mRefGroupId; std::cerr << std::endl; - std::cerr << "GroupName: " << pulse.mRefGroupName; + std::cerr << "GroupName: " << mPulse.mRefGroupName; std::cerr << std::endl; - std::cerr << "OrigMsgId: " << pulse.mRefOrigMsgId; + std::cerr << "OrigMsgId: " << mPulse.mRefOrigMsgId; std::cerr << std::endl; - std::cerr << "AuthorId: " << pulse.mRefAuthorId; + std::cerr << "AuthorId: " << mPulse.mRefAuthorId; std::cerr << std::endl; - std::cerr << "PublishTs: " << pulse.mRefPublishTs; + std::cerr << "PublishTs: " << mPulse.mRefPublishTs; std::cerr << std::endl; - std::cerr << "PulseText: " << pulse.mRefPulseText; + std::cerr << "PulseText: " << mPulse.mRefPulseText; std::cerr << std::endl; // fill in the parent. PulseDetails *parent = new PulseDetails( mHolder, - pulse.mRefGroupId, - pulse.mRefGroupName, - pulse.mRefOrigMsgId, - pulse.mRefAuthorId, - pulse.mRefPublishTs, - pulse.mRefPulseText); + mPulse.mRefGroupId, + mPulse.mRefGroupName, + mPulse.mRefOrigMsgId, + mPulse.mRefAuthorId, + mPulse.mRefPublishTs, + mPulse.mRefPulseText); + + parent->setBackground("sienna"); // add extra widget into layout. QVBoxLayout *vbox = new QVBoxLayout(); @@ -88,45 +90,8 @@ PulseItem::PulseItem(PulseHolder *holder, RsWirePulse &pulse, RsWireGroup &group // if its a reply, the real msg goes into reply slot. pulse_widget = widget_reply; } - else if (pulse.mPulseType & WIRE_PULSE_TYPE_REPLY_REFERENCE) + else { - // THIS IS A FAKE ONE... LEAVE IN UNTIL ITS HANDLED ELSEWHERE. - // NB: PARENT PublishTS and AuthorID appear wrong... - - std::cerr << "Installing Ref Msg"; - std::cerr << std::endl; - std::cerr << "GroupID: " << pulse.mRefGroupId; - std::cerr << std::endl; - std::cerr << "GroupName: " << pulse.mRefGroupName; - std::cerr << std::endl; - std::cerr << "OrigMsgId: " << pulse.mRefOrigMsgId; - std::cerr << std::endl; - std::cerr << "AuthorId: " << pulse.mRefAuthorId; - std::cerr << std::endl; - std::cerr << "PublishTs: " << pulse.mRefPublishTs; - std::cerr << std::endl; - std::cerr << "PulseText: " << pulse.mRefPulseText; - std::cerr << std::endl; - - // fill in the parent. - PulseDetails *parent = new PulseDetails( - mHolder, - pulse.mRefGroupId, - pulse.mRefGroupName, - pulse.mRefOrigMsgId, - pulse.mRefAuthorId, - pulse.mRefPublishTs, - pulse.mRefPulseText); - - // add extra widget into layout. - QVBoxLayout *vbox = new QVBoxLayout(); - vbox->addWidget(parent); - vbox->setContentsMargins(0,0,0,0); - widget_reply->setLayout(vbox); - - // if its a REF, the real msg goes into parent slot. - pulse_widget = widget_parent; - } else { // ORIGINAL PULSE. // hide widget_reply, as it will be empty. widget_reply->setVisible(false); @@ -135,7 +100,7 @@ PulseItem::PulseItem(PulseHolder *holder, RsWirePulse &pulse, RsWireGroup &group { std::cerr << "Adding Main Message"; std::cerr << std::endl; - PulseDetails *details = new PulseDetails(mHolder, pulse, group.mMeta.mGroupName, true); + PulseDetails *details = new PulseDetails(mHolder, &mPulse, group_ptr->mMeta.mGroupName, replies); // add extra widget into layout. QVBoxLayout *vbox = new QVBoxLayout(); @@ -144,10 +109,13 @@ PulseItem::PulseItem(PulseHolder *holder, RsWirePulse &pulse, RsWireGroup &group vbox->setContentsMargins(0,0,0,0); pulse_widget->setLayout(vbox); pulse_widget->setVisible(true); - // details->toggle(); } } +rstime_t PulseItem::publishTs() +{ + return mPulse.mMeta.mPublishTs; +} void PulseItem::removeItem() { @@ -178,6 +146,8 @@ void PulseItem::mousePressEvent(QMouseEvent *event) setSelected(true); QWidget::mousePressEvent(event); + + mHolder->notifyPulseSelection(this); } const QPixmap *PulseItem::getPixmap() diff --git a/retroshare-gui/src/gui/TheWire/PulseItem.h b/retroshare-gui/src/gui/TheWire/PulseItem.h index 03ac190fb..0e7395e0e 100644 --- a/retroshare-gui/src/gui/TheWire/PulseItem.h +++ b/retroshare-gui/src/gui/TheWire/PulseItem.h @@ -32,7 +32,7 @@ class PulseHolder public: virtual ~PulseHolder() {} virtual void deletePulseItem(PulseItem *, uint32_t ptype) = 0; - virtual void notifySelection(PulseItem *item, int ptype) = 0; + virtual void notifyPulseSelection(PulseItem *item) = 0; // Actions. virtual void follow(RsGxsGroupId &groupId) = 0; @@ -47,8 +47,9 @@ class PulseItem : public QWidget, private Ui::PulseItem public: PulseItem(PulseHolder *holder, std::string url); - PulseItem(PulseHolder *holder, RsWirePulse &pulse, RsWireGroup &group); + PulseItem(PulseHolder *holder, RsWirePulse *pulse_ptr, RsWireGroup *group_ptr, std::map replies); + rstime_t publishTs(); void removeItem(); void setSelected(bool on); diff --git a/retroshare-gui/src/gui/TheWire/PulseItem.ui b/retroshare-gui/src/gui/TheWire/PulseItem.ui index c032446a8..f12b3bda0 100644 --- a/retroshare-gui/src/gui/TheWire/PulseItem.ui +++ b/retroshare-gui/src/gui/TheWire/PulseItem.ui @@ -25,6 +25,18 @@ + + 2 + + + 2 + + + 2 + + + 2 + @@ -52,6 +64,21 @@ border-radius: 10px} QFrame::Raised + + 1 + + + 5 + + + 2 + + + 5 + + + 2 + @@ -81,7 +108,7 @@ border-radius: 10px} 10 - 40 + 0 @@ -93,8 +120,8 @@ border-radius: 10px} - 50 - 20 + 30 + 0 @@ -113,8 +140,8 @@ border-radius: 10px} - 50 - 20 + 30 + 0 @@ -127,7 +154,7 @@ border-radius: 10px} 10 - 40 + 0 diff --git a/retroshare-gui/src/gui/TheWire/WireDialog.cpp b/retroshare-gui/src/gui/TheWire/WireDialog.cpp index 7dd1e1199..e29a82137 100644 --- a/retroshare-gui/src/gui/TheWire/WireDialog.cpp +++ b/retroshare-gui/src/gui/TheWire/WireDialog.cpp @@ -37,10 +37,20 @@ * */ +#define GROUP_SET_ALL (0) +#define GROUP_SET_OWN (1) +#define GROUP_SET_SUBSCRIBED (2) +#define GROUP_SET_AUTO (3) +#define GROUP_SET_RECOMMENDED (4) +#define GROUP_SET_OTHERS (5) + + +#define WIRE_TOKEN_TYPE_SUBSCRIBE_CHANGE 1 + /** Constructor */ WireDialog::WireDialog(QWidget *parent) -: MainPage(parent) +: MainPage(parent), mGroupSet(GROUP_SET_ALL) { ui.setupUi(this); @@ -52,6 +62,8 @@ WireDialog::WireDialog(QWidget *parent) connect( ui.pushButton_Post, SIGNAL(clicked()), this, SLOT(createPulse())); connect( ui.toolButton_refresh, SIGNAL(clicked()), this, SLOT(refreshGroups())); + connect(ui.comboBox_groupSet, SIGNAL(currentIndexChanged(int)), this, SLOT(selectGroupSet(int))); + QTimer *timer = new QTimer(this); timer->connect(timer, SIGNAL(timeout()), this, SLOT(checkUpdate())); timer->start(1000); @@ -67,12 +79,6 @@ void WireDialog::refreshGroups() requestGroupData(); } -void WireDialog::addItem(QWidget *item) -{ - QLayout *alayout = ui.scrollAreaWidgetContents->layout(); - alayout->addWidget(item); -} - void WireDialog::addGroup(QWidget *item) { @@ -81,19 +87,11 @@ void WireDialog::addGroup(QWidget *item) } // PulseHolder interface. -void WireDialog::deletePulseItem(PulseItem *item, uint32_t type) +void WireDialog::deletePulseItem(PulseItem * /* item */, uint32_t /* type */) { return; } -void WireDialog::notifySelection(PulseItem *item, int ptype) -{ - std::cerr << "WireDialog::notifySelection() from : " << ptype << " " << item; - std::cerr << std::endl; - - notifyPulseSelection(item); -} - // Actions from PulseHolder. void WireDialog::follow(RsGxsGroupId &groupId) @@ -148,9 +146,6 @@ void WireDialog::reply(RsWirePulse &pulse, std::string &groupName) void WireDialog::notifyPulseSelection(PulseItem *item) { - std::cerr << "WireDialog::notifyPulseSelection() from : " << item; - std::cerr << std::endl; - if (mPulseSelected) { std::cerr << "WireDialog::notifyPulseSelection() unselecting old one : " << mPulseSelected; @@ -158,11 +153,42 @@ void WireDialog::notifyPulseSelection(PulseItem *item) mPulseSelected->setSelected(false); } - mPulseSelected = item; } + +void WireDialog::subscribe(RsGxsGroupId &groupId) +{ + uint32_t token; + rsWire->subscribeToGroup(token, groupId, true); + mWireQueue->queueRequest(token, TOKENREQ_GROUPINFO, RS_TOKREQ_ANSTYPE_ACK, WIRE_TOKEN_TYPE_SUBSCRIBE_CHANGE); +} + +void WireDialog::unsubscribe(RsGxsGroupId &groupId) +{ + uint32_t token; + rsWire->subscribeToGroup(token, groupId, false); + mWireQueue->queueRequest(token, TOKENREQ_GROUPINFO, RS_TOKREQ_ANSTYPE_ACK, WIRE_TOKEN_TYPE_SUBSCRIBE_CHANGE); +} + +void WireDialog::notifyGroupSelection(WireGroupItem *item) +{ + std::cerr << "WireDialog::notifyGroupSelection() from : " << item; + std::cerr << std::endl; + + if (mGroupSelected) + { + std::cerr << "WireDialog::notifyGroupSelection() unselecting old one : " << mGroupSelected; + std::cerr << std::endl; + + mGroupSelected->setSelected(false); + } + + mGroupSelected = item; +} + + void WireDialog::checkUpdate() { #if 0 @@ -207,22 +233,55 @@ void WireDialog::createPulse() mAddDialog->show(); } -void WireDialog::addPulse(RsWirePulse &pulse, RsWireGroup &group) +void WireDialog::addPulse(RsWirePulse *pulse, RsWireGroup *group, + std::map replies) { - std::cerr << "WireDialog::addPulse() GroupId : " << pulse.mMeta.mGroupId; - std::cerr << " MsgId : " << pulse.mMeta.mGroupId; + std::cerr << "WireDialog::addPulse() GroupId : " << pulse->mMeta.mGroupId; + std::cerr << " OrigMsgId : " << pulse->mMeta.mOrigMsgId; + std::cerr << " Replies : " << replies.size(); std::cerr << std::endl; - QWidget *item = new PulseItem(this, pulse, group); - addItem(item); + PulseItem *pulseItem = new PulseItem(this, pulse, group, replies); + + /* ensure its a boxlayout */ + QLayout *alayout = ui.scrollAreaWidgetContents->layout(); + QBoxLayout *boxlayout = dynamic_cast(alayout); + if (boxlayout == NULL) { + std::cerr << "WireDialog::addPulse() ERROR not boxlayout, inserting at end"; + std::cerr << std::endl; + alayout->addWidget(pulseItem); + return; + } + + /* iterate through layout, and insert at the correct time */ + for(int i = 0; i < alayout->count(); i++) + { + QLayoutItem *layoutItem = boxlayout->itemAt(i); + PulseItem *pitem = dynamic_cast(layoutItem->widget()); + if (pitem != NULL) + { + if (pitem->publishTs() < pulseItem->publishTs()) + { + std::cerr << "WireDialog::addPulse() Inserting at index: " << i; + std::cerr << std::endl; + /* insert at this index */ + boxlayout->insertWidget(i, pulseItem); + return; + } + } + } + // last item. + std::cerr << "WireDialog::addPulse() Inserting at end"; + std::cerr << std::endl; + boxlayout->addWidget(pulseItem); } -void WireDialog::addGroup(RsWireGroup &group) +void WireDialog::addGroup(const RsWireGroup &group) { std::cerr << "WireDialog::addGroup() GroupId : " << group.mMeta.mGroupId; std::cerr << std::endl; - addGroup(new WireGroupItem(group)); + addGroup(new WireGroupItem(this, group)); } void WireDialog::deletePulses() @@ -261,11 +320,6 @@ void WireDialog::deleteGroups() std::cerr << "WireDialog::deleteGroups()"; std::cerr << std::endl; - mAllGroups.clear(); - mOwnGroups.clear(); - ui.groupChooser->clear(); - - QLayout *alayout = ui.scrollAreaWidgetContents_groups->layout(); QLayoutItem *item; int i = 0; @@ -294,6 +348,10 @@ void WireDialog::deleteGroups() void WireDialog::updateGroups(std::vector& groups) { + mAllGroups.clear(); + mOwnGroups.clear(); + ui.groupChooser->clear(); + std::vector::const_iterator it; for(it = groups.begin(); it != groups.end(); it++) { // save list of all groups. @@ -310,8 +368,62 @@ void WireDialog::updateGroups(std::vector& groups) } -// LOAD DATA............................................... +void WireDialog::selectGroupSet(int index) +{ + std::cerr << "WireDialog::selectGroupSet(" << index << ")"; + std::cerr << std::endl; + mGroupSet = index; + if (mGroupSet < 0) { + mGroupSet = GROUP_SET_ALL; + } + showGroups(); +} + +void WireDialog::showGroups() +{ + deleteGroups(); + deletePulses(); + + /* depends on the comboBox */ + std::map::const_iterator it; + for (it = mAllGroups.begin(); it != mAllGroups.end(); it++) + { + bool add = (mGroupSet == GROUP_SET_ALL); + if (it->second.mMeta.mSubscribeFlags & GXS_SERV::GROUP_SUBSCRIBE_ADMIN) { + if (mGroupSet == GROUP_SET_OWN) { + add = true; + } + } + else if (it->second.mMeta.mSubscribeFlags & GXS_SERV::GROUP_SUBSCRIBE_SUBSCRIBED) { + if (mGroupSet == GROUP_SET_SUBSCRIBED) { + add = true; + } + if (mGroupSet == GROUP_SET_AUTO) { + add = true; + } + if (mGroupSet == GROUP_SET_RECOMMENDED) { + add = true; + } + } + else { + if (mGroupSet == GROUP_SET_OTHERS) { + add = true; + } + } + + if (add) { + addGroup(it->second); + // request data. + std::list grpIds; + grpIds.push_back(it->second.mMeta.mGroupId); + requestPulseData(grpIds); + } + } +} + + +// LOAD DATA............................................... void WireDialog::requestGroupData() { @@ -329,29 +441,12 @@ bool WireDialog::loadGroupData(const uint32_t &token) std::cerr << "WireDialog::loadGroupData()"; std::cerr << std::endl; - deleteGroups(); - deletePulses(); - std::vector groups; rsWire->getGroupData(token, groups); - std::vector::iterator vit = groups.begin(); - - for(; vit != groups.end(); ++vit) - { - RsWireGroup& group = *vit; - - std::cerr << " WireDialog::addGroup() GroupId: " << group.mMeta.mGroupId << std::endl; - - addGroup(group); - - std::list grpIds; - grpIds.push_back(group.mMeta.mGroupId); - requestPulseData(grpIds); - } - // save list of groups. updateGroups(groups); + showGroups(); return true; } @@ -367,43 +462,168 @@ void WireDialog::requestPulseData(const std::list& grpIds) mWireQueue->requestMsgInfo(token, RS_TOKREQ_ANSTYPE_DATA, opts, grpIds, 0); } + +/* LoadPulseData... + * + * group into threads, using std::map + * then sort by publishTS, using std::map + * then add into gui. + * - use pointers to avoid copying everywhere. + * + * should we mutex Groups, or copy so we don't lose a pointer? + * should be fine, as mAllGroups only modified from loadData calls. + ****** + * + * NB: Potentially, this should be changed to use GXS to do the bulk of the work. + * - request Top-Level Msgs, sorted by PublishTS. + * - Insert into GUI. + * - for each request children Msg, and fill in "replies" + * + * This needs sorted option on GXS Data fetch. + */ + +class PulseReplySet +{ +public: + PulseReplySet() : group(NULL), msg(NULL) {} + PulseReplySet(RsWirePulse *m, RsWireGroup *g) + : group(g), msg(m) {} + + RsWireGroup *group; + RsWirePulse *msg; + std::map replies; // orig ID -> replies. +}; + +class PulseOrderedReply +{ +public: + PulseOrderedReply() : group(NULL), msg(NULL) {} + PulseOrderedReply(RsWirePulse *m, RsWireGroup *g) + : group(g), msg(m) {} + + RsWireGroup *group; + RsWirePulse *msg; + std::map replies; // publish -> replies. +}; + bool WireDialog::loadPulseData(const uint32_t &token) { std::cerr << "WireDialog::loadPulseData()"; std::cerr << std::endl; - // clearPulses(); - std::vector pulses; rsWire->getPulseData(token, pulses); + std::list references; + std::map pulseGrouping; + std::vector::iterator vit = pulses.begin(); for(; vit != pulses.end(); vit++) { RsWirePulse& pulse = *vit; - - RsGxsGroupId &gid = pulse.mMeta.mGroupId; - std::map::iterator mit = mAllGroups.find(gid); - if (mit != mAllGroups.end()) + if (pulse.mPulseType & WIRE_PULSE_TYPE_REPLY_REFERENCE) { - RsWireGroup &group = mit->second; - addPulse(pulse, group); - std::cerr << "WireDialog::loadPulseData() GroupId: " << pulse.mMeta.mGroupId; + // store references to add in later. + std::cerr << "WireDialog::loadPulseData() REF: GroupId: " << pulse.mMeta.mGroupId; std::cerr << " PulseId: " << pulse.mMeta.mMsgId; std::cerr << std::endl; + references.push_back(&pulse); } else { - std::cerr << "WireDialog::loadPulseData() ERROR Missing GroupId: " << pulse.mMeta.mGroupId; - std::cerr << " PulseId: " << pulse.mMeta.mMsgId; - std::cerr << std::endl; + RsGxsGroupId &gid = pulse.mMeta.mGroupId; + std::map::iterator git = mAllGroups.find(gid); + if (git != mAllGroups.end()) + { + RsWireGroup &group = git->second; + std::cerr << "WireDialog::loadPulseData() MSG: GroupId: " << pulse.mMeta.mGroupId; + std::cerr << " PulseId: " << pulse.mMeta.mMsgId; + std::cerr << std::endl; + + // install into pulseGrouping. + pulseGrouping[pulse.mMeta.mOrigMsgId] = PulseReplySet(&pulse, &group); + } + else + { + std::cerr << "WireDialog::loadPulseData() ERROR Missing GroupId: " << pulse.mMeta.mGroupId; + std::cerr << " PulseId: " << pulse.mMeta.mMsgId; + std::cerr << std::endl; + } } } - // updatePulses(); + // add references. + std::list::iterator lrit; + for(lrit = references.begin(); lrit != references.end(); lrit++) + { + std::map::iterator pgit; + pgit = pulseGrouping.find((*lrit)->mMeta.mThreadId); + if (pgit != pulseGrouping.end()) + { + // install into reply map. + // TODO handle Edits / Latest MSGS. + std::map::iterator rmit; + rmit = pgit->second.replies.find((*lrit)->mMeta.mOrigMsgId); + if (rmit == pgit->second.replies.end()) + { + std::cerr << "WireDialog::loadPulseData() Installing REF: " << (*lrit)->mMeta.mOrigMsgId; + std::cerr << " to threadId: " << (*lrit)->mMeta.mThreadId; + std::cerr << std::endl; + pgit->second.replies[(*lrit)->mMeta.mOrigMsgId] = (*lrit); + } + else + { + std::cerr << "WireDialog::loadPulseData() ERROR Duplicate reply REF: " << (*lrit)->mMeta.mOrigMsgId; + std::cerr << std::endl; + } + } + else + { + // no original msg for REF. + std::cerr << "WireDialog::loadPulseData() ERROR No matching ThreadId REF: " << (*lrit)->mMeta.mThreadId; + std::cerr << std::endl; + } + } + references.clear(); + + // sort by publish time. + std::map pulseOrdering; + std::map::iterator pgit; + for(pgit = pulseGrouping.begin(); pgit != pulseGrouping.end(); pgit++) + { + PulseOrderedReply &msg = pulseOrdering[pgit->second.msg->mMeta.mPublishTs] = + PulseOrderedReply(pgit->second.msg, pgit->second.group); + std::map::iterator rmit; + for(rmit = pgit->second.replies.begin(); + rmit != pgit->second.replies.end(); rmit++) + { + msg.replies[rmit->second->mMeta.mPublishTs] = rmit->second; + } + } + + // now add to the GUI. + std::map::reverse_iterator poit; + for (poit = pulseOrdering.rbegin(); poit != pulseOrdering.rend(); poit++) + { + // add into GUI should insert at correct time point, amongst all other ones. + addPulse(poit->second.msg, poit->second.group, poit->second.replies); + } + return true; } +void WireDialog::acknowledgeGroup(const uint32_t &token, const uint32_t &userType) +{ + /* reload groups */ + std::cerr << "WireDialog::acknowledgeGroup(usertype: " << userType << ")"; + std::cerr << std::endl; + + RsGxsGroupId grpId; + rsWire->acknowledgeGrp(token, grpId); + + refreshGroups(); +} + /**************************** Request / Response Filling of Data ************************/ @@ -426,9 +646,9 @@ void WireDialog::loadRequest(const TokenQueue *queue, const TokenRequest &req) case RS_TOKREQ_ANSTYPE_DATA: loadGroupData(req.mToken); break; - // case RS_TOKREQ_ANSTYPE_ACK: - // acknowledgeGroup(req.mToken); - // break; + case RS_TOKREQ_ANSTYPE_ACK: + acknowledgeGroup(req.mToken, req.mUserType); + break; default: std::cerr << "WireDialog::loadRequest() ERROR: GROUP: INVALID ANS TYPE"; std::cerr << std::endl; diff --git a/retroshare-gui/src/gui/TheWire/WireDialog.h b/retroshare-gui/src/gui/TheWire/WireDialog.h index e50823ffd..738cedffd 100644 --- a/retroshare-gui/src/gui/TheWire/WireDialog.h +++ b/retroshare-gui/src/gui/TheWire/WireDialog.h @@ -29,13 +29,14 @@ #include #include "gui/TheWire/PulseItem.h" +#include "gui/TheWire/WireGroupItem.h" #include "gui/TheWire/PulseAddDialog.h" #include "util/TokenQueue.h" #define IMAGE_WIRE ":/images/kgames.png" -class WireDialog : public MainPage, public TokenResponse, public PulseHolder +class WireDialog : public MainPage, public TokenResponse, public PulseHolder, public WireGroupHolder { Q_OBJECT @@ -48,13 +49,17 @@ public: // PulseHolder interface. virtual void deletePulseItem(PulseItem *, uint32_t type); - virtual void notifySelection(PulseItem *item, int ptype); + virtual void notifyPulseSelection(PulseItem *item); virtual void follow(RsGxsGroupId &groupId); virtual void rate(RsGxsId &authorId); virtual void reply(RsWirePulse &pulse, std::string &groupName); - void notifyPulseSelection(PulseItem *item); + + // WireGroupHolder interface. + virtual void subscribe(RsGxsGroupId &groupId); + virtual void unsubscribe(RsGxsGroupId &groupId); + virtual void notifyGroupSelection(WireGroupItem *item); private slots: @@ -62,31 +67,38 @@ private slots: void createPulse(); void checkUpdate(); void refreshGroups(); + void selectGroupSet(int index); private: - void addItem(QWidget *item); void addGroup(QWidget *item); - void addPulse(RsWirePulse &pulse, RsWireGroup &group); - void addGroup(RsWireGroup &group); + void addPulse(RsWirePulse *pulse, RsWireGroup *group, + std::map replies); + + void addGroup(const RsWireGroup &group); void deletePulses(); void deleteGroups(); + void showGroups(); void updateGroups(std::vector &groups); // Loading Data. void requestGroupData(); bool loadGroupData(const uint32_t &token); + void acknowledgeGroup(const uint32_t &token, const uint32_t &userType); void requestPulseData(const std::list& grpIds); bool loadPulseData(const uint32_t &token); virtual void loadRequest(const TokenQueue *queue, const TokenRequest &req); + int mGroupSet; + PulseAddDialog *mAddDialog; PulseItem *mPulseSelected; + WireGroupItem *mGroupSelected; TokenQueue *mWireQueue; diff --git a/retroshare-gui/src/gui/TheWire/WireDialog.ui b/retroshare-gui/src/gui/TheWire/WireDialog.ui index ee69ee56b..84f76e5b1 100644 --- a/retroshare-gui/src/gui/TheWire/WireDialog.ui +++ b/retroshare-gui/src/gui/TheWire/WireDialog.ui @@ -116,7 +116,7 @@ 0 0 - 567 + 434 412 @@ -234,7 +234,7 @@ - 200 + 400 16777215 @@ -270,7 +270,7 @@ 0 0 - 129 + 262 416 @@ -296,7 +296,12 @@ - + + + + All + + Yourself diff --git a/retroshare-gui/src/gui/TheWire/WireGroupDialog.cpp b/retroshare-gui/src/gui/TheWire/WireGroupDialog.cpp index 119d29a9f..0bc0470b3 100644 --- a/retroshare-gui/src/gui/TheWire/WireGroupDialog.cpp +++ b/retroshare-gui/src/gui/TheWire/WireGroupDialog.cpp @@ -125,7 +125,7 @@ bool WireGroupDialog::service_CreateGroup(uint32_t &token, const RsGroupMetaData return true; } -bool WireGroupDialog::service_EditGroup(uint32_t &token, RsGroupMetaData &editedMeta) +bool WireGroupDialog::service_EditGroup(uint32_t & /* token */, RsGroupMetaData &editedMeta) { RsWireGroup grp; prepareWireGroup(grp, editedMeta); diff --git a/retroshare-gui/src/gui/TheWire/WireGroupItem.cpp b/retroshare-gui/src/gui/TheWire/WireGroupItem.cpp index 5c5606943..d1f2ae1e4 100644 --- a/retroshare-gui/src/gui/TheWire/WireGroupItem.cpp +++ b/retroshare-gui/src/gui/TheWire/WireGroupItem.cpp @@ -30,8 +30,8 @@ /** Constructor */ -WireGroupItem::WireGroupItem(RsWireGroup grp) -:QWidget(NULL), mGroup(grp), mType(0) +WireGroupItem::WireGroupItem(WireGroupHolder *holder, const RsWireGroup &grp) +:QWidget(NULL), mHolder(holder), mGroup(grp) { setupUi(this); setAttribute ( Qt::WA_DeleteOnClose, true ); @@ -42,10 +42,31 @@ WireGroupItem::WireGroupItem(RsWireGroup grp) void WireGroupItem::setup() { label_groupName->setText(QString::fromStdString(mGroup.mMeta.mGroupName)); - // label_authorId->setText(mGroup.mMeta.mAuthorId); + label_authorId->setId(mGroup.mMeta.mAuthorId); frame_details->setVisible(false); connect(toolButton_show, SIGNAL(clicked()), this, SLOT(show())); + connect(toolButton_subscribe, SIGNAL(clicked()), this, SLOT(subscribe())); + setGroupSet(); +} + +void WireGroupItem::setGroupSet() +{ + if (mGroup.mMeta.mSubscribeFlags & GXS_SERV::GROUP_SUBSCRIBE_ADMIN) { + toolButton_type->setText("Own"); + toolButton_subscribe->setText("N/A"); + toolButton_subscribe->setEnabled(false); + } + else if (mGroup.mMeta.mSubscribeFlags & GXS_SERV::GROUP_SUBSCRIBE_SUBSCRIBED) + { + toolButton_type->setText("Subcribed"); + toolButton_subscribe->setText("Unsubcribe"); + } + else + { + toolButton_type->setText("Other"); + toolButton_subscribe->setText("Subcribe"); + } } void WireGroupItem::show() @@ -53,12 +74,24 @@ void WireGroupItem::show() frame_details->setVisible(!frame_details->isVisible()); } +void WireGroupItem::subscribe() +{ + if (mGroup.mMeta.mSubscribeFlags & GXS_SERV::GROUP_SUBSCRIBE_SUBSCRIBED) + { + mHolder->unsubscribe(mGroup.mMeta.mGroupId); + } + else + { + mHolder->subscribe(mGroup.mMeta.mGroupId); + } +} + void WireGroupItem::removeItem() { } -void WireGroupItem::setSelected(bool on) +void WireGroupItem::setSelected(bool /* on */) { } diff --git a/retroshare-gui/src/gui/TheWire/WireGroupItem.h b/retroshare-gui/src/gui/TheWire/WireGroupItem.h index 9f6eac14f..82863ea89 100644 --- a/retroshare-gui/src/gui/TheWire/WireGroupItem.h +++ b/retroshare-gui/src/gui/TheWire/WireGroupItem.h @@ -27,12 +27,22 @@ class WireGroupItem; +class WireGroupHolder +{ +public: + virtual ~WireGroupHolder() {} + virtual void subscribe(RsGxsGroupId &groupId) = 0; + virtual void unsubscribe(RsGxsGroupId &groupId) = 0; + + virtual void notifyGroupSelection(WireGroupItem *item) = 0; +}; + class WireGroupItem : public QWidget, private Ui::WireGroupItem { Q_OBJECT public: - WireGroupItem(RsWireGroup grp); + WireGroupItem(WireGroupHolder *holder, const RsWireGroup &grp); void removeItem(); @@ -43,15 +53,17 @@ public: private slots: void show(); + void subscribe(); protected: void mousePressEvent(QMouseEvent *event); private: void setup(); + void setGroupSet(); + WireGroupHolder *mHolder; RsWireGroup mGroup; - uint32_t mType; bool mSelected; }; diff --git a/retroshare-gui/src/gui/TheWire/WireGroupItem.ui b/retroshare-gui/src/gui/TheWire/WireGroupItem.ui index f5939e03b..a71e1ed23 100644 --- a/retroshare-gui/src/gui/TheWire/WireGroupItem.ui +++ b/retroshare-gui/src/gui/TheWire/WireGroupItem.ui @@ -46,7 +46,7 @@ - + Type @@ -71,7 +71,7 @@ - + GxsIdLabel @@ -91,7 +91,7 @@ - + Sub/Un @@ -105,6 +105,13 @@ + + + GxsIdLabel + QLabel +
gui/gxs/GxsIdLabel.h
+
+
diff --git a/retroshare-gui/src/util/ClickableLabel.h b/retroshare-gui/src/util/ClickableLabel.h index 520608668..65070fd67 100644 --- a/retroshare-gui/src/util/ClickableLabel.h +++ b/retroshare-gui/src/util/ClickableLabel.h @@ -38,10 +38,10 @@ signals: protected: void mousePressEvent(QMouseEvent* event); - void enterEvent(QEvent *ev) override { setStyleSheet("QLabel { border: 2px solid #039bd5; }");} + void enterEvent(QEvent * /* ev */ ) override { setStyleSheet("QLabel { border: 2px solid #039bd5; }");} - void leaveEvent(QEvent *ev) override { setStyleSheet("QLabel { border: 2px solid #CCCCCC; border-radius: 3px; }");} + void leaveEvent(QEvent * /* ev */ ) override { setStyleSheet("QLabel { border: 2px solid #CCCCCC; border-radius: 3px; }");} }; -#endif // CLICKABLELABEL_H \ No newline at end of file +#endif // CLICKABLELABEL_H