diff --git a/build_scripts/Windows/build-libs/Makefile b/build_scripts/Windows/build-libs/Makefile index 75aedb421..11b60f77d 100755 --- a/build_scripts/Windows/build-libs/Makefile +++ b/build_scripts/Windows/build-libs/Makefile @@ -266,7 +266,7 @@ libs/curl-$(CURL_VERSION): $(DOWNLOAD_PATH)/curl-$(CURL_VERSION).tar.gz sqlcipher: libs/sqlcipher-$(SQLCIPHER_VERSION) $(DOWNLOAD_PATH)/tcl$(TCL_VERSION)-src.tar.gz: - wget http://prdownloads.sourceforge.net/tcl/tcl$(TCL_VERSION)-src.tar.gz -O $(DOWNLOAD_PATH)/tcl$(TCL_VERSION)-src.tar.gz + wget --no-check-certificate http://downloads.sourceforge.net/project/tcl/Tcl/$(TCL_VERSION)/tcl$(TCL_VERSION)-src.tar.gz -O $(DOWNLOAD_PATH)/tcl$(TCL_VERSION)-src.tar.gz $(DOWNLOAD_PATH)/sqlcipher-$(SQLCIPHER_VERSION).tar.gz: wget --no-check-certificate https://github.com/sqlcipher/sqlcipher/archive/v$(SQLCIPHER_VERSION).tar.gz -O $(DOWNLOAD_PATH)/sqlcipher-$(SQLCIPHER_VERSION).tar.gz diff --git a/libretroshare/src/grouter/p3grouter.cc b/libretroshare/src/grouter/p3grouter.cc index 072360a42..729e778ce 100644 --- a/libretroshare/src/grouter/p3grouter.cc +++ b/libretroshare/src/grouter/p3grouter.cc @@ -1624,11 +1624,18 @@ Sha1CheckSum p3GRouter::computeDataItemHash(RsGRouterGenericDataItem *data_item) RsTemporaryMemory mem(total_size) ; uint32_t offset = 0 ; - signature_serializer.serialise(data_item,mem,&total_size) ; - offset += signed_data_size ; + uint32_t tmp_size = total_size ; + signature_serializer.serialise(data_item,mem,&tmp_size) ; + if(tmp_size != signed_data_size) + std::cerr << "(EE) Some error occured in p3GRouter::computeDataItemHash(). Mismatched offset/data size" << std::endl; + + offset += tmp_size ; data_item->signature.SetTlv(mem, total_size,&offset) ; + if(offset != total_size) + std::cerr << "(EE) Some error occured in p3GRouter::computeDataItemHash(). Mismatched offset/data size" << std::endl; + return RsDirUtil::sha1sum(mem,total_size) ; } diff --git a/libretroshare/src/gxs/rsgxsdataaccess.cc b/libretroshare/src/gxs/rsgxsdataaccess.cc index 56899d4ce..8529b89f4 100644 --- a/libretroshare/src/gxs/rsgxsdataaccess.cc +++ b/libretroshare/src/gxs/rsgxsdataaccess.cc @@ -1576,11 +1576,20 @@ bool RsGxsDataAccess::getGroupStatistic(GroupStatisticRequest *req) req->mGroupStatistic.mNumChildMsgsNew = 0; req->mGroupStatistic.mNumChildMsgsUnread = 0; + std::set obsolete_msgs ; // stored message ids that are referred to as older versions of an existing message + + for(uint32_t i = 0; i < msgMetaV.size(); ++i) + if(!msgMetaV[i]->mOrigMsgId.isNull() && msgMetaV[i]->mOrigMsgId!=msgMetaV[i]->mMsgId) + obsolete_msgs.insert(msgMetaV[i]->mOrigMsgId); + for(uint32_t i = 0; i < msgMetaV.size(); ++i) { RsGxsMsgMetaData* m = msgMetaV[i]; req->mGroupStatistic.mTotalSizeOfMsgs += m->mMsgSize + m->serial_size(); + if(obsolete_msgs.find(m->mMsgId) != obsolete_msgs.end()) // skip obsolete messages. + continue; + if (IS_MSG_NEW(m->mMsgStatus)) { if (m->mParentId.isNull()) diff --git a/libretroshare/src/retroshare/rsgxschannels.h b/libretroshare/src/retroshare/rsgxschannels.h index b5d46bc3b..c55d46a72 100644 --- a/libretroshare/src/retroshare/rsgxschannels.h +++ b/libretroshare/src/retroshare/rsgxschannels.h @@ -60,6 +60,8 @@ public: public: RsMsgMetaData mMeta; + + std::set mOlderVersions ; std::string mMsg; // UTF8 encoded. std::list mFiles; diff --git a/retroshare-gui/src/gui/GenCertDialog.cpp b/retroshare-gui/src/gui/GenCertDialog.cpp index 11bd8f7dd..1887ca304 100644 --- a/retroshare-gui/src/gui/GenCertDialog.cpp +++ b/retroshare-gui/src/gui/GenCertDialog.cpp @@ -161,12 +161,12 @@ GenCertDialog::GenCertDialog(bool onlyGenerateIdentity, QWidget *parent) ui.keylength_comboBox->addItem("Very high (4096 bits)", QVariant(4096)); #if QT_VERSION >= 0x040700 - ui.node_input->setPlaceholderText(tr("[Required] Examples: Home, Laptop,...(Visible to friends).")) ; - ui.hiddenaddr_input->setPlaceholderText(tr("[Optional] Tor/I2P address (Example: xa76giaf6ifda7ri63i263.onion)")) ; - ui.name_input->setPlaceholderText(tr("[Required] Visible to friends, and friends of friends.")); - ui.nickname_input->setPlaceholderText(tr("[Optional] Used to write in chat rooms and forums. Can be set later.")); - ui.password_input->setPlaceholderText(tr("[Required] This password protects your data. Dont forget it!")); - ui.password_input_2->setPlaceholderText(tr("[Required] Type the same password again here.")); + ui.node_input->setPlaceholderText(tr("Node name")) ; + ui.hiddenaddr_input->setPlaceholderText(tr("Tor/I2P address")) ; + ui.name_input->setPlaceholderText(tr("Username")); + ui.nickname_input->setPlaceholderText(tr("Identity name")); + ui.password_input->setPlaceholderText(tr("Password")); + ui.password_input_2->setPlaceholderText(tr("Password again")); #endif ui.nickname_input->setMaxLength(RSID_MAXIMUM_NICKNAME_SIZE); @@ -294,7 +294,7 @@ void GenCertDialog::setupState() ui.entropy_bar->setVisible(true); ui.genButton->setVisible(true); - ui.genButton->setText(generate_new?tr("Generate new profile and node"):tr("Generate new node")); + ui.genButton->setText(generate_new?tr("Generate"):tr("Generate")); ui.hiddenaddr_input->setVisible(hidden_state); ui.hiddenaddr_label->setVisible(hidden_state); diff --git a/retroshare-gui/src/gui/GenCertDialog.ui b/retroshare-gui/src/gui/GenCertDialog.ui index 468c17693..9eb77800e 100644 --- a/retroshare-gui/src/gui/GenCertDialog.ui +++ b/retroshare-gui/src/gui/GenCertDialog.ui @@ -6,8 +6,8 @@ 0 0 - 533 - 544 + 520 + 611 @@ -34,13 +34,16 @@ 0 - + 0 0 + + + QFrame::StyledPanel @@ -48,6 +51,9 @@ QFrame::Raised + + 9 + @@ -105,19 +111,63 @@ - + - - QFrame::StyledPanel - - - QFrame::Raised - + + 24 + + + 24 + + + 24 + + + 24 + + + + + + 0 + 0 + + + + PGP Key Length + + + + + + + + + + + 24 + 24 + + + + + + + :/icons/svg/randomness.svg + + + true + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + @@ -125,17 +175,7 @@ - - - - PGP key length - - - Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter - - - - + @@ -163,42 +203,6 @@ - - - - This password is for PGP - - - Password - - - Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter - - - - - - - - 0 - 0 - - - - - - - - This password is for PGP - - - Password (check) - - - Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter - - - @@ -229,7 +233,7 @@ - + @@ -271,16 +275,6 @@ - - - - Node name - - - Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter - - - @@ -365,7 +359,7 @@ - + @@ -394,46 +388,6 @@ - - - - Profile name - - - Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter - - - - - - - Randomness - - - Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter - - - - - - - Node type - - - Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter - - - - - - - hidden address - - - Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter - - - @@ -498,20 +452,7 @@ - - - - - - - Chat identity - - - Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter - - - - + @@ -564,6 +505,191 @@ + + + + + 24 + 24 + + + + + + + :/icons/svg/person.svg + + + true + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + + + + + + 24 + 24 + + + + + + + + + + :/icons/svg/chat-lobbies.svg + + + true + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + + + + + + 24 + 24 + + + + + + + :/icons/svg/network.svg + + + true + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + + + + + + 24 + 24 + + + + + + + :/icons/svg/keyring.svg + + + true + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + + + + + + 24 + 24 + + + + This password is for PGP + + + + + + :/icons/svg/password.svg + + + true + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + + + + + + 24 + 24 + + + + This password is for PGP + + + + + + :/icons/svg/password.svg + + + true + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + + + + + + 24 + 24 + + + + + + + :/icons/svg/hidden.svg + + + true + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + + + + + + 24 + 24 + + + + + + + :/icons/svg/netgraph.svg + + + true + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + diff --git a/retroshare-gui/src/gui/NewsFeed.cpp b/retroshare-gui/src/gui/NewsFeed.cpp index fc42faf7f..4b08caec9 100644 --- a/retroshare-gui/src/gui/NewsFeed.cpp +++ b/retroshare-gui/src/gui/NewsFeed.cpp @@ -1403,7 +1403,7 @@ void NewsFeed::openChat(const RsPeerId &peerId) ChatDialog::chatFriend(ChatId(peerId)); } -void NewsFeed::openComments(uint32_t /*type*/, const RsGxsGroupId &/*groupId*/, const RsGxsMessageId &/*msgId*/, const QString &/*title*/) +void NewsFeed::openComments(uint32_t /*type*/, const RsGxsGroupId &/*groupId*/, const QVector& versions,const RsGxsMessageId &/*msgId*/, const QString &/*title*/) { std::cerr << "NewsFeed::openComments() Not Handled Yet"; std::cerr << std::endl; diff --git a/retroshare-gui/src/gui/NewsFeed.h b/retroshare-gui/src/gui/NewsFeed.h index 28b8dabaa..b97476435 100644 --- a/retroshare-gui/src/gui/NewsFeed.h +++ b/retroshare-gui/src/gui/NewsFeed.h @@ -58,7 +58,7 @@ public: virtual QScrollArea *getScrollArea(); virtual void deleteFeedItem(QWidget *item, uint32_t type); virtual void openChat(const RsPeerId& peerId); - virtual void openComments(uint32_t type, const RsGxsGroupId &groupId, const RsGxsMessageId &msgId, const QString &title); + virtual void openComments(uint32_t type, const RsGxsGroupId &groupId, const QVector &versions, const RsGxsMessageId &msgId, const QString &title); static void testFeeds(uint notifyFlags); static void testFeed(FeedNotify *feedNotify); diff --git a/retroshare-gui/src/gui/Posted/PostedItem.cpp b/retroshare-gui/src/gui/Posted/PostedItem.cpp index 8541e2c3e..d26b1e5c8 100644 --- a/retroshare-gui/src/gui/Posted/PostedItem.cpp +++ b/retroshare-gui/src/gui/Posted/PostedItem.cpp @@ -411,7 +411,13 @@ void PostedItem::loadComments() if (mFeedHolder) { QString title = QString::fromUtf8(mPost.mMeta.mMsgName.c_str()); - mFeedHolder->openComments(0, mPost.mMeta.mGroupId, mPost.mMeta.mMsgId, title); + +#warning (csoler) Posted item versions not handled yet. When it is the case, start here. + + QVector post_versions ; + post_versions.push_back(mPost.mMeta.mMsgId) ; + + mFeedHolder->openComments(0, mPost.mMeta.mGroupId, post_versions,mPost.mMeta.mMsgId, title); } } diff --git a/retroshare-gui/src/gui/Posted/PostedListWidget.cpp b/retroshare-gui/src/gui/Posted/PostedListWidget.cpp index a333d3fbd..d321933eb 100644 --- a/retroshare-gui/src/gui/Posted/PostedListWidget.cpp +++ b/retroshare-gui/src/gui/Posted/PostedListWidget.cpp @@ -139,9 +139,9 @@ void PostedListWidget::openChat(const RsPeerId & /*peerId*/) return; } -void PostedListWidget::openComments(uint32_t /*feed_type*/, const RsGxsGroupId &groupId, const RsGxsMessageId &msgId, const QString &title) +void PostedListWidget::openComments(uint32_t /*feed_type*/, const RsGxsGroupId &groupId, const QVector &versions, const RsGxsMessageId &msgId, const QString &title) { - emit loadComment(groupId, msgId, title); + emit loadComment(groupId, versions,msgId, title); } void PostedListWidget::newPost() diff --git a/retroshare-gui/src/gui/Posted/PostedListWidget.h b/retroshare-gui/src/gui/Posted/PostedListWidget.h index be6c5411f..89f95e995 100644 --- a/retroshare-gui/src/gui/Posted/PostedListWidget.h +++ b/retroshare-gui/src/gui/Posted/PostedListWidget.h @@ -52,7 +52,7 @@ public: virtual QScrollArea *getScrollArea(); virtual void deleteFeedItem(QWidget *item, uint32_t type); virtual void openChat(const RsPeerId& peerId); - virtual void openComments(uint32_t type, const RsGxsGroupId &groupId, const RsGxsMessageId &msgId, const QString &title); + virtual void openComments(uint32_t type, const RsGxsGroupId &groupId, const QVector &versions, const RsGxsMessageId &msgId, const QString &title); /* GXS functions */ virtual void loadRequest(const TokenQueue *queue, const TokenRequest &req); diff --git a/retroshare-gui/src/gui/StartDialog.ui b/retroshare-gui/src/gui/StartDialog.ui index 4665dfdc0..92b0c8075 100644 --- a/retroshare-gui/src/gui/StartDialog.ui +++ b/retroshare-gui/src/gui/StartDialog.ui @@ -17,6 +17,9 @@ :/images/logo/logo_32.png:/images/logo/logo_32.png + + false + 0 @@ -31,296 +34,310 @@ 0 - - - 0 + + + false - - 0 + + - - 0 + + QFrame::StyledPanel - - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - - 0 - 0 - - - - - - - - - 85 - 170 - 255 - - - - - - - - - 85 - 170 - 255 - - - - - - - - - 118 - 116 - 108 - - - - - - - - - 18 - - - - - - - :/images/logo/logo_spash2.png - - - - - - - Qt::Horizontal - - - - 48 - 20 - - - - - - - - - - Qt::Horizontal - - - QSizePolicy::Minimum - - - - 60 - 20 - - - - - - - - Qt::Vertical - - - - 20 - 40 - - - - - - - - Qt::Horizontal - - - QSizePolicy::Minimum - - - - 60 - 20 - - - - - - - - true - - - - 0 - 0 - - - - - - - - - - - 9 - + + + 0 + + + 0 + + + 0 + + + 0 + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + - - - Profile - Location: - - - - - - + + - 22 - 22 + 0 + 0 - - + + + + + + + 85 + 170 + 255 + + + + + + + + + 85 + 170 + 255 + + + + + + + + + 118 + 116 + 108 + + + + + - - :/icons/svg/person.svg - - - true - - - - - - - - - - - 22 - 22 - - - - - - - :/icons/svg/password.svg - - - true - - - - - - - QLineEdit::Password - - - Password - - - - - - - Remember Password - - - false - - - - - - 12 + 18 - Log In + - - true - - - false + + :/images/logo/logo_spash2.png + + + + Qt::Horizontal + + + + 48 + 20 + + + + - - - - - - - - Qt::Horizontal + + + + + Qt::Horizontal + + + QSizePolicy::Minimum + + + + 60 + 20 + + + + + + + + Qt::Vertical + + + + 20 + 40 + + + + + + + + Qt::Horizontal + + + QSizePolicy::Minimum + + + + 60 + 20 + + + + + + + + true + + + + 0 + 0 + + + + + + + + + + + 9 - - - 40 - 20 - - - - - - - - Opens a dialog for creating a new profile or + + + + Profile - Location: + + + + + + + + 22 + 22 + + + + + + + :/icons/svg/person.svg + + + true + + + + + + + + + + + 22 + 22 + + + + + + + :/icons/svg/password.svg + + + true + + + + + + + QLineEdit::Password + + + Password + + + + + + + Remember Password + + + false + + + + + + + + 12 + + + + Log In + + + true + + + false + + + + + + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + Opens a dialog for creating a new profile or adding locations to an existing profile. The current identities/locations will not be affected. - - - - - - <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> + + + + + + <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> <html><head><meta name="qrichtext" content="1" /><style type="text/css"> p, li { white-space: pre-wrap; } </style></head><body style=" font-family:'Sans'; font-size:10pt; font-weight:400; font-style:normal;"> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><a href="Create new Profile..."><span style=" font-family:'MS Shell Dlg 2'; font-size:8pt; text-decoration: underline; color:#0000ff;">Manage profiles and nodes...</span></a></p></body></html> - - - - - - + + + + + + + diff --git a/retroshare-gui/src/gui/chat/ChatWidget.cpp b/retroshare-gui/src/gui/chat/ChatWidget.cpp index aa9f5665a..681ff9c7e 100644 --- a/retroshare-gui/src/gui/chat/ChatWidget.cpp +++ b/retroshare-gui/src/gui/chat/ChatWidget.cpp @@ -1429,7 +1429,8 @@ void ChatWidget::colorChanged() void ChatWidget::chooseFont() { bool ok; - QFont font = QFontDialog::getFont(&ok, currentFont, this); + //Use NULL as parent as with this QFontDialog don't take care of title nether options. + QFont font = QFontDialog::getFont(&ok, currentFont, NULL, tr("Choose your font."),QFontDialog::DontUseNativeDialog); if (ok) { currentFont = font; setFont(); diff --git a/retroshare-gui/src/gui/feeds/FeedHolder.h b/retroshare-gui/src/gui/feeds/FeedHolder.h index d39947bcc..44b07777b 100644 --- a/retroshare-gui/src/gui/feeds/FeedHolder.h +++ b/retroshare-gui/src/gui/feeds/FeedHolder.h @@ -37,7 +37,7 @@ public: virtual QScrollArea *getScrollArea() = 0; virtual void deleteFeedItem(QWidget *item, uint32_t type) = 0; virtual void openChat(const RsPeerId& peerId) = 0; - virtual void openComments(uint32_t type, const RsGxsGroupId &groupId, const RsGxsMessageId &msgId, const QString &title) = 0; + virtual void openComments(uint32_t type, const RsGxsGroupId &groupId, const QVector &msg_versions, const RsGxsMessageId &msgId, const QString &title)=0; // Workaround for QTBUG-3372 void lockLayout(QWidget *feedItem, bool lock); diff --git a/retroshare-gui/src/gui/feeds/GxsChannelPostItem.cpp b/retroshare-gui/src/gui/feeds/GxsChannelPostItem.cpp index 22d90e5a2..2c0e1af84 100644 --- a/retroshare-gui/src/gui/feeds/GxsChannelPostItem.cpp +++ b/retroshare-gui/src/gui/feeds/GxsChannelPostItem.cpp @@ -35,6 +35,7 @@ #include "util/HandleRichText.h" #include "util/DateTime.h" #include "util/stringutil.h" +#include "gui/gxschannels/CreateGxsChannelMsg.h" #include @@ -63,9 +64,25 @@ GxsChannelPostItem::GxsChannelPostItem(FeedHolder *feedHolder, uint32_t feedId, std::cerr << std::endl; #endif + QVector v; + bool self = false; + + for(std::set::const_iterator it(post.mOlderVersions.begin());it!=post.mOlderVersions.end();++it) + { + if(*it == post.mMeta.mMsgId) + self = true ; + + v.push_back(*it) ; + } + if(!self) + v.push_back(post.mMeta.mMsgId); + + setMessageVersions(v) ; + setup(); - setGroup(group, false); + //setGroup(group, false); + requestGroup(); setPost(post); requestComment(); } @@ -127,6 +144,7 @@ void GxsChannelPostItem::setup() connect(ui->commentButton, SIGNAL(clicked()), this, SLOT(loadComments())); connect(ui->playButton, SIGNAL(clicked()), this, SLOT(play(void))); + connect(ui->editButton, SIGNAL(clicked()), this, SLOT(edit(void))); connect(ui->copyLinkButton, SIGNAL(clicked()), this, SLOT(copyMessageLink())); connect(ui->readButton, SIGNAL(toggled(bool)), this, SLOT(readToggled(bool))); @@ -166,6 +184,12 @@ bool GxsChannelPostItem::setGroup(const RsGxsChannelGroup &group, bool doFill) mGroup = group; + // if not publisher, hide the edit button. Without the publish key, there's no way to edit a message. + + std::cerr << "Group subscribe flags = " << std::hex << mGroup.mMeta.mSubscribeFlags << std::dec << std::endl; + if(!IS_GROUP_PUBLISHER(mGroup.mMeta.mSubscribeFlags)) + ui->editButton->hide(); + if (doFill) { fill(); } @@ -301,7 +325,7 @@ void GxsChannelPostItem::loadComment(const uint32_t &token) if (comNb == 1) { sComButText = sComButText.append("(1)"); } else if (comNb > 1) { - sComButText = tr("Comments").append("(%1)").arg(comNb); + sComButText = tr("Comments ").append("(%1)").arg(comNb); } ui->commentButton->setText(sComButText); } @@ -690,6 +714,12 @@ void GxsChannelPostItem::download() updateItem(); } +void GxsChannelPostItem::edit() +{ + CreateGxsChannelMsg *msgDialog = new CreateGxsChannelMsg(mGroup.mMeta.mGroupId,mPost.mMeta.mMsgId); + msgDialog->show(); +} + void GxsChannelPostItem::play() { std::list::iterator it; diff --git a/retroshare-gui/src/gui/feeds/GxsChannelPostItem.h b/retroshare-gui/src/gui/feeds/GxsChannelPostItem.h index 8574f4e16..a591e5e22 100644 --- a/retroshare-gui/src/gui/feeds/GxsChannelPostItem.h +++ b/retroshare-gui/src/gui/feeds/GxsChannelPostItem.h @@ -78,6 +78,7 @@ private slots: void readAndClearItem(); void download(); void play(); + void edit(); void loadComments(); void readToggled(bool checked); diff --git a/retroshare-gui/src/gui/feeds/GxsChannelPostItem.ui b/retroshare-gui/src/gui/feeds/GxsChannelPostItem.ui index 010436d7b..1d72a0693 100644 --- a/retroshare-gui/src/gui/feeds/GxsChannelPostItem.ui +++ b/retroshare-gui/src/gui/feeds/GxsChannelPostItem.ui @@ -6,8 +6,8 @@ 0 0 - 840 - 180 + 1052 + 338 @@ -332,6 +332,13 @@ + + + + Edit + + + diff --git a/retroshare-gui/src/gui/feeds/SubFileItem.cpp b/retroshare-gui/src/gui/feeds/SubFileItem.cpp index f8451e5ee..acaf76299 100644 --- a/retroshare-gui/src/gui/feeds/SubFileItem.cpp +++ b/retroshare-gui/src/gui/feeds/SubFileItem.cpp @@ -97,11 +97,12 @@ SubFileItem::SubFileItem(const RsFileHash &hash, const std::string &name, const void SubFileItem::Setup() { - connect( playButton, SIGNAL( clicked( void ) ), this, SLOT( play ( void ) ) ); - connect( downloadButton, SIGNAL( clicked( void ) ), this, SLOT( download ( void ) ) ); - connect( cancelButton, SIGNAL( clicked( void ) ), this, SLOT( cancel ( void ) ) ); - connect( copyLinkButton, SIGNAL( clicked( void ) ), this, SLOT( copyLink ( void ) ) ); - connect( saveButton, SIGNAL( clicked( void ) ), this, SLOT( save ( void ) ) ); + connect( playButton, SIGNAL( clicked( ) ), this, SLOT( play ( ) ) ); + connect( downloadButton, SIGNAL( clicked( ) ), this, SLOT( download ( ) ) ); + connect( cancelButton, SIGNAL( clicked( ) ), this, SLOT( cancel( ) ) ); + connect( deleteButton, SIGNAL( clicked( ) ), this, SLOT( del( ) ) ); + connect( copyLinkButton, SIGNAL( clicked( ) ), this, SLOT( copyLink ( ) ) ); + connect( saveButton, SIGNAL( clicked( ) ), this, SLOT( save ( ) ) ); /* once off check - if remote, check if we have it * NB: This check might be expensive - and it'll happen often! @@ -129,12 +130,21 @@ void SubFileItem::Setup() } } + deleteButton->setVisible(mFlag & SFI_FLAG_ALLOW_DELETE); + downloadButton->setVisible(mMode < SFI_STATE_LOCAL); + cancelButton->setVisible(mMode < SFI_STATE_LOCAL); + smaller(); updateItemStatic(); updateItem(); } +void SubFileItem::del() +{ + emit wantsToBeDeleted(); +} + bool SubFileItem::done() { return (mMode >= SFI_STATE_LOCAL); @@ -176,7 +186,7 @@ void SubFileItem::updateItemStatic() } /* get full path for local file */ - if ((mMode == SFI_STATE_LOCAL) || (mMode == SFI_STATE_UPLOAD)) + if (((mMode == SFI_STATE_LOCAL) || (mMode == SFI_STATE_UPLOAD))) { #ifdef DEBUG_ITEM std::cerr << "SubFileItem::updateItemStatic() STATE=Local/Upload checking path"; @@ -190,7 +200,10 @@ void SubFileItem::updateItemStatic() /* look up path */ if (!rsFiles->FileDetails(mFileHash, hintflags, fi)) { - mMode = SFI_STATE_ERROR; + if(mFlag & SFI_FLAG_ASSUME_FILE_READY) + mMode = SFI_STATE_REMOTE; + else + mMode = SFI_STATE_ERROR; #ifdef DEBUG_ITEM std::cerr << "SubFileItem::updateItemStatic() STATE=>Error No Details"; std::cerr << std::endl; @@ -241,6 +254,7 @@ void SubFileItem::updateItemStatic() case SFI_STATE_REMOTE: playButton->setEnabled(false); downloadButton->setEnabled(true); + downloadButton->setVisible(true); cancelButton->setEnabled(false); progressBar->setValue(0); diff --git a/retroshare-gui/src/gui/feeds/SubFileItem.h b/retroshare-gui/src/gui/feeds/SubFileItem.h index c3e094882..1228c9b88 100644 --- a/retroshare-gui/src/gui/feeds/SubFileItem.h +++ b/retroshare-gui/src/gui/feeds/SubFileItem.h @@ -40,7 +40,9 @@ const uint32_t SFI_STATE_UPLOAD = 0x0006; const uint32_t SFI_TYPE_CHANNEL = 0x0010; const uint32_t SFI_TYPE_ATTACH = 0x0020; -const uint32_t SFI_FLAG_CREATE = 0x1000; +const uint32_t SFI_FLAG_CREATE = 0x1000; +const uint32_t SFI_FLAG_ALLOW_DELETE = 0x2000; +const uint32_t SFI_FLAG_ASSUME_FILE_READY = 0x4000; //! This create a gui widget that allows users to access files shared by user @@ -86,10 +88,14 @@ private slots: void toggle(); void cancel(); + void del(); void save(); void updateItem(); +signals: + void wantsToBeDeleted(); + private: void Setup(); diff --git a/retroshare-gui/src/gui/feeds/SubFileItem.ui b/retroshare-gui/src/gui/feeds/SubFileItem.ui index 209f12ed8..d5c6b7181 100644 --- a/retroshare-gui/src/gui/feeds/SubFileItem.ui +++ b/retroshare-gui/src/gui/feeds/SubFileItem.ui @@ -6,12 +6,21 @@ 0 0 - 464 - 71 + 547 + 128 - + + 0 + + + 0 + + + 0 + + 0 @@ -26,27 +35,6 @@ QFrame::Sunken - - - - - - - 75 - true - true - - - - File Name - - - true - - - - - @@ -210,6 +198,41 @@ + + + + Remove this item + + + + + + + :/images/denied16.png:/images/denied16.png + + + + + + + + + + + + 75 + true + true + + + + File Name + + + true + + + diff --git a/retroshare-gui/src/gui/gxs/GxsCommentContainer.cpp b/retroshare-gui/src/gui/gxs/GxsCommentContainer.cpp index 890ca75b7..9f62a0359 100644 --- a/retroshare-gui/src/gui/gxs/GxsCommentContainer.cpp +++ b/retroshare-gui/src/gui/gxs/GxsCommentContainer.cpp @@ -54,7 +54,7 @@ void GxsCommentContainer::setup() ui.tabWidget->hideCloseButton(index); } -void GxsCommentContainer::commentLoad(const RsGxsGroupId &grpId, const RsGxsMessageId &msgId, const QString &title) +void GxsCommentContainer::commentLoad(const RsGxsGroupId &grpId, const std::set& msg_versions,const RsGxsMessageId &msgId, const QString &title) { QString comments = title; if (title.length() > MAX_COMMENT_TITLE) @@ -68,7 +68,7 @@ void GxsCommentContainer::commentLoad(const RsGxsGroupId &grpId, const RsGxsMess QWidget *commentHeader = createHeaderWidget(grpId, msgId); commentDialog->setCommentHeader(commentHeader); - commentDialog->commentLoad(grpId, msgId); + commentDialog->commentLoad(grpId, msg_versions, msgId); ui.tabWidget->addTab(commentDialog, comments); } diff --git a/retroshare-gui/src/gui/gxs/GxsCommentContainer.h b/retroshare-gui/src/gui/gxs/GxsCommentContainer.h index 086aee640..6388891df 100644 --- a/retroshare-gui/src/gui/gxs/GxsCommentContainer.h +++ b/retroshare-gui/src/gui/gxs/GxsCommentContainer.h @@ -40,7 +40,7 @@ public: GxsCommentContainer(QWidget *parent = 0); void setup(); - void commentLoad(const RsGxsGroupId &grpId, const RsGxsMessageId &msgId, const QString &title); + void commentLoad(const RsGxsGroupId &grpId, const std::set &msg_versions, const RsGxsMessageId &msgId, const QString &title); virtual GxsServiceDialog *createServiceDialog() = 0; virtual QString getServiceName() = 0; @@ -67,9 +67,9 @@ public: virtual ~GxsServiceDialog() { return; } - void commentLoad(const RsGxsGroupId &grpId, const RsGxsMessageId &msgId, const QString &title) + void commentLoad(const RsGxsGroupId &grpId, const std::set& msg_versions,const RsGxsMessageId &msgId, const QString &title) { - mContainer->commentLoad(grpId, msgId, title); + mContainer->commentLoad(grpId, msg_versions,msgId, title); } private: diff --git a/retroshare-gui/src/gui/gxs/GxsCommentDialog.cpp b/retroshare-gui/src/gui/gxs/GxsCommentDialog.cpp index cb97584b9..f846abc97 100644 --- a/retroshare-gui/src/gui/gxs/GxsCommentDialog.cpp +++ b/retroshare-gui/src/gui/gxs/GxsCommentDialog.cpp @@ -59,20 +59,16 @@ GxsCommentDialog::~GxsCommentDialog() delete(ui); } -void GxsCommentDialog::commentLoad(const RsGxsGroupId &grpId, const RsGxsMessageId &msgId) +void GxsCommentDialog::commentLoad(const RsGxsGroupId &grpId, const std::set& msg_versions,const RsGxsMessageId& most_recent_msgId) { - std::cerr << "GxsCommentDialog::commentLoad(" << grpId << ", " << msgId << ")"; + std::cerr << "GxsCommentDialog::commentLoad(" << grpId << ", most recent msg version: " << most_recent_msgId << ")"; std::cerr << std::endl; mGrpId = grpId; - mMsgId = msgId; + mMostRecentMsgId = most_recent_msgId; + mMsgVersions = msg_versions; - RsGxsGrpMsgIdPair threadId; - - threadId.first = grpId; - threadId.second = msgId; - - ui->treeWidget->requestComments(threadId); + ui->treeWidget->requestComments(mGrpId,msg_versions,most_recent_msgId); } void GxsCommentDialog::refresh() @@ -80,7 +76,7 @@ void GxsCommentDialog::refresh() std::cerr << "GxsCommentDialog::refresh()"; std::cerr << std::endl; - commentLoad(mGrpId, mMsgId); + commentLoad(mGrpId, mMsgVersions,mMostRecentMsgId); } void GxsCommentDialog::idChooserReady() diff --git a/retroshare-gui/src/gui/gxs/GxsCommentDialog.h b/retroshare-gui/src/gui/gxs/GxsCommentDialog.h index 6edeb0948..7874168a3 100644 --- a/retroshare-gui/src/gui/gxs/GxsCommentDialog.h +++ b/retroshare-gui/src/gui/gxs/GxsCommentDialog.h @@ -39,10 +39,10 @@ public: virtual ~GxsCommentDialog(); void setCommentHeader(QWidget *header); - void commentLoad(const RsGxsGroupId &grpId, const RsGxsMessageId &msgId); + void commentLoad(const RsGxsGroupId &grpId, const std::set &msg_versions, const RsGxsMessageId &most_recent_msgId); RsGxsGroupId groupId() { return mGrpId; } - RsGxsMessageId messageId() { return mMsgId; } + RsGxsMessageId messageId() { return mMostRecentMsgId; } private slots: void refresh(); @@ -51,7 +51,8 @@ private slots: private: RsGxsGroupId mGrpId; - RsGxsMessageId mMsgId; + RsGxsMessageId mMostRecentMsgId; + std::set mMsgVersions; /* UI - from Designer */ Ui::GxsCommentDialog *ui; diff --git a/retroshare-gui/src/gui/gxs/GxsCommentTreeWidget.cpp b/retroshare-gui/src/gui/gxs/GxsCommentTreeWidget.cpp index a99e815c7..d4f48ed96 100644 --- a/retroshare-gui/src/gui/gxs/GxsCommentTreeWidget.cpp +++ b/retroshare-gui/src/gui/gxs/GxsCommentTreeWidget.cpp @@ -22,8 +22,12 @@ */ #include +#include +#include +#include #include #include +#include #include "gui/common/RSElidedItemDelegate.h" #include "gui/gxs/GxsCommentTreeWidget.h" @@ -46,11 +50,73 @@ #define COMMENT_VOTE_ACK 0x001234 +#define POST_CELL_SIZE_ROLE (Qt::UserRole+1) +#define POST_COLOR_ROLE (Qt::UserRole+2) /* Images for context menu icons */ #define IMAGE_MESSAGE ":/images/folder-draft.png" -#define IMAGE_VOTEUP ":/images/vote_up.png" -#define IMAGE_VOTEDOWN ":/images/vote_down.png" +#define IMAGE_VOTEUP ":/images/vote_up.png" +#define IMAGE_VOTEDOWN ":/images/vote_down.png" + +// This class allows to draw the item using an appropriate size + +class MultiLinesCommentDelegate: public QStyledItemDelegate +{ +public: + MultiLinesCommentDelegate(QFontMetricsF f) : qf(f){} + + QSize sizeHint(const QStyleOptionViewItem &option, const QModelIndex &index) const + { + return index.data(POST_CELL_SIZE_ROLE).toSize() ; + } + + virtual void paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const + { + Q_ASSERT(index.isValid()); + + QStyleOptionViewItemV4 opt = option; + initStyleOption(&opt, index); + // disable default icon + opt.icon = QIcon(); + opt.text = QString(); + // draw default item + QApplication::style()->drawControl(QStyle::CE_ItemViewItem, &opt, painter, 0); + + const QRect r = option.rect; + + QTextDocument td ; + td.setHtml(""+index.data(Qt::DisplayRole).toString()+""); + QSizeF s = td.documentLayout()->documentSize(); + + int m = QFontMetricsF(QFont()).height(); + + QSize full_area(std::min(r.width(),(int)s.width())+m,std::min(r.height(),(int)s.height())+m); + + QPixmap px(full_area.width(),full_area.height()); + px.fill(); + QPainter p(&px) ; + p.setRenderHint(QPainter::Antialiasing); + + QPainterPath path ; + path.addRoundedRect(QRectF(m/4.0,m/4.0,s.width()+m/2.0,s.height()+m/2.0),m,m) ; + QPen pen(Qt::gray,m/7.0f); + p.setPen(pen); + p.fillPath(path,QColor::fromHsv( index.data(POST_COLOR_ROLE).toInt()/255.0*360,40,220)); // varies the color according to the post author + p.drawPath(path); + + QAbstractTextDocumentLayout::PaintContext ctx; + ctx.clip = QRectF(0,0,s.width(),s.height()); + p.translate(QPointF(m/2.0,m/2.0)); + td.documentLayout()->draw( &p, ctx ); + + painter->drawPixmap(r.topLeft(),px); + + const_cast(index.model())->setData(index,px.size(),POST_CELL_SIZE_ROLE); + } + +private: + QFontMetricsF qf; +}; GxsCommentTreeWidget::GxsCommentTreeWidget(QWidget *parent) :QTreeWidget(parent), mTokenQueue(NULL), mRsTokenService(NULL), mCommentService(NULL) @@ -62,6 +128,9 @@ GxsCommentTreeWidget::GxsCommentTreeWidget(QWidget *parent) itemDelegate->setSpacing(QSize(0, 2)); setItemDelegate(itemDelegate); setWordWrap(true); + + setItemDelegateForColumn(PCITEM_COLUMN_COMMENT,new MultiLinesCommentDelegate(QFontMetricsF(font()))) ; + // QFont font = QFont("ARIAL", 10); // font.setBold(true); @@ -85,14 +154,14 @@ GxsCommentTreeWidget::~GxsCommentTreeWidget() } } -void GxsCommentTreeWidget::setCurrentMsgId(QTreeWidgetItem *current, QTreeWidgetItem *previous) +void GxsCommentTreeWidget::setCurrentCommentMsgId(QTreeWidgetItem *current, QTreeWidgetItem *previous) { Q_UNUSED(previous); if(current) { - mCurrentMsgId = RsGxsMessageId(current->text(PCITEM_COLUMN_MSGID).toStdString()); + mCurrentCommentMsgId = RsGxsMessageId(current->text(PCITEM_COLUMN_MSGID).toStdString()); } } @@ -100,9 +169,9 @@ void GxsCommentTreeWidget::customPopUpMenu(const QPoint& /*point*/) { QMenu contextMnu( this ); QAction* action = contextMnu.addAction(QIcon(IMAGE_MESSAGE), tr("Reply to Comment"), this, SLOT(replyToComment())); - action->setDisabled(mCurrentMsgId.isNull()); + action->setDisabled(mCurrentCommentMsgId.isNull()); action = contextMnu.addAction(QIcon(IMAGE_MESSAGE), tr("Submit Comment"), this, SLOT(makeComment())); - action->setDisabled(mThreadId.first.isNull()); + action->setDisabled(mMsgVersions.empty()); contextMnu.addSeparator(); @@ -112,7 +181,7 @@ void GxsCommentTreeWidget::customPopUpMenu(const QPoint& /*point*/) action->setDisabled(mVoterId.isNull()); - if (!mCurrentMsgId.isNull()) + if (!mCurrentCommentMsgId.isNull()) { // not implemented yet /* @@ -138,7 +207,8 @@ void GxsCommentTreeWidget::voteUp() { std::cerr << "GxsCommentTreeWidget::voteUp()"; std::cerr << std::endl; - vote(mThreadId.first, mThreadId.second, mCurrentMsgId, mVoterId, true); + + vote(mGroupId, mLatestMsgId, mCurrentCommentMsgId, mVoterId, true); } @@ -146,7 +216,8 @@ void GxsCommentTreeWidget::voteDown() { std::cerr << "GxsCommentTreeWidget::voteDown()"; std::cerr << std::endl; - vote(mThreadId.first, mThreadId.second, mCurrentMsgId, mVoterId, false); + + vote(mGroupId, mLatestMsgId, mCurrentCommentMsgId, mVoterId, false); } void GxsCommentTreeWidget::setVoteId(const RsGxsId &voterId) @@ -216,16 +287,16 @@ void GxsCommentTreeWidget::banUser() void GxsCommentTreeWidget::makeComment() { - GxsCreateCommentDialog pcc(mTokenQueue, mCommentService, mThreadId, mThreadId.second, this); + GxsCreateCommentDialog pcc(mTokenQueue, mCommentService, std::make_pair(mGroupId,mLatestMsgId), mLatestMsgId, this); pcc.exec(); } void GxsCommentTreeWidget::replyToComment() { RsGxsGrpMsgIdPair msgId; - msgId.first = mThreadId.first; - msgId.second = mCurrentMsgId; - GxsCreateCommentDialog pcc(mTokenQueue, mCommentService, msgId, mThreadId.second, this); + msgId.first = mGroupId; + msgId.second = mCurrentCommentMsgId; + GxsCreateCommentDialog pcc(mTokenQueue, mCommentService, msgId, mLatestMsgId, this); pcc.exec(); } @@ -235,36 +306,44 @@ void GxsCommentTreeWidget::setup(RsTokenService *token_service, RsGxsCommentServ mCommentService = comment_service; mTokenQueue = new TokenQueue(token_service, this); connect(this, SIGNAL(customContextMenuRequested(QPoint)), this, SLOT(customPopUpMenu(QPoint))); - connect(this, SIGNAL(currentItemChanged(QTreeWidgetItem*,QTreeWidgetItem*)), this, SLOT(setCurrentMsgId(QTreeWidgetItem*, QTreeWidgetItem*))); + connect(this, SIGNAL(currentItemChanged(QTreeWidgetItem*,QTreeWidgetItem*)), this, SLOT(setCurrentCommentMsgId(QTreeWidgetItem*, QTreeWidgetItem*))); return; } /* Load Comments */ -void GxsCommentTreeWidget::requestComments(const RsGxsGrpMsgIdPair& threadId) +void GxsCommentTreeWidget::requestComments(const RsGxsGroupId& group, const std::set& message_versions,const RsGxsMessageId& most_recent_message) { /* request comments */ - mThreadId = threadId; - service_requestComments(threadId); + mGroupId = group ; + mMsgVersions = message_versions ; + mLatestMsgId = most_recent_message; + + service_requestComments(group,message_versions); } -void GxsCommentTreeWidget::service_requestComments(const RsGxsGrpMsgIdPair& threadId) +void GxsCommentTreeWidget::service_requestComments(const RsGxsGroupId& group_id,const std::set & msgIds) { /* request comments */ - std::cerr << "GxsCommentTreeWidget::service_requestComments(" << threadId.second << ")"; - std::cerr << std::endl; + std::cerr << "GxsCommentTreeWidget::service_requestComments for group " << group_id << std::endl; + + std::vector ids_to_ask; + + for(std::set::const_iterator it(msgIds.begin());it!=msgIds.end();++it) + { + std::cerr << " asking for msg " << *it << std::endl; + + ids_to_ask.push_back(std::make_pair(group_id,*it)); + } RsTokReqOptions opts; opts.mReqType = GXS_REQUEST_TYPE_MSG_RELATED_DATA; opts.mOptions = RS_TOKREQOPT_MSG_THREAD | RS_TOKREQOPT_MSG_LATEST; - std::vector msgIds; - msgIds.push_back(threadId); - uint32_t token; - mTokenQueue->requestMsgRelatedInfo(token, RS_TOKREQ_ANSTYPE_DATA, opts, msgIds, GXSCOMMENTS_LOADTHREAD); + mTokenQueue->requestMsgRelatedInfo(token, RS_TOKREQ_ANSTYPE_DATA, opts, ids_to_ask, GXSCOMMENTS_LOADTHREAD); } @@ -317,7 +396,7 @@ void GxsCommentTreeWidget::completeItems() parent->addChild(pit->second); } - else if (parentId == mThreadId.second) + else if (mMsgVersions.find(parentId) != mMsgVersions.end()) { std::cerr << "GxsCommentTreeWidget::completeItems() Added to topLevelItems"; std::cerr << std::endl; @@ -391,7 +470,7 @@ void GxsCommentTreeWidget::acknowledgeComment(const uint32_t &token) mCommentService->acknowledgeComment(token, msgId); // simply reload data - service_requestComments(mThreadId); + service_requestComments(mGroupId,mMsgVersions); } @@ -401,7 +480,7 @@ void GxsCommentTreeWidget::acknowledgeVote(const uint32_t &token) if (mCommentService->acknowledgeVote(token, msgId)) { // reload data if vote was added. - service_requestComments(mThreadId); + service_requestComments(mGroupId,mMsgVersions); } } @@ -441,6 +520,7 @@ void GxsCommentTreeWidget::service_loadThread(const uint32_t &token) RsGxsId authorId = comment.mMeta.mAuthorId; item->setId(authorId, PCITEM_COLUMN_AUTHOR, false); + item->setData(PCITEM_COLUMN_COMMENT,POST_COLOR_ROLE,QVariant(authorId.toByteArray()[1])); text = QString::number(comment.mScore); item->setText(PCITEM_COLUMN_SCORE, text); diff --git a/retroshare-gui/src/gui/gxs/GxsCommentTreeWidget.h b/retroshare-gui/src/gui/gxs/GxsCommentTreeWidget.h index e9f87bce6..dcc2db991 100644 --- a/retroshare-gui/src/gui/gxs/GxsCommentTreeWidget.h +++ b/retroshare-gui/src/gui/gxs/GxsCommentTreeWidget.h @@ -39,7 +39,7 @@ public: ~GxsCommentTreeWidget(); void setup(RsTokenService *token_service, RsGxsCommentService *comment_service); - void requestComments(const RsGxsGrpMsgIdPair& threadId); + void requestComments(const RsGxsGroupId& group, const std::set &message_versions, const RsGxsMessageId &most_recent_message); void getCurrentMsgId(RsGxsMessageId& parentId); void applyRankings(std::map& positions); @@ -49,7 +49,7 @@ public: protected: /* to be overloaded */ - virtual void service_requestComments(const RsGxsGrpMsgIdPair& threadId); + virtual void service_requestComments(const RsGxsGroupId &group_id, const std::set &msgIds); virtual void service_loadThread(const uint32_t &token); virtual QTreeWidgetItem *service_createMissingItem(const RsGxsMessageId& parent); @@ -65,7 +65,7 @@ protected: public slots: void customPopUpMenu(const QPoint& point); - void setCurrentMsgId(QTreeWidgetItem* current, QTreeWidgetItem* previous); + void setCurrentCommentMsgId(QTreeWidgetItem* current, QTreeWidgetItem* previous); void makeComment(); @@ -85,8 +85,10 @@ protected: const RsGxsMessageId &parentId, const RsGxsId &authorId, bool up); /* Data */ - RsGxsGrpMsgIdPair mThreadId; - RsGxsMessageId mCurrentMsgId; + RsGxsGroupId mGroupId; + std::set mMsgVersions; + RsGxsMessageId mLatestMsgId; + RsGxsMessageId mCurrentCommentMsgId; RsGxsId mVoterId; std::map mLoadingMap; diff --git a/retroshare-gui/src/gui/gxs/GxsFeedItem.cpp b/retroshare-gui/src/gui/gxs/GxsFeedItem.cpp index 328ae8bae..a3526796a 100644 --- a/retroshare-gui/src/gui/gxs/GxsFeedItem.cpp +++ b/retroshare-gui/src/gui/gxs/GxsFeedItem.cpp @@ -64,7 +64,10 @@ void GxsFeedItem::comments(const QString &title) if (mFeedHolder) { - mFeedHolder->openComments(feedId(), groupId(), messageId(), title); + if(mMessageVersions.empty()) + mFeedHolder->openComments(feedId(), groupId(),QVector(1,messageId()), messageId(), title); + else + mFeedHolder->openComments(feedId(), groupId(),mMessageVersions, messageId(), title); } } @@ -153,12 +156,12 @@ void GxsFeedItem::requestComment() opts.mReqType = GXS_REQUEST_TYPE_MSG_RELATED_DATA; opts.mOptions = RS_TOKREQOPT_MSG_THREAD | RS_TOKREQOPT_MSG_LATEST; - RsGxsGrpMsgIdPair msgIdPair; - msgIdPair.first = groupId(); - msgIdPair.second = messageId(); - std::vector msgIds; - msgIds.push_back(msgIdPair); + + for(uint32_t i=0;irequestMsgRelatedInfo(token, RS_TOKREQ_ANSTYPE_DATA, opts, msgIds, mTokenTypeComment); diff --git a/retroshare-gui/src/gui/gxs/GxsFeedItem.h b/retroshare-gui/src/gui/gxs/GxsFeedItem.h index 9f62ada2a..e2b4e5b1a 100644 --- a/retroshare-gui/src/gui/gxs/GxsFeedItem.h +++ b/retroshare-gui/src/gui/gxs/GxsFeedItem.h @@ -35,9 +35,12 @@ public: GxsFeedItem(FeedHolder *feedHolder, uint32_t feedId, const RsGxsGroupId &groupId, const RsGxsMessageId &messageId, bool isHome, RsGxsIfaceHelper *iface, bool autoUpdate); virtual ~GxsFeedItem(); - RsGxsMessageId messageId() { return mMessageId; } + RsGxsMessageId messageId() const { return mMessageId; } + const QVector& messageVersions() const { return mMessageVersions ; } + //To be able to update with thread message when comment is received. void setMessageId( RsGxsMessageId id) {mMessageId = id;} + void setMessageVersions( const QVector& v) { mMessageVersions = v;} protected: /* load message data */ @@ -61,6 +64,7 @@ protected slots: private: RsGxsMessageId mMessageId; + QVector mMessageVersions ; uint32_t mTokenTypeMessage; uint32_t mTokenTypeComment; }; diff --git a/retroshare-gui/src/gui/gxs/GxsGroupFeedItem.h b/retroshare-gui/src/gui/gxs/GxsGroupFeedItem.h index bfedd3111..9217c20a7 100644 --- a/retroshare-gui/src/gui/gxs/GxsGroupFeedItem.h +++ b/retroshare-gui/src/gui/gxs/GxsGroupFeedItem.h @@ -45,8 +45,8 @@ public: GxsGroupFeedItem(FeedHolder *feedHolder, uint32_t feedId, const RsGxsGroupId &groupId, bool isHome, RsGxsIfaceHelper *iface, bool autoUpdate); virtual ~GxsGroupFeedItem(); - RsGxsGroupId groupId() { return mGroupId; } - uint32_t feedId() { return mFeedId; } + RsGxsGroupId groupId() const { return mGroupId; } + uint32_t feedId() const { return mFeedId; } protected: uint32_t nextTokenType() { return ++mNextTokenType; } diff --git a/retroshare-gui/src/gui/gxs/GxsGroupFrameDialog.cpp b/retroshare-gui/src/gui/gxs/GxsGroupFrameDialog.cpp index 6ab4ca165..8ae997eab 100644 --- a/retroshare-gui/src/gui/gxs/GxsGroupFrameDialog.cpp +++ b/retroshare-gui/src/gui/gxs/GxsGroupFrameDialog.cpp @@ -525,7 +525,7 @@ void GxsGroupFrameDialog::sharePublishKey() shareUi.exec(); } -void GxsGroupFrameDialog::loadComment(const RsGxsGroupId &grpId, const RsGxsMessageId &msgId, const QString &title) +void GxsGroupFrameDialog::loadComment(const RsGxsGroupId &grpId, const QVector& msg_versions, const RsGxsMessageId &most_recent_msgId, const QString &title) { RsGxsCommentService *commentService = getCommentService(); if (!commentService) { @@ -533,7 +533,8 @@ void GxsGroupFrameDialog::loadComment(const RsGxsGroupId &grpId, const RsGxsMess return; } - GxsCommentDialog *commentDialog = commentWidget(msgId); + GxsCommentDialog *commentDialog = commentWidget(most_recent_msgId); + if (!commentDialog) { QString comments = title; if (title.length() > MAX_COMMENT_TITLE) @@ -544,12 +545,16 @@ void GxsGroupFrameDialog::loadComment(const RsGxsGroupId &grpId, const RsGxsMess commentDialog = new GxsCommentDialog(this, mInterface->getTokenService(), commentService); - QWidget *commentHeader = createCommentHeaderWidget(grpId, msgId); + QWidget *commentHeader = createCommentHeaderWidget(grpId, most_recent_msgId); if (commentHeader) { commentDialog->setCommentHeader(commentHeader); } - commentDialog->commentLoad(grpId, msgId); + std::set msgv; + for(int i=0;icommentLoad(grpId, msgv,most_recent_msgId); int index = ui->messageTabWidget->addTab(commentDialog, comments); ui->messageTabWidget->setTabIcon(index, QIcon(IMAGE_COMMENT)); @@ -620,12 +625,12 @@ GxsMessageFrameWidget *GxsGroupFrameDialog::createMessageWidget(const RsGxsGroup connect(msgWidget, SIGNAL(groupChanged(QWidget*)), this, SLOT(messageTabInfoChanged(QWidget*))); connect(msgWidget, SIGNAL(waitingChanged(QWidget*)), this, SLOT(messageTabWaitingChanged(QWidget*))); - connect(msgWidget, SIGNAL(loadComment(RsGxsGroupId,RsGxsMessageId,QString)), this, SLOT(loadComment(RsGxsGroupId,RsGxsMessageId,QString))); + connect(msgWidget, SIGNAL(loadComment(RsGxsGroupId,QVector,RsGxsMessageId,QString)), this, SLOT(loadComment(RsGxsGroupId,QVector,RsGxsMessageId,QString))); return msgWidget; } -GxsCommentDialog *GxsGroupFrameDialog::commentWidget(const RsGxsMessageId &msgId) +GxsCommentDialog *GxsGroupFrameDialog::commentWidget(const RsGxsMessageId& msgId) { int tabCount = ui->messageTabWidget->count(); for (int index = 0; index < tabCount; ++index) { diff --git a/retroshare-gui/src/gui/gxs/GxsGroupFrameDialog.h b/retroshare-gui/src/gui/gxs/GxsGroupFrameDialog.h index 3b74b8214..8138cc1e1 100644 --- a/retroshare-gui/src/gui/gxs/GxsGroupFrameDialog.h +++ b/retroshare-gui/src/gui/gxs/GxsGroupFrameDialog.h @@ -126,7 +126,7 @@ private slots: void sharePublishKey(); - void loadComment(const RsGxsGroupId &grpId, const RsGxsMessageId &msgId, const QString &title); + void loadComment(const RsGxsGroupId &grpId, const QVector& msg_versions,const RsGxsMessageId &most_recent_msgId, const QString &title); private: virtual QString text(TextType type) = 0; diff --git a/retroshare-gui/src/gui/gxs/GxsMessageFrameWidget.h b/retroshare-gui/src/gui/gxs/GxsMessageFrameWidget.h index d604be716..71d0ae2a1 100644 --- a/retroshare-gui/src/gui/gxs/GxsMessageFrameWidget.h +++ b/retroshare-gui/src/gui/gxs/GxsMessageFrameWidget.h @@ -54,7 +54,7 @@ public: signals: void groupChanged(QWidget *widget); void waitingChanged(QWidget *widget); - void loadComment(const RsGxsGroupId &groupId, const RsGxsMessageId &msgId, const QString &title); + void loadComment(const RsGxsGroupId &groupId, const QVector& msg_versions,const RsGxsMessageId &msgId, const QString &title); protected: virtual void setAllMessagesReadDo(bool read, uint32_t &token) = 0; diff --git a/retroshare-gui/src/gui/gxschannels/CreateGxsChannelMsg.cpp b/retroshare-gui/src/gui/gxschannels/CreateGxsChannelMsg.cpp index 8c6221fd2..beaa17042 100644 --- a/retroshare-gui/src/gui/gxschannels/CreateGxsChannelMsg.cpp +++ b/retroshare-gui/src/gui/gxschannels/CreateGxsChannelMsg.cpp @@ -38,11 +38,15 @@ //#define ENABLE_GENERATE -#define CREATEMSG_CHANNELINFO 0x002 +#define CREATEMSG_CHANNELINFO 0x002 +#define CREATEMSG_CHANNEL_POST_INFO 0x003 + +// #define DEBUG_CREATE_GXS_MSG /** Constructor */ -CreateGxsChannelMsg::CreateGxsChannelMsg(const RsGxsGroupId &cId) - : QDialog (NULL, Qt::WindowSystemMenuHint | Qt::WindowTitleHint | Qt::WindowMinMaxButtonsHint | Qt::WindowCloseButtonHint), mChannelId(cId) ,mCheckAttachment(true), mAutoMediaThumbNail(false) +CreateGxsChannelMsg::CreateGxsChannelMsg(const RsGxsGroupId &cId, RsGxsMessageId existing_post) + : QDialog (NULL, Qt::WindowSystemMenuHint | Qt::WindowTitleHint | Qt::WindowMinMaxButtonsHint | Qt::WindowCloseButtonHint), + mChannelId(cId) , mOrigPostId(existing_post),mCheckAttachment(true), mAutoMediaThumbNail(false) { /* Invoke the Qt Designer generated object setup routine */ setupUi(this); @@ -50,7 +54,11 @@ CreateGxsChannelMsg::CreateGxsChannelMsg(const RsGxsGroupId &cId) mChannelQueue = new TokenQueue(rsGxsChannels->getTokenService(), this); headerFrame->setHeaderImage(QPixmap(":/images/channels.png")); - headerFrame->setHeaderText(tr("New Channel Post")); + + if(!existing_post.isNull()) + headerFrame->setHeaderText(tr("Edit Channel Post")); + else + headerFrame->setHeaderText(tr("New Channel Post")); setAttribute ( Qt::WA_DeleteOnClose, true ); @@ -337,43 +345,63 @@ void CreateGxsChannelMsg::parseRsFileListAttachments(const std::string &attachLi } -void CreateGxsChannelMsg::addAttachment(const RsFileHash &hash, const std::string &fname, uint64_t size, bool local, const RsPeerId &srcId) +void CreateGxsChannelMsg::addAttachment(const RsFileHash &hash, const std::string &fname, uint64_t size, bool local, const RsPeerId &srcId, bool assume_file_ready) { /* add a SubFileItem to the attachment section */ +#ifdef DEBUG_CREATE_GXS_MSG std::cerr << "CreateGxsChannelMsg::addAttachment()"; std::cerr << std::endl; +#endif /* add widget in for new destination */ - uint32_t flags = SFI_TYPE_CHANNEL; + uint32_t flags = SFI_TYPE_CHANNEL | SFI_FLAG_ALLOW_DELETE ; + + if(assume_file_ready) + flags |= SFI_FLAG_ASSUME_FILE_READY; + if (local) - { flags |= SFI_STATE_LOCAL; - } else - { flags |= SFI_STATE_REMOTE; - } SubFileItem *file = new SubFileItem(hash, fname, "", size, flags, srcId); // destroyed when fileFrame (this subfileitem) is destroyed + connect(file,SIGNAL(wantsToBeDeleted()),this,SLOT(deleteAttachment())) ; + mAttachments.push_back(file); QLayout *layout = fileFrame->layout(); layout->addWidget(file); if (mCheckAttachment) - { checkAttachmentReady(); - } +} - return; +void CreateGxsChannelMsg::deleteAttachment() +{ + // grab the item who sent the request + + SubFileItem *file_item = qobject_cast(QObject::sender()); + + for(std::list::iterator it(mAttachments.begin());it!=mAttachments.end();) + if(*it == file_item) + { + SubFileItem *item = *it ; + it = mAttachments.erase(it) ; + fileFrame->layout()->removeWidget(file_item) ; + delete item ; + } + else + ++it; } void CreateGxsChannelMsg::addExtraFile() { /* add a SubFileItem to the attachment section */ +#ifdef DEBUG_CREATE_GXS_MSG std::cerr << "CreateGxsChannelMsg::addExtraFile() opening file dialog"; std::cerr << std::endl; +#endif QStringList files; if (misc::getOpenFileNames(this, RshareSettings::LASTDIR_EXTRAFILE, tr("Add Extra File"), "", files)) { @@ -386,8 +414,10 @@ void CreateGxsChannelMsg::addExtraFile() void CreateGxsChannelMsg::addAttachment(const std::string &path) { /* add a SubFileItem to the attachment section */ +#ifdef DEBUG_CREATE_GXS_MSG std::cerr << "CreateGxsChannelMsg::addAttachment()"; std::cerr << std::endl; +#endif if(mAutoMediaThumbNail) setThumbNail(path, 2000); @@ -522,8 +552,10 @@ void CreateGxsChannelMsg::checkAttachmentReady() void CreateGxsChannelMsg::cancelMsg() { +#ifdef DEBUG_CREATE_GXS_MSG std::cerr << "CreateGxsChannelMsg::cancelMsg() :" << "Deleting EXTRA attachments" << std::endl; +#endif std::cerr << std::endl; @@ -555,6 +587,15 @@ void CreateGxsChannelMsg::newChannelMsg() uint32_t token; mChannelQueue->requestGroupInfo(token, RS_TOKREQ_ANSTYPE_SUMMARY, opts, groupIds, CREATEMSG_CHANNELINFO); + + if(!mOrigPostId.isNull()) + { + GxsMsgReq message_ids; + + opts.mReqType = GXS_REQUEST_TYPE_MSG_DATA; + message_ids[mChannelId].push_back(mOrigPostId); + mChannelQueue->requestMsgInfo(token, RS_TOKREQ_ANSTYPE_SUMMARY, opts, message_ids, CREATEMSG_CHANNEL_POST_INFO); + } } } @@ -569,8 +610,10 @@ void CreateGxsChannelMsg::saveChannelInfo(const RsGroupMetaData &meta) void CreateGxsChannelMsg::sendMsg() { +#ifdef DEBUG_CREATE_GXS_MSG std::cerr << "CreateGxsChannelMsg::sendMsg()"; std::cerr << std::endl; +#endif /* construct message bits */ std::string subject = std::string(misc::removeNewLine(subjectEdit->text()).toUtf8()); @@ -628,6 +671,7 @@ void CreateGxsChannelMsg::sendMessage(const std::string &subject, const std::str post.mMeta.mThreadId.clear() ; post.mMeta.mMsgId.clear() ; + post.mMeta.mOrigMsgId = mOrigPostId; post.mMeta.mMsgName = subject; post.mMsg = msg; post.mFiles = files; @@ -686,10 +730,47 @@ void CreateGxsChannelMsg::addThumbnail() thumbnail_label->setPixmap(picture); } +void CreateGxsChannelMsg::loadChannelPostInfo(const uint32_t &token) +{ +#ifdef DEBUG_CREATE_GXS_MSG + std::cerr << "CreateGxsChannelMsg::loadChannelPostInfo()"; + std::cerr << std::endl; +#endif + + std::vector posts; + rsGxsChannels->getPostData(token, posts); + + if (posts.size() != 1) + { + std::cerr << "CreateGxsChannelMsg::loadChannelPostInfo() ERROR INVALID Number of posts in request" << std::endl; + return ; + } + + // now populate the widget with the channel post data. + const RsGxsChannelPost& post = posts[0]; + + if(post.mMeta.mGroupId != mChannelId || post.mMeta.mMsgId != mOrigPostId) + { + std::cerr << "CreateGxsChannelMsg::loadChannelPostInfo() ERROR INVALID post ID or channel ID" << std::endl; + return ; + } + + subjectEdit->setText(QString::fromUtf8(post.mMeta.mMsgName.c_str())) ; + msgEdit->setText(QString::fromUtf8(post.mMsg.c_str())) ; + + for(std::list::const_iterator it(post.mFiles.begin());it!=post.mFiles.end();++it) + addAttachment(it->mHash,it->mName,it->mSize,true,RsPeerId(),true); + + picture.loadFromData(post.mThumbnail.mData,post.mThumbnail.mSize,"PNG"); + thumbnail_label->setPixmap(picture); +} + void CreateGxsChannelMsg::loadChannelInfo(const uint32_t &token) { +#ifdef DEBUG_CREATE_GXS_MSG std::cerr << "CreateGxsChannelMsg::loadChannelInfo()"; std::cerr << std::endl; +#endif std::list groupInfo; rsGxsChannels->getGroupSummary(token, groupInfo); @@ -708,8 +789,10 @@ void CreateGxsChannelMsg::loadChannelInfo(const uint32_t &token) void CreateGxsChannelMsg::loadRequest(const TokenQueue *queue, const TokenRequest &req) { +#ifdef DEBUG_CREATE_GXS_MSG std::cerr << "CreateGxsChannelMsg::loadRequest() UserType: " << req.mUserType; std::cerr << std::endl; +#endif if (queue == mChannelQueue) { @@ -719,6 +802,9 @@ void CreateGxsChannelMsg::loadRequest(const TokenQueue *queue, const TokenReques case CREATEMSG_CHANNELINFO: loadChannelInfo(req.mToken); break; + case CREATEMSG_CHANNEL_POST_INFO: + loadChannelPostInfo(req.mToken); + break; default: std::cerr << "CreateGxsChannelMsg::loadRequest() UNKNOWN UserType "; std::cerr << std::endl; diff --git a/retroshare-gui/src/gui/gxschannels/CreateGxsChannelMsg.h b/retroshare-gui/src/gui/gxschannels/CreateGxsChannelMsg.h index dc1b51751..4a99ad9aa 100644 --- a/retroshare-gui/src/gui/gxschannels/CreateGxsChannelMsg.h +++ b/retroshare-gui/src/gui/gxschannels/CreateGxsChannelMsg.h @@ -38,13 +38,13 @@ class CreateGxsChannelMsg : public QDialog, public TokenResponse, private Ui::Cr public: /** Default Constructor */ - CreateGxsChannelMsg(const RsGxsGroupId& cId); + CreateGxsChannelMsg(const RsGxsGroupId& cId, RsGxsMessageId existing_post = RsGxsMessageId()); /** Default Destructor */ ~CreateGxsChannelMsg(); void addAttachment(const std::string &path); - void addAttachment(const RsFileHash &hash, const std::string &fname, uint64_t size, bool local, const RsPeerId &srcId); + void addAttachment(const RsFileHash &hash, const std::string &fname, uint64_t size, bool local, const RsPeerId &srcId,bool assume_file_ready = false); void newChannelMsg(); @@ -60,6 +60,7 @@ protected: private slots: void addExtraFile(); void checkAttachmentReady(); + void deleteAttachment(); void cancelMsg(); void sendMsg(); @@ -71,6 +72,7 @@ private slots: private: void loadChannelInfo(const uint32_t &token); + void loadChannelPostInfo(const uint32_t &token); void saveChannelInfo(const RsGroupMetaData &group); void parseRsFileListAttachments(const std::string &attachList); @@ -78,7 +80,9 @@ private: bool setThumbNail(const std::string& path, int frame); RsGxsGroupId mChannelId; + RsGxsMessageId mOrigPostId; RsGroupMetaData mChannelMeta; + RsMsgMetaData mOrigMeta; bool mChannelMetaLoaded; std::list mAttachments; diff --git a/retroshare-gui/src/gui/gxschannels/CreateGxsChannelMsg.ui b/retroshare-gui/src/gui/gxschannels/CreateGxsChannelMsg.ui index c9e4c3346..180a79672 100644 --- a/retroshare-gui/src/gui/gxschannels/CreateGxsChannelMsg.ui +++ b/retroshare-gui/src/gui/gxschannels/CreateGxsChannelMsg.ui @@ -6,8 +6,8 @@ 0 0 - 581 - 479 + 875 + 659 @@ -60,7 +60,7 @@ false - 0 + 1 @@ -302,8 +302,8 @@ p, li { white-space: pre-wrap; } 0 0 - 523 - 24 + 767 + 42 diff --git a/retroshare-gui/src/gui/gxschannels/GxsChannelPostsWidget.cpp b/retroshare-gui/src/gui/gxschannels/GxsChannelPostsWidget.cpp index 76c777607..58c4fef88 100644 --- a/retroshare-gui/src/gui/gxschannels/GxsChannelPostsWidget.cpp +++ b/retroshare-gui/src/gui/gxschannels/GxsChannelPostsWidget.cpp @@ -207,9 +207,9 @@ void GxsChannelPostsWidget::openChat(const RsPeerId & /*peerId*/) } // Callback from Widget->FeedHolder->ServiceDialog->CommentContainer->CommentDialog, -void GxsChannelPostsWidget::openComments(uint32_t /*type*/, const RsGxsGroupId &groupId, const RsGxsMessageId &msgId, const QString &title) +void GxsChannelPostsWidget::openComments(uint32_t /*type*/, const RsGxsGroupId &groupId, const QVector& msg_versions,const RsGxsMessageId &msgId, const QString &title) { - emit loadComment(groupId, msgId, title); + emit loadComment(groupId, msg_versions,msgId, title); } void GxsChannelPostsWidget::createMsg() @@ -398,7 +398,27 @@ void GxsChannelPostsWidget::filterChanged(int filter) void GxsChannelPostsWidget::createPostItem(const RsGxsChannelPost &post, bool related) { GxsChannelPostItem *item = NULL; - if (related) { + + if(!post.mMeta.mOrigMsgId.isNull()) + { + FeedItem *feedItem = ui->feedWidget->findGxsFeedItem(post.mMeta.mGroupId, post.mMeta.mOrigMsgId); + item = dynamic_cast(feedItem); + + if(item) + { + ui->feedWidget->removeFeedItem(item) ; + RsGxsChannelGroup dummyGroup; + dummyGroup.mMeta.mGroupId = groupId(); + dummyGroup.mMeta.mSubscribeFlags = 0xffffffff; + GxsChannelPostItem *item = new GxsChannelPostItem(this, 0, dummyGroup, post, true, false); + ui->feedWidget->addFeedItem(item, ROLE_PUBLISH, QDateTime::fromTime_t(post.mMeta.mPublishTs)); + + return ; + } + } + + if (related) + { FeedItem *feedItem = ui->feedWidget->findGxsFeedItem(post.mMeta.mGroupId, post.mMeta.mMsgId); item = dynamic_cast(feedItem); } @@ -438,8 +458,6 @@ void GxsChannelPostsWidget::insertChannelPosts(std::vector &po return; } - std::vector::const_reverse_iterator it; - int count = posts.size(); int pos = 0; @@ -447,18 +465,127 @@ void GxsChannelPostsWidget::insertChannelPosts(std::vector &po ui->feedWidget->setSortingEnabled(false); } - for (it = posts.rbegin(); it != posts.rend(); ++it) - { - if (thread && thread->stopped()) { - break; - } + // collect new versions of posts if any - if (thread) { - thread->emitAddPost(qVariantFromValue(*it), related, ++pos, count); - } else { - createPostItem(*it, related); +#ifdef DEBUG_CHANNEL + std::cerr << "Inserting channel posts" << std::endl; +#endif + + std::vector new_versions ; + for (uint32_t i=0;i search_map ; + for (uint32_t i=0;i versions ; + std::map::const_iterator vit ; + + while(search_map.end() != (vit=search_map.find(posts[current_index].mMeta.mOrigMsgId))) + { +#ifdef DEBUG_CHANNEL + std::cerr << " post at index " << current_index << " replaces a post at position " << vit->second ; +#endif + + // Now replace the post only if the new versionis more recent. It may happen indeed that the same post has been corrected multiple + // times. In this case, we only need to replace the post with the newest version + + uint32_t prev_index = current_index ; + current_index = vit->second ; + + if(posts[current_index].mMeta.mMsgId.isNull()) // This handles the branching situation where this post has been already erased. No need to go down further. + { +#ifdef DEBUG_CHANNEL + std::cerr << " already erased. Stopping." << std::endl; +#endif + break ; + } + + if(posts[current_index].mMeta.mPublishTs < posts[source_index].mMeta.mPublishTs) + { +#ifdef DEBUG_CHANNEL + std::cerr << " and is more recent => following" << std::endl; +#endif + for(std::set::const_iterator itt(posts[current_index].mOlderVersions.begin());itt!=posts[current_index].mOlderVersions.end();++itt) + posts[source_index].mOlderVersions.insert(*itt); + + posts[source_index].mOlderVersions.insert(posts[current_index].mMeta.mMsgId); + posts[current_index].mMeta.mMsgId.clear(); // clear the msg Id so the post will be ignored + } +#ifdef DEBUG_CHANNEL + else + std::cerr << " but is older -> Stopping" << std::endl; +#endif + } + } + } + +#ifdef DEBUG_CHANNEL + std::cerr << "Now adding posts..." << std::endl; +#endif + + for (std::vector::const_reverse_iterator it = posts.rbegin(); it != posts.rend(); ++it) + { +#ifdef DEBUG_CHANNEL + std::cerr << " adding post: " << (*it).mMeta.mMsgId ; +#endif + + if(!(*it).mMeta.mMsgId.isNull()) + { +#ifdef DEBUG_CHANNEL + std::cerr << " added" << std::endl; +#endif + + if (thread && thread->stopped()) + break; + + if (thread) + thread->emitAddPost(qVariantFromValue(*it), related, ++pos, count); + else + createPostItem(*it, related); } - } +#ifdef DEBUG_CHANNEL + else + std::cerr << " skipped" << std::endl; +#endif + } if (!thread) { ui->feedWidget->setSortingEnabled(true); diff --git a/retroshare-gui/src/gui/gxschannels/GxsChannelPostsWidget.h b/retroshare-gui/src/gui/gxschannels/GxsChannelPostsWidget.h index 541fcc506..ddeb474a0 100644 --- a/retroshare-gui/src/gui/gxschannels/GxsChannelPostsWidget.h +++ b/retroshare-gui/src/gui/gxschannels/GxsChannelPostsWidget.h @@ -61,7 +61,7 @@ public: virtual QScrollArea *getScrollArea(); virtual void deleteFeedItem(QWidget *item, uint32_t type); virtual void openChat(const RsPeerId& peerId); - virtual void openComments(uint32_t type, const RsGxsGroupId &groupId, const RsGxsMessageId &msgId, const QString &title); + virtual void openComments(uint32_t type, const RsGxsGroupId &groupId, const QVector &msg_versions, const RsGxsMessageId &msgId, const QString &title); protected: /* GxsMessageFramePostWidget */ diff --git a/retroshare-gui/src/gui/gxschannels/GxsChannelPostsWidget.ui b/retroshare-gui/src/gui/gxschannels/GxsChannelPostsWidget.ui index e93296003..47f98bcdf 100644 --- a/retroshare-gui/src/gui/gxschannels/GxsChannelPostsWidget.ui +++ b/retroshare-gui/src/gui/gxschannels/GxsChannelPostsWidget.ui @@ -6,8 +6,8 @@ 0 0 - 793 - 465 + 880 + 557 @@ -454,7 +454,7 @@ <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> <html><head><meta name="qrichtext" content="1" /><style type="text/css"> p, li { white-space: pre-wrap; } -</style></head><body style=" font-family:'Sans Serif'; font-size:9pt; font-weight:400; font-style:normal;"> +</style></head><body style=" font-family:'Sans'; font-size:9pt; font-weight:400; font-style:normal;"> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'MS Shell Dlg 2'; font-size:8pt;">Description</span></p></body></html> diff --git a/retroshare-gui/src/gui/icons.qrc b/retroshare-gui/src/gui/icons.qrc index e9b7d32bd..737b12ae3 100644 --- a/retroshare-gui/src/gui/icons.qrc +++ b/retroshare-gui/src/gui/icons.qrc @@ -1,5 +1,7 @@ + icons/svg/hidden.svg + icons/svg/randomness.svg icons/svg/password.svg icons/stars/star0.png icons/stars/star1.png diff --git a/retroshare-gui/src/gui/icons/svg/hidden.svg b/retroshare-gui/src/gui/icons/svg/hidden.svg new file mode 100644 index 000000000..da6e57656 --- /dev/null +++ b/retroshare-gui/src/gui/icons/svg/hidden.svg @@ -0,0 +1,71 @@ + + + +image/svg+xml \ No newline at end of file diff --git a/retroshare-gui/src/gui/icons/svg/randomness.svg b/retroshare-gui/src/gui/icons/svg/randomness.svg new file mode 100644 index 000000000..b0b8e0b9f --- /dev/null +++ b/retroshare-gui/src/gui/icons/svg/randomness.svg @@ -0,0 +1,197 @@ + + + +image/svg+xml \ No newline at end of file diff --git a/retroshare-gui/src/gui/images.qrc b/retroshare-gui/src/gui/images.qrc index fbdb66d3d..887cb6620 100644 --- a/retroshare-gui/src/gui/images.qrc +++ b/retroshare-gui/src/gui/images.qrc @@ -1,5 +1,6 @@ + images/logo/background.png images/logo/logo_spash2.png images/network_map.png images/global_switch_on.png diff --git a/retroshare-gui/src/gui/images/logo/background.png b/retroshare-gui/src/gui/images/logo/background.png new file mode 100644 index 000000000..e6a8c5619 Binary files /dev/null and b/retroshare-gui/src/gui/images/logo/background.png differ diff --git a/retroshare-gui/src/gui/qss/stylesheet/Standard.qss b/retroshare-gui/src/gui/qss/stylesheet/Standard.qss index c3f0c1012..8b746991b 100644 --- a/retroshare-gui/src/gui/qss/stylesheet/Standard.qss +++ b/retroshare-gui/src/gui/qss/stylesheet/Standard.qss @@ -665,49 +665,49 @@ IdEditDialog QLabel#info_label background-color: qlineargradient(x1:0, y1:0, x2:0, y2:1, stop:0 #FFFFD7, stop:1 #FFFFB2); } GenCertDialog QComboBox#genPGPuser { - border: 4px solid #0099cc; + border: 2px solid #0099cc; border-radius: 6px; background: white; font: bold; } GenCertDialog QSpinBox#hiddenport_spinBox { - border: 4px solid #0099cc; + border: 2px solid #0099cc; border-radius: 6px; background: white; font: bold; } GenCertDialog QLineEdit#hiddenaddr_input { - border: 4px solid #0099cc; + border: 2px solid #0099cc; border-radius: 6px; background: white; font: bold; } GenCertDialog QLineEdit#password_input_2 { - border: 4px solid #0099cc; + border: 2px solid #0099cc; border-radius: 6px; background: white; font: bold; } GenCertDialog QLineEdit#password_input { - border: 4px solid #0099cc; + border: 2px solid #0099cc; border-radius: 6px; background: white; font: bold; } GenCertDialog QLineEdit#nickname_input { - border: 4px solid #0099cc; + border: 2px solid #0099cc; border-radius: 6px; background: white; font: bold; } GenCertDialog QLineEdit#node_input { - border: 4px solid #0099cc; + border: 2px solid #0099cc; border-radius: 6px; background: white; font: bold; } GenCertDialog QLineEdit#name_input { - border: 4px solid #0099cc; + border: 2px solid #0099cc; border-radius: 6px; background: white; font: bold; @@ -772,4 +772,14 @@ StartDialog QPushButton#loadButton { StartDialog QPushButton#loadButton:hover { border-image: url(:/images/btn_blue_hover.png) 4; -} \ No newline at end of file +} + +StartDialog QFrame#loginframe{ + background-image: url(:/images/logo/background.png); + background-repeat: repeat; +} + +GenCertDialog QFrame#profileframe{ + background-image: url(:/images/logo/background.png); + background-repeat: repeat; +} diff --git a/retroshare-gui/src/gui/settings/ChatPage.cpp b/retroshare-gui/src/gui/settings/ChatPage.cpp index 23669840e..81e54c802 100644 --- a/retroshare-gui/src/gui/settings/ChatPage.cpp +++ b/retroshare-gui/src/gui/settings/ChatPage.cpp @@ -416,7 +416,7 @@ ChatPage::load() void ChatPage::on_pushButtonChangeChatFont_clicked() { bool ok; - QFont font = QFontDialog::getFont(&ok, fontTempChat, this); + QFont font = QFontDialog::getFont(&ok, fontTempChat, this, tr("Choose your default font for Chat."),QFontDialog::DontUseNativeDialog); if (ok) { fontTempChat = font; // using fontTempChat.rawname() does not always work! @@ -424,6 +424,7 @@ void ChatPage::on_pushButtonChangeChatFont_clicked() QStringList fontname = fontTempChat.toString().split(","); ui.labelChatFontPreview->setText(fontname[0]); ui.labelChatFontPreview->setFont(fontTempChat); + updateChatParams(); } } diff --git a/retroshare-gui/src/gui/settings/ChatPage.ui b/retroshare-gui/src/gui/settings/ChatPage.ui index 152e3530e..14d1cc6f8 100644 --- a/retroshare-gui/src/gui/settings/ChatPage.ui +++ b/retroshare-gui/src/gui/settings/ChatPage.ui @@ -14,7 +14,7 @@ - 2 + 0 @@ -866,7 +866,7 @@ QTabWidget::North - 2 + 0