diff --git a/libretroshare/src/retroshare/rswire.h b/libretroshare/src/retroshare/rswire.h index 580d3f279..f7225d581 100644 --- a/libretroshare/src/retroshare/rswire.h +++ b/libretroshare/src/retroshare/rswire.h @@ -3,7 +3,7 @@ * * * libretroshare: retroshare core library * * * - * Copyright 2012-2012 by Robert Fernie * + * Copyright 2012-2020 by Robert Fernie * * * * This program is free software: you can redistribute it and/or modify * * it under the terms of the GNU Lesser General Public License as * @@ -45,11 +45,7 @@ class RsWireGroup /*********************************************************************** - * So pulses operate in the following modes. - * - * => Standard, a post to your own group. - * => @User, gets duplicated on each user's group. - * => RT, duplicated as child of original post. + * RsWire - is intended to be a Twitter clone - but fully decentralised. * * From Twitter: * twitter can be: embedded, replied to, favourited, unfavourited, @@ -73,6 +69,36 @@ class RsWirePlace }; +/************************************************************************ + * Pulse comes in three flavours. + * + * + * Original Msg Pulse + * - Spontaneous msg, on your own group. + * - mPulseType = WIRE_PULSE_TYPE_ORIGINAL_MSG + * - Ref fields are empty. + * + * Reply to a Pulse (i.e Retweet), has two parts. + * as we want the retweet to reference the original, and the original to know about reply. + * This info will be duplicated in two msgs - but allow data to spread easier. + * + * Reply Msg Pulse, will be Top-Level Msg on Publisher's Group. + * - mPulseMode = WIRE_PULSE_TYPE_REPLY_MSG + * - Ref fields refer to Parent (InReplyTo) Msg. + * + * Reply Reference, is Child Msg of Parent Msg, on Parent Publisher's Group. + * - mPulseMode = WIRE_PULSE_TYPE_REPLY_REFERENCE + * - Ref fields refer to Reply Msg. + * - NB: This Msg requires Parent Msg for complete info, while other two are self-contained. + ***********************************************************************/ + +#define WIRE_PULSE_TYPE_ORIGINAL_MSG (0x0001) +#define WIRE_PULSE_TYPE_REPLY_MSG (0x0002) +#define WIRE_PULSE_TYPE_REPLY_REFERENCE (0x0004) + +#define WIRE_PULSE_TYPE_SENTIMENT_POSITIVE (0x0010) +#define WIRE_PULSE_TYPE_SENTIMENT_NEUTRAL (0x0020) +#define WIRE_PULSE_TYPE_SENTIMENT_NEGATIVE (0x0040) class RsWirePulse { @@ -80,19 +106,26 @@ class RsWirePulse RsMsgMetaData mMeta; - std::string mPulseText; // all the text is stored here. - std::string mHashTags; + // Store actual Pulse here. + std::string mPulseText; -// These will be added at some point. -// std::string mInReplyPulse; + uint32_t mPulseType; -// uint32_t mPulseFlags; + // These Ref to the related (parent or reply) if reply (MODE_REPLY_MSG set) + // Mode REPLY_MSG only REPLY_REFERENCE + RsGxsGroupId mRefGroupId; // PARENT_GrpId REPLY_GrpId + std::string mRefGroupName; // PARENT_GrpName REPLY_GrpName + RsGxsMessageId mRefOrigMsgId; // PARENT_OrigMsgId REPLY_OrigMsgId + RsGxsId mRefAuthorId; // PARENT_AuthorId REPLY_AuthorId + rstime_t mRefPublishTs; // PARENT_PublishTs REPLY_PublishTs + std::string mRefPulseText; // PARENT_PulseText REPLY_PulseText -// std::list mMentions; -// std::list mHashTags; -// std::list mUrls; - -// RsWirePlace mPlace; + // Open Question. Do we want these additional fields? + // These can potentially be added at some point. + // std::list mMentions; + // std::list mHashTags; + // std::list mUrls; + // RsWirePlace mPlace; }; @@ -107,6 +140,13 @@ class RsWire: public RsGxsIfaceHelper explicit RsWire(RsGxsIface& gxs) : RsGxsIfaceHelper(gxs) {} virtual ~RsWire() {} + /*! + * To acquire a handle to token service handler + * needed to make requests to the service + * @return handle to token service for this gxs service + */ + virtual RsTokenService* getTokenService() = 0; + /* Specific Service Data */ virtual bool getGroupData(const uint32_t &token, std::vector &groups) = 0; virtual bool getPulseData(const uint32_t &token, std::vector &pulses) = 0; diff --git a/libretroshare/src/rsitems/rswireitems.cc b/libretroshare/src/rsitems/rswireitems.cc index c00012975..65360dbf4 100644 --- a/libretroshare/src/rsitems/rswireitems.cc +++ b/libretroshare/src/rsitems/rswireitems.cc @@ -29,16 +29,16 @@ RsItem *RsGxsWireSerialiser::create_item(uint16_t service,uint8_t item_subtype) const { - if(service != RS_SERVICE_GXS_TYPE_WIRE) - return NULL ; + if(service != RS_SERVICE_GXS_TYPE_WIRE) + return NULL ; - switch(item_subtype) - { - case RS_PKT_SUBTYPE_WIRE_GROUP_ITEM: return new RsGxsWireGroupItem(); - case RS_PKT_SUBTYPE_WIRE_PULSE_ITEM: return new RsGxsWirePulseItem(); - default: - return NULL ; - } + switch(item_subtype) + { + case RS_PKT_SUBTYPE_WIRE_GROUP_ITEM: return new RsGxsWireGroupItem(); + case RS_PKT_SUBTYPE_WIRE_PULSE_ITEM: return new RsGxsWirePulseItem(); + default: + return NULL ; + } } void RsGxsWireGroupItem::clear() @@ -48,18 +48,30 @@ void RsGxsWireGroupItem::clear() void RsGxsWireGroupItem::serial_process(RsGenericSerializer::SerializeJob j,RsGenericSerializer::SerializeContext& ctx) { - RsTypeSerializer::serial_process(j,ctx,TLV_TYPE_STR_DESCR,group.mDescription,"group.mDescription") ; + RsTypeSerializer::serial_process(j,ctx,TLV_TYPE_STR_DESCR,group.mDescription,"group.mDescription") ; } void RsGxsWirePulseItem::clear() { pulse.mPulseText.clear(); - pulse.mHashTags.clear(); + pulse.mPulseType = 0; + pulse.mRefGroupId.clear(); + pulse.mRefGroupName.clear(); + pulse.mRefOrigMsgId.clear(); + pulse.mRefAuthorId.clear(); + pulse.mRefPulseText.clear(); } void RsGxsWirePulseItem::serial_process(RsGenericSerializer::SerializeJob j,RsGenericSerializer::SerializeContext& ctx) { - RsTypeSerializer::serial_process(j,ctx,TLV_TYPE_STR_MSG,pulse.mPulseText,"pulse.mPulseText") ; - RsTypeSerializer::serial_process(j,ctx,TLV_TYPE_STR_HASH_TAG,pulse.mHashTags,"pulse.mHashTags") ; + RsTypeSerializer::serial_process(j,ctx,TLV_TYPE_STR_MSG,pulse.mPulseText,"pulse.mPulseText") ; + RsTypeSerializer::serial_process(j,ctx,TLV_TYPE_UINT32_PARAM,pulse.mPulseType,"pulse.mPulseType") ; + RsTypeSerializer::serial_process(j,ctx,pulse.mRefGroupId,"pulse.mRefGroupId") ; + RsTypeSerializer::serial_process(j,ctx,TLV_TYPE_STR_NAME,pulse.mRefGroupName,"pulse.mRefGroupName") ; + RsTypeSerializer::serial_process(j,ctx,pulse.mRefOrigMsgId,"pulse.mRefOrigMsgId") ; + RsTypeSerializer::serial_process(j,ctx,pulse.mRefAuthorId,"pulse.mRefAuthorId") ; + RsTypeSerializer::serial_process(j,ctx,pulse.mRefPublishTs,"pulse.mRefPublishTs") ; + RsTypeSerializer::serial_process(j,ctx,TLV_TYPE_STR_MSG,pulse.mRefPulseText,"pulse.mRefPulseText") ; + } diff --git a/libretroshare/src/rsserver/rsinit.cc b/libretroshare/src/rsserver/rsinit.cc index 886660049..5de23251a 100644 --- a/libretroshare/src/rsserver/rsinit.cc +++ b/libretroshare/src/rsserver/rsinit.cc @@ -1381,8 +1381,7 @@ int RsServer::StartupRetroShare() #ifdef RS_USE_WIRE /**** Wire GXS service ****/ RsGeneralDataService* wire_ds = new RsDataService(currGxsDir + "/", "wire_db", - RS_SERVICE_GXS_TYPE_WIRE, - NULL, rsInitConfig->gxs_passwd); + RS_SERVICE_GXS_TYPE_WIRE, NULL, rsInitConfig->gxs_passwd); p3Wire *mWire = new p3Wire(wire_ds, NULL, mGxsIdService); @@ -1826,7 +1825,7 @@ int RsServer::StartupRetroShare() startServiceThread(mPhoto, "gxs photo"); #endif #if RS_USE_WIRE - startServiceThread(mPhoto, "gxs wire"); + startServiceThread(mWire, "gxs wire"); #endif // cores ready start up GXS net servers @@ -1843,7 +1842,7 @@ int RsServer::StartupRetroShare() startServiceThread(photo_ns, "gxs photo ns"); #endif #if RS_USE_WIRE - startServiceThread(photo_ns, "gxs wire ns"); + startServiceThread(wire_ns, "gxs wire ns"); #endif # ifdef RS_GXS_TRANS diff --git a/libretroshare/src/services/p3wire.cc b/libretroshare/src/services/p3wire.cc index 762a8b8af..18119c9a3 100644 --- a/libretroshare/src/services/p3wire.cc +++ b/libretroshare/src/services/p3wire.cc @@ -3,7 +3,7 @@ * * * libretroshare: retroshare core library * * * - * Copyright 2012-2012 by Robert Fernie * + * Copyright 2012-2020 by Robert Fernie * * * * This program is free software: you can redistribute it and/or modify * * it under the terms of the GNU Lesser General Public License as * @@ -83,6 +83,10 @@ void p3Wire::service_tick() return; } +RsTokenService* p3Wire::getTokenService() { + + return RsGenExchange::getTokenService(); +} void p3Wire::notifyChanges(std::vector& changes) { @@ -175,12 +179,12 @@ bool p3Wire::createGroup(uint32_t &token, RsWireGroup &group) groupItem->group = group; groupItem->meta = group.mMeta; - std::cerr << "p3Wire::createGroup(): "; + std::cerr << "p3Wire::createGroup(): "; std::cerr << std::endl; std::cerr << group; std::cerr << std::endl; - std::cerr << "p3Wire::createGroup() pushing to RsGenExchange"; + std::cerr << "p3Wire::createGroup() pushing to RsGenExchange"; std::cerr << std::endl; RsGenExchange::publishGroup(token, groupItem); @@ -193,11 +197,11 @@ bool p3Wire::createPulse(uint32_t &token, RsWirePulse &pulse) std::cerr << "p3Wire::createPulse(): " << pulse; std::cerr << std::endl; - RsGxsWirePulseItem* pulseItem = new RsGxsWirePulseItem(); - pulseItem->pulse = pulse; - pulseItem->meta = pulse.mMeta; + RsGxsWirePulseItem* pulseItem = new RsGxsWirePulseItem(); + pulseItem->pulse = pulse; + pulseItem->meta = pulse.mMeta; - RsGenExchange::publishMsg(token, pulseItem); + RsGenExchange::publishMsg(token, pulseItem); return true; } diff --git a/libretroshare/src/services/p3wire.h b/libretroshare/src/services/p3wire.h index 3858d158e..4a589205b 100644 --- a/libretroshare/src/services/p3wire.h +++ b/libretroshare/src/services/p3wire.h @@ -3,7 +3,7 @@ * * * libretroshare: retroshare core library * * * - * Copyright 2012-2012 by Robert Fernie * + * Copyright 2012-2020 by Robert Fernie * * * * This program is free software: you can redistribute it and/or modify * * it under the terms of the GNU Lesser General Public License as * @@ -34,37 +34,33 @@ * */ - class p3Wire: public RsGenExchange, public RsWire { public: - p3Wire(RsGeneralDataService* gds, RsNetworkExchangeService* nes, RsGixs *gixs); -virtual RsServiceInfo getServiceInfo(); -static uint32_t wireAuthenPolicy(); + p3Wire(RsGeneralDataService* gds, RsNetworkExchangeService* nes, RsGixs *gixs); + virtual RsServiceInfo getServiceInfo(); + static uint32_t wireAuthenPolicy(); protected: - -virtual void notifyChanges(std::vector& changes) ; + virtual void notifyChanges(std::vector& changes) ; public: + virtual void service_tick(); -virtual void service_tick(); + virtual RsTokenService* getTokenService(); - /* Specific Service Data */ -virtual bool getGroupData(const uint32_t &token, std::vector &groups); -virtual bool getPulseData(const uint32_t &token, std::vector &pulses); + /* Specific Service Data */ + virtual bool getGroupData(const uint32_t &token, std::vector &groups); + virtual bool getPulseData(const uint32_t &token, std::vector &pulses); -virtual bool createGroup(uint32_t &token, RsWireGroup &group); -virtual bool createPulse(uint32_t &token, RsWirePulse &pulse); + virtual bool createGroup(uint32_t &token, RsWireGroup &group); + virtual bool createPulse(uint32_t &token, RsWirePulse &pulse); - private: - -virtual void generateDummyData(); -std::string genRandomId(); +private: + virtual void generateDummyData(); + std::string genRandomId(); RsMutex mWireMtx; - - }; #endif diff --git a/retroshare-gui/src/gui/TheWire/PulseAddDialog.cpp b/retroshare-gui/src/gui/TheWire/PulseAddDialog.cpp index 94361b8dd..1e0d58ea6 100644 --- a/retroshare-gui/src/gui/TheWire/PulseAddDialog.cpp +++ b/retroshare-gui/src/gui/TheWire/PulseAddDialog.cpp @@ -1,7 +1,7 @@ /******************************************************************************* * gui/TheWire/PulseAddDialog.cpp * * * - * Copyright (c) 2012 Robert Fernie * + * Copyright (c) 2012-2020 Robert Fernie * * * * This program is free software: you can redistribute it and/or modify * * it under the terms of the GNU Affero General Public License as * @@ -18,39 +18,58 @@ * * *******************************************************************************/ -#include "gui/TheWire/PulseAddDialog.h" - -#include "gui/PhotoShare/PhotoDrop.h" - #include +#include "PulseDetails.h" + +#include "PulseAddDialog.h" + + /** Constructor */ PulseAddDialog::PulseAddDialog(QWidget *parent) -: QWidget(parent) +: QWidget(parent), mIsReply(false), mWaitingRefMsg(false) { ui.setupUi(this); + mWireQueue = new TokenQueue(rsWire->getTokenService(), this); + connect(ui.pushButton_Post, SIGNAL( clicked( void ) ), this, SLOT( postPulse( void ) ) ); connect(ui.pushButton_AddURL, SIGNAL( clicked( void ) ), this, SLOT( addURL( void ) ) ); connect(ui.pushButton_AddTo, SIGNAL( clicked( void ) ), this, SLOT( addTo( void ) ) ); connect(ui.pushButton_Cancel, SIGNAL( clicked( void ) ), this, SLOT( cancelPulse( void ) ) ); -#if 0 - connect(ui.scrollAreaWidgetContents, SIGNAL( buttonStatus( uint32_t ) ), this, SLOT( updateMoveButtons( uint32_t ) ) ); - connect(ui.pushButton_ShiftRight, SIGNAL( clicked( void ) ), ui.scrollAreaWidgetContents, SLOT( moveRight( void ) ) ); - connect(ui.pushButton_EditPhotoDetails, SIGNAL( clicked( void ) ), this, SLOT( showPhotoDetails( void ) ) ); +} - connect(ui.pushButton_Publish, SIGNAL( clicked( void ) ), this, SLOT( publishAlbum( void ) ) ); -#endif +void PulseAddDialog::setGroup(RsWireGroup &group) +{ + ui.label_groupName->setText(QString::fromStdString(group.mMeta.mGroupName)); + ui.label_idName->setText(QString::fromStdString(group.mMeta.mAuthorId.toStdString())); + mGroup = group; +} - mPhotoDetails = NULL; +void PulseAddDialog::setReplyTo(RsWirePulse &pulse, std::string &groupName) +{ + mIsReply = true; + mReplyToPulse = pulse; + mReplyGroupName = groupName; + + { + PulseDetails *details = new PulseDetails(NULL, pulse, groupName, true); + // add extra widget into layout. + QVBoxLayout *vbox = new QVBoxLayout(); + vbox->addWidget(details); + vbox->setSpacing(1); + vbox->setContentsMargins(0,0,0,0); + ui.widget_replyto->setLayout(vbox); + ui.widget_replyto->setVisible(true); + } } void PulseAddDialog::addURL() { - std::cerr << "PulseAddDialog::addURL()"; - std::cerr << std::endl; + std::cerr << "PulseAddDialog::addURL()"; + std::cerr << std::endl; return; } @@ -58,8 +77,8 @@ void PulseAddDialog::addURL() void PulseAddDialog::addTo() { - std::cerr << "PulseAddDialog::addTo()"; - std::cerr << std::endl; + std::cerr << "PulseAddDialog::addTo()"; + std::cerr << std::endl; return; } @@ -67,8 +86,8 @@ void PulseAddDialog::addTo() void PulseAddDialog::cancelPulse() { - std::cerr << "PulseAddDialog::cancelPulse()"; - std::cerr << std::endl; + std::cerr << "PulseAddDialog::cancelPulse()"; + std::cerr << std::endl; clearDialog(); hide(); @@ -77,130 +96,203 @@ void PulseAddDialog::cancelPulse() } - -void PulseAddDialog::updateMoveButtons(uint32_t status) -{ - std::cerr << "PulseAddDialog::updateMoveButtons(" << status << ")"; - std::cerr << std::endl; - -#if 0 - switch(status) - { - case PHOTO_SHIFT_NO_BUTTONS: - ui.pushButton_ShiftLeft->setEnabled(false); - ui.pushButton_ShiftRight->setEnabled(false); - break; - case PHOTO_SHIFT_LEFT_ONLY: - ui.pushButton_ShiftLeft->setEnabled(true); - ui.pushButton_ShiftRight->setEnabled(false); - break; - case PHOTO_SHIFT_RIGHT_ONLY: - ui.pushButton_ShiftLeft->setEnabled(false); - ui.pushButton_ShiftRight->setEnabled(true); - break; - case PHOTO_SHIFT_BOTH: - ui.pushButton_ShiftLeft->setEnabled(true); - ui.pushButton_ShiftRight->setEnabled(true); - break; - } -#endif -} - - -void PulseAddDialog::showPhotoDetails() -{ - -#if 0 - std::cerr << "PulseAddDialog::showPhotoDetails()"; - std::cerr << std::endl; - - if (!mPhotoDetails) - { - mPhotoDetails = new PhotoDetailsDialog(NULL); - } - - PhotoItem *item = ui.scrollAreaWidgetContents->getSelectedPhotoItem(); - - mPhotoDetails->setPhotoItem(item); - mPhotoDetails->show(); -#endif -} - - - - void PulseAddDialog::postPulse() { - std::cerr << "PulseAddDialog::postPulse()"; - std::cerr << std::endl; - -#if 0 - /* we need to iterate through each photoItem, and extract the details */ - - - RsPhotoAlbum album; - RsPhotoThumbnail albumThumb; - - album.mShareOptions.mShareType = 0; - album.mShareOptions.mShareGroupId = "unknown"; - album.mShareOptions.mPublishKey = "unknown"; - album.mShareOptions.mCommentMode = 0; - album.mShareOptions.mResizeMode = 0; - - album.mTitle = ui.lineEdit_Title->text().toStdString(); - album.mCategory = "Unknown"; - album.mCaption = ui.lineEdit_Caption->text().toStdString(); - album.mWhere = ui.lineEdit_Where->text().toStdString(); - album.mWhen = ui.lineEdit_When->text().toStdString(); - - if (rsPhoto->submitAlbumDetails(album, albumThumb)) + std::cerr << "PulseAddDialog::postPulse()"; + std::cerr << std::endl; + if (mIsReply) { - /* now have path and album id */ - int photoCount = ui.scrollAreaWidgetContents->getPhotoCount(); - - for(int i = 0; i < photoCount; ++i) - { - RsPhotoPhoto photo; - RsPhotoThumbnail thumbnail; - PhotoItem *item = ui.scrollAreaWidgetContents->getPhotoIdx(i); - photo = item->mDetails; - item->getPhotoThumbnail(thumbnail); - - photo.mAlbumId = album.mAlbumId; - photo.mOrder = i; - - /* scale photo if needed */ - if (album.mShareOptions.mResizeMode) - { - /* */ - - } - /* save image to album path */ - photo.path = "unknown"; - - rsPhoto->submitPhoto(photo, thumbnail); - } + postReplyPulse(); } + else + { + postOriginalPulse(); + } +} + + +void PulseAddDialog::postOriginalPulse() +{ + std::cerr << "PulseAddDialog::postOriginalPulse()"; + std::cerr << std::endl; + + RsWirePulse pulse; + + pulse.mMeta.mGroupId = mGroup.mMeta.mGroupId; + pulse.mMeta.mAuthorId = mGroup.mMeta.mAuthorId; + pulse.mMeta.mThreadId.clear(); + pulse.mMeta.mParentId.clear(); + pulse.mMeta.mOrigMsgId.clear(); + + pulse.mPulseType = WIRE_PULSE_TYPE_ORIGINAL_MSG; + pulse.mPulseText = ui.textEdit_Pulse->toPlainText().toStdString(); + // all mRefs should empty. + + uint32_t token; + rsWire->createPulse(token, pulse); -#endif clearDialog(); - hide(); } -void PulseAddDialog::clearDialog() +void PulseAddDialog::postReplyPulse() { + std::cerr << "PulseAddDialog::postReplyPulse()"; + std::cerr << std::endl; - ui.textEdit_Pulse->setPlainText(""); -#if 0 - ui.lineEdit_Title->setText(QString("title")); - ui.lineEdit_Caption->setText(QString("Caption")); - ui.lineEdit_Where->setText(QString("Where")); - ui.lineEdit_When->setText(QString("When")); + RsWirePulse pulse; - ui.scrollAreaWidgetContents->clearPhotos(); -#endif + pulse.mMeta.mGroupId = mGroup.mMeta.mGroupId; + pulse.mMeta.mAuthorId = mGroup.mMeta.mAuthorId; + pulse.mMeta.mThreadId.clear(); + pulse.mMeta.mParentId.clear(); + pulse.mMeta.mOrigMsgId.clear(); + + pulse.mPulseType = WIRE_PULSE_TYPE_REPLY_MSG; + pulse.mPulseText = ui.textEdit_Pulse->toPlainText().toStdString(); + + // mRefs refer to parent post. + pulse.mRefGroupId = mReplyToPulse.mMeta.mGroupId; + pulse.mRefGroupName = mReplyGroupName; + pulse.mRefOrigMsgId = mReplyToPulse.mMeta.mOrigMsgId; + pulse.mRefAuthorId = mReplyToPulse.mMeta.mAuthorId; + pulse.mRefPublishTs = mReplyToPulse.mMeta.mPublishTs; + pulse.mRefPulseText = mReplyToPulse.mPulseText; + + // Need Pulse MsgID before we can create associated Reference. + mWaitingRefMsg = true; + + uint32_t token; + rsWire->createPulse(token, pulse); + mWireQueue->queueRequest(token, TOKENREQ_MSGINFO, RS_TOKREQ_ANSTYPE_ACK, 0); } + +void PulseAddDialog::postRefPulse(RsWirePulse &pulse) +{ + std::cerr << "PulseAddDialog::postRefPulse() create Reference!"; + std::cerr << std::endl; + + // Reference Pulse. posted on Parent's Group. + RsWirePulse refPulse; + + refPulse.mMeta.mGroupId = mReplyToPulse.mMeta.mGroupId; + refPulse.mMeta.mAuthorId = mGroup.mMeta.mAuthorId; // own author Id. + refPulse.mMeta.mThreadId = mReplyToPulse.mMeta.mOrigMsgId; + refPulse.mMeta.mParentId = mReplyToPulse.mMeta.mOrigMsgId; + refPulse.mMeta.mOrigMsgId.clear(); + + refPulse.mPulseType = WIRE_PULSE_TYPE_REPLY_REFERENCE; + // Dont put parent PulseText into refPulse - it is available on Thread Msg. + // otherwise gives impression it is correctly setup Parent / Reply... + // when in fact the parent PublishTS, and AuthorId are wrong. + refPulse.mPulseText = ""; + + // refs refer back to own Post. + refPulse.mRefGroupId = mGroup.mMeta.mGroupId; + refPulse.mRefGroupName = mGroup.mMeta.mGroupName; + refPulse.mRefOrigMsgId = pulse.mMeta.mOrigMsgId; + refPulse.mRefAuthorId = mGroup.mMeta.mAuthorId; + refPulse.mRefPublishTs = pulse.mMeta.mPublishTs; + refPulse.mRefPulseText = pulse.mPulseText; + + uint32_t token; + rsWire->createPulse(token, refPulse); + + clearDialog(); + hide(); +} + +void PulseAddDialog::clearDialog() +{ + ui.textEdit_Pulse->setPlainText(""); +} + + +void PulseAddDialog::acknowledgeMessage(const uint32_t &token) +{ + std::cerr << "PulseAddDialog::acknowledgeMessage()"; + std::cerr << std::endl; + + std::pair p; + rsWire->acknowledgeMsg(token, p); + + if (mWaitingRefMsg) + { + std::cerr << "PulseAddDialog::acknowledgeMessage() Waiting Ref Msg"; + std::cerr << std::endl; + mWaitingRefMsg = false; + + // request photo data. + GxsMsgReq req; + std::set msgIds; + msgIds.insert(p.second); + req[p.first] = msgIds; + + RsTokReqOptions opts; + opts.mReqType = GXS_REQUEST_TYPE_MSG_DATA; + uint32_t token; + mWireQueue->requestMsgInfo(token, RS_TOKREQ_ANSTYPE_DATA, opts, req, 0); + } + else + { + std::cerr << "PulseAddDialog::acknowledgeMessage() Not Waiting Ref Msg"; + std::cerr << std::endl; + } +} + +void PulseAddDialog::loadPulseData(const uint32_t &token) +{ + std::cerr << "PulseAddDialog::loadPulseData()"; + std::cerr << std::endl; + std::vector pulses; + rsWire->getPulseData(token, pulses); + + if (pulses.size() != 1) + { + std::cerr << "PulseAddDialog::loadPulseData() Error Too many pulses"; + std::cerr << std::endl; + return; + } + + std::cerr << "PulseAddDialog::loadPulseData() calling postRefMsg"; + std::cerr << std::endl; + + RsWirePulse& pulse = pulses[0]; + postRefPulse(pulse); +} + + +/**************************** Request / Response Filling of Data ************************/ + +void PulseAddDialog::loadRequest(const TokenQueue *queue, const TokenRequest &req) +{ + if (queue == mWireQueue) + { + /* now switch on req */ + switch(req.mType) + { + case TOKENREQ_MSGINFO: + switch(req.mAnsType) + { + case RS_TOKREQ_ANSTYPE_ACK: + acknowledgeMessage(req.mToken); + break; + case RS_TOKREQ_ANSTYPE_DATA: + loadPulseData(req.mToken); + break; + default: + std::cerr << "PulseAddDialog::loadRequest() ERROR: MSG: INVALID ANS TYPE"; + std::cerr << std::endl; + break; + } + break; + default: + std::cerr << "PulseAddDialog::loadRequest() ERROR: INVALID TYPE"; + std::cerr << std::endl; + break; + } + } +} diff --git a/retroshare-gui/src/gui/TheWire/PulseAddDialog.h b/retroshare-gui/src/gui/TheWire/PulseAddDialog.h index 79c82128f..e48ecfeea 100644 --- a/retroshare-gui/src/gui/TheWire/PulseAddDialog.h +++ b/retroshare-gui/src/gui/TheWire/PulseAddDialog.h @@ -1,7 +1,7 @@ /******************************************************************************* * gui/TheWire/PulseAddDialog.h * * * - * Copyright (c) 2012 Robert Fernie * + * Copyright (c) 2012-2020 Robert Fernie * * * * This program is free software: you can redistribute it and/or modify * * it under the terms of the GNU Affero General Public License as * @@ -23,30 +23,46 @@ #include "ui_PulseAddDialog.h" -#include +#include +#include "util/TokenQueue.h" -class PhotoDetailsDialog; - -class PulseAddDialog : public QWidget +class PulseAddDialog : public QWidget, public TokenResponse { Q_OBJECT public: PulseAddDialog(QWidget *parent = 0); -private slots: - void showPhotoDetails(); - void updateMoveButtons(uint32_t status); + void setGroup(RsWireGroup &group); + void setReplyTo(RsWirePulse &pulse, std::string &groupName); +private slots: void addURL(); void addTo(); void postPulse(); void cancelPulse(); void clearDialog(); +private: + void postOriginalPulse(); + void postReplyPulse(); + void postRefPulse(RsWirePulse &pulse); + + void acknowledgeMessage(const uint32_t &token); + void loadPulseData(const uint32_t &token); + void loadRequest(const TokenQueue *queue, const TokenRequest &req); + protected: - PhotoDetailsDialog *mPhotoDetails; + RsWireGroup mGroup; // where we want to post from. + + // if this is a reply + bool mIsReply; + std::string mReplyGroupName; + RsWirePulse mReplyToPulse; + bool mWaitingRefMsg; + + TokenQueue* mWireQueue; Ui::PulseAddDialog ui; }; diff --git a/retroshare-gui/src/gui/TheWire/PulseAddDialog.ui b/retroshare-gui/src/gui/TheWire/PulseAddDialog.ui index 08110c603..cdcbf632c 100644 --- a/retroshare-gui/src/gui/TheWire/PulseAddDialog.ui +++ b/retroshare-gui/src/gui/TheWire/PulseAddDialog.ui @@ -14,196 +14,75 @@ - - - - Qt::Vertical + + + + QFrame::StyledPanel - - - - 160 - 16777215 - - - - QFrame::StyledPanel - - - QFrame::Raised - - - - 0 - - - 0 - - - - - - 0 - 0 - - - - true - - - - - 0 - 0 - 156 - 184 - - - - - - - - 12 - 75 - true - - - - Post From: - - - - - - - Account 1 - - - - - - - Account 2 - - - - - - - Account 3 - - - - - - - Qt::Vertical - - - - 20 - 0 - - - - - - - - - - - - - true - - - - - 0 - 0 - 158 - 372 - - - + + QFrame::Raised + + + + - + - Add to Pulse + In Reply to: - + + + + 11 + 75 + true + + - filter + Positive / Neutral / Negative - - - true + + + Qt::Horizontal - - - - 0 - 0 - 138 - 286 - - - - - - - Account 1 - - - - - - - Account 2 - - - - - - - Account 3 - - - - - - - Qt::Vertical - - - - 20 - 70 - - - - - - - + + + 238 + 20 + + + - - + + + + + - - - + + + QFrame::StyledPanel + + + QFrame::Raised + + + + + + + + + URL Adder @@ -252,14 +131,14 @@ - + Cancel - + Qt::Horizontal @@ -272,17 +151,159 @@ - + Post Pulse to Wire + + + + Qt::Vertical + + + + + 160 + 16777215 + + + + QFrame::StyledPanel + + + QFrame::Raised + + + + + + + 12 + 75 + true + + + + Post From: + + + + + + + GroupLabel + + + + + + + IDLabel + + + + + + + + true + + + + + 0 + 0 + 150 + 423 + + + + + + + Add to Pulse + + + + + + + filter + + + + + + + true + + + + + 0 + 0 + 130 + 341 + + + + + + + Account 1 + + + + + + + Account 2 + + + + + + + Account 3 + + + + + + + Qt::Vertical + + + + 20 + 70 + + + + + + + + + + + + + + + + GxsIdLabel + QLabel +
gui/gxs/GxsIdLabel.h
+
+
- + diff --git a/retroshare-gui/src/gui/TheWire/PulseDetails.cpp b/retroshare-gui/src/gui/TheWire/PulseDetails.cpp new file mode 100644 index 000000000..7bb1f2615 --- /dev/null +++ b/retroshare-gui/src/gui/TheWire/PulseDetails.cpp @@ -0,0 +1,144 @@ +/******************************************************************************* + * gui/TheWire/PulseDetails.cpp * + * * + * Copyright (c) 2020 Robert Fernie * + * * + * This program is free software: you can redistribute it and/or modify * + * it under the terms of the GNU Affero 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 Affero General Public License for more details. * + * * + * You should have received a copy of the GNU Affero General Public License * + * along with this program. If not, see . * + * * + *******************************************************************************/ + +#include +#include +#include +#include + +#include "PulseDetails.h" + +#include "util/DateTime.h" + +#include +#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) +{ + setupUi(this); + setAttribute ( Qt::WA_DeleteOnClose, true ); + setup(); +} + +PulseDetails::PulseDetails(PulseHolder *actions, + RsGxsGroupId &parentGroupId, + std::string &parentGroupName, + RsGxsMessageId &parentOrigMsgId, + RsGxsId &parentAuthorId, + rstime_t &parentPublishTs, + std::string &parentPulseText) +:QWidget(NULL), mActions(actions), mPulse(), mGroupName(parentGroupName), mIsOriginal(false) +{ + setupUi(this); + setAttribute ( Qt::WA_DeleteOnClose, true ); + + // reuse Meta data structure. + mPulse.mMeta.mGroupId = parentGroupId; + mPulse.mMeta.mOrigMsgId = parentOrigMsgId; + mPulse.mMeta.mAuthorId = parentAuthorId; + mPulse.mMeta.mPublishTs = parentPublishTs; + mPulse.mPulseText = parentPulseText; + setup(); +} + +void PulseDetails::setup() +{ + connect(toolButton_expand, SIGNAL(clicked()), this, SLOT(toggle())); + + connect(toolButton_follow, SIGNAL(clicked()), this, SLOT(follow())); + connect(toolButton_rate, SIGNAL(clicked()), this, SLOT(rate())); + connect(toolButton_reply, SIGNAL(clicked()), this, SLOT(reply())); + + label_wireName->setText(QString::fromStdString(mGroupName)); + label_idName->setId(mPulse.mMeta.mAuthorId); + + label_date->setText(DateTime::formatDateTime(mPulse.mMeta.mPublishTs)); + label_summary->setText(getSummary()); + + // label_icon->setText(); + textBrowser->setPlainText(QString::fromStdString(mPulse.mPulseText)); + frame_expand->setVisible(false); +} + + +void PulseDetails::toggle() +{ + if (frame_expand->isVisible()) { + // switch to minimal view. + label_summary->setVisible(true); + frame_expand->setVisible(false); + } else { + // switch to expanded view. + label_summary->setVisible(false); + frame_expand->setVisible(true); + } +} + +QString PulseDetails::getSummary() +{ + std::string summary = mPulse.mPulseText; + std::cerr << "PulseDetails::getSummary() orig: " << summary; + std::cerr << std::endl; + int len = summary.size(); + bool in_whitespace = false; + for (int i = 0; i < len; i++) + { + if (isspace(summary[i])) { + if (in_whitespace) { + // trim + summary.erase(i, 1); + // rollback index / len. + --i; + --len; + } else { + // replace whitespace with space. + summary[i] = ' '; + in_whitespace = true; + } + } else { + in_whitespace = false; + } + } + std::cerr << "PulseDetails::getSummary() summary: " << summary; + std::cerr << std::endl; + + return QString::fromStdString(summary); +} + +void PulseDetails::follow() +{ + // follow group. + mActions->follow(mPulse.mMeta.mGroupId); +} + +void PulseDetails::rate() +{ + // rate author + mActions->rate(mPulse.mMeta.mAuthorId); +} + +void PulseDetails::reply() +{ + mActions->reply(mPulse, mGroupName); +} + + diff --git a/retroshare-gui/src/gui/TheWire/PulseDetails.h b/retroshare-gui/src/gui/TheWire/PulseDetails.h new file mode 100644 index 000000000..6b063eab9 --- /dev/null +++ b/retroshare-gui/src/gui/TheWire/PulseDetails.h @@ -0,0 +1,62 @@ +/******************************************************************************* + * gui/TheWire/PulseDetails.h * + * * + * Copyright (c) 2020 Robert Fernie * + * * + * This program is free software: you can redistribute it and/or modify * + * it under the terms of the GNU Affero 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 Affero General Public License for more details. * + * * + * You should have received a copy of the GNU Affero General Public License * + * along with this program. If not, see . * + * * + *******************************************************************************/ + +#ifndef MRK_PULSE_DETAILS_H +#define MRK_PULSE_DETAILS_H + +#include "ui_PulseDetails.h" +#include "PulseItem.h" + +#include + +class PulseDetails : public QWidget, private Ui::PulseDetails +{ + Q_OBJECT + +public: + PulseDetails(PulseHolder *actions, RsWirePulse &pulse, std::string &groupName, bool is_original); + + // when Reply parent.... + PulseDetails(PulseHolder *actions, + RsGxsGroupId &parentGroupId, + std::string &parentGroupName, + RsGxsMessageId &parentOrigMsgId, + RsGxsId &parentAuthorId, + rstime_t &parentPublishTs, + std::string &parentPulseText); + + void setup(); + +private slots: + void toggle(); + void follow(); + void rate(); + void reply(); + +private: + QString getSummary(); + + PulseHolder *mActions; + RsWirePulse mPulse; + std::string mGroupName; + bool mIsOriginal; +}; + +#endif diff --git a/retroshare-gui/src/gui/TheWire/PulseDetails.ui b/retroshare-gui/src/gui/TheWire/PulseDetails.ui new file mode 100644 index 000000000..3739dd0da --- /dev/null +++ b/retroshare-gui/src/gui/TheWire/PulseDetails.ui @@ -0,0 +1,185 @@ + + + PulseDetails + + + + 0 + 0 + 750 + 166 + + + + Form + + + + + + + + \/ + + + + + + + WireGroupName + + + + + + + Qt::Horizontal + + + QSizePolicy::Preferred + + + + 20 + 20 + + + + + + + + idLabel + + + + + + + Qt::Horizontal + + + + 128 + 20 + + + + + + + + Summary Text/ date + + + + + + + Qt::Horizontal + + + QSizePolicy::Preferred + + + + 20 + 20 + + + + + + + + TextLabel + + + + + + + + + QFrame::StyledPanel + + + QFrame::Raised + + + + + + + + follow + + + + + + + reply + + + + + + + rate + + + + + + + + + + + + 80 + 80 + + + + Image + + + + + + + Qt::Vertical + + + QSizePolicy::Expanding + + + + 20 + 5 + + + + + + + + + + + + + + + + + GxsIdLabel + QLabel +
gui/gxs/GxsIdLabel.h
+
+
+ + +
diff --git a/retroshare-gui/src/gui/TheWire/PulseItem.cpp b/retroshare-gui/src/gui/TheWire/PulseItem.cpp index 16b01d3a4..3b452ffdf 100644 --- a/retroshare-gui/src/gui/TheWire/PulseItem.cpp +++ b/retroshare-gui/src/gui/TheWire/PulseItem.cpp @@ -1,7 +1,7 @@ /******************************************************************************* * gui/TheWire/PulseItem.cpp * * * - * Copyright (c) 2012 Robert Fernie * + * Copyright (c) 2012-2020 Robert Fernie * * * * This program is free software: you can redistribute it and/or modify * * it under the terms of the GNU Affero General Public License as * @@ -25,6 +25,8 @@ #include "PulseItem.h" +#include "PulseDetails.h" + #include #include @@ -34,14 +36,119 @@ /** Constructor */ -PulseItem::PulseItem(PulseHolder *parent, std::string path) -:QWidget(NULL), mParent(parent), mType(0) +PulseItem::PulseItem(PulseHolder *holder, std::string path) +:QWidget(NULL), mHolder(holder), mType(0) { - setupUi(this); - setAttribute ( Qt::WA_DeleteOnClose, true ); + setupUi(this); + setAttribute ( Qt::WA_DeleteOnClose, true ); } +PulseItem::PulseItem(PulseHolder *holder, RsWirePulse &pulse, RsWireGroup &group) +:QWidget(NULL), mHolder(holder), 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) { + + std::cerr << "Installing Reply 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_parent->setLayout(vbox); + + // if its a reply, the real msg goes into reply slot. + pulse_widget = widget_reply; + } + else if (pulse.mPulseType & WIRE_PULSE_TYPE_REPLY_REFERENCE) + { + // 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); + } + + { + std::cerr << "Adding Main Message"; + std::cerr << std::endl; + PulseDetails *details = new PulseDetails(mHolder, pulse, group.mMeta.mGroupName, true); + + // add extra widget into layout. + QVBoxLayout *vbox = new QVBoxLayout(); + vbox->addWidget(details); + vbox->setSpacing(1); + vbox->setContentsMargins(0,0,0,0); + pulse_widget->setLayout(vbox); + pulse_widget->setVisible(true); + // details->toggle(); + } +} + + void PulseItem::removeItem() { } @@ -52,29 +159,29 @@ void PulseItem::setSelected(bool on) bool PulseItem::isSelected() { - return mSelected; + return mSelected; } void PulseItem::mousePressEvent(QMouseEvent *event) { - /* We can be very cunning here? - * grab out position. - * flag ourselves as selected. - * then pass the mousePressEvent up for handling by the parent - */ + /* We can be very cunning here? + * grab out position. + * flag ourselves as selected. + * then pass the mousePressEvent up for handling by the parent + */ - QPoint pos = event->pos(); + QPoint pos = event->pos(); - std::cerr << "PulseItem::mousePressEvent(" << pos.x() << ", " << pos.y() << ")"; - std::cerr << std::endl; + std::cerr << "PulseItem::mousePressEvent(" << pos.x() << ", " << pos.y() << ")"; + std::cerr << std::endl; - setSelected(true); + setSelected(true); - QWidget::mousePressEvent(event); + QWidget::mousePressEvent(event); } const QPixmap *PulseItem::getPixmap() { - return NULL; + return NULL; } diff --git a/retroshare-gui/src/gui/TheWire/PulseItem.h b/retroshare-gui/src/gui/TheWire/PulseItem.h index 6bfeb3506..03ac190fb 100644 --- a/retroshare-gui/src/gui/TheWire/PulseItem.h +++ b/retroshare-gui/src/gui/TheWire/PulseItem.h @@ -1,7 +1,7 @@ /******************************************************************************* * gui/TheWire/PulseItem.h * * * - * Copyright (c) 2012 Robert Fernie * + * Copyright (c) 2012-2020 Robert Fernie * * * * This program is free software: you can redistribute it and/or modify * * it under the terms of the GNU Affero General Public License as * @@ -23,37 +23,48 @@ #include "ui_PulseItem.h" +#include + class PulseItem; class PulseHolder { - public: -virtual void deletePulseItem(PulseItem *, uint32_t ptype) = 0; -virtual void notifySelection(PulseItem *item, int ptype) = 0; +public: + virtual ~PulseHolder() {} + virtual void deletePulseItem(PulseItem *, uint32_t ptype) = 0; + virtual void notifySelection(PulseItem *item, int ptype) = 0; + + // Actions. + virtual void follow(RsGxsGroupId &groupId) = 0; + virtual void rate(RsGxsId &authorId) = 0; + virtual void reply(RsWirePulse &pulse, std::string &groupName) = 0; }; + class PulseItem : public QWidget, private Ui::PulseItem { Q_OBJECT public: - PulseItem(PulseHolder *parent, std::string url); + PulseItem(PulseHolder *holder, std::string url); + PulseItem(PulseHolder *holder, RsWirePulse &pulse, RsWireGroup &group); - void removeItem(); + void removeItem(); - void setSelected(bool on); - bool isSelected(); + void setSelected(bool on); + bool isSelected(); - const QPixmap *getPixmap(); + const QPixmap *getPixmap(); protected: - void mousePressEvent(QMouseEvent *event); + void mousePressEvent(QMouseEvent *event); private: - PulseHolder *mParent; - uint32_t mType; - bool mSelected; + PulseHolder *mHolder; + RsWirePulse mPulse; + uint32_t mType; + bool mSelected; }; #endif diff --git a/retroshare-gui/src/gui/TheWire/PulseItem.ui b/retroshare-gui/src/gui/TheWire/PulseItem.ui index 6a0286af8..c032446a8 100644 --- a/retroshare-gui/src/gui/TheWire/PulseItem.ui +++ b/retroshare-gui/src/gui/TheWire/PulseItem.ui @@ -6,10 +6,16 @@ 0 0 - 615 - 232 + 802 + 322 + + + 0 + 0 + + 9 @@ -18,7 +24,7 @@ - + @@ -27,6 +33,12 @@ 0 + + + 0 + 0 + + QFrame#frame{border: 2px solid #CCCCCC; background: qlineargradient(x1: 0, y1: 0, x2: 0, y2: 1, @@ -39,164 +51,103 @@ border-radius: 10px} QFrame::Raised - - - - - - 75 - 75 - - - - - 75 - 75 - - - - QLabel#label{border: 2px solid black; -background: qlineargradient(x1: 0, y1: 0, x2: 0, y2: 1, - stop: 0 #EEEEEE, stop: 1 #CCCCCC); -border-radius: 10px} - - - - - - :/images/konversation.png - - - Qt::AlignCenter - - - - - - - - - - 0 - 0 - - - - - 9 - 75 - true - - - - From - - - - - - - - 0 - 0 - - - - - 9 - - - - Signed by - - - true - - - - - - - - - - - - 0 - 0 - - - - - 9 - 75 - true - - - - Date - - - - - - - - 0 - 0 - - - - - 9 - - - - You eyes only - - - true - - - - - - - - - - - - Qt::Vertical - - - - 48 - 75 - - - - - + + - - - ... + + + + 20 + 0 + + + + + 0 + 0 + + + + QFrame::StyledPanel - - - ... + + + Qt::Vertical - + + + 10 + 40 + + + - - - ... + + + Qt::Horizontal + + + + 50 + 20 + + + + + + + + + + + + Qt::Horizontal + + + QSizePolicy::Preferred + + + + 50 + 20 + + + + + + + + Qt::Vertical + + + + 10 + 40 + + + + + + + + + 20 + 0 + + + + + 0 + 0 + + + + QFrame::StyledPanel @@ -208,7 +159,7 @@ border-radius: 10px}
- + diff --git a/retroshare-gui/src/gui/TheWire/TheWire_images.qrc b/retroshare-gui/src/gui/TheWire/TheWire_images.qrc new file mode 100644 index 000000000..7919a4500 --- /dev/null +++ b/retroshare-gui/src/gui/TheWire/TheWire_images.qrc @@ -0,0 +1,15 @@ + + + images/kuickshow.png + images/kview_24.png + images/kview_64.png + images/album_64.png + images/album_subscribe.png + images/album_unsubscribe.png + images/album_create_64.png + images/album_default_128.png + images/my_album_48.png + images/subscribed_album_48.png + images/friends_album_48.png + + diff --git a/retroshare-gui/src/gui/TheWire/WireDialog.cpp b/retroshare-gui/src/gui/TheWire/WireDialog.cpp index 90ce66ea1..7dd1e1199 100644 --- a/retroshare-gui/src/gui/TheWire/WireDialog.cpp +++ b/retroshare-gui/src/gui/TheWire/WireDialog.cpp @@ -1,7 +1,7 @@ /******************************************************************************* * gui/TheWire/WireDialog.cpp * * * - * Copyright (c) 2012 Robert Fernie * + * Copyright (c) 2012-2020 Robert Fernie * * * * This program is free software: you can redistribute it and/or modify * * it under the terms of the GNU Affero General Public License as * @@ -20,40 +20,24 @@ #include "WireDialog.h" +#include "WireGroupDialog.h" +#include "WireGroupItem.h" + #include -#include +#include #include #include #include - -/****** - * #define PHOTO_DEBUG 1 - *****/ - +#include /**************************************************************** - * New Photo Display Widget. + * TheWire Display Widget. * - * This has two 'lists'. - * Top list shows Albums. - * Lower list is photos from the selected Album. - * - * Notes: - * Each Item will be an AlbumItem, which contains a thumbnail & random details. - * We will limit Items to < 100. With a 'Filter to see more message. - * - * Thumbnails will come from Service. - * Option to Share albums / pictures onward (if permissions allow). - * Option to Download the albums to a specified directory. (is this required if sharing an album?) - * - * Will introduce a FullScreen SlideShow later... first get basics happening. */ - - /** Constructor */ WireDialog::WireDialog(QWidget *parent) : MainPage(parent) @@ -63,36 +47,103 @@ WireDialog::WireDialog(QWidget *parent) mAddDialog = NULL; mPulseSelected = NULL; - connect( ui.pushButton_Post, SIGNAL(clicked()), this, SLOT(OpenOrShowPulseAddDialog())); - //connect( ui.pushButton_Accounts, SIGNAL(clicked()), this, SLOT(OpenOrShowAccountDialog())); + connect( ui.toolButton_createAccount, SIGNAL(clicked()), this, SLOT(createGroup())); + connect( ui.toolButton_createPulse, SIGNAL(clicked()), this, SLOT(createPulse())); + connect( ui.pushButton_Post, SIGNAL(clicked()), this, SLOT(createPulse())); + connect( ui.toolButton_refresh, SIGNAL(clicked()), this, SLOT(refreshGroups())); QTimer *timer = new QTimer(this); timer->connect(timer, SIGNAL(timeout()), this, SLOT(checkUpdate())); timer->start(1000); + /* setup TokenQueue */ + mWireQueue = new TokenQueue(rsWire->getTokenService(), this); + requestGroupData(); +} + +void WireDialog::refreshGroups() +{ + requestGroupData(); +} + +void WireDialog::addItem(QWidget *item) +{ + QLayout *alayout = ui.scrollAreaWidgetContents->layout(); + alayout->addWidget(item); } +void WireDialog::addGroup(QWidget *item) +{ + QLayout *alayout = ui.scrollAreaWidgetContents_groups->layout(); + alayout->addWidget(item); +} + +// PulseHolder interface. +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; + std::cerr << "WireDialog::notifySelection() from : " << ptype << " " << item; + std::cerr << std::endl; notifyPulseSelection(item); +} -#if 0 - switch(ptype) + + // Actions from PulseHolder. +void WireDialog::follow(RsGxsGroupId &groupId) +{ + std::cerr << "WireDialog::follow("; + std::cerr << groupId.toStdString(); + std::cerr << ")"; + std::cerr << std::endl; +} + +void WireDialog::rate(RsGxsId &authorId) +{ + std::cerr << "WireDialog::rate("; + std::cerr << authorId.toStdString(); + std::cerr << ")"; + std::cerr << std::endl; +} + +void WireDialog::reply(RsWirePulse &pulse, std::string &groupName) +{ + std::cerr << "WireDialog::reply("; + std::cerr << pulse.mMeta.mGroupId.toStdString(); + std::cerr << ","; + std::cerr << pulse.mMeta.mOrigMsgId.toStdString(); + std::cerr << ")"; + std::cerr << std::endl; + + if (!mAddDialog) { - default: - case PHOTO_ITEM_TYPE_ALBUM: - notifyAlbumSelection(item); - break; - case PHOTO_ITEM_TYPE_PHOTO: - notifyPhotoSelection(item); - break; + mAddDialog = new PulseAddDialog(NULL); + mAddDialog->hide(); } -#endif + + int idx = ui.groupChooser->currentIndex(); + if (idx < 0) { + std::cerr << "WireDialog::reply() ERROR GETTING AuthorId!"; + std::cerr << std::endl; + + QMessageBox::warning(this, tr("RetroShare"),tr("Please create or choose Wire Groupd first"), QMessageBox::Ok, QMessageBox::Ok); + return; + } + + // publishing group. + RsWireGroup group = mOwnGroups[idx]; + mAddDialog->setGroup(group); + + // establish replyTo. + mAddDialog->setReplyTo(pulse, groupName); + + mAddDialog->show(); } void WireDialog::notifyPulseSelection(PulseItem *item) @@ -127,331 +178,305 @@ void WireDialog::checkUpdate() return; } - -/*************** New Photo Dialog ***************/ - -void WireDialog::OpenOrShowPulseAddDialog() +void WireDialog::createGroup() { - if (mAddDialog) - { - mAddDialog->show(); - } - else + WireGroupDialog wireCreate(mWireQueue, this); + wireCreate.exec(); +} + +void WireDialog::createPulse() +{ + if (!mAddDialog) { mAddDialog = new PulseAddDialog(NULL); - mAddDialog->show(); - } -} - - -bool WireDialog::matchesAlbumFilter(const RsPhotoAlbum &album) -{ - - return true; -} - -double WireDialog::AlbumScore(const RsPhotoAlbum &album) -{ - return 1; -} - - -bool WireDialog::matchesPhotoFilter(const RsPhotoPhoto &photo) -{ - - return true; -} - -double WireDialog::PhotoScore(const RsPhotoPhoto &photo) -{ - return 1; -} - - -bool WireDialog::FilterNSortAlbums(const std::list &albumIds, std::list &filteredAlbumIds, int count) -{ -#if 0 - std::multimap sortedAlbums; - std::multimap::iterator sit; - std::list::const_iterator it; - - for(it = albumIds.begin(); it != albumIds.end(); ++it) - { - RsPhotoAlbum album; - rsPhoto->getAlbum(*it, album); - - if (matchesAlbumFilter(album)) - { - double score = AlbumScore(album); - - sortedAlbums.insert(std::make_pair(score, *it)); - } + mAddDialog->hide(); } - int i; - for (sit = sortedAlbums.begin(), i = 0; (sit != sortedAlbums.end()) && (i < count); ++sit, ++i) - { - filteredAlbumIds.push_back(sit->second); - } -#endif - return true; -} - - -bool WireDialog::FilterNSortPhotos(const std::list &photoIds, std::list &filteredPhotoIds, int count) -{ -#if 0 - std::multimap sortedPhotos; - std::multimap::iterator sit; - std::list::const_iterator it; - - int i = 0; - for(it = photoIds.begin(); it != photoIds.end(); ++it, ++i) - { - RsPhotoPhoto photo; - rsPhoto->getPhoto(*it, photo); - - if (matchesPhotoFilter(photo)) - { - double score = i; //PhotoScore(album); - sortedPhotos.insert(std::make_pair(score, *it)); - } - } - - for (sit = sortedPhotos.begin(), i = 0; (sit != sortedPhotos.end()) && (i < count); ++sit, ++i) - { - filteredPhotoIds.push_back(sit->second); - } -#endif - return true; -} - - - -void WireDialog::insertAlbums() -{ -#if 0 - /* clear it all */ - clearAlbums(); - //ui.albumLayout->clear(); - - /* create a list of albums */ - - - std::list albumIds; - std::list filteredAlbumIds; - std::list::iterator it; - - rsPhoto->getAlbumList(albumIds); - - /* Filter Albums */ /* Sort Albums */ -#define MAX_ALBUMS 50 - - int count = MAX_ALBUMS; - FilterNSortAlbums(albumIds, filteredAlbumIds, count); - - for(it = filteredAlbumIds.begin(); it != filteredAlbumIds.end(); ++it) - { - addAlbum(*it); - } - - insertPhotosForAlbum(filteredAlbumIds); -#endif -} - -void WireDialog::insertPhotosForSelectedAlbum() -{ -#if 0 - std::cerr << "WireDialog::insertPhotosForSelectedAlbum()"; - std::cerr << std::endl; - - clearPhotos(); - - std::list albumIds; - if (mAlbumSelected) - { - albumIds.push_back(mAlbumSelected->mDetails.mAlbumId); - - std::cerr << "WireDialog::insertPhotosForSelectedAlbum() AlbumId: " << mAlbumSelected->mDetails.mAlbumId; + int idx = ui.groupChooser->currentIndex(); + if (idx < 0) { + std::cerr << "WireDialog::createPulse() ERROR GETTING AuthorId!"; std::cerr << std::endl; + + QMessageBox::warning(this, tr("RetroShare"),tr("Please create or choose Wire Groupd first"), QMessageBox::Ok, QMessageBox::Ok); + return; } - insertPhotosForAlbum(albumIds); -#endif + RsWireGroup group = mOwnGroups[idx]; + + mAddDialog->setGroup(group); + mAddDialog->show(); } - -void WireDialog::addAlbum(const std::string &id) +void WireDialog::addPulse(RsWirePulse &pulse, RsWireGroup &group) { -#if 0 - RsPhotoAlbum album; - rsPhoto->getAlbum(id, album); - - - RsPhotoThumbnail thumbnail; - rsPhoto->getAlbumThumbnail(id, thumbnail); - - std::cerr << " WireDialog::addAlbum() AlbumId: " << album.mAlbumId << std::endl; - - PulseItem *item = new PulseItem(this, album, thumbnail); - QLayout *alayout = ui.scrollAreaWidgetContents->layout(); - alayout->addWidget(item); -#endif -} - -void WireDialog::clearAlbums() -{ -#if 0 - std::cerr << "WireDialog::clearAlbums()" << std::endl; - - std::list photoItems; - std::list::iterator pit; - - QLayout *alayout = ui.scrollAreaWidgetContents->layout(); - int count = alayout->count(); - for(int i = 0; i < count; ++i) - { - QLayoutItem *litem = alayout->itemAt(i); - if (!litem) - { - std::cerr << "WireDialog::clearAlbums() missing litem"; - std::cerr << std::endl; - continue; - } - - PulseItem *item = dynamic_cast(litem->widget()); - if (item) - { - std::cerr << "WireDialog::clearAlbums() item: " << item; - std::cerr << std::endl; - - photoItems.push_back(item); - } - else - { - std::cerr << "WireDialog::clearAlbums() Found Child, which is not a PulseItem???"; - std::cerr << std::endl; - } - } - - for(pit = photoItems.begin(); pit != photoItems.end(); ++pit) - { - PulseItem *item = *pit; - alayout->removeWidget(item); - delete item; - } - mAlbumSelected = NULL; -#endif -} - -void WireDialog::clearPhotos() -{ -#if 0 - std::cerr << "WireDialog::clearPhotos()" << std::endl; - - std::list photoItems; - std::list::iterator pit; - - QLayout *alayout = ui.scrollAreaWidgetContents_2->layout(); - int count = alayout->count(); - for(int i = 0; i < count; ++i) - { - QLayoutItem *litem = alayout->itemAt(i); - if (!litem) - { - std::cerr << "WireDialog::clearPhotos() missing litem"; - std::cerr << std::endl; - continue; - } - - PulseItem *item = dynamic_cast(litem->widget()); - if (item) - { - std::cerr << "WireDialog::clearPhotos() item: " << item; - std::cerr << std::endl; - - photoItems.push_back(item); - } - else - { - std::cerr << "WireDialog::clearPhotos() Found Child, which is not a PulseItem???"; - std::cerr << std::endl; - } - } - - for(pit = photoItems.begin(); pit != photoItems.end(); ++pit) - { - PulseItem *item = *pit; - alayout->removeWidget(item); - delete item; - } - - mPhotoSelected = NULL; -#endif - -} - - -void WireDialog::insertPhotosForAlbum(const std::list &albumIds) -{ -#if 0 - /* clear it all */ - clearPhotos(); - //ui.photoLayout->clear(); - - /* create a list of albums */ - - std::list ids; - std::list photoIds; - std::list filteredPhotoIds; - std::list::const_iterator it; - - for(it = albumIds.begin(); it != albumIds.end(); ++it) - { - rsPhoto->getPhotoList(*it, photoIds); - } - - /* Filter Albums */ /* Sort Albums */ -#define MAX_PHOTOS 50 - - int count = MAX_PHOTOS; - - FilterNSortPhotos(photoIds, filteredPhotoIds, MAX_PHOTOS); - - for(it = filteredPhotoIds.begin(); it != filteredPhotoIds.end(); ++it) - { - addPhoto(*it); - } -#endif -} - - -void WireDialog::addPhoto(const std::string &id) -{ -#if 0 - RsPhotoPhoto photo; - rsPhoto->getPhoto(id,photo); - - RsPhotoThumbnail thumbnail; - rsPhoto->getPhotoThumbnail(id, thumbnail); - - std::cerr << "WireDialog::addPhoto() AlbumId: " << photo.mAlbumId; - std::cerr << " PhotoId: " << photo.mId; + std::cerr << "WireDialog::addPulse() GroupId : " << pulse.mMeta.mGroupId; + std::cerr << " MsgId : " << pulse.mMeta.mGroupId; std::cerr << std::endl; - PulseItem *item = new PulseItem(this, photo, thumbnail); - QLayout *alayout = ui.scrollAreaWidgetContents_2->layout(); - alayout->addWidget(item); -#endif + QWidget *item = new PulseItem(this, pulse, group); + addItem(item); } - -void WireDialog::deletePulseItem(PulseItem *item, uint32_t type) +void WireDialog::addGroup(RsWireGroup &group) { + std::cerr << "WireDialog::addGroup() GroupId : " << group.mMeta.mGroupId; + std::cerr << std::endl; + + addGroup(new WireGroupItem(group)); +} + +void WireDialog::deletePulses() +{ + std::cerr << "WireDialog::deletePulses()"; + std::cerr << std::endl; + + QLayout *alayout = ui.scrollAreaWidgetContents->layout(); + QLayoutItem *item; + int i = 0; + while (i < alayout->count()) + { + item = alayout->itemAt(i); + QWidget *widget = item->widget(); + if (NULL != dynamic_cast(widget)) + { + std::cerr << "WireDialog::deletePulses() Removing Item at: " << i; + std::cerr << std::endl; + + item = alayout->takeAt(i); + delete item->widget(); + delete item; + } + else + { + std::cerr << "WireDialog::deletePulses() Leaving Item at: " << i; + std::cerr << std::endl; + + i++; + } + } +} + +void WireDialog::deleteGroups() +{ + std::cerr << "WireDialog::deleteGroups()"; + std::cerr << std::endl; + + mAllGroups.clear(); + mOwnGroups.clear(); + ui.groupChooser->clear(); - return; + QLayout *alayout = ui.scrollAreaWidgetContents_groups->layout(); + QLayoutItem *item; + int i = 0; + while (i < alayout->count()) + { + item = alayout->itemAt(i); + QWidget *widget = item->widget(); + if (NULL != dynamic_cast(widget)) + { + std::cerr << "WireDialog::deleteGroups() Removing Item at: " << i; + std::cerr << std::endl; + + item = alayout->takeAt(i); + delete item->widget(); + delete item; + } + else + { + std::cerr << "WireDialog::deleteGroups() Leaving Item at: " << i; + std::cerr << std::endl; + + i++; + } + } +} + +void WireDialog::updateGroups(std::vector& groups) +{ + std::vector::const_iterator it; + for(it = groups.begin(); it != groups.end(); it++) { + // save list of all groups. + mAllGroups[it->mMeta.mGroupId] = *it; + + if (it->mMeta.mSubscribeFlags & GXS_SERV::GROUP_SUBSCRIBE_ADMIN) + { + // grab own groups. + // setup Chooser too. + mOwnGroups.push_back(*it); + ui.groupChooser->addItem(QString::fromStdString(it->mMeta.mGroupName)); + } + } } +// LOAD DATA............................................... + + +void WireDialog::requestGroupData() +{ + std::cerr << "WireDialog::requestGroupData()"; + std::cerr << std::endl; + + RsTokReqOptions opts; + uint32_t token; + opts.mReqType = GXS_REQUEST_TYPE_GROUP_DATA; + mWireQueue->requestGroupInfo(token, RS_TOKREQ_ANSTYPE_DATA, opts, 0); +} + +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); + return true; +} + +void WireDialog::requestPulseData(const std::list& grpIds) +{ + std::cerr << "WireDialog::requestPulseData()"; + std::cerr << std::endl; + + RsTokReqOptions opts; + opts.mReqType = GXS_REQUEST_TYPE_MSG_DATA; + opts.mOptions = RS_TOKREQOPT_MSG_LATEST; + uint32_t token; + mWireQueue->requestMsgInfo(token, RS_TOKREQ_ANSTYPE_DATA, opts, grpIds, 0); +} + +bool WireDialog::loadPulseData(const uint32_t &token) +{ + std::cerr << "WireDialog::loadPulseData()"; + std::cerr << std::endl; + + // clearPulses(); + + std::vector pulses; + rsWire->getPulseData(token, pulses); + + 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()) + { + RsWireGroup &group = mit->second; + addPulse(pulse, group); + std::cerr << "WireDialog::loadPulseData() GroupId: " << pulse.mMeta.mGroupId; + std::cerr << " PulseId: " << pulse.mMeta.mMsgId; + std::cerr << std::endl; + } + else + { + std::cerr << "WireDialog::loadPulseData() ERROR Missing GroupId: " << pulse.mMeta.mGroupId; + std::cerr << " PulseId: " << pulse.mMeta.mMsgId; + std::cerr << std::endl; + } + } + + // updatePulses(); + return true; +} + + +/**************************** Request / Response Filling of Data ************************/ + +void WireDialog::loadRequest(const TokenQueue *queue, const TokenRequest &req) +{ + std::cerr << "WireDialog::loadRequest()"; + std::cerr << std::endl; + + if (queue == mWireQueue) + { + /* now switch on req */ + switch(req.mType) + { + case TOKENREQ_GROUPINFO: + switch(req.mAnsType) + { + // case RS_TOKREQ_ANSTYPE_LIST: + // loadGroupList(req.mToken); + // break; + case RS_TOKREQ_ANSTYPE_DATA: + loadGroupData(req.mToken); + break; + // case RS_TOKREQ_ANSTYPE_ACK: + // acknowledgeGroup(req.mToken); + // break; + default: + std::cerr << "WireDialog::loadRequest() ERROR: GROUP: INVALID ANS TYPE"; + std::cerr << std::endl; + break; + } + break; + case TOKENREQ_MSGINFO: + switch(req.mAnsType) + { +#if 0 + case RS_TOKREQ_ANSTYPE_LIST: + loadPhotoList(req.mToken); + break; + case RS_TOKREQ_ANSTYPE_ACK: + acknowledgeMessage(req.mToken); + break; +#endif + case RS_TOKREQ_ANSTYPE_DATA: + loadPulseData(req.mToken); + break; + default: + std::cerr << "WireDialog::loadRequest() ERROR: MSG: INVALID ANS TYPE"; + std::cerr << std::endl; + break; + } + break; +#if 0 + case TOKENREQ_MSGRELATEDINFO: + switch(req.mAnsType) + { + case RS_TOKREQ_ANSTYPE_DATA: + loadPhotoData(req.mToken); + break; + default: + std::cerr << "WireDialog::loadRequest() ERROR: MSG: INVALID ANS TYPE"; + std::cerr << std::endl; + break; + } + break; +#endif + default: + std::cerr << "WireDialog::loadRequest() ERROR: INVALID TYPE"; + std::cerr << std::endl; + break; + } + } +} + + +/**************************** Request / Response Filling of Data ************************/ diff --git a/retroshare-gui/src/gui/TheWire/WireDialog.h b/retroshare-gui/src/gui/TheWire/WireDialog.h index ae948b958..e50823ffd 100644 --- a/retroshare-gui/src/gui/TheWire/WireDialog.h +++ b/retroshare-gui/src/gui/TheWire/WireDialog.h @@ -1,7 +1,7 @@ /******************************************************************************* * gui/TheWire/WireDialog.h * * * - * Copyright (c) 2012 Robert Fernie * + * Copyright (c) 2012-2020 Robert Fernie * * * * This program is free software: you can redistribute it and/or modify * * it under the terms of the GNU Affero General Public License as * @@ -24,67 +24,75 @@ #include "retroshare-gui/mainpage.h" #include "ui_WireDialog.h" -#include +#include #include #include "gui/TheWire/PulseItem.h" #include "gui/TheWire/PulseAddDialog.h" +#include "util/TokenQueue.h" + #define IMAGE_WIRE ":/images/kgames.png" -class WireDialog : public MainPage, public PulseHolder +class WireDialog : public MainPage, public TokenResponse, public PulseHolder { Q_OBJECT public: WireDialog(QWidget *parent = 0); - virtual QIcon iconPixmap() const { return QIcon(IMAGE_WIRE) ; } - virtual QString pageName() const { return tr("The Wire") ; } - virtual QString helpText() const { return ""; } + virtual QIcon iconPixmap() const { return QIcon(IMAGE_WIRE) ; } + virtual QString pageName() const { return tr("The Wire") ; } + virtual QString helpText() const { return ""; } -virtual void deletePulseItem(PulseItem *, uint32_t type); -virtual void notifySelection(PulseItem *item, int ptype); + // PulseHolder interface. + virtual void deletePulseItem(PulseItem *, uint32_t type); + virtual void notifySelection(PulseItem *item, int ptype); + + virtual void follow(RsGxsGroupId &groupId); + virtual void rate(RsGxsId &authorId); + virtual void reply(RsWirePulse &pulse, std::string &groupName); void notifyPulseSelection(PulseItem *item); private slots: + void createGroup(); + void createPulse(); void checkUpdate(); - void OpenOrShowPulseAddDialog(); + void refreshGroups(); private: + void addItem(QWidget *item); + void addGroup(QWidget *item); + void addPulse(RsWirePulse &pulse, RsWireGroup &group); + void addGroup(RsWireGroup &group); - /* TODO: These functions must be filled in for proper filtering to work - * and tied to the GUI input - */ + void deletePulses(); + void deleteGroups(); + void updateGroups(std::vector &groups); - bool matchesAlbumFilter(const RsPhotoAlbum &album); - double AlbumScore(const RsPhotoAlbum &album); - bool matchesPhotoFilter(const RsPhotoPhoto &photo); - double PhotoScore(const RsPhotoPhoto &photo); + // Loading Data. + void requestGroupData(); + bool loadGroupData(const uint32_t &token); - /* Grunt work of setting up the GUI */ + void requestPulseData(const std::list& grpIds); + bool loadPulseData(const uint32_t &token); - bool FilterNSortAlbums(const std::list &albumIds, std::list &filteredAlbumIds, int count); - bool FilterNSortPhotos(const std::list &photoIds, std::list &filteredPhotoIds, int count); - void insertAlbums(); - void insertPhotosForAlbum(const std::list &albumIds); - void insertPhotosForSelectedAlbum(); - - void addAlbum(const std::string &id); - void addPhoto(const std::string &id); - - void clearAlbums(); - void clearPhotos(); + virtual void loadRequest(const TokenQueue *queue, const TokenRequest &req); PulseAddDialog *mAddDialog; PulseItem *mPulseSelected; + TokenQueue *mWireQueue; + + std::map mAllGroups; + std::vector mOwnGroups; + /* UI - from Designer */ Ui::WireDialog ui; diff --git a/retroshare-gui/src/gui/TheWire/WireDialog.ui b/retroshare-gui/src/gui/TheWire/WireDialog.ui index 3f6074b37..ee69ee56b 100644 --- a/retroshare-gui/src/gui/TheWire/WireDialog.ui +++ b/retroshare-gui/src/gui/TheWire/WireDialog.ui @@ -10,16 +10,168 @@ 557 + + + 0 + 0 + + - + + + + + 0 + 0 + + + + QFrame::StyledPanel + + + QFrame::Raised + + + + + + Create Account + + + + + + + Post Pulse + + + + + + + ... + + + + + + + ... + + + + + + + ... + + + + + + + Qt::Horizontal + + + + 296 + 20 + + + + + + + + Refresh + + + + + + + + + + Settings + + + + + + + + + + true + + + Qt::AlignBottom|Qt::AlignLeading|Qt::AlignLeft + + + + + 0 + 0 + 567 + 412 + + + + QWidget#scrollAreaWidgetContents{border: none;} + + + + 0 + + + 0 + + + 0 + + + 0 + + + 0 + + + + + Qt::Vertical + + + + 20 + 40 + + + + + + + + + - - + + + + + - TimeRange + Search/Filter + + + + + + + Network Wide @@ -66,40 +218,23 @@ - - - - - + + - Search/Filter + TimeRange - - - - Network Wide - - - - - - - Manage Accounts - - - - + - 160 + 200 16777215 @@ -113,7 +248,16 @@ 0 - + + 0 + + + 0 + + + 0 + + 0 @@ -121,126 +265,16 @@ true - + 0 0 - 156 - 469 + 129 + 416 - - - - Showing: - - - - 0 - - - - - Yourself - - - - - - - Friends - - - - - - - Following - - - - - - - All - - - - - - - Qt::Horizontal - - - - - - - Custom - - - - - - - - - - Account 1 - - - - - - - Account 2 - - - - - - - Account 3 - - - - - - - CheckBox - - - - - - - CheckBox - - - - - - - CheckBox - - - - - - - CheckBox - - - - - - - CheckBox - - - @@ -261,51 +295,36 @@ - - - - true - - - Qt::AlignBottom|Qt::AlignLeading|Qt::AlignLeft - - - - - 0 - 0 - 540 - 465 - + + + + + Yourself - - QWidget#scrollAreaWidgetContents{border: none;} + + + + Subscribed - - - 0 - - - 0 - - - - - Qt::Vertical - - - - 20 - 40 - - - - - - + + + + Auto + + + + + Recommended + + + + + Others + + - + Post Pulse to Wire @@ -315,7 +334,7 @@ - + diff --git a/retroshare-gui/src/gui/TheWire/WireGroupDialog.cpp b/retroshare-gui/src/gui/TheWire/WireGroupDialog.cpp new file mode 100644 index 000000000..119d29a9f --- /dev/null +++ b/retroshare-gui/src/gui/TheWire/WireGroupDialog.cpp @@ -0,0 +1,180 @@ +/******************************************************************************* + * gui/TheWire/WireGroupDialog.cpp * + * * + * Copyright (C) 2020 by Robert Fernie * + * * + * This program is free software: you can redistribute it and/or modify * + * it under the terms of the GNU Affero 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 Affero General Public License for more details. * + * * + * You should have received a copy of the GNU Affero General Public License * + * along with this program. If not, see . * + * * + *******************************************************************************/ +#include + +#include "WireGroupDialog.h" +#include "gui/gxs/GxsIdDetails.h" + +#include + +const uint32_t WireCreateEnabledFlags = ( + GXS_GROUP_FLAGS_NAME | + GXS_GROUP_FLAGS_ICON | + GXS_GROUP_FLAGS_DESCRIPTION | + GXS_GROUP_FLAGS_DISTRIBUTION | + // GXS_GROUP_FLAGS_PUBLISHSIGN | + // GXS_GROUP_FLAGS_SHAREKEYS | // disabled because the UI doesn't handle it yet. + // GXS_GROUP_FLAGS_PERSONALSIGN | + // GXS_GROUP_FLAGS_COMMENTS | + GXS_GROUP_FLAGS_EXTRA | + 0); + +uint32_t WireCreateDefaultsFlags = ( GXS_GROUP_DEFAULTS_DISTRIB_PUBLIC | + // GXS_GROUP_DEFAULTS_DISTRIB_GROUP | + // GXS_GROUP_DEFAULTS_DISTRIB_LOCAL | + + GXS_GROUP_DEFAULTS_PUBLISH_OPEN | + // GXS_GROUP_DEFAULTS_PUBLISH_THREADS | + // GXS_GROUP_DEFAULTS_PUBLISH_REQUIRED | + // GXS_GROUP_DEFAULTS_PUBLISH_ENCRYPTED | + + // GXS_GROUP_DEFAULTS_PERSONAL_GPG | + GXS_GROUP_DEFAULTS_PERSONAL_REQUIRED | + // GXS_GROUP_DEFAULTS_PERSONAL_IFNOPUB | + + // GXS_GROUP_DEFAULTS_COMMENTS_YES | + GXS_GROUP_DEFAULTS_COMMENTS_NO | + 0); + +uint32_t WireEditEnabledFlags = WireCreateEnabledFlags; +uint32_t WireEditDefaultsFlags = WireCreateDefaultsFlags; + +WireGroupDialog::WireGroupDialog(TokenQueue *tokenQueue, QWidget *parent) + : GxsGroupDialog(tokenQueue, WireCreateEnabledFlags, WireCreateDefaultsFlags, parent) +{ +} + +WireGroupDialog::WireGroupDialog(TokenQueue *tokenExternalQueue, RsTokenService *tokenService, Mode mode, RsGxsGroupId groupId, QWidget *parent) + : GxsGroupDialog(tokenExternalQueue, tokenService, mode, groupId, WireEditEnabledFlags, WireEditDefaultsFlags, parent) +{ +} + +void WireGroupDialog::initUi() +{ + switch (mode()) + { + case MODE_CREATE: + setUiText(UITYPE_SERVICE_HEADER, tr("Create New Wire")); + setUiText(UITYPE_BUTTONBOX_OK, tr("Create")); + break; + case MODE_SHOW: + setUiText(UITYPE_SERVICE_HEADER, tr("Wire")); + break; + case MODE_EDIT: + setUiText(UITYPE_SERVICE_HEADER, tr("Edit Wire")); + setUiText(UITYPE_BUTTONBOX_OK, tr("Update Wire")); + break; + } + + setUiText(UITYPE_ADD_ADMINS_CHECKBOX, tr("Add Wire Admins")); + setUiText(UITYPE_CONTACTS_DOCK, tr("Select Wire Admins")); +} + +QPixmap WireGroupDialog::serviceImage() +{ + return QPixmap(":/images/wire_create_64.png"); +} + +void WireGroupDialog::prepareWireGroup(RsWireGroup &group, const RsGroupMetaData &meta) +{ + group.mMeta = meta; + group.mDescription = getDescription().toUtf8().constData(); + +#if 0 + QPixmap pixmap = getLogo(); + + if (!pixmap.isNull()) { + QByteArray ba; + QBuffer buffer(&ba); + + buffer.open(QIODevice::WriteOnly); + pixmap.save(&buffer, "PNG"); // writes image into ba in PNG format + + group.mThumbnail.copy((uint8_t *) ba.data(), ba.size()); + } else { + group.mThumbnail.clear(); + } +#endif + +} + +bool WireGroupDialog::service_CreateGroup(uint32_t &token, const RsGroupMetaData &meta) +{ + // Specific Function. + RsWireGroup grp; + prepareWireGroup(grp, meta); + + rsWire->createGroup(token, grp); + return true; +} + +bool WireGroupDialog::service_EditGroup(uint32_t &token, RsGroupMetaData &editedMeta) +{ + RsWireGroup grp; + prepareWireGroup(grp, editedMeta); + + std::cerr << "WireGroupDialog::service_EditGroup() submitting changes"; + std::cerr << std::endl; + + // TODO: no interface here, yet. + // rsWire->updateGroup(token, grp); + return true; +} + +bool WireGroupDialog::service_loadGroup(uint32_t token, Mode /*mode*/, RsGroupMetaData& groupMetaData, QString &description) +{ + std::cerr << "WireGroupDialog::service_loadGroup(" << token << ")"; + std::cerr << std::endl; + + std::vector groups; + if (!rsWire->getGroupData(token, groups)) + { + std::cerr << "WireGroupDialog::service_loadGroup() Error getting GroupData"; + std::cerr << std::endl; + return false; + } + + if (groups.size() != 1) + { + std::cerr << "WireGroupDialog::service_loadGroup() Error Group.size() != 1"; + std::cerr << std::endl; + return false; + } + + std::cerr << "WireGroupDialog::service_loadGroup() Unfinished Loading"; + std::cerr << std::endl; + + const RsWireGroup &group = groups[0]; + groupMetaData = group.mMeta; + description = QString::fromUtf8(group.mDescription.c_str()); + +#if 0 + if (group.mThumbnail.mData) { + QPixmap pixmap; + if (GxsIdDetails::loadPixmapFromData(group.mThumbnail.mData, group.mThumbnail.mSize, pixmap,GxsIdDetails::ORIGINAL)) { + setLogo(pixmap); + } + } else { + setLogo(QPixmap(":/images/album_create_64.png")); + } +#endif + + return true; +} diff --git a/retroshare-gui/src/gui/TheWire/WireGroupDialog.h b/retroshare-gui/src/gui/TheWire/WireGroupDialog.h new file mode 100644 index 000000000..9a4b614c9 --- /dev/null +++ b/retroshare-gui/src/gui/TheWire/WireGroupDialog.h @@ -0,0 +1,46 @@ +/******************************************************************************* + * gui/TheWire/WireGroupDialog.h * + * * + * Copyright (C) 2020 by Robert Fernie * + * * + * This program is free software: you can redistribute it and/or modify * + * it under the terms of the GNU Affero 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 Affero General Public License for more details. * + * * + * You should have received a copy of the GNU Affero General Public License * + * along with this program. If not, see . * + * * + *******************************************************************************/ + +#ifndef _WIRE_GROUP_DIALOG_H +#define _WIRE_GROUP_DIALOG_H + +#include "gui/gxs/GxsGroupDialog.h" +#include + +class WireGroupDialog : public GxsGroupDialog +{ + Q_OBJECT + +public: + WireGroupDialog(TokenQueue *tokenQueue, QWidget *parent); + WireGroupDialog(TokenQueue *tokenExternalQueue, RsTokenService *tokenService, Mode mode, RsGxsGroupId groupId, QWidget *parent); + +protected: + virtual void initUi(); + virtual QPixmap serviceImage(); + virtual bool service_CreateGroup(uint32_t &token, const RsGroupMetaData &meta); + virtual bool service_loadGroup(uint32_t token, Mode mode, RsGroupMetaData& groupMetaData, QString &description); + virtual bool service_EditGroup(uint32_t &token, RsGroupMetaData &editedMeta); + +private: + void prepareWireGroup(RsWireGroup &group, const RsGroupMetaData &meta); +}; + +#endif diff --git a/retroshare-gui/src/gui/TheWire/WireGroupItem.cpp b/retroshare-gui/src/gui/TheWire/WireGroupItem.cpp new file mode 100644 index 000000000..5c5606943 --- /dev/null +++ b/retroshare-gui/src/gui/TheWire/WireGroupItem.cpp @@ -0,0 +1,92 @@ +/******************************************************************************* + * gui/TheWire/WireGroupItem.cpp * + * * + * Copyright (c) 2020 Robert Fernie * + * * + * This program is free software: you can redistribute it and/or modify * + * it under the terms of the GNU Affero 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 Affero General Public License for more details. * + * * + * You should have received a copy of the GNU Affero General Public License * + * along with this program. If not, see . * + * * + *******************************************************************************/ + +#include +#include +#include +#include + +#include "WireGroupItem.h" + +#include +#include + +/** Constructor */ + +WireGroupItem::WireGroupItem(RsWireGroup grp) +:QWidget(NULL), mGroup(grp), mType(0) +{ + setupUi(this); + setAttribute ( Qt::WA_DeleteOnClose, true ); + setup(); + +} + +void WireGroupItem::setup() +{ + label_groupName->setText(QString::fromStdString(mGroup.mMeta.mGroupName)); + // label_authorId->setText(mGroup.mMeta.mAuthorId); + frame_details->setVisible(false); + + connect(toolButton_show, SIGNAL(clicked()), this, SLOT(show())); +} + +void WireGroupItem::show() +{ + frame_details->setVisible(!frame_details->isVisible()); +} + + +void WireGroupItem::removeItem() +{ +} + +void WireGroupItem::setSelected(bool on) +{ +} + +bool WireGroupItem::isSelected() +{ + return mSelected; +} + +void WireGroupItem::mousePressEvent(QMouseEvent *event) +{ + /* We can be very cunning here? + * grab out position. + * flag ourselves as selected. + * then pass the mousePressEvent up for handling by the parent + */ + + QPoint pos = event->pos(); + + std::cerr << "WireGroupItem::mousePressEvent(" << pos.x() << ", " << pos.y() << ")"; + std::cerr << std::endl; + + setSelected(true); + + QWidget::mousePressEvent(event); +} + +const QPixmap *WireGroupItem::getPixmap() +{ + return NULL; +} + diff --git a/retroshare-gui/src/gui/TheWire/WireGroupItem.h b/retroshare-gui/src/gui/TheWire/WireGroupItem.h new file mode 100644 index 000000000..9f6eac14f --- /dev/null +++ b/retroshare-gui/src/gui/TheWire/WireGroupItem.h @@ -0,0 +1,58 @@ +/******************************************************************************* + * gui/TheWire/WireGroupItem.h * + * * + * Copyright (c) 2020 Robert Fernie * + * * + * This program is free software: you can redistribute it and/or modify * + * it under the terms of the GNU Affero 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 Affero General Public License for more details. * + * * + * You should have received a copy of the GNU Affero General Public License * + * along with this program. If not, see . * + * * + *******************************************************************************/ + +#ifndef MRK_WIRE_GROUP_ITEM_H +#define MRK_WIRE_GROUP_ITEM_H + +#include "ui_WireGroupItem.h" + +#include + +class WireGroupItem; + +class WireGroupItem : public QWidget, private Ui::WireGroupItem +{ + Q_OBJECT + +public: + WireGroupItem(RsWireGroup grp); + + void removeItem(); + + void setSelected(bool on); + bool isSelected(); + + const QPixmap *getPixmap(); + +private slots: + void show(); + +protected: + void mousePressEvent(QMouseEvent *event); + +private: + void setup(); + + RsWireGroup mGroup; + uint32_t mType; + bool mSelected; +}; + +#endif diff --git a/retroshare-gui/src/gui/TheWire/WireGroupItem.ui b/retroshare-gui/src/gui/TheWire/WireGroupItem.ui new file mode 100644 index 000000000..f5939e03b --- /dev/null +++ b/retroshare-gui/src/gui/TheWire/WireGroupItem.ui @@ -0,0 +1,110 @@ + + + WireGroupItem + + + + 0 + 0 + 276 + 114 + + + + Form + + + + + + QFrame::StyledPanel + + + QFrame::Raised + + + + + + + + WireGroupName + + + + + + + Qt::Horizontal + + + + 118 + 20 + + + + + + + + Type + + + + + + + \/ + + + + + + + + + QFrame::StyledPanel + + + QFrame::Raised + + + + + + GxsIdLabel + + + + + + + Qt::Horizontal + + + + 61 + 20 + + + + + + + + Sub/Un + + + + + + + + + + + + + + diff --git a/retroshare-gui/src/retroshare-gui.pro b/retroshare-gui/src/retroshare-gui.pro index f0a901e39..01bb92012 100644 --- a/retroshare-gui/src/retroshare-gui.pro +++ b/retroshare-gui/src/retroshare-gui.pro @@ -1225,15 +1225,23 @@ gxsthewire { DEFINES += RS_USE_WIRE HEADERS += gui/TheWire/PulseItem.h \ + gui/TheWire/PulseDetails.h \ gui/TheWire/WireDialog.h \ + gui/TheWire/WireGroupItem.h \ + gui/TheWire/WireGroupDialog.h \ gui/TheWire/PulseAddDialog.h \ FORMS += gui/TheWire/PulseItem.ui \ + gui/TheWire/PulseDetails.ui \ + gui/TheWire/WireGroupItem.ui \ gui/TheWire/WireDialog.ui \ gui/TheWire/PulseAddDialog.ui \ SOURCES += gui/TheWire/PulseItem.cpp \ + gui/TheWire/PulseDetails.cpp \ gui/TheWire/WireDialog.cpp \ + gui/TheWire/WireGroupItem.cpp \ + gui/TheWire/WireGroupDialog.cpp \ gui/TheWire/PulseAddDialog.cpp \ }