From 54d0d8ab8bac01fc32bf14467231cc4fbc731e7f Mon Sep 17 00:00:00 2001 From: defnax Date: Wed, 25 Dec 2019 17:16:58 +0100 Subject: [PATCH 01/44] Added new Card View for Posted --- .../src/gui/Posted/PostedCardView.cpp | 545 ++++++++++++++++++ .../src/gui/Posted/PostedCardView.h | 96 +++ .../src/gui/Posted/PostedCardView.ui | 527 +++++++++++++++++ retroshare-gui/src/gui/Posted/PostedItem.cpp | 5 + .../src/gui/Posted/PostedListWidget.cpp | 246 +++++++- .../src/gui/Posted/PostedListWidget.h | 9 + .../src/gui/Posted/PostedListWidget.ui | 199 +++++-- .../src/gui/Posted/Posted_images.qrc | 6 +- retroshare-gui/src/gui/Posted/images/card.png | Bin 0 -> 2257 bytes .../src/gui/Posted/images/classic.png | Bin 0 -> 2361 bytes .../src/gui/Posted/images/down-arrow.png | Bin 2005 -> 2641 bytes .../src/gui/Posted/images/down-hover.png | Bin 0 -> 1848 bytes .../src/gui/Posted/images/notes.png | Bin 1771 -> 2227 bytes .../src/gui/Posted/images/up-arrow.png | Bin 1925 -> 2603 bytes .../src/gui/Posted/images/up-hover.png | Bin 0 -> 1823 bytes .../src/gui/qss/stylesheet/Standard.qss | 4 + retroshare-gui/src/retroshare-gui.pro | 3 + 17 files changed, 1591 insertions(+), 49 deletions(-) create mode 100644 retroshare-gui/src/gui/Posted/PostedCardView.cpp create mode 100644 retroshare-gui/src/gui/Posted/PostedCardView.h create mode 100644 retroshare-gui/src/gui/Posted/PostedCardView.ui create mode 100644 retroshare-gui/src/gui/Posted/images/card.png create mode 100644 retroshare-gui/src/gui/Posted/images/classic.png create mode 100644 retroshare-gui/src/gui/Posted/images/down-hover.png create mode 100644 retroshare-gui/src/gui/Posted/images/up-hover.png diff --git a/retroshare-gui/src/gui/Posted/PostedCardView.cpp b/retroshare-gui/src/gui/Posted/PostedCardView.cpp new file mode 100644 index 000000000..f7f59a056 --- /dev/null +++ b/retroshare-gui/src/gui/Posted/PostedCardView.cpp @@ -0,0 +1,545 @@ +/******************************************************************************* + * retroshare-gui/src/gui/Posted/PostedCardView.cpp * + * * + * Copyright (C) 2019 Retroshare Team * + * * + * 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 "rshare.h" +#include "PostedCardView.h" +#include "gui/feeds/FeedHolder.h" +#include "gui/gxs/GxsIdDetails.h" +#include "util/misc.h" +#include "util/HandleRichText.h" + +#include "ui_PostedCardView.h" + +#include +#include + +#define LINK_IMAGE ":/images/thumb-link.png" + +/** Constructor */ + +PostedCardView::PostedCardView(FeedHolder *feedHolder, uint32_t feedId, const RsGxsGroupId &groupId, const RsGxsMessageId &messageId, bool isHome, bool autoUpdate) : + GxsFeedItem(feedHolder, feedId, groupId, messageId, isHome, rsPosted, autoUpdate) +{ + setup(); + + requestGroup(); + requestMessage(); + requestComment(); +} + +PostedCardView::PostedCardView(FeedHolder *feedHolder, uint32_t feedId, const RsPostedGroup &group, const RsPostedPost &post, bool isHome, bool autoUpdate) : + GxsFeedItem(feedHolder, feedId, post.mMeta.mGroupId, post.mMeta.mMsgId, isHome, rsPosted, autoUpdate) +{ + setup(); + + mMessageId = post.mMeta.mMsgId; + + + setGroup(group, false); + setPost(post); + requestComment(); +} + +PostedCardView::PostedCardView(FeedHolder *feedHolder, uint32_t feedId, const RsPostedPost &post, bool isHome, bool autoUpdate) : + GxsFeedItem(feedHolder, feedId, post.mMeta.mGroupId, post.mMeta.mMsgId, isHome, rsPosted, autoUpdate) +{ + setup(); + + requestGroup(); + setPost(post); + requestComment(); +} + +PostedCardView::~PostedCardView() +{ + delete(ui); +} + +void PostedCardView::setup() +{ + /* Invoke the Qt Designer generated object setup routine */ + ui = new Ui::PostedCardView; + ui->setupUi(this); + + setAttribute(Qt::WA_DeleteOnClose, true); + + mInFill = false; + + /* clear ui */ + ui->titleLabel->setText(tr("Loading")); + ui->dateLabel->clear(); + ui->fromLabel->clear(); + ui->siteLabel->clear(); + + /* general ones */ + connect(ui->clearButton, SIGNAL(clicked()), this, SLOT(removeItem())); + + /* specific */ + connect(ui->readAndClearButton, SIGNAL(clicked()), this, SLOT(readAndClearItem())); + + connect(ui->commentButton, SIGNAL( clicked()), this, SLOT(loadComments())); + connect(ui->voteUpButton, SIGNAL(clicked()), this, SLOT(makeUpVote())); + connect(ui->voteDownButton, SIGNAL(clicked()), this, SLOT( makeDownVote())); + connect(ui->readButton, SIGNAL(toggled(bool)), this, SLOT(readToggled(bool))); + + QAction *CopyLinkAction = new QAction(QIcon(""),tr("Copy RetroShare Link"), this); + connect(CopyLinkAction, SIGNAL(triggered()), this, SLOT(copyMessageLink())); + + + int S = QFontMetricsF(font()).height() ; + + ui->voteUpButton->setIconSize(QSize(S*1.5,S*1.5)); + ui->voteDownButton->setIconSize(QSize(S*1.5,S*1.5)); + ui->commentButton->setIconSize(QSize(S*1.5,S*1.5)); + ui->readButton->setIconSize(QSize(S*1.5,S*1.5)); + ui->shareButton->setIconSize(QSize(S*1.5,S*1.5)); + + QMenu *menu = new QMenu(); + menu->addAction(CopyLinkAction); + ui->shareButton->setMenu(menu); + + ui->clearButton->hide(); + ui->readAndClearButton->hide(); +} + +bool PostedCardView::setGroup(const RsPostedGroup &group, bool doFill) +{ + if (groupId() != group.mMeta.mGroupId) { + std::cerr << "PostedCardView::setGroup() - Wrong id, cannot set post"; + std::cerr << std::endl; + return false; + } + + mGroup = group; + + if (doFill) { + fill(); + } + + return true; +} + +bool PostedCardView::setPost(const RsPostedPost &post, bool doFill) +{ + if (groupId() != post.mMeta.mGroupId || messageId() != post.mMeta.mMsgId) { + std::cerr << "PostedCardView::setPost() - Wrong id, cannot set post"; + std::cerr << std::endl; + return false; + } + + mPost = post; + + if (doFill) { + fill(); + } + + return true; +} + +void PostedCardView::loadGroup(const uint32_t &token) +{ + std::vector groups; + if (!rsPosted->getGroupData(token, groups)) + { + std::cerr << "PostedCardView::loadGroup() ERROR getting data"; + std::cerr << std::endl; + return; + } + + if (groups.size() != 1) + { + std::cerr << "PostedCardView::loadGroup() Wrong number of Items"; + std::cerr << std::endl; + return; + } + + setGroup(groups[0]); +} + +void PostedCardView::loadMessage(const uint32_t &token) +{ + std::vector posts; + std::vector cmts; + if (!rsPosted->getPostData(token, posts, cmts)) + { + std::cerr << "GxsChannelPostItem::loadMessage() ERROR getting data"; + std::cerr << std::endl; + return; + } + + if (posts.size() == 1) + { + setPost(posts[0]); + } + else if (cmts.size() == 1) + { + RsGxsComment cmt = cmts[0]; + + //ui->newCommentLabel->show(); + //ui->commLabel->show(); + //ui->commLabel->setText(QString::fromUtf8(cmt.mComment.c_str())); + + //Change this item to be uploaded with thread element. + setMessageId(cmt.mMeta.mThreadId); + requestMessage(); + } + else + { + std::cerr << "GxsChannelPostItem::loadMessage() Wrong number of Items. Remove It."; + std::cerr << std::endl; + removeItem(); + return; + } +} + +void PostedCardView::loadComment(const uint32_t &token) +{ + std::vector cmts; + if (!rsPosted->getRelatedComments(token, cmts)) + { + std::cerr << "GxsChannelPostItem::loadComment() ERROR getting data"; + std::cerr << std::endl; + return; + } + + size_t comNb = cmts.size(); + QString sComButText = tr("Comment"); + if (comNb == 1) { + sComButText = sComButText.append("(1)"); + } else if (comNb > 1) { + sComButText = " " + tr("Comments").append(" (%1)").arg(comNb); + } + ui->commentButton->setText(sComButText); +} + +void PostedCardView::fill() +{ + if (isLoading()) { + /* Wait for all requests */ + return; + } + + QPixmap sqpixmap2 = QPixmap(":/images/thumb-default.png"); + + mInFill = true; + int desired_height = 1.5*(ui->voteDownButton->height() + ui->voteUpButton->height() + ui->scoreLabel->height()); + int desired_width = sqpixmap2.width()*desired_height/(float)sqpixmap2.height(); + + QDateTime qtime; + qtime.setTime_t(mPost.mMeta.mPublishTs); + QString timestamp = qtime.toString("hh:mm dd-MMM-yyyy"); + QString timestamp2 = misc::timeRelativeToNow(mPost.mMeta.mPublishTs); + ui->dateLabel->setText(timestamp2); + ui->dateLabel->setToolTip(timestamp); + + ui->fromLabel->setId(mPost.mMeta.mAuthorId); + + // Use QUrl to check/parse our URL + // The only combination that seems to work: load as EncodedUrl, extract toEncoded(). + QByteArray urlarray(mPost.mLink.c_str()); + QUrl url = QUrl::fromEncoded(urlarray.trimmed()); + QString urlstr = "Invalid Link"; + QString sitestr = "Invalid Link"; + + bool urlOkay = url.isValid(); + if (urlOkay) + { + QString scheme = url.scheme(); + if ((scheme != "https") + && (scheme != "http") + && (scheme != "ftp") + && (scheme != "retroshare")) + { + urlOkay = false; + sitestr = "Invalid Link Scheme"; + } + } + + if (urlOkay) + { + urlstr = QString(" "); + urlstr += messageName(); + urlstr += QString(" "); + + QString siteurl = url.toEncoded(); + sitestr = QString(" %2 ").arg(siteurl).arg(siteurl); + + ui->titleLabel->setText(urlstr); + }else + { + ui->titleLabel->setText(messageName()); + + } + + if (urlarray.isEmpty()) + { + ui->siteLabel->hide(); + } + + ui->siteLabel->setText(sitestr); + + if(mPost.mImage.mData != NULL) + { + QPixmap pixmap; + GxsIdDetails::loadPixmapFromData(mPost.mImage.mData, mPost.mImage.mSize, pixmap,GxsIdDetails::ORIGINAL); + // Wiping data - as its been passed to thumbnail. + + QPixmap sqpixmap = pixmap.scaled(desired_width,desired_height, Qt::KeepAspectRatioByExpanding, Qt::SmoothTransformation); + + ui->pictureLabel->setPixmap(pixmap); + } + else if (mPost.mImage.mData == NULL) + { + ui->picture_frame->hide(); + } + else + { + ui->picture_frame->show(); + } + + + //QString score = "Hot" + QString::number(post.mHotScore); + //score += " Top" + QString::number(post.mTopScore); + //score += " New" + QString::number(post.mNewScore); + + QString score = QString::number(mPost.mTopScore); + + ui->scoreLabel->setText(score); + + // FIX THIS UP LATER. + ui->notes->setText(RsHtml().formatText(NULL, QString::fromUtf8(mPost.mNotes.c_str()), RSHTML_FORMATTEXT_EMBED_SMILEYS | RSHTML_FORMATTEXT_EMBED_LINKS)); + + if(ui->notes->text().isEmpty()) + ui->notes->hide(); + // differences between Feed or Top of Comment. + if (mFeedHolder) + { + // feed. + //frame_comment->show(); + ui->commentButton->show(); + + if (mPost.mComments) + { + QString commentText = QString::number(mPost.mComments); + commentText += " "; + commentText += tr("Comments"); + ui->commentButton->setText(commentText); + } + else + { + ui->commentButton->setText(tr("Comment")); + } + + setReadStatus(IS_MSG_NEW(mPost.mMeta.mMsgStatus), IS_MSG_UNREAD(mPost.mMeta.mMsgStatus) || IS_MSG_NEW(mPost.mMeta.mMsgStatus)); + } + else + { + // no feed. + //frame_comment->hide(); + ui->commentButton->hide(); + + ui->readButton->hide(); + ui->newLabel->hide(); + } + + if (mIsHome) + { + ui->clearButton->hide(); + ui->readAndClearButton->hide(); + } + else + { + ui->clearButton->show(); + ui->readAndClearButton->show(); + } + + // disable voting buttons - if they have already voted. + if (mPost.mMeta.mMsgStatus & GXS_SERV::GXS_MSG_STATUS_VOTE_MASK) + { + ui->voteUpButton->setEnabled(false); + ui->voteDownButton->setEnabled(false); + } + +#if 0 + uint32_t up, down, nComments; + + bool ok = rsPosted->retrieveScores(mPost.mMeta.mServiceString, up, down, nComments); + + if(ok) + { + int32_t vote = up - down; + scoreLabel->setText(QString::number(vote)); + + numCommentsLabel->setText("

# Comments: " + + QString::number(nComments) + "

"); + } +#endif + + mInFill = false; + + emit sizeChanged(this); +} + +const RsPostedPost &PostedCardView::getPost() const +{ + return mPost; +} + +RsPostedPost &PostedCardView::post() +{ + return mPost; +} + +QString PostedCardView::groupName() +{ + return QString::fromUtf8(mGroup.mMeta.mGroupName.c_str()); +} + +QString PostedCardView::messageName() +{ + return QString::fromUtf8(mPost.mMeta.mMsgName.c_str()); +} + +void PostedCardView::makeDownVote() +{ + RsGxsGrpMsgIdPair msgId; + msgId.first = mPost.mMeta.mGroupId; + msgId.second = mPost.mMeta.mMsgId; + + ui->voteUpButton->setEnabled(false); + ui->voteDownButton->setEnabled(false); + + emit vote(msgId, false); +} + +void PostedCardView::makeUpVote() +{ + RsGxsGrpMsgIdPair msgId; + msgId.first = mPost.mMeta.mGroupId; + msgId.second = mPost.mMeta.mMsgId; + + ui->voteUpButton->setEnabled(false); + ui->voteDownButton->setEnabled(false); + + emit vote(msgId, true); +} + +void PostedCardView::loadComments() +{ + std::cerr << "PostedCardView::loadComments()"; + std::cerr << std::endl; + + if (mFeedHolder) + { + QString title = QString::fromUtf8(mPost.mMeta.mMsgName.c_str()); + +#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); + } +} + +void PostedCardView::setReadStatus(bool isNew, bool isUnread) +{ + if (isUnread) + { + ui->readButton->setChecked(true); + ui->readButton->setIcon(QIcon(":/images/message-state-unread.png")); + } + else + { + ui->readButton->setChecked(false); + ui->readButton->setIcon(QIcon(":/images/message-state-read.png")); + } + + ui->newLabel->setVisible(isNew); + + ui->mainFrame->setProperty("new", isNew); + ui->mainFrame->style()->unpolish(ui->mainFrame); + ui->mainFrame->style()->polish( ui->mainFrame); +} + +void PostedCardView::readToggled(bool checked) +{ + if (mInFill) { + return; + } + + RsGxsGrpMsgIdPair msgPair = std::make_pair(groupId(), messageId()); + + uint32_t token; + rsPosted->setMessageReadStatus(token, msgPair, !checked); + + setReadStatus(false, checked); +} + +void PostedCardView::readAndClearItem() +{ +#ifdef DEBUG_ITEM + std::cerr << "PostedCardView::readAndClearItem()"; + std::cerr << std::endl; +#endif + + readToggled(false); + removeItem(); +} + + +void PostedCardView::doExpand(bool open) +{ + /*if (open) + { + + } + else + { + + } + + emit sizeChanged(this);*/ + +} + +void PostedCardView::copyMessageLink() +{ + if (groupId().isNull() || mMessageId.isNull()) { + return; + } + + RetroShareLink link = RetroShareLink::createGxsMessageLink(RetroShareLink::TYPE_POSTED, groupId(), mMessageId, messageName()); + + if (link.valid()) { + QList urls; + urls.push_back(link); + RSLinkClipboard::copyLinks(urls); + } +} diff --git a/retroshare-gui/src/gui/Posted/PostedCardView.h b/retroshare-gui/src/gui/Posted/PostedCardView.h new file mode 100644 index 000000000..7cf51f682 --- /dev/null +++ b/retroshare-gui/src/gui/Posted/PostedCardView.h @@ -0,0 +1,96 @@ +/******************************************************************************* + * retroshare-gui/src/gui/Posted/PostedCardView.h * + * * + * Copyright (C) 2019 by Retroshare Team * + * * + * 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 _POSTED_CARDVIEW_H +#define _POSTED_CARDVIEW_H + +#include + +#include +#include "gui/gxs/GxsFeedItem.h" + +namespace Ui { +class PostedCardView; +} + +class FeedHolder; +class RsPostedPost; + +class PostedCardView : public GxsFeedItem +{ + Q_OBJECT + +public: + PostedCardView(FeedHolder *parent, uint32_t feedId, const RsGxsGroupId &groupId, const RsGxsMessageId &messageId, bool isHome, bool autoUpdate); + PostedCardView(FeedHolder *parent, uint32_t feedId, const RsPostedGroup &group, const RsPostedPost &post, bool isHome, bool autoUpdate); + PostedCardView(FeedHolder *parent, uint32_t feedId, const RsPostedPost &post, bool isHome, bool autoUpdate); + virtual ~PostedCardView(); + + bool setGroup(const RsPostedGroup& group, bool doFill = true); + bool setPost(const RsPostedPost& post, bool doFill = true); + + const RsPostedPost &getPost() const; + RsPostedPost &post(); + +protected: + /* FeedItem */ + virtual void doExpand(bool open); + +private slots: + void loadComments(); + void makeUpVote(); + void makeDownVote(); + void readToggled(bool checked); + void readAndClearItem(); + void copyMessageLink(); + +signals: + void vote(const RsGxsGrpMsgIdPair& msgId, bool up); + +protected: + /* GxsGroupFeedItem */ + virtual QString groupName(); + virtual void loadGroup(const uint32_t &token); + virtual RetroShareLink::enumType getLinkType() { return RetroShareLink::TYPE_UNKNOWN; } + + /* GxsFeedItem */ + virtual QString messageName(); + virtual void loadMessage(const uint32_t &token); + virtual void loadComment(const uint32_t &token); + +private: + void setup(); + void fill(); + void setReadStatus(bool isNew, bool isUnread); + +private: + bool mInFill; + + RsPostedGroup mGroup; + RsPostedPost mPost; + RsGxsMessageId mMessageId; + + /** Qt Designer generated object */ + Ui::PostedCardView *ui; +}; + +//Q_DECLARE_METATYPE(RsPostedPost) + +#endif diff --git a/retroshare-gui/src/gui/Posted/PostedCardView.ui b/retroshare-gui/src/gui/Posted/PostedCardView.ui new file mode 100644 index 000000000..125c56d39 --- /dev/null +++ b/retroshare-gui/src/gui/Posted/PostedCardView.ui @@ -0,0 +1,527 @@ + + + PostedCardView + + + + 0 + 0 + 614 + 160 + + + + + + + + + + + 0 + + + 0 + + + 0 + + + 0 + + + 0 + + + + + + 0 + 0 + + + + false + + + QFrame::Box + + + QFrame::Sunken + + + + 0 + + + 0 + + + 0 + + + 2 + + + 0 + + + 6 + + + + + + 0 + 0 + + + + + Arial + 10 + 75 + true + + + + This is a very very very very loooooooooooooooonnnnnnnnnnnnnnnnng title don't you think? Yes it is and should wrap around I hope + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignTop + + + true + + + true + + + Qt::LinksAccessibleByMouse|Qt::TextSelectableByMouse + + + + + + + + 0 + 0 + + + + site + + + true + + + + + + + 5 + + + 0 + + + 6 + + + + + + 0 + 0 + + + + + 50 + false + + + + Posted by + + + + + + + + 0 + 0 + + + + Signed by + + + true + + + + + + + + 0 + 0 + + + + You eyes only + + + true + + + + + + + + 24 + 16777215 + + + + Qt::NoFocus + + + Toggle Message Read Status + + + + :/images/message-state-unread.png:/images/message-state-unread.png + + + true + + + false + + + true + + + + + + + New + + + + + + + Qt::Horizontal + + + QSizePolicy::Expanding + + + + 70 + 20 + + + + + + + + + + + 37 + 0 + + + + + + + QFrame::NoFrame + + + QFrame::Plain + + + + 0 + + + 3 + + + 3 + + + 3 + + + 3 + + + + + + 0 + 0 + + + + Vote up + + + + + + + :/images/up-arrow.png:/images/up-arrow.png + + + true + + + + + + + + 9 + + + + 0 + + + Qt::AlignCenter + + + + + + + + 0 + 0 + + + + + 0 + 0 + + + + Vote down + + + + + + \/ + + + + :/images/down-arrow.png:/images/down-arrow.png + + + true + + + + + + + Qt::Vertical + + + QSizePolicy::Expanding + + + + 20 + 5 + + + + + + + + + + + + + Comments + + + + :/images/comments.png:/images/comments.png + + + Qt::ToolButtonTextBesideIcon + + + true + + + + + + + Share + + + + :/images/share.png:/images/share.png + + + true + + + + + + + Qt::Horizontal + + + + 308 + 20 + + + + + + + + + 24 + 16777215 + + + + Qt::NoFocus + + + Set as read and remove item + + + + :/icons/png/correct.png:/icons/png/correct.png + + + + + + + + 24 + 16777215 + + + + Qt::NoFocus + + + Remove Item + + + + :/icons/png/exit2.png:/icons/png/exit2.png + + + + + + + + + + + + true + + + true + + + Qt::LinksAccessibleByMouse|Qt::TextSelectableByKeyboard|Qt::TextSelectableByMouse + + + + + + + + + + Qt::Horizontal + + + + 219 + 18 + + + + + + + + PictureLabel + + + true + + + + + + + Qt::Horizontal + + + + 268 + 17 + + + + + + + + + + + + + + + GxsIdLabel + QLabel +
gui/gxs/GxsIdLabel.h
+
+ + StyledLabel + QLabel +
gui/common/StyledLabel.h
+
+
+ + + + + + +
diff --git a/retroshare-gui/src/gui/Posted/PostedItem.cpp b/retroshare-gui/src/gui/Posted/PostedItem.cpp index 5d4e00a93..8907d7261 100644 --- a/retroshare-gui/src/gui/Posted/PostedItem.cpp +++ b/retroshare-gui/src/gui/Posted/PostedItem.cpp @@ -302,6 +302,11 @@ void PostedItem::fill() } + if (urlarray.isEmpty()) + { + ui->siteLabel->hide(); + } + ui->siteLabel->setText(sitestr); if(mPost.mImage.mData != NULL) diff --git a/retroshare-gui/src/gui/Posted/PostedListWidget.cpp b/retroshare-gui/src/gui/Posted/PostedListWidget.cpp index 8a1973457..e918cc03d 100644 --- a/retroshare-gui/src/gui/Posted/PostedListWidget.cpp +++ b/retroshare-gui/src/gui/Posted/PostedListWidget.cpp @@ -19,6 +19,7 @@ *******************************************************************************/ #include +#include #include "PostedListWidget.h" #include "ui_PostedListWidget.h" @@ -26,10 +27,12 @@ #include "gui/gxs/GxsIdDetails.h" #include "PostedCreatePostDialog.h" #include "PostedItem.h" +#include "PostedCardView.h" #include "gui/common/UIStateHelper.h" #include "gui/RetroShareLink.h" #include "util/HandleRichText.h" #include "util/DateTime.h" +#include "gui/settings/rsharesettings.h" #include #include "retroshare/rsgxscircles.h" @@ -39,6 +42,10 @@ #define TOPIC_DEFAULT_IMAGE ":/icons/png/posted.png" +/* View mode */ +#define VIEW_MODE_CLASSIC 1 +#define VIEW_MODE_CARD 2 + /** Constructor */ PostedListWidget::PostedListWidget(const RsGxsGroupId &postedId, QWidget *parent) : GxsMessageFramePostWidget(rsPosted, parent), @@ -61,6 +68,12 @@ PostedListWidget::PostedListWidget(const RsGxsGroupId &postedId, QWidget *parent connect(ui->comboBox, SIGNAL(currentIndexChanged(int)), this, SLOT(getRankings(int))); + QSignalMapper *signalMapper = new QSignalMapper(this); + connect(ui->classicViewButton, SIGNAL(clicked()), signalMapper, SLOT(map())); + connect(ui->cardViewButton, SIGNAL(clicked()), signalMapper, SLOT(map())); + signalMapper->setMapping(ui->classicViewButton, VIEW_MODE_CLASSIC); + signalMapper->setMapping(ui->cardViewButton, VIEW_MODE_CARD); + connect(signalMapper, SIGNAL(mapped(int)), this, SLOT(setViewMode(int))); // default sort method. mSortMethod = RsPosted::HotRankType; @@ -101,17 +114,23 @@ PostedListWidget::~PostedListWidget() delete(ui); } -void PostedListWidget::processSettings(bool /*load*/) +void PostedListWidget::processSettings(bool load) { -// Settings->beginGroup(QString("PostedListWidget")); -// -// if (load) { -// // load settings -// } else { -// // save settings -// } -// -// Settings->endGroup(); + Settings->beginGroup(QString("PostedListWidget")); + + if (load) { + // load settings + + /* View mode */ + setViewMode(Settings->value("viewMode", VIEW_MODE_CLASSIC).toInt()); + } else { + // save settings + + /* View mode */ + Settings->setValue("viewMode", viewMode()); + } + + Settings->endGroup(); } QIcon PostedListWidget::groupIcon() @@ -141,6 +160,13 @@ QScrollArea *PostedListWidget::getScrollArea() return ui->scrollArea; } +// Overloaded from FeedHolder. +/*QScrollArea *PostedListWidget::getScrollArea() +{ + return ui->scrollAreaCardView; +}*/ + + void PostedListWidget::deleteFeedItem(QWidget */*item*/, uint32_t /*type*/) { std::cerr << "PostedListWidget::deleteFeedItem() Nah"; @@ -404,11 +430,23 @@ void PostedListWidget::loadPost(const RsPostedPost &post) PostedItem *item = new PostedItem(this, 0, dummyGroup, post, true, false); connect(item, SIGNAL(vote(RsGxsGrpMsgIdPair,bool)), this, SLOT(submitVote(RsGxsGrpMsgIdPair,bool))); mPosts.insert(post.mMeta.mMsgId, item); - //QLayout *alayout = ui.scrollAreaWidgetContents->layout(); - //alayout->addWidget(item); + mPostItems.push_back(item); } +void PostedListWidget::loadPostCardView(const RsPostedPost &post) +{ + /* Group is not always available because of the TokenQueue */ + RsPostedGroup dummyGroup; + dummyGroup.mMeta.mGroupId = groupId(); + + PostedCardView *cvitem = new PostedCardView(this, 0, dummyGroup, post, true, false); + connect(cvitem, SIGNAL(vote(RsGxsGrpMsgIdPair,bool)), this, SLOT(submitVote(RsGxsGrpMsgIdPair,bool))); + mCVPosts.insert(post.mMeta.mMsgId, cvitem); + + mPostCardView.push_back(cvitem); +} + static bool CmpPIHot(const GxsFeedItem *a, const GxsFeedItem *b) { const PostedItem *aa = dynamic_cast(a); @@ -461,6 +499,58 @@ static bool CmpPINew(const GxsFeedItem *a, const GxsFeedItem *b) return (aa->getPost().mNewScore > bb->getPost().mNewScore); } +static bool CVHot(const GxsFeedItem *a, const GxsFeedItem *b) +{ + const PostedCardView *aa = dynamic_cast(a); + const PostedCardView *bb = dynamic_cast(b); + + if (!aa || !bb) { + return true; + } + + const RsPostedPost &postA = aa->getPost(); + const RsPostedPost &postB = bb->getPost(); + + if (postA.mHotScore == postB.mHotScore) + { + return (postA.mNewScore > postB.mNewScore); + } + + return (postA.mHotScore > postB.mHotScore); +} + +static bool CVTop(const GxsFeedItem *a, const GxsFeedItem *b) +{ + const PostedCardView *aa = dynamic_cast(a); + const PostedCardView *bb = dynamic_cast(b); + + if (!aa || !bb) { + return true; + } + + const RsPostedPost &postA = aa->getPost(); + const RsPostedPost &postB = bb->getPost(); + + if (postA.mTopScore == postB.mTopScore) + { + return (postA.mNewScore > postB.mNewScore); + } + + return (postA.mTopScore > postB.mTopScore); +} + +static bool CVNew(const GxsFeedItem *a, const GxsFeedItem *b) +{ + const PostedCardView *aa = dynamic_cast(a); + const PostedCardView *bb = dynamic_cast(b); + + if (!aa || !bb) { + return true; + } + + return (aa->getPost().mNewScore > bb->getPost().mNewScore); +} + void PostedListWidget::applyRanking() { /* uses current settings to sort posts, then add to layout */ @@ -477,16 +567,19 @@ void PostedListWidget::applyRanking() std::cerr << "PostedListWidget::applyRanking() HOT"; std::cerr << std::endl; qSort(mPostItems.begin(), mPostItems.end(), CmpPIHot); + qSort(mPostCardView.begin(), mPostCardView.end(), CVHot); break; case RsPosted::NewRankType: std::cerr << "PostedListWidget::applyRanking() NEW"; std::cerr << std::endl; qSort(mPostItems.begin(), mPostItems.end(), CmpPINew); + qSort(mPostCardView.begin(), mPostCardView.end(), CVNew); break; case RsPosted::TopRankType: std::cerr << "PostedListWidget::applyRanking() TOP"; std::cerr << std::endl; qSort(mPostItems.begin(), mPostItems.end(), CmpPITop); + qSort(mPostCardView.begin(), mPostCardView.end(), CVTop); break; } mLastSortMethod = mSortMethod; @@ -496,8 +589,11 @@ void PostedListWidget::applyRanking() /* go through list (skipping out-of-date items) to get */ QLayout *alayout = ui->scrollAreaWidgetContents->layout(); + + int counter = 0; time_t min_ts = 0; + foreach (PostedItem *item, mPostItems) { std::cerr << "PostedListWidget::applyRanking() Item: " << item; @@ -534,11 +630,52 @@ void PostedListWidget::applyRanking() ++counter; } + // Card View + QLayout *cviewlayout = ui->scrollAreaWidgetContentsCardView->layout(); + + foreach (PostedCardView *item, mPostCardView) + { + std::cerr << "PostedListWidget::applyRanking() Item: " << item; + std::cerr << std::endl; + + if (item->getPost().mMeta.mPublishTs < min_ts) + { + std::cerr << "\t Skipping OLD"; + std::cerr << std::endl; + item->hide(); + continue; + } + + if (counter >= mPostIndex + mPostShow) + { + std::cerr << "\t END - Counter too high"; + std::cerr << std::endl; + item->hide(); + } + else if (counter >= mPostIndex) + { + std::cerr << "\t Adding to Layout"; + std::cerr << std::endl; + /* add it in! */ + cviewlayout->addWidget(item); + item->show(); + } + else + { + std::cerr << "\t Skipping to Low"; + std::cerr << std::endl; + item->hide(); + } + ++counter; + } + std::cerr << "PostedListWidget::applyRanking() Loaded New Order"; std::cerr << std::endl; // trigger a redraw. ui->scrollAreaWidgetContents->update(); + ui->scrollAreaWidgetContentsCardView->update(); + } void PostedListWidget::blank() @@ -548,10 +685,17 @@ void PostedListWidget::blank() } void PostedListWidget::clearPosts() { - /* clear all messages */ + /* clear all classic view messages */ foreach (PostedItem *item, mPostItems) { delete(item); } + + /* clear all card view messages */ + foreach (PostedCardView *item, mPostCardView) { + delete(item); + } + + mPostCardView.clear(); mPostItems.clear(); mPosts.clear(); } @@ -601,6 +745,45 @@ void PostedListWidget::shallowClearPosts() PostedItem *item = *pit; alayout->removeWidget(item); } + + + //Posted Card view + + std::list postedCardViewItems; + std::list::iterator pcvit; + + QLayout *cviewlayout = ui->scrollAreaWidgetContentsCardView->layout(); + int countcv = cviewlayout->count(); + for(int i = 0; i < countcv; ++i) + { + QLayoutItem *litem = cviewlayout->itemAt(i); + if (!litem) + { + std::cerr << "PostedListWidget::shallowClearPosts() missing litem"; + std::cerr << std::endl; + continue; + } + + PostedCardView *item = dynamic_cast(litem->widget()); + if (item) + { + std::cerr << "PostedListWidget::shallowClearPosts() item: " << item; + std::cerr << std::endl; + + postedCardViewItems.push_back(item); + } + else + { + std::cerr << "PostedListWidget::shallowClearPosts() Found Child, which is not a PostedItem???"; + std::cerr << std::endl; + } + } + + for(pcvit = postedCardViewItems.begin(); pcvit != postedCardViewItems.end(); ++pcvit) + { + PostedCardView *item = *pcvit; + cviewlayout->removeWidget(item); + } } bool PostedListWidget::insertGroupData(const uint32_t &token, RsGroupMetaData &metaData) @@ -628,6 +811,7 @@ void PostedListWidget::insertAllPosts(const uint32_t &token, GxsMessageFramePost { RsPostedPost& p = *vit; loadPost(p); + loadPostCardView(p); } applyRanking(); @@ -721,3 +905,39 @@ void PostedListWidget::loadRequest(const TokenQueue *queue, const TokenRequest & GxsMessageFramePostWidget::loadRequest(queue, req); } + +int PostedListWidget::viewMode() +{ + if (ui->classicViewButton->isChecked()) { + return VIEW_MODE_CLASSIC; + } else if (ui->cardViewButton->isChecked()) { + return VIEW_MODE_CARD; + } + + /* Default */ + return VIEW_MODE_CLASSIC; +} + +void PostedListWidget::setViewMode(int viewMode) +{ + switch (viewMode) { + case VIEW_MODE_CLASSIC: + ui->stackedWidget->setCurrentIndex(0); + + + ui->classicViewButton->setChecked(true); + ui->cardViewButton->setChecked(false); + + break; + case VIEW_MODE_CARD: + ui->stackedWidget->setCurrentIndex(1); + + ui->cardViewButton->setChecked(true); + ui->classicViewButton->setChecked(false); + + break; + default: + setViewMode(VIEW_MODE_CLASSIC); + return; + } +} diff --git a/retroshare-gui/src/gui/Posted/PostedListWidget.h b/retroshare-gui/src/gui/Posted/PostedListWidget.h index 8184a444c..ddd726513 100644 --- a/retroshare-gui/src/gui/Posted/PostedListWidget.h +++ b/retroshare-gui/src/gui/Posted/PostedListWidget.h @@ -29,6 +29,7 @@ class RsPostedGroup; class RsPostedPost; class PostedItem; +class PostedCardView; namespace Ui { class PostedListWidget; @@ -79,16 +80,21 @@ private slots: void showNext(); void showPrev(); + void setViewMode(int viewMode); + private: void processSettings(bool load); void updateShowText(); + int viewMode(); + /*! * Only removes it from layout */ void shallowClearPosts(); void loadPost(const RsPostedPost &post); + void loadPostCardView(const RsPostedPost &post); void insertPostedDetails(const RsPostedGroup &group); @@ -115,6 +121,9 @@ private: QMap mPosts; QList mPostItems; + QMap mCVPosts; + QList mPostCardView; + /* UI - from Designer */ Ui::PostedListWidget *ui; }; diff --git a/retroshare-gui/src/gui/Posted/PostedListWidget.ui b/retroshare-gui/src/gui/Posted/PostedListWidget.ui index cb9b906ef..304a79c76 100644 --- a/retroshare-gui/src/gui/Posted/PostedListWidget.ui +++ b/retroshare-gui/src/gui/Posted/PostedListWidget.ui @@ -7,16 +7,13 @@ 0 0 616 - 428 + 595 Form - - - 3 - + 0 @@ -29,7 +26,10 @@ 0 - + + 0 + + QFrame::Box @@ -37,12 +37,9 @@ QFrame::Sunken - - - 6 - + - 4 + 6 2 @@ -164,6 +161,59 @@ + + + + 0 + + + + + Classic view + + + + :/images/classic.png:/images/classic.png + + + + 24 + 24 + + + + true + + + true + + + + + + + Card View + + + + :/images/card.png:/images/card.png + + + + 24 + 24 + + + + true + + + true + + + + + @@ -205,7 +255,7 @@ - + QFrame::StyledPanel @@ -478,30 +528,13 @@ p, li { white-space: pre-wrap; } - - - - true + + + + 1 - - - - 0 - 0 - 614 - 16 - - - - - 0 - 0 - - - - - 0 - + + 0 @@ -514,6 +547,102 @@ p, li { white-space: pre-wrap; } 0 + + + + true + + + + + 0 + 0 + 614 + 16 + + + + + 0 + 0 + + + + + 0 + + + 0 + + + 0 + + + 0 + + + 0 + + + + + + + + + + + 0 + + + 0 + + + 0 + + + 0 + + + + + true + + + + + 0 + 0 + 614 + 16 + + + + + 0 + 0 + + + + + 0 + + + 0 + + + 0 + + + 0 + + + 0 + + + + + diff --git a/retroshare-gui/src/gui/Posted/Posted_images.qrc b/retroshare-gui/src/gui/Posted/Posted_images.qrc index 8c713b53f..2a1a10d0c 100644 --- a/retroshare-gui/src/gui/Posted/Posted_images.qrc +++ b/retroshare-gui/src/gui/Posted/Posted_images.qrc @@ -1,6 +1,6 @@ - images/posted_16.png + images/posted_16.png images/posted_24.png images/posted_32.png images/posted_48.png @@ -23,5 +23,9 @@ images/link.png images/post.png images/photo.png + images/classic.png + images/card.png + images/down-hover.png + images/up-hover.png diff --git a/retroshare-gui/src/gui/Posted/images/card.png b/retroshare-gui/src/gui/Posted/images/card.png new file mode 100644 index 0000000000000000000000000000000000000000..47cc72d0aebe2905a7b9a6f12524a854f7989337 GIT binary patch literal 2257 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 uT(nXx4Jcq(#rqfY8#Dy~ literal 0 HcmV?d00001 diff --git a/retroshare-gui/src/gui/Posted/images/notes.png b/retroshare-gui/src/gui/Posted/images/notes.png index a73a039685015b38071a49b50d19fa42355ee9d6..800eec4925c9836d8c30bc89dab6e31d2e500287 100644 GIT binary patch literal 2227 zcmb7`c{J2}AIHBKd$P4yB2BVn2_v#xUG=kO2_*&-$=DKxAwu)yUdO#sc`}OVe^FU{bvF+E zXqmx&cK)IF5!2f$u8$2QD^+?TPM?%tOZV2-(yWb*OdpO9ol8(9j^#22J6otV!M~c9 zJJL+A1xsffe39!|Rpgj%tB|#SqRif4WB6E8d%_%U-CDo6mAL)fgShG%G??Yt#H1lgYf?T)fENF@v{7 z_1Y821_k}@Ej7kAHeDfsfq^XNe$r;IGX>KWkcF&!W>e6g)m*(6LGj$Y-mU`J{GC(s z27LZIB|O>gTyj zAWul6JeAQgGyQ_34E=WH$%ZV8cUZdHNJ&+d??ps;KeQzI*Sxbq9>0$YoV_Eo1k24V zgtvWG1K(#b&sjIg<`%}r9*%xGSa4h8eNBFH2I+MEvyA!oDsaoj#>UmmyP47fIPPhFOSy#Lpyn861f=c<>j@hc~3!< zhMmMh>mu<%a~|tGgC9P8*mly=l=}6FPlq(EnSfN-PH?aD_B)&yGwezWkfe)%LJQ30 zBN4<=ON@H~zWim+htP1pql1yL0f}nkrNM-DPClBm<4hTuYE2IoFGDp%JM`^tJ6G3v z1ea%P;dP#h;baq94+SaN|8s4MVt&Jp;;H-fRoLgAo}Tt`nZlBii9PJcc*}lxx!>pP zEH#|bolGED1OI_+7iOgR zKJhseVQwFps!=W*VOAV9_V$_?$G#8I%;<5dd=gtSK(|AJGb`X`Zl?M1=qOi=~5y}ax%h96@ zhSfD_ms<&?nApl_l`A3_E5MEmG$y3Zr2ZK)(~v*A{9l`M-p665$|XHv?}?8R_@s4a*Fmsb%@&GJ!DK zcr8CXM_7rMb86E5u1$cWG=z)$@|b;1 zV5`mFa2K(tl}x~sU$x!wt`se+F|RYp8y&A23qt~%LonON((n`eopmb=>x~V79XhRy z8Ky+NH{vQN;=tLwT7Fo_v`}qDDNkjS=SkAN;aj z>>+4>i&X#JFJHc((Ovre>OTgm0Jz~U2lL3uT_#B%G)zI%U_*PG0FK1rS#z?}>Z#1I zTAABr_R!_8bIGoO(?RTy_<4se4lA>_;dkD;H9$0wN=sQ%>~E-g`USxQl}A2EOYVD< zv%r7Z>WZ5`@o(1u0RLaaT^Q}Lw3hcjd{`701>BgI8T{!Qvc&d@2#s;eos~J?!krtU zC%?G6CAtyShk|xHr`uMFW5r(Xr3uEyP@~lK4`>2?dM{B8jA2=(%gx`lCWB#!dI+gR5tz6>Zbg)5V3Xi{r`j z7Gg%GCMFom*AIJyl+@KxVP?gpA~DAo{F#U&xOTn!&P!3dcGV5UlEOkA)8YYfu;l7@ zHoo^(zGq88|IDMeE-M?uK119D`8-*6hFc^7IsmK%{qwMzS{8OR+9Ke&SrMrk)xeU= z_*4hQE8+%#8Mfk?PY;6&t(&9ML}`kfDLb#z#btM_7Q6nQ%YsaabL%t1-~C)F)lBfg O08VypQ2m*}+y4S+ED(GE delta 1697 zcmZuxdo8xu!$y; zc1)@9$Rsp_r5f*2gji098Af3$OFR2GyJtK5&pqdJ?z#7T&gb*Fw`$#tMz)Qb5d?q{ zgg6k;GJes;6jF|GbF%k2Qz#ie80q7yt0MhKpY=%j!X4`+(ACgS?{PX3fu;W1lteAQ zm?Uh;_(A`InuUka6WoEQ&0$v# zPeS>Ih)c0u_@cKfIXlae=9YU`V>^qUTne;P-JGc9pbGs_t(ZB6#>B?C+f!5Ga|x-H zx1NTSkdx!jc1;zCOeh$b$KyrfQ!^1~d&K?U1zgxQ6#=|c!zUHGJ4E8BIr$YnZE&}K&X-}_;v$=47%6D-@QQMJcz{j zvI6G~_(U8(H7Xw{27ga~JJC_hNv;}bH&r*-*SBkDKrMUo9<8!*=WbEh_}8K zkvLM7PrAh=5pKxT;jMMkE9Cn@3g*VC3(vN8EQ-7DBED`PL3Z;!r4|gRMjR5V=IU^O z{qdHMJ|mBL=qG;F^`lO*THAqst@XJMDMMRETt%1is1DU!1127O8t1uzE8neCAM6o6lx9n7<7vqb@ zPikNHmThU8cysC8Utf=V1jsVdQj6fLc{wWm);dHgcy2n6~ILyOtKQRyN8E|;U-q; zWJD!Zsh_kh|En->&h4@ND5Aqpk7)53QVlHbGyK6^1_C@oP6rPWgl^IVRpa}!W?>^b z#_2hqXwlhvgSjWz5c0dqaixkULCXRb-lX3Cpq8xBZsYoEWXn@WLF@aEDSEl?^91#$ z`A^jz?&j`<$-Nf$HJ>TL%wfm(jXAaBy>|@K7xWq7Lh4wTy_Xwp%?QGM zc6Jp$;yZUolp~`1xeb=fhX6 z+e58=wJ5A>qnJRZhFsMtf;Z_v)u zgQbv4k0)oq(vcEU64YB|DNo@9ulU>?v$QQ$ZI4XH?Am3pKYPI(P6`CtJGi!u^*+tb z&4#c?Z>;6vTBO#UhOf&D4@ol#B$_B%aA*BniGkNX_-u~hUv$=#G_2cV1D)+%Un$YF zkf*uH{FBRo#v{+^pJArnw{m4@hiem+=uBRg-B+yxZQm^^!Ev;!59Yp6DC%UnUyF8W zA?r_t?ZDK+H#sg$A?a>qw36}TjiPIlhv%s+aXPv^@vs`Nk8C1V19x(S%VW06QCwN! z&~8jE2+97B0RIB$Q*Hig>BZqeQh5{U9WRX}IgVpxF4kOhL1MAlHX5VVX{4hk#xwI2~xBs&Y-l8^JkT;I8|kQ9fgt4@#p2w{?CuU cIgbs2Q*~`8I`KIUKn(!k=1g>|a0pKL9r;WWVE_OC diff --git a/retroshare-gui/src/gui/Posted/images/up-arrow.png b/retroshare-gui/src/gui/Posted/images/up-arrow.png index 728ccf06831c0b198216e764ae1c945379cb695c..7f276af8f19d77442672c5704e91618fcf57b70f 100644 GIT binary patch delta 2557 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 G$o~M4rsX&u00~a3y8)-vBP*7-ZbZ>KLZ*U+Wt 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 Oa=?e+@6~dg&iV`CYdLTL literal 0 HcmV?d00001 diff --git a/retroshare-gui/src/gui/qss/stylesheet/Standard.qss b/retroshare-gui/src/gui/qss/stylesheet/Standard.qss index 282f4917f..4abbd0eff 100644 --- a/retroshare-gui/src/gui/qss/stylesheet/Standard.qss +++ b/retroshare-gui/src/gui/qss/stylesheet/Standard.qss @@ -857,6 +857,10 @@ PostedItem QLabel#fromBoldLabel, QLabel#fromLabel, QLabel#dateLabel, QLabel#site color: #787c7e; } +PostedCardView QFrame#voteFrame { + background: #f8f9fa; +} + GxsCommentDialog QComboBox#sortBox { font: bold; color: #0099cc; diff --git a/retroshare-gui/src/retroshare-gui.pro b/retroshare-gui/src/retroshare-gui.pro index 188bd9546..67540cc3a 100644 --- a/retroshare-gui/src/retroshare-gui.pro +++ b/retroshare-gui/src/retroshare-gui.pro @@ -1344,6 +1344,7 @@ posted { HEADERS += gui/Posted/PostedDialog.h \ gui/Posted/PostedListWidget.h \ gui/Posted/PostedItem.h \ + gui/Posted/PostedCardView.h \ gui/Posted/PostedGroupDialog.h \ gui/feeds/PostedGroupItem.h \ gui/Posted/PostedCreatePostDialog.h \ @@ -1355,6 +1356,7 @@ posted { FORMS += gui/Posted/PostedListWidget.ui \ gui/feeds/PostedGroupItem.ui \ gui/Posted/PostedItem.ui \ + gui/Posted/PostedCardView.ui \ gui/Posted/PostedCreatePostDialog.ui \ #gui/Posted/PostedDialog.ui \ @@ -1365,6 +1367,7 @@ posted { gui/Posted/PostedListWidget.cpp \ gui/feeds/PostedGroupItem.cpp \ gui/Posted/PostedItem.cpp \ + gui/Posted/PostedCardView.cpp \ gui/Posted/PostedGroupDialog.cpp \ gui/Posted/PostedCreatePostDialog.cpp \ gui/Posted/PostedUserNotify.cpp From f99224e1c0123b3bacf9a73a1a401dbcec80cae9 Mon Sep 17 00:00:00 2001 From: defnax Date: Fri, 27 Dec 2019 19:53:06 +0100 Subject: [PATCH 02/44] fixed loading issue for card view --- retroshare-gui/src/gui/Posted/PostedListWidget.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/retroshare-gui/src/gui/Posted/PostedListWidget.cpp b/retroshare-gui/src/gui/Posted/PostedListWidget.cpp index e918cc03d..20a94d5d2 100644 --- a/retroshare-gui/src/gui/Posted/PostedListWidget.cpp +++ b/retroshare-gui/src/gui/Posted/PostedListWidget.cpp @@ -37,7 +37,7 @@ #include #include "retroshare/rsgxscircles.h" -#define POSTED_DEFAULT_LISTING_LENGTH 10 +#define POSTED_DEFAULT_LISTING_LENGTH 30 #define POSTED_MAX_INDEX 10000 #define TOPIC_DEFAULT_IMAGE ":/icons/png/posted.png" @@ -841,6 +841,7 @@ void PostedListWidget::insertPosts(const uint32_t &token) std::cerr << std::endl; /* insert new entry */ loadPost(p); + loadPostCardView(p); } } From 76f803316e64281cb0f7a48dddc3c50c3d314648 Mon Sep 17 00:00:00 2001 From: hunbernd Date: Sat, 28 Dec 2019 18:51:22 +0100 Subject: [PATCH 03/44] Really fixed loading issue for card view --- retroshare-gui/src/gui/Posted/PostedListWidget.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/retroshare-gui/src/gui/Posted/PostedListWidget.cpp b/retroshare-gui/src/gui/Posted/PostedListWidget.cpp index 20a94d5d2..177d1fad8 100644 --- a/retroshare-gui/src/gui/Posted/PostedListWidget.cpp +++ b/retroshare-gui/src/gui/Posted/PostedListWidget.cpp @@ -37,7 +37,7 @@ #include #include "retroshare/rsgxscircles.h" -#define POSTED_DEFAULT_LISTING_LENGTH 30 +#define POSTED_DEFAULT_LISTING_LENGTH 10 #define POSTED_MAX_INDEX 10000 #define TOPIC_DEFAULT_IMAGE ":/icons/png/posted.png" @@ -631,6 +631,7 @@ void PostedListWidget::applyRanking() } // Card View + counter = 0; QLayout *cviewlayout = ui->scrollAreaWidgetContentsCardView->layout(); foreach (PostedCardView *item, mPostCardView) From fc9ce4fddd5de8f14b8cb9e539251761d14e99ac Mon Sep 17 00:00:00 2001 From: hunbernd Date: Sat, 28 Dec 2019 22:21:24 +0100 Subject: [PATCH 04/44] Image optimizer can output byte array --- retroshare-gui/src/util/HandleRichText.cpp | 2 +- retroshare-gui/src/util/imageutil.cpp | 50 ++++++++++++---------- retroshare-gui/src/util/imageutil.h | 6 ++- 3 files changed, 33 insertions(+), 25 deletions(-) diff --git a/retroshare-gui/src/util/HandleRichText.cpp b/retroshare-gui/src/util/HandleRichText.cpp index 7818c984d..c500a6bb9 100644 --- a/retroshare-gui/src/util/HandleRichText.cpp +++ b/retroshare-gui/src/util/HandleRichText.cpp @@ -1185,7 +1185,7 @@ bool RsHtml::makeEmbeddedImage(const QImage &originalImage, QString &embeddedIma { rstime::RsScopeTimer s("Embed image"); QImage opt; - return ImageUtil::optimizeSize(embeddedImage, originalImage, opt, maxPixels, maxBytes); + return ImageUtil::optimizeSizeHtml(embeddedImage, originalImage, opt, maxPixels, maxBytes); } QString RsHtml::plainText(const QString &text) diff --git a/retroshare-gui/src/util/imageutil.cpp b/retroshare-gui/src/util/imageutil.cpp index 648fe392c..7ca920e84 100644 --- a/retroshare-gui/src/util/imageutil.cpp +++ b/retroshare-gui/src/util/imageutil.cpp @@ -68,12 +68,12 @@ void ImageUtil::extractImage(QWidget *window, QTextCursor cursor) } } -bool ImageUtil::optimizeSize(QString &html, const QImage& original, QImage &optimized, int maxPixels, int maxBytes) +bool ImageUtil::optimizeSizeBytes(QByteArray &bytearray, const QImage &original, QImage &optimized, int maxPixels, int maxBytes) { //nothing to do if it fits into the limits optimized = original; if ((maxPixels <= 0) || (optimized.width()*optimized.height() <= maxPixels)) { - if(checkSize(html, optimized, maxBytes) <= maxBytes) { + if(checkSize(bytearray, optimized) <= maxBytes) { return true; } } @@ -94,14 +94,14 @@ bool ImageUtil::optimizeSize(QString &html, const QImage& original, QImage &opti //if maxBytes not defined, do not reduce color space, just downscale if(maxBytes <= 0) { - checkSize(html, optimized = original.scaledToWidth(maxwidth, Qt::SmoothTransformation), maxBytes); + checkSize(bytearray, optimized = original.scaledToWidth(maxwidth, Qt::SmoothTransformation)); return true; } //Use binary search to find a suitable image size + linear regression to guess the file size - double maxsize = (double)checkSize(html, optimized = original.scaledToWidth(maxwidth, Qt::SmoothTransformation).convertToFormat(QImage::Format_Indexed8, ct, Qt::ThresholdDither), maxBytes); + double maxsize = (double)checkSize(bytearray, optimized = original.scaledToWidth(maxwidth, Qt::SmoothTransformation).convertToFormat(QImage::Format_Indexed8, ct, Qt::ThresholdDither)); if(maxsize <= maxBytes) return true; //success - double minsize = (double)checkSize(html, optimized = original.scaledToWidth(minwidth, Qt::SmoothTransformation).convertToFormat(QImage::Format_Indexed8, ct, Qt::ThresholdDither), maxBytes); + double minsize = (double)checkSize(bytearray, optimized = original.scaledToWidth(minwidth, Qt::SmoothTransformation).convertToFormat(QImage::Format_Indexed8, ct, Qt::ThresholdDither)); if(minsize > maxBytes) return false; //impossible // std::cout << "maxS: " << maxsize << " minS: " << minsize << std::endl; @@ -114,7 +114,7 @@ bool ImageUtil::optimizeSize(QString &html, const QImage& original, QImage &opti double b = maxsize - m * ((double)maxwidth * (double)maxwidth / whratio); double a = ((double)(maxBytes - region/2) - b) / m; //maxBytes - region/2 target the center of the accepted region int nextwidth = (int)sqrt(a * whratio); - int nextsize = checkSize(html, optimized = original.scaledToWidth(nextwidth, Qt::SmoothTransformation).convertToFormat(QImage::Format_Indexed8, ct, Qt::ThresholdDither), maxBytes); + int nextsize = checkSize(bytearray, optimized = original.scaledToWidth(nextwidth, Qt::SmoothTransformation).convertToFormat(QImage::Format_Indexed8, ct, Qt::ThresholdDither)); if(nextsize <= maxBytes) { minsize = nextsize; minwidth = nextwidth; @@ -136,34 +136,40 @@ bool ImageUtil::optimizeSize(QString &html, const QImage& original, QImage &opti //std::cout << html.toStdString() << std::endl; } -int ImageUtil::checkSize(QString &embeddedImage, const QImage &img, int maxBytes) +bool ImageUtil::optimizeSizeHtml(QString &html, const QImage& original, QImage &optimized, int maxPixels, int maxBytes) +{ + QByteArray bytearray; + if(maxBytes > 0){ + maxBytes = maxBytes * 3/4 - 50; //base64 and html stuff + } + + if(optimizeSizeBytes(bytearray, original, optimized, maxPixels, maxBytes)) + { + QByteArray encodedByteArray = bytearray.toBase64(); + html = ""); + return true; + } + return false; +} + +int ImageUtil::checkSize(QByteArray &bytearray, const QImage &img) { rstime::RsScopeTimer st("Check size"); - QByteArray bytearray; + bytearray.clear(); QBuffer buffer(&bytearray); int size = 0; //std::cout << QString("Trying image: format PNG, size %1x%2, colors %3\n").arg(img.width()).arg(img.height()).arg(img.colorCount()).toStdString(); if (buffer.open(QIODevice::WriteOnly)) { if (img.save(&buffer, "PNG", 0)) { - size = bytearray.length() * 4/3; - if((maxBytes > 0) && (size > maxBytes)) // *4/3 for base64 - { - //std::cout << QString("\tToo large, size: %1, limit: %2 bytes\n").arg(bytearray.length() * 4/3).arg(maxBytes).toStdString(); - }else{ - //std::cout << QString("\tOK, size: %1, limit: %2 bytes\n").arg(bytearray.length() * 4/3).arg(maxBytes).toStdString(); - QByteArray encodedByteArray = bytearray.toBase64(); - //embeddedImage = ""); - } + size = bytearray.length(); } else { std::cerr << "ImageUtil: image can't be saved to buffer" << std::endl; } - buffer.close(); - bytearray.clear(); + buffer.close(); } else { std::cerr << "ImageUtil: buffer can't be opened" << std::endl; } diff --git a/retroshare-gui/src/util/imageutil.h b/retroshare-gui/src/util/imageutil.h index dfea67282..4af33d1c5 100644 --- a/retroshare-gui/src/util/imageutil.h +++ b/retroshare-gui/src/util/imageutil.h @@ -23,6 +23,7 @@ #include #include +#include #include class ImageUtil @@ -31,10 +32,11 @@ public: ImageUtil(); static void extractImage(QWidget *window, QTextCursor cursor); - static bool optimizeSize(QString &html, const QImage& original, QImage &optimized, int maxPixels = -1, int maxBytes = -1); + static bool optimizeSizeHtml(QString &html, const QImage& original, QImage &optimized, int maxPixels = -1, int maxBytes = -1); + static bool optimizeSizeBytes(QByteArray &bytearray, const QImage& original, QImage &optimized, int maxPixels = -1, int maxBytes = -1); private: - static int checkSize(QString& embeddedImage, const QImage& img, int maxBytes = -1); + static int checkSize(QByteArray& embeddedImage, const QImage& img); static void quantization(const QImage& img, QVector& palette); static void quantization(QList::iterator begin, QList::iterator end, int depth, QVector& palette); static void avgbucket(QList::iterator begin, QList::iterator end, QVector& palette); From 419a9a520c0665ac23fdbfe6d5895c7f4e0c416b Mon Sep 17 00:00:00 2001 From: hunbernd Date: Sun, 29 Dec 2019 14:19:19 +0100 Subject: [PATCH 05/44] Removed redundant title inputbox --- .../src/gui/Posted/PostedCreatePostDialog.cpp | 11 +-- .../src/gui/Posted/PostedCreatePostDialog.ui | 78 +++++++++---------- 2 files changed, 41 insertions(+), 48 deletions(-) diff --git a/retroshare-gui/src/gui/Posted/PostedCreatePostDialog.cpp b/retroshare-gui/src/gui/Posted/PostedCreatePostDialog.cpp index c822bb492..9fd400d3c 100644 --- a/retroshare-gui/src/gui/Posted/PostedCreatePostDialog.cpp +++ b/retroshare-gui/src/gui/Posted/PostedCreatePostDialog.cpp @@ -90,14 +90,7 @@ void PostedCreatePostDialog::createPost() post.mNotes = std::string(text.toUtf8()); post.mMeta.mAuthorId = authorId; - - if(!ui->titleEdit->text().isEmpty()) - { - post.mMeta.mMsgName = std::string(ui->titleEdit->text().toUtf8()); - }else - { - post.mMeta.mMsgName = std::string(ui->titleEditLink->text().toUtf8()); - } + post.mMeta.mMsgName = std::string(ui->titleEdit->text().toUtf8()); QByteArray ba; QBuffer buffer(&ba); @@ -111,7 +104,7 @@ void PostedCreatePostDialog::createPost() post.mImage.copy((uint8_t *) ba.data(), ba.size()); } - if(ui->titleEdit->text().isEmpty()&& ui->titleEditLink->text().isEmpty()) { + if(ui->titleEdit->text().isEmpty()) { /* error message */ QMessageBox::warning(this, "RetroShare", tr("Please add a Title"), QMessageBox::Ok, QMessageBox::Ok); return; //Don't add a empty title!! diff --git a/retroshare-gui/src/gui/Posted/PostedCreatePostDialog.ui b/retroshare-gui/src/gui/Posted/PostedCreatePostDialog.ui index d64c3ad01..dcfa504a2 100644 --- a/retroshare-gui/src/gui/Posted/PostedCreatePostDialog.ui +++ b/retroshare-gui/src/gui/Posted/PostedCreatePostDialog.ui @@ -128,6 +128,22 @@ + + + + Qt::Horizontal + + + QSizePolicy::Expanding + + + + 40 + 20 + + + + @@ -199,7 +215,7 @@ - + @@ -226,23 +242,7 @@ - - - - Qt::Horizontal - - - QSizePolicy::Expanding - - - - 40 - 20 - - - - - + @@ -258,7 +258,7 @@ - + 0 @@ -277,16 +277,9 @@ 0 - + - - - - Title - - - @@ -397,14 +390,14 @@ 0 - + Url - + Qt::Vertical @@ -417,18 +410,11 @@ - - - - Title - - - - + @@ -444,6 +430,22 @@ + + + + + 0 + 0 + + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter + + + Title + + + @@ -475,8 +477,6 @@ - - From 9381b744aabdbaecfa2b4fe2cba9ec0e65007002 Mon Sep 17 00:00:00 2001 From: hunbernd Date: Sun, 29 Dec 2019 16:14:31 +0100 Subject: [PATCH 06/44] Auto resize image to fit into 34kB --- .../src/gui/Posted/PostedCreatePostDialog.cpp | 39 ++++++++++++------- .../src/gui/Posted/PostedCreatePostDialog.h | 4 +- 2 files changed, 27 insertions(+), 16 deletions(-) diff --git a/retroshare-gui/src/gui/Posted/PostedCreatePostDialog.cpp b/retroshare-gui/src/gui/Posted/PostedCreatePostDialog.cpp index 9fd400d3c..9d188c75b 100644 --- a/retroshare-gui/src/gui/Posted/PostedCreatePostDialog.cpp +++ b/retroshare-gui/src/gui/Posted/PostedCreatePostDialog.cpp @@ -20,6 +20,7 @@ #include #include +#include #include "PostedCreatePostDialog.h" #include "ui_PostedCreatePostDialog.h" @@ -34,6 +35,8 @@ #include +#include + PostedCreatePostDialog::PostedCreatePostDialog(TokenQueue* tokenQ, RsPosted *posted, const RsGxsGroupId& grpId, QWidget *parent): QDialog(parent, Qt::WindowSystemMenuHint | Qt::WindowTitleHint | Qt::WindowMinimizeButtonHint | Qt::WindowMaximizeButtonHint | Qt::WindowCloseButtonHint), mTokenQueue(tokenQ), mPosted(posted), mGrpId(grpId), @@ -91,17 +94,11 @@ void PostedCreatePostDialog::createPost() post.mMeta.mAuthorId = authorId; post.mMeta.mMsgName = std::string(ui->titleEdit->text().toUtf8()); - - QByteArray ba; - QBuffer buffer(&ba); - if(!picture.isNull()) + if(imagebytes.size() > 0) { // send posted image - - buffer.open(QIODevice::WriteOnly); - picture.save(&buffer, "PNG"); // writes image into ba in PNG format - post.mImage.copy((uint8_t *) ba.data(), ba.size()); + post.mImage.copy((uint8_t *) imagebytes.data(), imagebytes.size()); } if(ui->titleEdit->text().isEmpty()) { @@ -119,15 +116,27 @@ void PostedCreatePostDialog::createPost() void PostedCreatePostDialog::addPicture() { - QPixmap img = misc::getOpenThumbnailedPicture(this, tr("Load thumbnail picture"), 800, 600); + imagefilename = ""; + imagebytes.clear(); - if (img.isNull()) - return; + // select a picture file + if (misc::getOpenFileName(window(), RshareSettings::LASTDIR_IMAGES, tr("Load Picture File"), "Pictures (*.png *.xpm *.jpg *.jpeg *.gif *.webp )", imagefilename)) { + QString encodedImage; + int maxMessageSize = 34000; //34 kB + QImage image; + if (image.load (imagefilename) == false) { + fprintf (stderr, "RsHtml::makeEmbeddedImage() - image \"%s\" can't be load\n", imagefilename.toLatin1().constData()); + return; + } - picture = img; - - // to show the selected - ui->imageLabel->setPixmap(picture); + QImage opt; + if(ImageUtil::optimizeSizeBytes(imagebytes, image, opt, 800*600, maxMessageSize)) { + ui->imageLabel->setPixmap(QPixmap::fromImage(opt)); + } else { + imagefilename = ""; + imagebytes.clear(); + } + } } void PostedCreatePostDialog::on_postButton_clicked() diff --git a/retroshare-gui/src/gui/Posted/PostedCreatePostDialog.h b/retroshare-gui/src/gui/Posted/PostedCreatePostDialog.h index de13358fb..64313608e 100644 --- a/retroshare-gui/src/gui/Posted/PostedCreatePostDialog.h +++ b/retroshare-gui/src/gui/Posted/PostedCreatePostDialog.h @@ -43,7 +43,9 @@ public: explicit PostedCreatePostDialog(TokenQueue* tokenQ, RsPosted* posted, const RsGxsGroupId& grpId, QWidget *parent = 0); ~PostedCreatePostDialog(); - QPixmap picture; +private: + QString imagefilename; + QByteArray imagebytes; private slots: void createPost(); From d49443caf34dca0bb451014e350bdb03a3d4b8a4 Mon Sep 17 00:00:00 2001 From: hunbernd Date: Mon, 30 Dec 2019 00:04:36 +0100 Subject: [PATCH 07/44] Fixed bug preventing hashing files from file paths with special characters --- libretroshare/src/util/rsdir.cc | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/libretroshare/src/util/rsdir.cc b/libretroshare/src/util/rsdir.cc index a890ed8f1..1b794f982 100644 --- a/libretroshare/src/util/rsdir.cc +++ b/libretroshare/src/util/rsdir.cc @@ -254,7 +254,13 @@ int RsDirUtil::breakupDirList(const std::string& path, /**** Copied and Tweaked from ftcontroller ***/ bool RsDirUtil::fileExists(const std::string& filename) { +#ifdef WINDOWS_SYS + std::wstring wfilename; + librs::util::ConvertUtf8ToUtf16(filename, wfilename); + return ( _waccess( wfilename.c_str(), F_OK ) != -1 ); +#else return ( access( filename.c_str(), F_OK ) != -1 ); +#endif } bool RsDirUtil::moveFile(const std::string& source,const std::string& dest) From 8a0eb9705f828d1bd8c01476da9f57d12fe77908 Mon Sep 17 00:00:00 2001 From: defnax Date: Mon, 30 Dec 2019 20:48:04 +0100 Subject: [PATCH 08/44] Fixed Card View display by anmo --- retroshare-gui/src/gui/Posted/PostedListWidget.cpp | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/retroshare-gui/src/gui/Posted/PostedListWidget.cpp b/retroshare-gui/src/gui/Posted/PostedListWidget.cpp index 20a94d5d2..a25c4a4cf 100644 --- a/retroshare-gui/src/gui/Posted/PostedListWidget.cpp +++ b/retroshare-gui/src/gui/Posted/PostedListWidget.cpp @@ -37,7 +37,7 @@ #include #include "retroshare/rsgxscircles.h" -#define POSTED_DEFAULT_LISTING_LENGTH 30 +#define POSTED_DEFAULT_LISTING_LENGTH 10 #define POSTED_MAX_INDEX 10000 #define TOPIC_DEFAULT_IMAGE ":/icons/png/posted.png" @@ -630,7 +630,8 @@ void PostedListWidget::applyRanking() ++counter; } - // Card View + // Card View + counter = 0; QLayout *cviewlayout = ui->scrollAreaWidgetContentsCardView->layout(); foreach (PostedCardView *item, mPostCardView) From 349f0e0c310dcf87fd2d2c61283bc1fdb1e7e7c7 Mon Sep 17 00:00:00 2001 From: hunbernd Date: Mon, 30 Dec 2019 00:05:23 +0100 Subject: [PATCH 09/44] Link the original image --- .../src/gui/Posted/PostedCreatePostDialog.cpp | 53 ++++++++++++++++-- .../src/gui/Posted/PostedCreatePostDialog.h | 2 + .../src/gui/Posted/PostedCreatePostDialog.ui | 55 +++++++++++++------ 3 files changed, 87 insertions(+), 23 deletions(-) diff --git a/retroshare-gui/src/gui/Posted/PostedCreatePostDialog.cpp b/retroshare-gui/src/gui/Posted/PostedCreatePostDialog.cpp index 9d188c75b..d64195006 100644 --- a/retroshare-gui/src/gui/Posted/PostedCreatePostDialog.cpp +++ b/retroshare-gui/src/gui/Posted/PostedCreatePostDialog.cpp @@ -21,6 +21,7 @@ #include #include #include +#include #include "PostedCreatePostDialog.h" #include "ui_PostedCreatePostDialog.h" @@ -37,6 +38,8 @@ #include +#include + PostedCreatePostDialog::PostedCreatePostDialog(TokenQueue* tokenQ, RsPosted *posted, const RsGxsGroupId& grpId, QWidget *parent): QDialog(parent, Qt::WindowSystemMenuHint | Qt::WindowTitleHint | Qt::WindowMinimizeButtonHint | Qt::WindowMaximizeButtonHint | Qt::WindowCloseButtonHint), mTokenQueue(tokenQ), mPosted(posted), mGrpId(grpId), @@ -55,6 +58,10 @@ PostedCreatePostDialog::PostedCreatePostDialog(TokenQueue* tokenQ, RsPosted *pos setAttribute ( Qt::WA_DeleteOnClose, true ); ui->RichTextEditWidget->setPlaceHolderTextPosted(); + + ui->hashBox->setAutoHide(true); + ui->hashBox->setDefaultTransferRequestFlags(RS_FILE_REQ_ANONYMOUS_ROUTING); + connect(ui->hashBox, SIGNAL(fileHashingFinished(QList)), this, SLOT(fileHashingFinished(QList))); /* fill in the available OwnIds for signing */ ui->idChooser->loadIds(IDCHOOSER_ID_REQUIRED, RsGxsId()); @@ -88,9 +95,11 @@ void PostedCreatePostDialog::createPost() post.mMeta.mGroupId = mGrpId; post.mLink = std::string(ui->linkEdit->text().toUtf8()); - QString text; - text = ui->RichTextEditWidget->toHtml(); - post.mNotes = std::string(text.toUtf8()); + if(!ui->RichTextEditWidget->toPlainText().trimmed().isEmpty()) { + QString text; + text = ui->RichTextEditWidget->toHtml(); + post.mNotes = std::string(text.toUtf8()); + } post.mMeta.mAuthorId = authorId; post.mMeta.mMsgName = std::string(ui->titleEdit->text().toUtf8()); @@ -114,18 +123,33 @@ void PostedCreatePostDialog::createPost() accept(); } -void PostedCreatePostDialog::addPicture() +void PostedCreatePostDialog::fileHashingFinished(QList hashedFiles) { + if(hashedFiles.length() > 0) { //It seems like it returns 0 if hashing cancelled + HashedFile hashedFile = hashedFiles[0]; //Should be exactly one file + RetroShareLink link; + link = RetroShareLink::createFile(hashedFile.filename, hashedFile.size, QString::fromStdString(hashedFile.hash.toStdString())); + ui->linkEdit->setText(link.toString()); + } + ui->submitButton->setEnabled(true); + ui->pushButton->setEnabled(true); +} + +void PostedCreatePostDialog::addPicture() +{ imagefilename = ""; imagebytes.clear(); + QPixmap empty; + ui->imageLabel->setPixmap(empty); // select a picture file if (misc::getOpenFileName(window(), RshareSettings::LASTDIR_IMAGES, tr("Load Picture File"), "Pictures (*.png *.xpm *.jpg *.jpeg *.gif *.webp )", imagefilename)) { QString encodedImage; int maxMessageSize = 34000; //34 kB QImage image; - if (image.load (imagefilename) == false) { + if (image.load(imagefilename) == false) { fprintf (stderr, "RsHtml::makeEmbeddedImage() - image \"%s\" can't be load\n", imagefilename.toLatin1().constData()); + imagefilename = ""; return; } @@ -135,8 +159,27 @@ void PostedCreatePostDialog::addPicture() } else { imagefilename = ""; imagebytes.clear(); + return; } } + + //Do we need to hash the image? + QMessageBox::StandardButton answer; + answer = QMessageBox::question(this, tr("Post image"), tr("Do you want to share and link the original image?"), QMessageBox::Yes|QMessageBox::No); + if (answer == QMessageBox::Yes) { + if(!ui->linkEdit->text().trimmed().isEmpty()) { + answer = QMessageBox::question(this, tr("Post image"), tr("You already added a link.
Do you want to replace it?"), QMessageBox::Yes|QMessageBox::No); + } + } + + //If still yes then link it + if(answer == QMessageBox::Yes) { + ui->submitButton->setEnabled(false); + ui->pushButton->setEnabled(false); + QStringList files; + files.append(imagefilename); + ui->hashBox->addAttachments(files,RS_FILE_REQ_ANONYMOUS_ROUTING); + } } void PostedCreatePostDialog::on_postButton_clicked() diff --git a/retroshare-gui/src/gui/Posted/PostedCreatePostDialog.h b/retroshare-gui/src/gui/Posted/PostedCreatePostDialog.h index 64313608e..c89802e40 100644 --- a/retroshare-gui/src/gui/Posted/PostedCreatePostDialog.h +++ b/retroshare-gui/src/gui/Posted/PostedCreatePostDialog.h @@ -22,6 +22,7 @@ #define POSTEDCREATEPOSTDIALOG_H #include +#include #include "retroshare/rsposted.h" #include "util/RichTextEdit.h" @@ -53,6 +54,7 @@ private slots: void on_postButton_clicked(); void on_imageButton_clicked(); void on_linkButton_clicked(); + void fileHashingFinished(QList hashedFiles); private: QString mLink; diff --git a/retroshare-gui/src/gui/Posted/PostedCreatePostDialog.ui b/retroshare-gui/src/gui/Posted/PostedCreatePostDialog.ui index dcfa504a2..7fed42641 100644 --- a/retroshare-gui/src/gui/Posted/PostedCreatePostDialog.ui +++ b/retroshare-gui/src/gui/Posted/PostedCreatePostDialog.ui @@ -293,20 +293,7 @@ 0 - - - - Qt::Horizontal - - - - 447 - 20 - - - - - + Preview @@ -363,6 +350,26 @@ + + + + Qt::Horizontal + + + + 447 + 20 + + + + + + + + Picture size is limited to 34 KB + + + @@ -370,10 +377,16 @@ - - - - Picture size is limited to 34 KB + + + + + 0 + 0 + + + + true @@ -457,6 +470,12 @@ QLabel

gui/common/StyledLabel.h
+ + HashBox + QScrollArea +
gui/common/HashBox.h
+ 1 +
HeaderFrame QFrame From 778c5ea47d2e62fe2884ce81c7bafbe28afb50ea Mon Sep 17 00:00:00 2001 From: hunbernd Date: Thu, 2 Jan 2020 18:43:35 +0100 Subject: [PATCH 10/44] Do not allow posting too large messages --- .../src/gui/Posted/PostedCreatePostDialog.cpp | 22 ++++++++++++------- .../src/gui/Posted/PostedCreatePostDialog.h | 1 + .../src/gui/Posted/PostedCreatePostDialog.ui | 2 +- 3 files changed, 16 insertions(+), 9 deletions(-) diff --git a/retroshare-gui/src/gui/Posted/PostedCreatePostDialog.cpp b/retroshare-gui/src/gui/Posted/PostedCreatePostDialog.cpp index d64195006..75cda9943 100644 --- a/retroshare-gui/src/gui/Posted/PostedCreatePostDialog.cpp +++ b/retroshare-gui/src/gui/Posted/PostedCreatePostDialog.cpp @@ -75,6 +75,12 @@ PostedCreatePostDialog::~PostedCreatePostDialog() void PostedCreatePostDialog::createPost() { + if(ui->titleEdit->text().isEmpty()) { + /* error message */ + QMessageBox::warning(this, "RetroShare", tr("Please add a Title"), QMessageBox::Ok, QMessageBox::Ok); + return; //Don't add a empty title!! + } + RsGxsId authorId; switch (ui->idChooser->getChosenId(authorId)) { case GxsIdChooser::KnowId: @@ -108,13 +114,14 @@ void PostedCreatePostDialog::createPost() { // send posted image post.mImage.copy((uint8_t *) imagebytes.data(), imagebytes.size()); + } + + int msgsize = post.mLink.length() + post.mMeta.mMsgName.length() + post.mNotes.length() + imagebytes.size(); + if(msgsize > MAXMESSAGESIZE) { + QString errormessage = QString(tr("Message is too large.
actual size: %1 bytes, maximum size: %2 bytes.")).arg(msgsize).arg(MAXMESSAGESIZE); + QMessageBox::warning(this, "RetroShare", errormessage, QMessageBox::Ok, QMessageBox::Ok); + return; } - - if(ui->titleEdit->text().isEmpty()) { - /* error message */ - QMessageBox::warning(this, "RetroShare", tr("Please add a Title"), QMessageBox::Ok, QMessageBox::Ok); - return; //Don't add a empty title!! - }//if(ui->titleEdit->text().isEmpty()) uint32_t token; mPosted->createPost(token, post); @@ -145,7 +152,6 @@ void PostedCreatePostDialog::addPicture() // select a picture file if (misc::getOpenFileName(window(), RshareSettings::LASTDIR_IMAGES, tr("Load Picture File"), "Pictures (*.png *.xpm *.jpg *.jpeg *.gif *.webp )", imagefilename)) { QString encodedImage; - int maxMessageSize = 34000; //34 kB QImage image; if (image.load(imagefilename) == false) { fprintf (stderr, "RsHtml::makeEmbeddedImage() - image \"%s\" can't be load\n", imagefilename.toLatin1().constData()); @@ -154,7 +160,7 @@ void PostedCreatePostDialog::addPicture() } QImage opt; - if(ImageUtil::optimizeSizeBytes(imagebytes, image, opt, 800*600, maxMessageSize)) { + if(ImageUtil::optimizeSizeBytes(imagebytes, image, opt, 800*600, MAXMESSAGESIZE - 1000)) { //Leave space for other stuff ui->imageLabel->setPixmap(QPixmap::fromImage(opt)); } else { imagefilename = ""; diff --git a/retroshare-gui/src/gui/Posted/PostedCreatePostDialog.h b/retroshare-gui/src/gui/Posted/PostedCreatePostDialog.h index c89802e40..1f25da94b 100644 --- a/retroshare-gui/src/gui/Posted/PostedCreatePostDialog.h +++ b/retroshare-gui/src/gui/Posted/PostedCreatePostDialog.h @@ -47,6 +47,7 @@ public: private: QString imagefilename; QByteArray imagebytes; + const int MAXMESSAGESIZE = 32000; private slots: void createPost(); diff --git a/retroshare-gui/src/gui/Posted/PostedCreatePostDialog.ui b/retroshare-gui/src/gui/Posted/PostedCreatePostDialog.ui index 7fed42641..e55256443 100644 --- a/retroshare-gui/src/gui/Posted/PostedCreatePostDialog.ui +++ b/retroshare-gui/src/gui/Posted/PostedCreatePostDialog.ui @@ -366,7 +366,7 @@ - Picture size is limited to 34 KB + Post size is limited to 32 KB, pictures will be downscaled. From 246029736d031ec885404c8f0796b8e864070dbc Mon Sep 17 00:00:00 2001 From: defnax Date: Sat, 4 Jan 2020 17:01:58 +0100 Subject: [PATCH 11/44] Added anmos changes & own improvements Added the changes from anmo Added to store/load last used identity for posted composer Added remove button for remove the attached image Fixed to hide the Notes button when there is not text content (PosteItem) Fixed the ui margins better look --- libretroshare/src/util/rsdir.cc | 6 + .../src/gui/Posted/PostedCreatePostDialog.cpp | 153 +++- .../src/gui/Posted/PostedCreatePostDialog.h | 10 +- .../src/gui/Posted/PostedCreatePostDialog.ui | 655 ++++++++++-------- retroshare-gui/src/gui/Posted/PostedItem.cpp | 6 +- .../src/gui/Posted/Posted_images.qrc | 2 + .../src/gui/Posted/images/linkext.png | Bin 0 -> 660 bytes .../src/gui/Posted/images/trashcan.png | Bin 0 -> 1366 bytes retroshare-gui/src/util/imageutil.cpp | 50 +- retroshare-gui/src/util/imageutil.h | 6 +- 10 files changed, 533 insertions(+), 355 deletions(-) create mode 100644 retroshare-gui/src/gui/Posted/images/linkext.png create mode 100644 retroshare-gui/src/gui/Posted/images/trashcan.png diff --git a/libretroshare/src/util/rsdir.cc b/libretroshare/src/util/rsdir.cc index a890ed8f1..1b794f982 100644 --- a/libretroshare/src/util/rsdir.cc +++ b/libretroshare/src/util/rsdir.cc @@ -254,7 +254,13 @@ int RsDirUtil::breakupDirList(const std::string& path, /**** Copied and Tweaked from ftcontroller ***/ bool RsDirUtil::fileExists(const std::string& filename) { +#ifdef WINDOWS_SYS + std::wstring wfilename; + librs::util::ConvertUtf8ToUtf16(filename, wfilename); + return ( _waccess( wfilename.c_str(), F_OK ) != -1 ); +#else return ( access( filename.c_str(), F_OK ) != -1 ); +#endif } bool RsDirUtil::moveFile(const std::string& source,const std::string& dest) diff --git a/retroshare-gui/src/gui/Posted/PostedCreatePostDialog.cpp b/retroshare-gui/src/gui/Posted/PostedCreatePostDialog.cpp index c822bb492..4cfe282e9 100644 --- a/retroshare-gui/src/gui/Posted/PostedCreatePostDialog.cpp +++ b/retroshare-gui/src/gui/Posted/PostedCreatePostDialog.cpp @@ -20,6 +20,8 @@ #include #include +#include +#include #include "PostedCreatePostDialog.h" #include "ui_PostedCreatePostDialog.h" @@ -34,6 +36,10 @@ #include +#include + +#include + PostedCreatePostDialog::PostedCreatePostDialog(TokenQueue* tokenQ, RsPosted *posted, const RsGxsGroupId& grpId, QWidget *parent): QDialog(parent, Qt::WindowSystemMenuHint | Qt::WindowTitleHint | Qt::WindowMinimizeButtonHint | Qt::WindowMaximizeButtonHint | Qt::WindowCloseButtonHint), mTokenQueue(tokenQ), mPosted(posted), mGrpId(grpId), @@ -52,19 +58,58 @@ PostedCreatePostDialog::PostedCreatePostDialog(TokenQueue* tokenQ, RsPosted *pos setAttribute ( Qt::WA_DeleteOnClose, true ); ui->RichTextEditWidget->setPlaceHolderTextPosted(); + + ui->hashBox->setAutoHide(true); + ui->hashBox->setDefaultTransferRequestFlags(RS_FILE_REQ_ANONYMOUS_ROUTING); + connect(ui->hashBox, SIGNAL(fileHashingFinished(QList)), this, SLOT(fileHashingFinished(QList))); /* fill in the available OwnIds for signing */ ui->idChooser->loadIds(IDCHOOSER_ID_REQUIRED, RsGxsId()); + + ui->removeButton->hide(); + + /* load settings */ + processSettings(true); } PostedCreatePostDialog::~PostedCreatePostDialog() { Settings->saveWidgetInformation(this); + + // save settings + processSettings(false); + delete ui; } +void PostedCreatePostDialog::processSettings(bool load) +{ + Settings->beginGroup(QString("PostedCreatePostDialog")); + + if (load) { + // load settings + + // state of ID Chooser combobox + int index = Settings->value("IDChooser", 0).toInt(); + ui->idChooser->setCurrentIndex(index); + } else { + // save settings + + // state of ID Chooser combobox + Settings->setValue("IDChooser", ui->idChooser->currentIndex()); + } + + Settings->endGroup(); +} + void PostedCreatePostDialog::createPost() { + if(ui->titleEdit->text().isEmpty()) { + /* error message */ + QMessageBox::warning(this, "RetroShare", tr("Please add a Title"), QMessageBox::Ok, QMessageBox::Ok); + return; //Don't add a empty title!! + } + RsGxsId authorId; switch (ui->idChooser->getChosenId(authorId)) { case GxsIdChooser::KnowId: @@ -85,37 +130,27 @@ void PostedCreatePostDialog::createPost() post.mMeta.mGroupId = mGrpId; post.mLink = std::string(ui->linkEdit->text().toUtf8()); - QString text; - text = ui->RichTextEditWidget->toHtml(); - post.mNotes = std::string(text.toUtf8()); + if(!ui->RichTextEditWidget->toPlainText().trimmed().isEmpty()) { + QString text; + text = ui->RichTextEditWidget->toHtml(); + post.mNotes = std::string(text.toUtf8()); + } post.mMeta.mAuthorId = authorId; - - if(!ui->titleEdit->text().isEmpty()) - { - post.mMeta.mMsgName = std::string(ui->titleEdit->text().toUtf8()); - }else - { - post.mMeta.mMsgName = std::string(ui->titleEditLink->text().toUtf8()); - } - - QByteArray ba; - QBuffer buffer(&ba); + post.mMeta.mMsgName = std::string(ui->titleEdit->text().toUtf8()); - if(!picture.isNull()) + if(imagebytes.size() > 0) { // send posted image + post.mImage.copy((uint8_t *) imagebytes.data(), imagebytes.size()); + } - buffer.open(QIODevice::WriteOnly); - picture.save(&buffer, "PNG"); // writes image into ba in PNG format - post.mImage.copy((uint8_t *) ba.data(), ba.size()); + int msgsize = post.mLink.length() + post.mMeta.mMsgName.length() + post.mNotes.length() + imagebytes.size(); + if(msgsize > MAXMESSAGESIZE) { + QString errormessage = QString(tr("Message is too large.
actual size: %1 bytes, maximum size: %2 bytes.")).arg(msgsize).arg(MAXMESSAGESIZE); + QMessageBox::warning(this, "RetroShare", errormessage, QMessageBox::Ok, QMessageBox::Ok); + return; } - - if(ui->titleEdit->text().isEmpty()&& ui->titleEditLink->text().isEmpty()) { - /* error message */ - QMessageBox::warning(this, "RetroShare", tr("Please add a Title"), QMessageBox::Ok, QMessageBox::Ok); - return; //Don't add a empty title!! - }//if(ui->titleEdit->text().isEmpty()) uint32_t token; mPosted->createPost(token, post); @@ -124,17 +159,64 @@ void PostedCreatePostDialog::createPost() accept(); } -void PostedCreatePostDialog::addPicture() +void PostedCreatePostDialog::fileHashingFinished(QList hashedFiles) { - QPixmap img = misc::getOpenThumbnailedPicture(this, tr("Load thumbnail picture"), 800, 600); + if(hashedFiles.length() > 0) { //It seems like it returns 0 if hashing cancelled + HashedFile hashedFile = hashedFiles[0]; //Should be exactly one file + RetroShareLink link; + link = RetroShareLink::createFile(hashedFile.filename, hashedFile.size, QString::fromStdString(hashedFile.hash.toStdString())); + ui->linkEdit->setText(link.toString()); + } + ui->submitButton->setEnabled(true); + ui->pushButton->setEnabled(true); +} - if (img.isNull()) - return; +void PostedCreatePostDialog::addPicture() +{ + imagefilename = ""; + imagebytes.clear(); + QPixmap empty; + ui->imageLabel->setPixmap(empty); - picture = img; + // select a picture file + if (misc::getOpenFileName(window(), RshareSettings::LASTDIR_IMAGES, tr("Load Picture File"), "Pictures (*.png *.xpm *.jpg *.jpeg *.gif *.webp )", imagefilename)) { + QString encodedImage; + QImage image; + if (image.load(imagefilename) == false) { + fprintf (stderr, "RsHtml::makeEmbeddedImage() - image \"%s\" can't be load\n", imagefilename.toLatin1().constData()); + imagefilename = ""; + return; + } - // to show the selected - ui->imageLabel->setPixmap(picture); + QImage opt; + if(ImageUtil::optimizeSizeBytes(imagebytes, image, opt, 800*600, MAXMESSAGESIZE - 1000)) { //Leave space for other stuff + ui->imageLabel->setPixmap(QPixmap::fromImage(opt)); + } else { + imagefilename = ""; + imagebytes.clear(); + return; + } + } + + //Do we need to hash the image? + QMessageBox::StandardButton answer; + answer = QMessageBox::question(this, tr("Post image"), tr("Do you want to share and link the original image?"), QMessageBox::Yes|QMessageBox::No); + if (answer == QMessageBox::Yes) { + if(!ui->linkEdit->text().trimmed().isEmpty()) { + answer = QMessageBox::question(this, tr("Post image"), tr("You already added a link.
Do you want to replace it?"), QMessageBox::Yes|QMessageBox::No); + } + } + + //If still yes then link it + if(answer == QMessageBox::Yes) { + ui->submitButton->setEnabled(false); + ui->pushButton->setEnabled(false); + QStringList files; + files.append(imagefilename); + ui->hashBox->addAttachments(files,RS_FILE_REQ_ANONYMOUS_ROUTING); + } + + ui->removeButton->show(); } void PostedCreatePostDialog::on_postButton_clicked() @@ -151,3 +233,12 @@ void PostedCreatePostDialog::on_linkButton_clicked() { ui->stackedWidget->setCurrentIndex(2); } + +void PostedCreatePostDialog::on_removeButton_clicked() +{ + imagefilename = ""; + imagebytes.clear(); + QPixmap empty; + ui->imageLabel->setPixmap(empty); + ui->removeButton->hide(); +} diff --git a/retroshare-gui/src/gui/Posted/PostedCreatePostDialog.h b/retroshare-gui/src/gui/Posted/PostedCreatePostDialog.h index de13358fb..4a5dc7788 100644 --- a/retroshare-gui/src/gui/Posted/PostedCreatePostDialog.h +++ b/retroshare-gui/src/gui/Posted/PostedCreatePostDialog.h @@ -22,6 +22,7 @@ #define POSTEDCREATEPOSTDIALOG_H #include +#include #include "retroshare/rsposted.h" #include "util/RichTextEdit.h" @@ -43,7 +44,10 @@ public: explicit PostedCreatePostDialog(TokenQueue* tokenQ, RsPosted* posted, const RsGxsGroupId& grpId, QWidget *parent = 0); ~PostedCreatePostDialog(); - QPixmap picture; +private: + QString imagefilename; + QByteArray imagebytes; + const int MAXMESSAGESIZE = 32000; private slots: void createPost(); @@ -51,8 +55,12 @@ private slots: void on_postButton_clicked(); void on_imageButton_clicked(); void on_linkButton_clicked(); + void on_removeButton_clicked(); + void fileHashingFinished(QList hashedFiles); private: + void processSettings(bool load); + QString mLink; QString mNotes; TokenQueue* mTokenQueue; diff --git a/retroshare-gui/src/gui/Posted/PostedCreatePostDialog.ui b/retroshare-gui/src/gui/Posted/PostedCreatePostDialog.ui index d64c3ad01..60ecfa3ec 100644 --- a/retroshare-gui/src/gui/Posted/PostedCreatePostDialog.ui +++ b/retroshare-gui/src/gui/Posted/PostedCreatePostDialog.ui @@ -7,7 +7,7 @@ 0 0 575 - 429 + 529
@@ -48,6 +48,338 @@ QFrame::Raised + + + + 0 + + + + + 0 + + + 0 + + + 0 + + + 0 + + + + + + + + + + 0 + + + 0 + + + 0 + + + + + Preview + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + 250 + 200 + + + + + 800 + 200 + + + + + + + true + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + Remove image + + + + :/images/trashcan.png:/images/trashcan.png + + + + 24 + 24 + + + + true + + + + + + + + + + Qt::Horizontal + + + + 447 + 20 + + + + + + + + Post size is limited to 32 KB, pictures will be downscaled. + + + + + + + Add Picture + + + + + + + + 0 + 0 + + + + true + + + + + + + + + 0 + + + 6 + + + 0 + + + + + Url + + + + + + + Qt::Vertical + + + + 20 + 248 + + + + + + + + + + + + + + + 0 + 0 + + + + Post as + + + + + + + + 0 + 0 + + + + + + + + + + + 0 + 0 + + + + + + + Post + + + + + + + + 0 + 0 + + + + Qt::Horizontal + + + QDialogButtonBox::Cancel + + + + + + + 2 + + + + + Post + + + + :/images/post.png:/images/post.png + + + + 24 + 24 + + + + + + + + Image + + + + :/images/photo.png:/images/photo.png + + + + 24 + 24 + + + + + + + + Link + + + + :/images/link.png:/images/link.png + + + + 24 + 24 + + + + + + + + Qt::Horizontal + + + + 298 + 20 + + + + + + @@ -128,105 +460,7 @@ - - - - 2 - - - - - Post - - - - :/images/post.png:/images/post.png - - - - 24 - 24 - - - - - - - - Image - - - - :/images/photo.png:/images/photo.png - - - - 24 - 24 - - - - - - - - Link - - - - :/images/link.png:/images/link.png - - - - 24 - 24 - - - - - - - - Qt::Horizontal - - - - 298 - 20 - - - - - - - - - - - - - 0 - 0 - - - - Post as - - - - - - - - 0 - 0 - - - - - - - + Qt::Horizontal @@ -242,207 +476,28 @@ - - - - - 0 - 0 - - - - Qt::Horizontal - - - QDialogButtonBox::Cancel - - - - - - 0 + + + 6 - - - - 0 + + + + + 0 + 0 + - - 6 + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter - - 0 + + Title - - 0 - - - - - - - - Title - - - - - - - - - 0 - - - 0 - - - 0 - - - - - Qt::Horizontal - - - - 447 - 20 - - - - - - - - Preview - - - - - - - 250 - 200 - - - - - 800 - 200 - - - - - - - true - - - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - - - - Add Picture - - - - - - - Picture size is limited to 34 KB - - - - - - - - - 0 - - - 6 - - - 0 - - - - - Url - - - - - - - Qt::Vertical - - - - 20 - 248 - - - - - - - - Title - - - - - - - - - - - - 0 - 0 - - - - - - - Post - - +
+
+ @@ -455,6 +510,12 @@ QLabel
gui/common/StyledLabel.h
+ + HashBox + QScrollArea +
gui/common/HashBox.h
+ 1 +
HeaderFrame QFrame @@ -475,8 +536,6 @@ - - diff --git a/retroshare-gui/src/gui/Posted/PostedItem.cpp b/retroshare-gui/src/gui/Posted/PostedItem.cpp index 8907d7261..cc422c788 100644 --- a/retroshare-gui/src/gui/Posted/PostedItem.cpp +++ b/retroshare-gui/src/gui/Posted/PostedItem.cpp @@ -21,6 +21,7 @@ #include #include #include +#include #include "rshare.h" #include "PostedItem.h" @@ -342,7 +343,10 @@ void PostedItem::fill() // FIX THIS UP LATER. ui->notes->setText(RsHtml().formatText(NULL, QString::fromUtf8(mPost.mNotes.c_str()), RSHTML_FORMATTEXT_EMBED_SMILEYS | RSHTML_FORMATTEXT_EMBED_LINKS)); - if(ui->notes->text().isEmpty()) + QTextDocument doc; + doc.setHtml(ui->notes->text()); + + if(doc.toPlainText().trimmed().isEmpty()) ui->notesButton->hide(); // differences between Feed or Top of Comment. if (mFeedHolder) diff --git a/retroshare-gui/src/gui/Posted/Posted_images.qrc b/retroshare-gui/src/gui/Posted/Posted_images.qrc index 2a1a10d0c..9c2be0db4 100644 --- a/retroshare-gui/src/gui/Posted/Posted_images.qrc +++ b/retroshare-gui/src/gui/Posted/Posted_images.qrc @@ -21,11 +21,13 @@ images/share.png images/notes.png images/link.png + images/linkext.png images/post.png images/photo.png images/classic.png images/card.png images/down-hover.png images/up-hover.png + images/trashcan.png diff --git a/retroshare-gui/src/gui/Posted/images/linkext.png b/retroshare-gui/src/gui/Posted/images/linkext.png new file mode 100644 index 0000000000000000000000000000000000000000..8fa5953a079e7da7ddbc50fa19b04a659aac32b6 GIT binary patch literal 660 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!63?wyl`GbKJOS+@4BLl<6e(pbstU$g(vPY0F z14ES>14Ba#1H&(%P{RubhEf9thF1v;3|2E37{m+a>uK5+*#Kcre9>83F5NMx&|a6$`}@1WC5#ZnR%6A<{6+k!;EXpP+iv;=0UZy z%>in;2Gqhb_X<>&pIwkx9&&vwQ8V zK%h{qr;B5V#O36K1H2M58yaRdwodJpWwEf>xudtCp|O2>zdR3%1j|7tr$Yw1N{bR0 zl?^50?|3*(l2&AR2D?NY%?PN}v7CMhd8i!PC{xWt~$(695gb;t>D< literal 0 HcmV?d00001 diff --git a/retroshare-gui/src/gui/Posted/images/trashcan.png b/retroshare-gui/src/gui/Posted/images/trashcan.png new file mode 100644 index 0000000000000000000000000000000000000000..d812bcfe58e5e1b195c2879b64cea4847a69959b GIT binary patch literal 1366 zcmeAS@N?(olHy`uVBq!ia0vp^4Is?H0wgodS2_SGmUKs7M+SzC{oH>NS%G|oWRDy)vIg-4nJ@ErkR#;MwT(m+A>5>H=O_9u+Y0-6?b+dk$4EmZMzaSW-r^>%Kwhe)8r@%_fD zV>vf3;f@q3QQffO%~E#3%_}^bSF|r`Ul7r(vFh&C7lsF?MaBOMn+x}=5Vgx#vMWqIiLuIk*ong6tZ|Gk&??acA_zm2QY=1QiE{Pg>K=H602 z&GXBcv=+$p@>Z>!Y<0DGpJc|p&xi7@pQaavwQE^M7HQq~_Qdw(b^w#SBzwqY(e{lRahH}yP zZE-WN-um#R|NWB>BD4Iv z|Nm5&&wsJ%_O@%^8Mb%GPktO(d788R-R!HDF*3y~k8GZl>A2+Ry7iOmIQgUZn(kCw ze`ibWq6>fb6y<$b6Oy$$H}*B-2d)0klP}(GvRxU%^{pg)V*0b^S92=o`$oNc@Z|vG z;VS19mo`6RTxwkCyEN(iEblLeHyqn{;`9-DwYe;F4Y%m={Pbd+Rx%6){o9+y|JAGy+GPcx(?RdPyB|RqXVsZ8T-;M5>e+@-u zudcC@eW!kz1Ms=b+gxMJ72%ABkk#Z z;jcuIPLWgkjAxo|VR_2AF5j2%o4cC5hz-6rhgoE`!rm*=vl;iu$z9pIWSuQ%+v0P6 zCGod%?tgSGUvV(9EbJY-RQEgI=5+;)|8zy!+8vKxX?^G0?XOlo<-~iKwQ8@KH`KSE za80kj@2dB(PTy}8*Vk?Di`Gnhrn2J4nVTZ!MK-Y~A294N{<7iyrsx?74=xAXN&UPl z51;+-0@l8*}Jc z<`)j;%bSg=R`&!lywclcsoSH|%k;w5*=`@>4I!WBHQWjBwX>YQn=AMVE>=&FmSZhC z^hNM)V$iOlLut|yY#VkrhX-BBnf>3Rd`;2zhc3B)tQY*6r?uRyWclAq>rQ38n~^u= z(Cp>2?@uvXm6$b8e*GKYneS`lpinR(g8$%zH2 Ydih1^v)|cB0TnTLy85}Sb4q9e0OlJt+5i9m literal 0 HcmV?d00001 diff --git a/retroshare-gui/src/util/imageutil.cpp b/retroshare-gui/src/util/imageutil.cpp index 648fe392c..7ca920e84 100644 --- a/retroshare-gui/src/util/imageutil.cpp +++ b/retroshare-gui/src/util/imageutil.cpp @@ -68,12 +68,12 @@ void ImageUtil::extractImage(QWidget *window, QTextCursor cursor) } } -bool ImageUtil::optimizeSize(QString &html, const QImage& original, QImage &optimized, int maxPixels, int maxBytes) +bool ImageUtil::optimizeSizeBytes(QByteArray &bytearray, const QImage &original, QImage &optimized, int maxPixels, int maxBytes) { //nothing to do if it fits into the limits optimized = original; if ((maxPixels <= 0) || (optimized.width()*optimized.height() <= maxPixels)) { - if(checkSize(html, optimized, maxBytes) <= maxBytes) { + if(checkSize(bytearray, optimized) <= maxBytes) { return true; } } @@ -94,14 +94,14 @@ bool ImageUtil::optimizeSize(QString &html, const QImage& original, QImage &opti //if maxBytes not defined, do not reduce color space, just downscale if(maxBytes <= 0) { - checkSize(html, optimized = original.scaledToWidth(maxwidth, Qt::SmoothTransformation), maxBytes); + checkSize(bytearray, optimized = original.scaledToWidth(maxwidth, Qt::SmoothTransformation)); return true; } //Use binary search to find a suitable image size + linear regression to guess the file size - double maxsize = (double)checkSize(html, optimized = original.scaledToWidth(maxwidth, Qt::SmoothTransformation).convertToFormat(QImage::Format_Indexed8, ct, Qt::ThresholdDither), maxBytes); + double maxsize = (double)checkSize(bytearray, optimized = original.scaledToWidth(maxwidth, Qt::SmoothTransformation).convertToFormat(QImage::Format_Indexed8, ct, Qt::ThresholdDither)); if(maxsize <= maxBytes) return true; //success - double minsize = (double)checkSize(html, optimized = original.scaledToWidth(minwidth, Qt::SmoothTransformation).convertToFormat(QImage::Format_Indexed8, ct, Qt::ThresholdDither), maxBytes); + double minsize = (double)checkSize(bytearray, optimized = original.scaledToWidth(minwidth, Qt::SmoothTransformation).convertToFormat(QImage::Format_Indexed8, ct, Qt::ThresholdDither)); if(minsize > maxBytes) return false; //impossible // std::cout << "maxS: " << maxsize << " minS: " << minsize << std::endl; @@ -114,7 +114,7 @@ bool ImageUtil::optimizeSize(QString &html, const QImage& original, QImage &opti double b = maxsize - m * ((double)maxwidth * (double)maxwidth / whratio); double a = ((double)(maxBytes - region/2) - b) / m; //maxBytes - region/2 target the center of the accepted region int nextwidth = (int)sqrt(a * whratio); - int nextsize = checkSize(html, optimized = original.scaledToWidth(nextwidth, Qt::SmoothTransformation).convertToFormat(QImage::Format_Indexed8, ct, Qt::ThresholdDither), maxBytes); + int nextsize = checkSize(bytearray, optimized = original.scaledToWidth(nextwidth, Qt::SmoothTransformation).convertToFormat(QImage::Format_Indexed8, ct, Qt::ThresholdDither)); if(nextsize <= maxBytes) { minsize = nextsize; minwidth = nextwidth; @@ -136,34 +136,40 @@ bool ImageUtil::optimizeSize(QString &html, const QImage& original, QImage &opti //std::cout << html.toStdString() << std::endl; } -int ImageUtil::checkSize(QString &embeddedImage, const QImage &img, int maxBytes) +bool ImageUtil::optimizeSizeHtml(QString &html, const QImage& original, QImage &optimized, int maxPixels, int maxBytes) +{ + QByteArray bytearray; + if(maxBytes > 0){ + maxBytes = maxBytes * 3/4 - 50; //base64 and html stuff + } + + if(optimizeSizeBytes(bytearray, original, optimized, maxPixels, maxBytes)) + { + QByteArray encodedByteArray = bytearray.toBase64(); + html = ""); + return true; + } + return false; +} + +int ImageUtil::checkSize(QByteArray &bytearray, const QImage &img) { rstime::RsScopeTimer st("Check size"); - QByteArray bytearray; + bytearray.clear(); QBuffer buffer(&bytearray); int size = 0; //std::cout << QString("Trying image: format PNG, size %1x%2, colors %3\n").arg(img.width()).arg(img.height()).arg(img.colorCount()).toStdString(); if (buffer.open(QIODevice::WriteOnly)) { if (img.save(&buffer, "PNG", 0)) { - size = bytearray.length() * 4/3; - if((maxBytes > 0) && (size > maxBytes)) // *4/3 for base64 - { - //std::cout << QString("\tToo large, size: %1, limit: %2 bytes\n").arg(bytearray.length() * 4/3).arg(maxBytes).toStdString(); - }else{ - //std::cout << QString("\tOK, size: %1, limit: %2 bytes\n").arg(bytearray.length() * 4/3).arg(maxBytes).toStdString(); - QByteArray encodedByteArray = bytearray.toBase64(); - //embeddedImage = ""); - } + size = bytearray.length(); } else { std::cerr << "ImageUtil: image can't be saved to buffer" << std::endl; } - buffer.close(); - bytearray.clear(); + buffer.close(); } else { std::cerr << "ImageUtil: buffer can't be opened" << std::endl; } diff --git a/retroshare-gui/src/util/imageutil.h b/retroshare-gui/src/util/imageutil.h index dfea67282..4af33d1c5 100644 --- a/retroshare-gui/src/util/imageutil.h +++ b/retroshare-gui/src/util/imageutil.h @@ -23,6 +23,7 @@ #include #include +#include #include class ImageUtil @@ -31,10 +32,11 @@ public: ImageUtil(); static void extractImage(QWidget *window, QTextCursor cursor); - static bool optimizeSize(QString &html, const QImage& original, QImage &optimized, int maxPixels = -1, int maxBytes = -1); + static bool optimizeSizeHtml(QString &html, const QImage& original, QImage &optimized, int maxPixels = -1, int maxBytes = -1); + static bool optimizeSizeBytes(QByteArray &bytearray, const QImage& original, QImage &optimized, int maxPixels = -1, int maxBytes = -1); private: - static int checkSize(QString& embeddedImage, const QImage& img, int maxBytes = -1); + static int checkSize(QByteArray& embeddedImage, const QImage& img); static void quantization(const QImage& img, QVector& palette); static void quantization(QList::iterator begin, QList::iterator end, int depth, QVector& palette); static void avgbucket(QList::iterator begin, QList::iterator end, QVector& palette); From c6c767a67efedd370be60b35d34a2cdc4724259c Mon Sep 17 00:00:00 2001 From: defnax Date: Sun, 5 Jan 2020 19:18:08 +0100 Subject: [PATCH 12/44] forget to commit this --- retroshare-gui/src/util/HandleRichText.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/retroshare-gui/src/util/HandleRichText.cpp b/retroshare-gui/src/util/HandleRichText.cpp index 7818c984d..c500a6bb9 100644 --- a/retroshare-gui/src/util/HandleRichText.cpp +++ b/retroshare-gui/src/util/HandleRichText.cpp @@ -1185,7 +1185,7 @@ bool RsHtml::makeEmbeddedImage(const QImage &originalImage, QString &embeddedIma { rstime::RsScopeTimer s("Embed image"); QImage opt; - return ImageUtil::optimizeSize(embeddedImage, originalImage, opt, maxPixels, maxBytes); + return ImageUtil::optimizeSizeHtml(embeddedImage, originalImage, opt, maxPixels, maxBytes); } QString RsHtml::plainText(const QString &text) From a988b1dd8b98303162a2d385a25f077df5a0db8f Mon Sep 17 00:00:00 2001 From: hunbernd Date: Sun, 5 Jan 2020 20:59:16 +0100 Subject: [PATCH 13/44] Handle an edge case in imageutil --- retroshare-gui/src/util/imageutil.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/retroshare-gui/src/util/imageutil.cpp b/retroshare-gui/src/util/imageutil.cpp index a14443cf7..47029505e 100644 --- a/retroshare-gui/src/util/imageutil.cpp +++ b/retroshare-gui/src/util/imageutil.cpp @@ -142,6 +142,7 @@ bool ImageUtil::optimizeSizeHtml(QString &html, const QImage& original, QImage & QByteArray bytearray; if(maxBytes > 0){ maxBytes = maxBytes * 3/4 - 50; //base64 and html stuff + if(maxBytes < 1) maxBytes = 1; } if(optimizeSizeBytes(bytearray, original, optimized, maxPixels, maxBytes)) From 5efd318cb596aa18372ab5788d98fb10478744f7 Mon Sep 17 00:00:00 2001 From: hunbernd Date: Sun, 5 Jan 2020 21:00:13 +0100 Subject: [PATCH 14/44] Rise post size --- retroshare-gui/src/gui/Posted/PostedCreatePostDialog.cpp | 3 ++- retroshare-gui/src/gui/Posted/PostedCreatePostDialog.h | 2 +- retroshare-gui/src/gui/Posted/PostedCreatePostDialog.ui | 2 +- 3 files changed, 4 insertions(+), 3 deletions(-) diff --git a/retroshare-gui/src/gui/Posted/PostedCreatePostDialog.cpp b/retroshare-gui/src/gui/Posted/PostedCreatePostDialog.cpp index 4cfe282e9..9e1e64d5c 100644 --- a/retroshare-gui/src/gui/Posted/PostedCreatePostDialog.cpp +++ b/retroshare-gui/src/gui/Posted/PostedCreatePostDialog.cpp @@ -62,6 +62,7 @@ PostedCreatePostDialog::PostedCreatePostDialog(TokenQueue* tokenQ, RsPosted *pos ui->hashBox->setAutoHide(true); ui->hashBox->setDefaultTransferRequestFlags(RS_FILE_REQ_ANONYMOUS_ROUTING); connect(ui->hashBox, SIGNAL(fileHashingFinished(QList)), this, SLOT(fileHashingFinished(QList))); + ui->sizeWarningLabel->setText(QString("Post size is limited to %1 KB, pictures will be downscaled.").arg(MAXMESSAGESIZE / 1024)); /* fill in the available OwnIds for signing */ ui->idChooser->loadIds(IDCHOOSER_ID_REQUIRED, RsGxsId()); @@ -189,7 +190,7 @@ void PostedCreatePostDialog::addPicture() } QImage opt; - if(ImageUtil::optimizeSizeBytes(imagebytes, image, opt, 800*600, MAXMESSAGESIZE - 1000)) { //Leave space for other stuff + if(ImageUtil::optimizeSizeBytes(imagebytes, image, opt, 800*600, MAXMESSAGESIZE - 2000)) { //Leave space for other stuff ui->imageLabel->setPixmap(QPixmap::fromImage(opt)); } else { imagefilename = ""; diff --git a/retroshare-gui/src/gui/Posted/PostedCreatePostDialog.h b/retroshare-gui/src/gui/Posted/PostedCreatePostDialog.h index 4a5dc7788..5aed59950 100644 --- a/retroshare-gui/src/gui/Posted/PostedCreatePostDialog.h +++ b/retroshare-gui/src/gui/Posted/PostedCreatePostDialog.h @@ -47,7 +47,7 @@ public: private: QString imagefilename; QByteArray imagebytes; - const int MAXMESSAGESIZE = 32000; + const int MAXMESSAGESIZE = 199000; private slots: void createPost(); diff --git a/retroshare-gui/src/gui/Posted/PostedCreatePostDialog.ui b/retroshare-gui/src/gui/Posted/PostedCreatePostDialog.ui index 60ecfa3ec..a4ecfbb6c 100644 --- a/retroshare-gui/src/gui/Posted/PostedCreatePostDialog.ui +++ b/retroshare-gui/src/gui/Posted/PostedCreatePostDialog.ui @@ -187,7 +187,7 @@ - + Post size is limited to 32 KB, pictures will be downscaled. From b96fecfcbbe88ba38678eac72f08dff394a4dae7 Mon Sep 17 00:00:00 2001 From: defnax Date: Mon, 6 Jan 2020 00:25:05 +0100 Subject: [PATCH 15/44] Added gif & webp for RichtextEditor * Added gif & webp for RichtextEditor picture attachments * Attempt to fix attached picture layout issue on Card View --- .../src/gui/Posted/PostedCardView.ui | 28 ++++++------------- retroshare-gui/src/util/RichTextEdit.cpp | 2 +- 2 files changed, 10 insertions(+), 20 deletions(-) diff --git a/retroshare-gui/src/gui/Posted/PostedCardView.ui b/retroshare-gui/src/gui/Posted/PostedCardView.ui index 125c56d39..8c6fe0e84 100644 --- a/retroshare-gui/src/gui/Posted/PostedCardView.ui +++ b/retroshare-gui/src/gui/Posted/PostedCardView.ui @@ -7,7 +7,7 @@ 0 0 614 - 160 + 182 @@ -462,19 +462,9 @@ - - - - Qt::Horizontal - - - - 219 - 18 - - - - + + 0 + @@ -507,16 +497,16 @@ - - GxsIdLabel - QLabel -
gui/gxs/GxsIdLabel.h
-
StyledLabel QLabel
gui/common/StyledLabel.h
+ + GxsIdLabel + QLabel +
gui/gxs/GxsIdLabel.h
+
diff --git a/retroshare-gui/src/util/RichTextEdit.cpp b/retroshare-gui/src/util/RichTextEdit.cpp index 541e6c3eb..613aa1c19 100644 --- a/retroshare-gui/src/util/RichTextEdit.cpp +++ b/retroshare-gui/src/util/RichTextEdit.cpp @@ -585,7 +585,7 @@ void RichTextEdit::setText(const QString& text) { void RichTextEdit::insertImage() { QString file; - if (misc::getOpenFileName(window(), RshareSettings::LASTDIR_IMAGES, tr("Load Picture File"), "Pictures (*.png *.xpm *.jpg *.jpeg)", file)) { + if (misc::getOpenFileName(window(), RshareSettings::LASTDIR_IMAGES, tr("Load Picture File"), "Pictures (*.png *.xpm *.jpg *.jpeg *.gif *.webp)", file)) { QString encodedImage; if (RsHtml::makeEmbeddedImage(file, encodedImage, 640*480, MAX_ALLOWED_GXS_MESSAGE_SIZE - 200)) { QTextDocumentFragment fragment = QTextDocumentFragment::fromHtml(encodedImage); From f482e681e38149d7a87d218f73ac03ff016ed33d Mon Sep 17 00:00:00 2001 From: defnax Date: Mon, 6 Jan 2020 01:28:20 +0100 Subject: [PATCH 16/44] fixing margins & hide notes field when its empty --- retroshare-gui/src/gui/Posted/PostedCardView.cpp | 6 +++++- retroshare-gui/src/gui/Posted/PostedCardView.ui | 9 +++++++++ 2 files changed, 14 insertions(+), 1 deletion(-) diff --git a/retroshare-gui/src/gui/Posted/PostedCardView.cpp b/retroshare-gui/src/gui/Posted/PostedCardView.cpp index f7f59a056..e5fd646ce 100644 --- a/retroshare-gui/src/gui/Posted/PostedCardView.cpp +++ b/retroshare-gui/src/gui/Posted/PostedCardView.cpp @@ -21,6 +21,7 @@ #include #include #include +#include #include "rshare.h" #include "PostedCardView.h" @@ -332,7 +333,10 @@ void PostedCardView::fill() // FIX THIS UP LATER. ui->notes->setText(RsHtml().formatText(NULL, QString::fromUtf8(mPost.mNotes.c_str()), RSHTML_FORMATTEXT_EMBED_SMILEYS | RSHTML_FORMATTEXT_EMBED_LINKS)); - if(ui->notes->text().isEmpty()) + QTextDocument doc; + doc.setHtml(ui->notes->text()); + + if(doc.toPlainText().trimmed().isEmpty()) ui->notes->hide(); // differences between Feed or Top of Comment. if (mFeedHolder) diff --git a/retroshare-gui/src/gui/Posted/PostedCardView.ui b/retroshare-gui/src/gui/Posted/PostedCardView.ui index 8c6fe0e84..fa026e6f9 100644 --- a/retroshare-gui/src/gui/Posted/PostedCardView.ui +++ b/retroshare-gui/src/gui/Posted/PostedCardView.ui @@ -465,6 +465,15 @@ 0 + + 0 + + + 0 + + + 0 + From c210bf4b9e91bf8755e920f6c00f9f9477dae9e3 Mon Sep 17 00:00:00 2001 From: defnax Date: Mon, 6 Jan 2020 14:35:57 +0100 Subject: [PATCH 17/44] set default picture dimensions to 640*480 like same as embeded html image * set default picture dimensions to 640*480 like same as embeded html image --- retroshare-gui/src/gui/Posted/PostedCreatePostDialog.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/retroshare-gui/src/gui/Posted/PostedCreatePostDialog.cpp b/retroshare-gui/src/gui/Posted/PostedCreatePostDialog.cpp index 9e1e64d5c..490b6dd19 100644 --- a/retroshare-gui/src/gui/Posted/PostedCreatePostDialog.cpp +++ b/retroshare-gui/src/gui/Posted/PostedCreatePostDialog.cpp @@ -190,7 +190,7 @@ void PostedCreatePostDialog::addPicture() } QImage opt; - if(ImageUtil::optimizeSizeBytes(imagebytes, image, opt, 800*600, MAXMESSAGESIZE - 2000)) { //Leave space for other stuff + if(ImageUtil::optimizeSizeBytes(imagebytes, image, opt, 640*480, MAXMESSAGESIZE - 2000)) { //Leave space for other stuff ui->imageLabel->setPixmap(QPixmap::fromImage(opt)); } else { imagefilename = ""; From 846767e83b900a5de8148e84bcb4c9f29d07a18b Mon Sep 17 00:00:00 2001 From: defnax Date: Mon, 6 Jan 2020 17:02:17 +0100 Subject: [PATCH 18/44] Improved the Image attach Page --- .../src/gui/Posted/PostedCreatePostDialog.cpp | 11 +- .../src/gui/Posted/PostedCreatePostDialog.ui | 284 ++++++++++++------ 2 files changed, 194 insertions(+), 101 deletions(-) diff --git a/retroshare-gui/src/gui/Posted/PostedCreatePostDialog.cpp b/retroshare-gui/src/gui/Posted/PostedCreatePostDialog.cpp index 490b6dd19..ddacd4895 100644 --- a/retroshare-gui/src/gui/Posted/PostedCreatePostDialog.cpp +++ b/retroshare-gui/src/gui/Posted/PostedCreatePostDialog.cpp @@ -50,7 +50,7 @@ PostedCreatePostDialog::PostedCreatePostDialog(TokenQueue* tokenQ, RsPosted *pos connect(ui->submitButton, SIGNAL(clicked()), this, SLOT(createPost())); connect(ui->buttonBox, SIGNAL(rejected()), this, SLOT(close())); - connect(ui->pushButton, SIGNAL(clicked() ), this , SLOT(addPicture())); + connect(ui->addPicButton, SIGNAL(clicked() ), this , SLOT(addPicture())); ui->headerFrame->setHeaderImage(QPixmap(":/icons/png/postedlinks.png")); ui->headerFrame->setHeaderText(tr("Create a new Post")); @@ -169,7 +169,7 @@ void PostedCreatePostDialog::fileHashingFinished(QList hashedFiles) ui->linkEdit->setText(link.toString()); } ui->submitButton->setEnabled(true); - ui->pushButton->setEnabled(true); + ui->addPicButton->setEnabled(true); } void PostedCreatePostDialog::addPicture() @@ -192,6 +192,8 @@ void PostedCreatePostDialog::addPicture() QImage opt; if(ImageUtil::optimizeSizeBytes(imagebytes, image, opt, 640*480, MAXMESSAGESIZE - 2000)) { //Leave space for other stuff ui->imageLabel->setPixmap(QPixmap::fromImage(opt)); + ui->stackedWidgetPicture->setCurrentIndex(1); + ui->removeButton->show(); } else { imagefilename = ""; imagebytes.clear(); @@ -211,13 +213,13 @@ void PostedCreatePostDialog::addPicture() //If still yes then link it if(answer == QMessageBox::Yes) { ui->submitButton->setEnabled(false); - ui->pushButton->setEnabled(false); + ui->addPicButton->setEnabled(false); QStringList files; files.append(imagefilename); ui->hashBox->addAttachments(files,RS_FILE_REQ_ANONYMOUS_ROUTING); } - ui->removeButton->show(); + } void PostedCreatePostDialog::on_postButton_clicked() @@ -242,4 +244,5 @@ void PostedCreatePostDialog::on_removeButton_clicked() QPixmap empty; ui->imageLabel->setPixmap(empty); ui->removeButton->hide(); + ui->stackedWidgetPicture->setCurrentIndex(0); } diff --git a/retroshare-gui/src/gui/Posted/PostedCreatePostDialog.ui b/retroshare-gui/src/gui/Posted/PostedCreatePostDialog.ui index a4ecfbb6c..50abd48a2 100644 --- a/retroshare-gui/src/gui/Posted/PostedCreatePostDialog.ui +++ b/retroshare-gui/src/gui/Posted/PostedCreatePostDialog.ui @@ -7,7 +7,7 @@ 0 0 575 - 529 + 518 @@ -77,19 +77,44 @@ 0 + + 0 + 0 0 - + + + + + 0 + 0 + + + + true + + + + Preview - - + + + 0 + + + 0 + + + 0 + + Qt::Horizontal @@ -102,29 +127,7 @@ - - - - - 250 - 200 - - - - - 800 - 200 - - - - - - - true - - - - + Qt::Horizontal @@ -137,82 +140,168 @@ - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - Remove image - - - - :/images/trashcan.png:/images/trashcan.png - - - - 24 - 24 - - - - true + + + + 0 + + + + + + 9 + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + Add Picture + + + + :/icons/png/add-image.png:/icons/png/add-image.png + + + + 24 + 24 + + + + + + + + Post size is limited to 32 KB, pictures will be downscaled. + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + Qt::Vertical + + + + 20 + 40 + + + + + + + + + + Qt::Horizontal + + + + 267 + 138 + + + + + + + + + + 2 + + + 2 + + + 0 + + + 2 + + + + + + 800 + 200 + + + + + + + true + + + + + + + Qt::Horizontal + + + + 188 + 17 + + + + + + + + Remove image + + + + :/images/trashcan.png:/images/trashcan.png + + + + 24 + 24 + + + + true + + + + + - - - - Qt::Horizontal - - - - 447 - 20 - - - - - - - - Post size is limited to 32 KB, pictures will be downscaled. - - - - - - - Add Picture - - - - - - - - 0 - 0 - - - - true - - - @@ -536,6 +625,7 @@ + From 5b9a275e8107b2baae6ba32812e1e876a69a02c2 Mon Sep 17 00:00:00 2001 From: hunbernd Date: Tue, 7 Jan 2020 19:14:57 +0100 Subject: [PATCH 19/44] Fixes the build problem with the new notification system. PostedCardView uses the same identifier as PostedItem. --- retroshare-gui/src/gui/Posted/PostedCardView.h | 2 ++ 1 file changed, 2 insertions(+) diff --git a/retroshare-gui/src/gui/Posted/PostedCardView.h b/retroshare-gui/src/gui/Posted/PostedCardView.h index 7cf51f682..7fc303680 100644 --- a/retroshare-gui/src/gui/Posted/PostedCardView.h +++ b/retroshare-gui/src/gui/Posted/PostedCardView.h @@ -49,6 +49,8 @@ public: const RsPostedPost &getPost() const; RsPostedPost &post(); + uint64_t uniqueIdentifier() const override { return hash_64bits("PostedItem " + mMessageId.toStdString()); } + protected: /* FeedItem */ virtual void doExpand(bool open); From d0fcd90ccca109f8bdb23a4ed39061c47df900fc Mon Sep 17 00:00:00 2001 From: defnax Date: Fri, 10 Jan 2020 19:27:58 +0100 Subject: [PATCH 20/44] Added Picture View Dialog for open the picture in a external View * Added Picture View Dialog for open the picture in a external View * Added a clickable Label for Classic Views Thumbnail label to open Picture via one click * Imroved the Classic & Card views dark stylesheets for better look and feel --- retroshare-gui/src/gui/Posted/PhotoView.cpp | 76 +++++++ retroshare-gui/src/gui/Posted/PhotoView.h | 62 ++++++ retroshare-gui/src/gui/Posted/PhotoView.ui | 200 ++++++++++++++++++ .../src/gui/Posted/PostedCardView.ui | 4 +- retroshare-gui/src/gui/Posted/PostedItem.cpp | 33 ++- retroshare-gui/src/gui/Posted/PostedItem.h | 1 + retroshare-gui/src/gui/Posted/PostedItem.ui | 84 ++++---- retroshare-gui/src/qss/qdarkstyle-v2.qss | 91 +++++++- retroshare-gui/src/qss/qdarkstyle.qss | 79 ++++++- retroshare-gui/src/retroshare-gui.pro | 6 +- retroshare-gui/src/util/ClickableLabel.cpp | 35 +++ retroshare-gui/src/util/ClickableLabel.h | 47 ++++ 12 files changed, 665 insertions(+), 53 deletions(-) create mode 100644 retroshare-gui/src/gui/Posted/PhotoView.cpp create mode 100644 retroshare-gui/src/gui/Posted/PhotoView.h create mode 100644 retroshare-gui/src/gui/Posted/PhotoView.ui create mode 100644 retroshare-gui/src/util/ClickableLabel.cpp create mode 100644 retroshare-gui/src/util/ClickableLabel.h diff --git a/retroshare-gui/src/gui/Posted/PhotoView.cpp b/retroshare-gui/src/gui/Posted/PhotoView.cpp new file mode 100644 index 000000000..ed6628151 --- /dev/null +++ b/retroshare-gui/src/gui/Posted/PhotoView.cpp @@ -0,0 +1,76 @@ +/******************************************************************************* + * retroshare-gui/src/gui/Posted/PhotoView.cpp * + * * + * Copyright (C) 2020 by RetroShare Team * + * * + * 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 "PhotoView.h" + +#include +#include +#include + +#include "gui/gxs/GxsIdDetails.h" +#include + +/** Constructor */ +PhotoView::PhotoView(QWidget *parent) +: QDialog(parent), + ui(new Ui::PhotoView) +{ + /* Invoke the Qt Designer generated object setup routine */ + ui->setupUi(this); + + ui->shareButton->hide(); +} + +/** Destructor */ +PhotoView::~PhotoView() +{ + delete ui; +} + +void PhotoView::setPixmap(const QPixmap& pixmap) +{ + ui->photoLabel->setPixmap(pixmap); +} + +void PhotoView::setTitle(const QString& text) +{ + ui->titleLabel->setText(text); +} + +void PhotoView::setName(const RsGxsId& authorID) +{ + ui->nameLabel->setId(authorID); + + RsIdentityDetails idDetails ; + rsIdentity->getIdDetails(authorID,idDetails); + + QPixmap pixmap ; + + if(idDetails.mAvatar.mSize == 0 || !GxsIdDetails::loadPixmapFromData(idDetails.mAvatar.mData, idDetails.mAvatar.mSize, pixmap,GxsIdDetails::SMALL)) + pixmap = GxsIdDetails::makeDefaultIcon(authorID,GxsIdDetails::SMALL); + + ui->avatarWidget->setPixmap(pixmap); +} + +void PhotoView::setTime(const QString& text) +{ + ui->timeLabel->setText(text); +} + diff --git a/retroshare-gui/src/gui/Posted/PhotoView.h b/retroshare-gui/src/gui/Posted/PhotoView.h new file mode 100644 index 000000000..9de96b620 --- /dev/null +++ b/retroshare-gui/src/gui/Posted/PhotoView.h @@ -0,0 +1,62 @@ +/******************************************************************************* + * retroshare-gui/src/gui/Posted/PhotoView.h * + * * + * Copyright (C) 2020 by RetroShare Team * + * * + * 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 _PHOTO_VIEW_H +#define _PHOTO_VIEW_H + +#include "ui_PhotoView.h" + +#include + +namespace Ui { + class PhotoView; +} + +class PhotoView : public QDialog +{ + Q_OBJECT + +public: + /** Default Constructor */ + PhotoView(QWidget *parent = 0); + + /** Default Destructor */ + ~PhotoView(); + + +public slots: + void setPixmap(const QPixmap& pixmap); + void setTitle (const QString &text); + void setName(const RsGxsId& authorID); + void setTime(const QString& text); + +private slots: + + +private: + + + /** Qt Designer generated object */ + Ui::PhotoView *ui; + +}; + +#endif + diff --git a/retroshare-gui/src/gui/Posted/PhotoView.ui b/retroshare-gui/src/gui/Posted/PhotoView.ui new file mode 100644 index 000000000..9d159500a --- /dev/null +++ b/retroshare-gui/src/gui/Posted/PhotoView.ui @@ -0,0 +1,200 @@ + + + PhotoView + + + + 0 + 0 + 565 + 464 + + + + Photo View + + + Qt::LeftToRight + + + + + + + MS Sans Serif + 11 + 75 + true + + + + TextLabel + + + true + + + + + + + + 0 + 0 + + + + + 0 + + + 0 + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + + + + + + MS Sans Serif + 9 + 50 + false + + + + Posted by + + + + + + + + 24 + 24 + + + + + 24 + 24 + + + + + + + + + MS Sans Serif + 9 + + + + TextLabel + + + + + + + + MS Sans Serif + 9 + + + + TextLabel + + + + + + + Qt::Horizontal + + + + 398 + 20 + + + + + + + + Share + + + + :/images/share.png:/images/share.png + + + Qt::ToolButtonTextBesideIcon + + + true + + + + + + + + + + GxsIdLabel + QLabel +
gui/gxs/GxsIdLabel.h
+
+ + AvatarWidget + QWidget +
gui/common/AvatarWidget.h
+ 1 +
+
+ + + + + +
diff --git a/retroshare-gui/src/gui/Posted/PostedCardView.ui b/retroshare-gui/src/gui/Posted/PostedCardView.ui index fa026e6f9..8cbbd4d56 100644 --- a/retroshare-gui/src/gui/Posted/PostedCardView.ui +++ b/retroshare-gui/src/gui/Posted/PostedCardView.ui @@ -180,7 +180,7 @@
- + 24 @@ -203,7 +203,7 @@ false - + true diff --git a/retroshare-gui/src/gui/Posted/PostedItem.cpp b/retroshare-gui/src/gui/Posted/PostedItem.cpp index cc422c788..b797a1dbe 100644 --- a/retroshare-gui/src/gui/Posted/PostedItem.cpp +++ b/retroshare-gui/src/gui/Posted/PostedItem.cpp @@ -29,7 +29,7 @@ #include "gui/gxs/GxsIdDetails.h" #include "util/misc.h" #include "util/HandleRichText.h" - +#include "PhotoView.h" #include "ui_PostedItem.h" #include @@ -110,11 +110,12 @@ void PostedItem::setup() connect(ui->notesButton, SIGNAL(clicked()), this, SLOT( toggleNotes())); connect(ui->readButton, SIGNAL(toggled(bool)), this, SLOT(readToggled(bool))); - + connect(ui->thumbnailLabel, SIGNAL(clicked()), this, SLOT(viewPicture())); + QAction *CopyLinkAction = new QAction(QIcon(""),tr("Copy RetroShare Link"), this); connect(CopyLinkAction, SIGNAL(triggered()), this, SLOT(copyMessageLink())); - - + + int S = QFontMetricsF(font()).height() ; ui->voteUpButton->setIconSize(QSize(S*1.5,S*1.5)); @@ -319,6 +320,7 @@ void PostedItem::fill() QPixmap sqpixmap = pixmap.scaled(desired_width,desired_height, Qt::KeepAspectRatioByExpanding, Qt::SmoothTransformation); ui->thumbnailLabel->setPixmap(sqpixmap); ui->pictureLabel->setPixmap(pixmap); + ui->thumbnailLabel->setToolTip(tr("Click to view Picture")); } else if (urlOkay && (mPost.mImage.mData == NULL)) { @@ -578,3 +580,26 @@ void PostedItem::toggleNotes() } } + +void PostedItem::viewPicture() +{ + if(mPost.mImage.mData == NULL) { + return; + } + + QString timestamp = misc::timeRelativeToNow(mPost.mMeta.mPublishTs); + QPixmap pixmap; + GxsIdDetails::loadPixmapFromData(mPost.mImage.mData, mPost.mImage.mSize, pixmap,GxsIdDetails::ORIGINAL); + RsGxsId authorID = mPost.mMeta.mAuthorId; + + PhotoView *PView = new PhotoView(this); + + PView->setPixmap(pixmap); + PView->setTitle(messageName()); + PView->setName(authorID); + PView->setTime(timestamp); + + PView->show(); + + /* window will destroy itself! */ +} diff --git a/retroshare-gui/src/gui/Posted/PostedItem.h b/retroshare-gui/src/gui/Posted/PostedItem.h index 7bb920a6c..76e612321 100644 --- a/retroshare-gui/src/gui/Posted/PostedItem.h +++ b/retroshare-gui/src/gui/Posted/PostedItem.h @@ -63,6 +63,7 @@ private slots: void toggle(); void copyMessageLink(); void toggleNotes(); + void viewPicture(); signals: void vote(const RsGxsGrpMsgIdPair& msgId, bool up); diff --git a/retroshare-gui/src/gui/Posted/PostedItem.ui b/retroshare-gui/src/gui/Posted/PostedItem.ui index 164ba1a89..f470fea00 100644 --- a/retroshare-gui/src/gui/Posted/PostedItem.ui +++ b/retroshare-gui/src/gui/Posted/PostedItem.ui @@ -7,7 +7,7 @@ 0 0 825 - 339 + 337
@@ -109,6 +109,9 @@ Vote up + + + @@ -148,8 +151,8 @@ Vote down - - \/ + + @@ -185,7 +188,7 @@ 6 - + 0 @@ -267,6 +270,9 @@ true + + Qt::LinksAccessibleByMouse|Qt::TextSelectableByMouse + @@ -415,6 +421,9 @@ + + Expand + @@ -428,7 +437,7 @@ - + 24 @@ -451,7 +460,7 @@ false - + true @@ -482,6 +491,18 @@ + + + 0 + 0 + + + + + 0 + 22 + + Share @@ -489,6 +510,9 @@ :/images/share.png:/images/share.png + + false + true @@ -529,24 +553,6 @@
- - - 0 - 0 - - - - - 50 - 44 - - - - - 50 - 44 - - Qt::NoFocus @@ -561,24 +567,6 @@ - - - 0 - 0 - - - - - 50 - 44 - - - - - 50 - 44 - - Qt::NoFocus @@ -634,6 +622,9 @@ true + + Qt::LinksAccessibleByMouse|Qt::TextSelectableByMouse + @@ -714,11 +705,16 @@ QLabel
gui/gxs/GxsIdLabel.h
+ + ClickableLabel + QLabel +
util/ClickableLabel.h
+
- - + + diff --git a/retroshare-gui/src/qss/qdarkstyle-v2.qss b/retroshare-gui/src/qss/qdarkstyle-v2.qss index 90324f9ab..a1988ad6d 100644 --- a/retroshare-gui/src/qss/qdarkstyle-v2.qss +++ b/retroshare-gui/src/qss/qdarkstyle-v2.qss @@ -934,6 +934,7 @@ QPushButton::menu-indicator { subcontrol-origin: padding; subcontrol-position: bottom right; bottom: 4px; + } QPushButton:pressed { @@ -1836,6 +1837,7 @@ QToolBox QScrollArea QWidget QWidget { QFrame { border-radius: 4px; border: 1px solid #32414B; + } QFrame[frameShape="0"] { @@ -2045,4 +2047,91 @@ GxsChannelPostsWidget QToolButton#subscribeToolButton::menu-arrow { GxsChannelPostsWidget QToolButton#subscribeToolButton::menu-button { image: none; -} \ No newline at end of file +} + +QTabBar#smTab::tab{ + height: 32px; + width: 32px; +} + +PostedCreatePostDialog QPushButton#submitButton { + font: bold; + font-size: 15px; + color: white; + background: #0099cc; + border-radius: 4px; + min-width: 2em; + +} + +PostedCreatePostDialog QPushButton#submitButton:hover { + background: #03b1f3; + border-radius: 4px; + min-width: 2em; + +} + +PostedItem QFrame#mainFrame { + border-radius: 4px; + border: 1px solid #32414B; + background-color: #19232D; + +} + +GxsChannelPostItem QFrame#mainFrame { + border-radius: 4px; + border: 1px solid #32414B; + background-color: #19232D; + +} + +PostedItem QPushButton#shareButton +{ + background-color: transparent; + min-width: 80px; + max-height: 22px; + +} + +PostedItem QLabel#scoreLabel +{ + background-color: transparent; + +} + +PostedItem QFrame#voteFrame { + background: #141415; +} + +PostedItem QToolButton#voteDownButton, QToolButton#voteUpButton +{ + border: none; + +} + +PostedCardView QPushButton#shareButton +{ + background-color: transparent; + min-width: 80px; + max-height: 22px; + +} + +PostedCardView QFrame#voteFrame { + background: #141415; +} + +PostedCardView QFrame#mainFrame { + + background-color: #19232D; + +} + +PostedCardView QFrame#mainFrame [new=false]{ + background: #19232D; +} + +PostedCardView > QFrame#mainFrame[new=true] { + background-color: #005000; +} + diff --git a/retroshare-gui/src/qss/qdarkstyle.qss b/retroshare-gui/src/qss/qdarkstyle.qss index 3e0927975..053c4d105 100644 --- a/retroshare-gui/src/qss/qdarkstyle.qss +++ b/retroshare-gui/src/qss/qdarkstyle.qss @@ -996,7 +996,7 @@ QToolButton::menu-arrow:open { QPushButton::menu-indicator { subcontrol-origin: padding; subcontrol-position: bottom right; - left: 8px; + } QTableView @@ -1209,3 +1209,80 @@ GxsChannelPostsWidget QToolButton#subscribeToolButton::menu-button { image: none; } + +QTabBar#smTab::tab{ + height: 32px; + width: 32px; +} + +PostedCreatePostDialog QPushButton#submitButton { + font: bold; + font-size: 15px; + color: white; + background: #0099cc; + border-radius: 4px; + min-width: 2em; + +} + +PostedCreatePostDialog QPushButton#submitButton:hover { + background: #03b1f3; + border-radius: 4px; + min-width: 2em; + +} + +GxsForumThreadWidget QLabel#forumName +{ + qproperty-fontSizeFactor: 140; + color: #0099cc; + font-size: 15px; + font: bold; +} + +PostedItem QPushButton#shareButton +{ + background-color: transparent; + border: none; + min-width: 75px; + max-height: 22px; +} + +PostedCardView QPushButton#shareButton +{ + background-color: transparent; + border: none; + min-width: 75px; +} + +PostedItem QFrame#voteFrame { + background: #141415; +} + +PostedCardView QFrame#voteFrame { + background: #141415; +} + +QPushButton#shareButton:hover, QPushButton#shareButton::menu-button:hover { + background-color: #4A4949; + border: 1px solid gray; +} + +PostedItem QToolButton#voteDownButton, QToolButton#voteUpButton, QToolButton#expandButton, QToolButton#readButton, +QToolButton#commentButton, QToolButton#notesButton +{ + border: none; +} + +PostedCardView QToolButton#voteDownButton, QToolButton#voteUpButton +{ + border: none; +} + +PostedCardView QFrame#mainFrame [new=false]{ + background: #302F2F; +} + +PostedCardView > QFrame#mainFrame[new=true] { + background-color: #005000; +} diff --git a/retroshare-gui/src/retroshare-gui.pro b/retroshare-gui/src/retroshare-gui.pro index 67540cc3a..6cad0904a 100644 --- a/retroshare-gui/src/retroshare-gui.pro +++ b/retroshare-gui/src/retroshare-gui.pro @@ -469,6 +469,7 @@ HEADERS += rshare.h \ util/QtVersion.h \ util/RsFile.h \ util/qtthreadsutils.h \ + util/ClickableLabel.h \ gui/profile/ProfileWidget.h \ gui/profile/ProfileManager.h \ gui/profile/StatusMessage.h \ @@ -828,6 +829,7 @@ SOURCES += main.cpp \ util/ObjectPainter.cpp \ util/RsFile.cpp \ util/RichTextEdit.cpp \ + util/ClickableLabel.cpp \ gui/profile/ProfileWidget.cpp \ gui/profile/StatusMessage.cpp \ gui/profile/ProfileManager.cpp \ @@ -1348,6 +1350,7 @@ posted { gui/Posted/PostedGroupDialog.h \ gui/feeds/PostedGroupItem.h \ gui/Posted/PostedCreatePostDialog.h \ + gui/Posted/PhotoView.h \ gui/Posted/PostedUserNotify.h #gui/Posted/PostedCreateCommentDialog.h \ @@ -1358,7 +1361,7 @@ posted { gui/Posted/PostedItem.ui \ gui/Posted/PostedCardView.ui \ gui/Posted/PostedCreatePostDialog.ui \ - + gui/Posted/PhotoView.ui #gui/Posted/PostedDialog.ui \ #gui/Posted/PostedComments.ui \ #gui/Posted/PostedCreateCommentDialog.ui @@ -1370,6 +1373,7 @@ posted { gui/Posted/PostedCardView.cpp \ gui/Posted/PostedGroupDialog.cpp \ gui/Posted/PostedCreatePostDialog.cpp \ + gui/Posted/PhotoView.cpp \ gui/Posted/PostedUserNotify.cpp #gui/Posted/PostedDialog.cpp \ diff --git a/retroshare-gui/src/util/ClickableLabel.cpp b/retroshare-gui/src/util/ClickableLabel.cpp new file mode 100644 index 000000000..7b7ccb5fb --- /dev/null +++ b/retroshare-gui/src/util/ClickableLabel.cpp @@ -0,0 +1,35 @@ +/******************************************************************************* + * retroshare-gui/src/util/ClickableLabel.cpp * + * * + * Copyright (C) 2020 by RetroShare Team * + * * + * 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 "ClickableLabel.h" + +/** Constructor */ +ClickableLabel::ClickableLabel(QWidget* parent, Qt::WindowFlags f) + : QLabel(parent) { + +} + +ClickableLabel::~ClickableLabel() { + +} + +void ClickableLabel::mousePressEvent(QMouseEvent* event) { + emit clicked(); +} \ No newline at end of file diff --git a/retroshare-gui/src/util/ClickableLabel.h b/retroshare-gui/src/util/ClickableLabel.h new file mode 100644 index 000000000..c9506cec0 --- /dev/null +++ b/retroshare-gui/src/util/ClickableLabel.h @@ -0,0 +1,47 @@ +/******************************************************************************* + * retroshare-gui/src/util/ClickableLabel.h * + * * + * Copyright (C) 2020 by RetroShare Team * + * * + * 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 CLICKABLELABEL_H +#define CLICKABLELABEL_H + +#include +#include +#include + +class ClickableLabel : public QLabel { + Q_OBJECT + +public: + explicit ClickableLabel(QWidget* parent = Q_NULLPTR, Qt::WindowFlags f = Qt::WindowFlags()); + ~ClickableLabel(); + +signals: + void clicked(); + +protected: + void mousePressEvent(QMouseEvent* event); + + void enterEvent(QEvent *ev) override { setStyleSheet("QLabel { border: 1px solid #3A3939; }");} + + void leaveEvent(QEvent *ev) override { setStyleSheet("QLabel { border: none; }");} + +}; + +#endif // CLICKABLELABEL_H \ No newline at end of file From 737980bf12afbbe4698c678be3aeae997f6390c9 Mon Sep 17 00:00:00 2001 From: defnax Date: Mon, 13 Jan 2020 13:19:26 +0100 Subject: [PATCH 21/44] added delete on close --- retroshare-gui/src/gui/Posted/PhotoView.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/retroshare-gui/src/gui/Posted/PhotoView.cpp b/retroshare-gui/src/gui/Posted/PhotoView.cpp index ed6628151..dba09a239 100644 --- a/retroshare-gui/src/gui/Posted/PhotoView.cpp +++ b/retroshare-gui/src/gui/Posted/PhotoView.cpp @@ -35,6 +35,8 @@ PhotoView::PhotoView(QWidget *parent) /* Invoke the Qt Designer generated object setup routine */ ui->setupUi(this); + setAttribute(Qt::WA_DeleteOnClose, true); + ui->shareButton->hide(); } From b1f45536a223254e1ca4caf80941c39b61ddc6c7 Mon Sep 17 00:00:00 2001 From: defnax Date: Mon, 13 Jan 2020 15:36:55 +0100 Subject: [PATCH 22/44] added temporary solution to not stretch the pixmap out of the window --- retroshare-gui/src/gui/Posted/PhotoView.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/retroshare-gui/src/gui/Posted/PhotoView.cpp b/retroshare-gui/src/gui/Posted/PhotoView.cpp index dba09a239..25e8ad92f 100644 --- a/retroshare-gui/src/gui/Posted/PhotoView.cpp +++ b/retroshare-gui/src/gui/Posted/PhotoView.cpp @@ -48,7 +48,9 @@ PhotoView::~PhotoView() void PhotoView::setPixmap(const QPixmap& pixmap) { - ui->photoLabel->setPixmap(pixmap); + QPixmap sqpixmap = pixmap.scaled(600,480, Qt::KeepAspectRatio, Qt::SmoothTransformation); + + ui->photoLabel->setPixmap(sqpixmap); } void PhotoView::setTitle(const QString& text) From b333a96da2b23b900c46e491afaf9db542557ecc Mon Sep 17 00:00:00 2001 From: defnax Date: Mon, 13 Jan 2020 16:23:54 +0100 Subject: [PATCH 23/44] attempt to fix issues with pictures which width are bigger to fit on Label --- retroshare-gui/src/gui/Posted/PostedCardView.cpp | 8 +++++++- retroshare-gui/src/gui/Posted/PostedItem.cpp | 9 ++++++++- 2 files changed, 15 insertions(+), 2 deletions(-) diff --git a/retroshare-gui/src/gui/Posted/PostedCardView.cpp b/retroshare-gui/src/gui/Posted/PostedCardView.cpp index e5fd646ce..82bd8b9c3 100644 --- a/retroshare-gui/src/gui/Posted/PostedCardView.cpp +++ b/retroshare-gui/src/gui/Posted/PostedCardView.cpp @@ -309,8 +309,14 @@ void PostedCardView::fill() // Wiping data - as its been passed to thumbnail. QPixmap sqpixmap = pixmap.scaled(desired_width,desired_height, Qt::KeepAspectRatioByExpanding, Qt::SmoothTransformation); + + QPixmap squaledpixmap = pixmap.scaled(640,480, Qt::KeepAspectRatio, Qt::SmoothTransformation); + + if(pixmap.width() > 800) + ui->pictureLabel->setPixmap(squaledpixmap); + else + ui->pictureLabel->setPixmap(pixmap); - ui->pictureLabel->setPixmap(pixmap); } else if (mPost.mImage.mData == NULL) { diff --git a/retroshare-gui/src/gui/Posted/PostedItem.cpp b/retroshare-gui/src/gui/Posted/PostedItem.cpp index b797a1dbe..b165f2f00 100644 --- a/retroshare-gui/src/gui/Posted/PostedItem.cpp +++ b/retroshare-gui/src/gui/Posted/PostedItem.cpp @@ -319,8 +319,15 @@ void PostedItem::fill() QPixmap sqpixmap = pixmap.scaled(desired_width,desired_height, Qt::KeepAspectRatioByExpanding, Qt::SmoothTransformation); ui->thumbnailLabel->setPixmap(sqpixmap); - ui->pictureLabel->setPixmap(pixmap); ui->thumbnailLabel->setToolTip(tr("Click to view Picture")); + + QPixmap squaledpixmap = pixmap.scaled(640,480, Qt::KeepAspectRatio, Qt::SmoothTransformation); + + if(pixmap.width() > 800) + ui->pictureLabel->setPixmap(squaledpixmap); + else + ui->pictureLabel->setPixmap(pixmap); + } else if (urlOkay && (mPost.mImage.mData == NULL)) { From ca60e1d094fc41f1d42adb7b2326b909a4b189ae Mon Sep 17 00:00:00 2001 From: defnax Date: Mon, 13 Jan 2020 23:36:09 +0100 Subject: [PATCH 24/44] corrected to use the right value --- retroshare-gui/src/gui/Posted/PhotoView.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/retroshare-gui/src/gui/Posted/PhotoView.cpp b/retroshare-gui/src/gui/Posted/PhotoView.cpp index 25e8ad92f..06a83f827 100644 --- a/retroshare-gui/src/gui/Posted/PhotoView.cpp +++ b/retroshare-gui/src/gui/Posted/PhotoView.cpp @@ -48,7 +48,7 @@ PhotoView::~PhotoView() void PhotoView::setPixmap(const QPixmap& pixmap) { - QPixmap sqpixmap = pixmap.scaled(600,480, Qt::KeepAspectRatio, Qt::SmoothTransformation); + QPixmap sqpixmap = pixmap.scaled(640,480, Qt::KeepAspectRatio, Qt::SmoothTransformation); ui->photoLabel->setPixmap(sqpixmap); } From c1efdac7f6a4fbbdae8e06fbfca174f7a30c149a Mon Sep 17 00:00:00 2001 From: defnax Date: Tue, 14 Jan 2020 23:22:01 +0100 Subject: [PATCH 25/44] get the share button usable for copy the rs link --- retroshare-gui/src/gui/Posted/PhotoView.cpp | 27 ++++++++++++++++++-- retroshare-gui/src/gui/Posted/PhotoView.h | 7 +++-- retroshare-gui/src/gui/Posted/PhotoView.ui | 16 ++++++++++++ retroshare-gui/src/gui/Posted/PostedItem.cpp | 2 ++ 4 files changed, 48 insertions(+), 4 deletions(-) diff --git a/retroshare-gui/src/gui/Posted/PhotoView.cpp b/retroshare-gui/src/gui/Posted/PhotoView.cpp index 06a83f827..16b74c793 100644 --- a/retroshare-gui/src/gui/Posted/PhotoView.cpp +++ b/retroshare-gui/src/gui/Posted/PhotoView.cpp @@ -25,7 +25,10 @@ #include #include "gui/gxs/GxsIdDetails.h" +#include "gui/RetroShareLink.h" + #include +#include /** Constructor */ PhotoView::PhotoView(QWidget *parent) @@ -36,8 +39,8 @@ PhotoView::PhotoView(QWidget *parent) ui->setupUi(this); setAttribute(Qt::WA_DeleteOnClose, true); - - ui->shareButton->hide(); + + connect(ui->shareButton, SIGNAL(clicked()), this, SLOT(copyMessageLink())); } /** Destructor */ @@ -78,3 +81,23 @@ void PhotoView::setTime(const QString& text) ui->timeLabel->setText(text); } +void PhotoView::setGroupId(const RsGxsGroupId &groupId) +{ + mGroupId = groupId; +} + +void PhotoView::setMessageId(const RsGxsMessageId& messageId) +{ + mMessageId = messageId ; +} + +void PhotoView::copyMessageLink() +{ + RetroShareLink link = RetroShareLink::createGxsMessageLink(RetroShareLink::TYPE_POSTED, mGroupId, mMessageId, ui->titleLabel->text()); + + if (link.valid()) { + QList urls; + urls.push_back(link); + RSLinkClipboard::copyLinks(urls); + } +} diff --git a/retroshare-gui/src/gui/Posted/PhotoView.h b/retroshare-gui/src/gui/Posted/PhotoView.h index 9de96b620..d44406af3 100644 --- a/retroshare-gui/src/gui/Posted/PhotoView.h +++ b/retroshare-gui/src/gui/Posted/PhotoView.h @@ -46,12 +46,15 @@ public slots: void setTitle (const QString &text); void setName(const RsGxsId& authorID); void setTime(const QString& text); + void setGroupId(const RsGxsGroupId &groupId); + void setMessageId(const RsGxsMessageId& messageId); private slots: - + void copyMessageLink(); private: - + RsGxsMessageId mMessageId; + RsGxsGroupId mGroupId; /** Qt Designer generated object */ Ui::PhotoView *ui; diff --git a/retroshare-gui/src/gui/Posted/PhotoView.ui b/retroshare-gui/src/gui/Posted/PhotoView.ui index 9d159500a..9c540bc28 100644 --- a/retroshare-gui/src/gui/Posted/PhotoView.ui +++ b/retroshare-gui/src/gui/Posted/PhotoView.ui @@ -145,6 +145,19 @@ + + + + + MS Sans Serif + 9 + + + + ago + + + @@ -160,6 +173,9 @@ + + Copy RetroShare link + Share diff --git a/retroshare-gui/src/gui/Posted/PostedItem.cpp b/retroshare-gui/src/gui/Posted/PostedItem.cpp index b165f2f00..dacf83a53 100644 --- a/retroshare-gui/src/gui/Posted/PostedItem.cpp +++ b/retroshare-gui/src/gui/Posted/PostedItem.cpp @@ -605,6 +605,8 @@ void PostedItem::viewPicture() PView->setTitle(messageName()); PView->setName(authorID); PView->setTime(timestamp); + PView->setGroupId(groupId()); + PView->setMessageId(mMessageId); PView->show(); From 5dffe2e3d89194fbdb7fcfe670bb9243362a6abb Mon Sep 17 00:00:00 2001 From: defnax Date: Wed, 15 Jan 2020 22:27:05 +0100 Subject: [PATCH 26/44] fixing stylesheets for clickable label --- retroshare-gui/src/qss/qdarkstyle-v2.qss | 6 +++++- retroshare-gui/src/qss/qdarkstyle.qss | 5 +++++ retroshare-gui/src/util/ClickableLabel.h | 2 +- 3 files changed, 11 insertions(+), 2 deletions(-) diff --git a/retroshare-gui/src/qss/qdarkstyle-v2.qss b/retroshare-gui/src/qss/qdarkstyle-v2.qss index a1988ad6d..c9e951921 100644 --- a/retroshare-gui/src/qss/qdarkstyle-v2.qss +++ b/retroshare-gui/src/qss/qdarkstyle-v2.qss @@ -2109,6 +2109,11 @@ PostedItem QToolButton#voteDownButton, QToolButton#voteUpButton } +PostedItem QLabel#thumbnailLabel{ + border: 2px solid #CCCCCC; + border-radius: 3px; +} + PostedCardView QPushButton#shareButton { background-color: transparent; @@ -2134,4 +2139,3 @@ PostedCardView QFrame#mainFrame [new=false]{ PostedCardView > QFrame#mainFrame[new=true] { background-color: #005000; } - diff --git a/retroshare-gui/src/qss/qdarkstyle.qss b/retroshare-gui/src/qss/qdarkstyle.qss index 053c4d105..ef8495956 100644 --- a/retroshare-gui/src/qss/qdarkstyle.qss +++ b/retroshare-gui/src/qss/qdarkstyle.qss @@ -1274,6 +1274,11 @@ QToolButton#commentButton, QToolButton#notesButton border: none; } +PostedItem QLabel#thumbnailLabel{ + border: 2px solid #CCCCCC; + border-radius: 3px; +} + PostedCardView QToolButton#voteDownButton, QToolButton#voteUpButton { border: none; diff --git a/retroshare-gui/src/util/ClickableLabel.h b/retroshare-gui/src/util/ClickableLabel.h index c9506cec0..ec1c66b8d 100644 --- a/retroshare-gui/src/util/ClickableLabel.h +++ b/retroshare-gui/src/util/ClickableLabel.h @@ -40,7 +40,7 @@ protected: void enterEvent(QEvent *ev) override { setStyleSheet("QLabel { border: 1px solid #3A3939; }");} - void leaveEvent(QEvent *ev) override { setStyleSheet("QLabel { border: none; }");} + void leaveEvent(QEvent *ev) override { setStyleSheet("QLabel { border: 2px solid #CCCCCC; border-radius: 3px; }");} }; From dcddda81f3ec8fe3795f8886a571d1dd063f3413 Mon Sep 17 00:00:00 2001 From: defnax Date: Sun, 19 Jan 2020 22:29:47 +0100 Subject: [PATCH 27/44] set stylesheet for the new label & removed old stylesheets from the channel item --- .../src/gui/qss/stylesheet/Standard.qss | 23 ++++++++++--------- 1 file changed, 12 insertions(+), 11 deletions(-) diff --git a/retroshare-gui/src/gui/qss/stylesheet/Standard.qss b/retroshare-gui/src/gui/qss/stylesheet/Standard.qss index 4abbd0eff..3e9a063cf 100644 --- a/retroshare-gui/src/gui/qss/stylesheet/Standard.qss +++ b/retroshare-gui/src/gui/qss/stylesheet/Standard.qss @@ -396,11 +396,6 @@ GxsChannelPostItem QLabel#newLabel { border-radius: 3px; } -GxsChannelPostItem QFrame#msgFrame { - border: 2px solid #238; - border-radius: 10px; -} - GxsChannelPostItem QLabel#logoLabel { border: 2px solid #D3D3D3; } @@ -430,12 +425,6 @@ ForumMsgItem QFrame#prevFrame { border-radius: 10px; } -SubFileItem > QFrame#frame { - border: 2px solid #238; - background: white; - border-radius: 10px; -} - SubFileItem QProgressBar#progressBar { border: 1px solid black; text-align: center; @@ -857,6 +846,18 @@ PostedItem QLabel#fromBoldLabel, QLabel#fromLabel, QLabel#dateLabel, QLabel#site color: #787c7e; } +PostedItem QLabel#newLabel { + border: 1px solid #167BE7; + background-color: qlineargradient(x1: 0, y1: 0, x2: 0, y2: 1, stop: 0 #2291E0, stop: 1 #3EB3FF); + border-radius: 3px; +} + +PostedCardView QLabel#newLabel { + border: 1px solid #167BE7; + background-color: qlineargradient(x1: 0, y1: 0, x2: 0, y2: 1, stop: 0 #2291E0, stop: 1 #3EB3FF); + border-radius: 3px; +} + PostedCardView QFrame#voteFrame { background: #f8f9fa; } From 21cf49a0097b6e5679f78a0713a9db19a2de5495 Mon Sep 17 00:00:00 2001 From: defnax Date: Mon, 20 Jan 2020 20:12:26 +0100 Subject: [PATCH 28/44] added to check pixmap width & height before scale, only scale when needed --- retroshare-gui/src/gui/Posted/PhotoView.cpp | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/retroshare-gui/src/gui/Posted/PhotoView.cpp b/retroshare-gui/src/gui/Posted/PhotoView.cpp index 16b74c793..5e099ba01 100644 --- a/retroshare-gui/src/gui/Posted/PhotoView.cpp +++ b/retroshare-gui/src/gui/Posted/PhotoView.cpp @@ -53,7 +53,10 @@ void PhotoView::setPixmap(const QPixmap& pixmap) { QPixmap sqpixmap = pixmap.scaled(640,480, Qt::KeepAspectRatio, Qt::SmoothTransformation); - ui->photoLabel->setPixmap(sqpixmap); + if(pixmap.width() > 800 || pixmap.height() > 700) + ui->photoLabel->setPixmap(sqpixmap); + else + ui->photoLabel->setPixmap(pixmap); } void PhotoView::setTitle(const QString& text) @@ -67,7 +70,7 @@ void PhotoView::setName(const RsGxsId& authorID) RsIdentityDetails idDetails ; rsIdentity->getIdDetails(authorID,idDetails); - + QPixmap pixmap ; if(idDetails.mAvatar.mSize == 0 || !GxsIdDetails::loadPixmapFromData(idDetails.mAvatar.mData, idDetails.mAvatar.mSize, pixmap,GxsIdDetails::SMALL)) From f8f77f122e726313e2452c61eb430f5aaeeb21bf Mon Sep 17 00:00:00 2001 From: defnax Date: Tue, 21 Jan 2020 01:50:33 +0100 Subject: [PATCH 29/44] attempt to improve --- retroshare-gui/src/gui/Posted/PhotoView.cpp | 14 ++++++++++---- retroshare-gui/src/gui/Posted/PostedCardView.cpp | 14 ++++++-------- retroshare-gui/src/gui/Posted/PostedItem.cpp | 12 ++++++------ 3 files changed, 22 insertions(+), 18 deletions(-) diff --git a/retroshare-gui/src/gui/Posted/PhotoView.cpp b/retroshare-gui/src/gui/Posted/PhotoView.cpp index 5e099ba01..fcfd374e1 100644 --- a/retroshare-gui/src/gui/Posted/PhotoView.cpp +++ b/retroshare-gui/src/gui/Posted/PhotoView.cpp @@ -51,12 +51,17 @@ PhotoView::~PhotoView() void PhotoView::setPixmap(const QPixmap& pixmap) { - QPixmap sqpixmap = pixmap.scaled(640,480, Qt::KeepAspectRatio, Qt::SmoothTransformation); - - if(pixmap.width() > 800 || pixmap.height() > 700) + QPixmap sqpixmap; + if(pixmap.width() > 800 ){ + QPixmap sqpixmap = pixmap.scaled(640,480, Qt::KeepAspectRatio, Qt::SmoothTransformation); ui->photoLabel->setPixmap(sqpixmap); - else + }else if (pixmap.height() > 600){ + QPixmap sqpixmap = pixmap.scaled(480,640, Qt::KeepAspectRatio, Qt::SmoothTransformation); + ui->photoLabel->setPixmap(sqpixmap); + } + else{ ui->photoLabel->setPixmap(pixmap); + } } void PhotoView::setTitle(const QString& text) @@ -102,5 +107,6 @@ void PhotoView::copyMessageLink() QList urls; urls.push_back(link); RSLinkClipboard::copyLinks(urls); + QMessageBox::information(NULL,tr("information"),tr("The Retrohare link was copied to your clipboard.")) ; } } diff --git a/retroshare-gui/src/gui/Posted/PostedCardView.cpp b/retroshare-gui/src/gui/Posted/PostedCardView.cpp index 82bd8b9c3..1fef4f160 100644 --- a/retroshare-gui/src/gui/Posted/PostedCardView.cpp +++ b/retroshare-gui/src/gui/Posted/PostedCardView.cpp @@ -308,15 +308,13 @@ void PostedCardView::fill() GxsIdDetails::loadPixmapFromData(mPost.mImage.mData, mPost.mImage.mSize, pixmap,GxsIdDetails::ORIGINAL); // Wiping data - as its been passed to thumbnail. - QPixmap sqpixmap = pixmap.scaled(desired_width,desired_height, Qt::KeepAspectRatioByExpanding, Qt::SmoothTransformation); - - QPixmap squaledpixmap = pixmap.scaled(640,480, Qt::KeepAspectRatio, Qt::SmoothTransformation); - - if(pixmap.width() > 800) - ui->pictureLabel->setPixmap(squaledpixmap); - else + QPixmap scaledpixmap; + if(pixmap.width() > 800){ + QPixmap scaledpixmap = pixmap.scaledToWidth(800, Qt::SmoothTransformation); + ui->pictureLabel->setPixmap(scaledpixmap); + }else{ ui->pictureLabel->setPixmap(pixmap); - + } } else if (mPost.mImage.mData == NULL) { diff --git a/retroshare-gui/src/gui/Posted/PostedItem.cpp b/retroshare-gui/src/gui/Posted/PostedItem.cpp index dacf83a53..b09452a8e 100644 --- a/retroshare-gui/src/gui/Posted/PostedItem.cpp +++ b/retroshare-gui/src/gui/Posted/PostedItem.cpp @@ -321,13 +321,13 @@ void PostedItem::fill() ui->thumbnailLabel->setPixmap(sqpixmap); ui->thumbnailLabel->setToolTip(tr("Click to view Picture")); - QPixmap squaledpixmap = pixmap.scaled(640,480, Qt::KeepAspectRatio, Qt::SmoothTransformation); - - if(pixmap.width() > 800) - ui->pictureLabel->setPixmap(squaledpixmap); - else + QPixmap scaledpixmap; + if(pixmap.width() > 800){ + QPixmap scaledpixmap = pixmap.scaledToWidth(800, Qt::SmoothTransformation); + ui->pictureLabel->setPixmap(scaledpixmap); + }else{ ui->pictureLabel->setPixmap(pixmap); - + } } else if (urlOkay && (mPost.mImage.mData == NULL)) { From 27c4503cfb77b80e2bfd1e8a15912f8591ae0b0f Mon Sep 17 00:00:00 2001 From: defnax Date: Tue, 21 Jan 2020 16:22:56 +0100 Subject: [PATCH 30/44] Added the new class for resize the image if the window is resized --- retroshare-gui/src/retroshare-gui.pro | 2 + .../src/util/AspectRatioPixmapLabel.cpp | 56 +++++++++++++++++++ .../src/util/AspectRatioPixmapLabel.h | 43 ++++++++++++++ 3 files changed, 101 insertions(+) create mode 100644 retroshare-gui/src/util/AspectRatioPixmapLabel.cpp create mode 100644 retroshare-gui/src/util/AspectRatioPixmapLabel.h diff --git a/retroshare-gui/src/retroshare-gui.pro b/retroshare-gui/src/retroshare-gui.pro index 6cad0904a..37d8aa335 100644 --- a/retroshare-gui/src/retroshare-gui.pro +++ b/retroshare-gui/src/retroshare-gui.pro @@ -470,6 +470,7 @@ HEADERS += rshare.h \ util/RsFile.h \ util/qtthreadsutils.h \ util/ClickableLabel.h \ + util/AspectRatioPixmapLabel.h \ gui/profile/ProfileWidget.h \ gui/profile/ProfileManager.h \ gui/profile/StatusMessage.h \ @@ -830,6 +831,7 @@ SOURCES += main.cpp \ util/RsFile.cpp \ util/RichTextEdit.cpp \ util/ClickableLabel.cpp \ + util/AspectRatioPixmapLabel.cpp \ gui/profile/ProfileWidget.cpp \ gui/profile/StatusMessage.cpp \ gui/profile/ProfileManager.cpp \ diff --git a/retroshare-gui/src/util/AspectRatioPixmapLabel.cpp b/retroshare-gui/src/util/AspectRatioPixmapLabel.cpp new file mode 100644 index 000000000..d8da057e6 --- /dev/null +++ b/retroshare-gui/src/util/AspectRatioPixmapLabel.cpp @@ -0,0 +1,56 @@ +/******************************************************************************* + * retroshare-gui/src/util/AspectRatioPixmapLabel.cpp * + * * + * Copyright (C) 2019 Retroshare Team * + * * + * 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 "AspectRatioPixmapLabel.h" + +AspectRatioPixmapLabel::AspectRatioPixmapLabel(QWidget *parent) : + QLabel(parent) +{ + this->setMinimumSize(1,1); + setScaledContents(false); +} + +void AspectRatioPixmapLabel::setPixmap ( const QPixmap & p) +{ + pix = p; + QLabel::setPixmap(scaledPixmap()); +} + +int AspectRatioPixmapLabel::heightForWidth( int width ) const +{ + return pix.isNull() ? this->height() : ((qreal)pix.height()*width)/pix.width(); +} + +QSize AspectRatioPixmapLabel::sizeHint() const +{ + int w = this->width(); + return QSize( w, heightForWidth(w) ); +} + +QPixmap AspectRatioPixmapLabel::scaledPixmap() const +{ + return pix.scaled(this->size(), Qt::KeepAspectRatio, Qt::SmoothTransformation); +} + +void AspectRatioPixmapLabel::resizeEvent(QResizeEvent * e) +{ + if(!pix.isNull()) + QLabel::setPixmap(scaledPixmap()); +} diff --git a/retroshare-gui/src/util/AspectRatioPixmapLabel.h b/retroshare-gui/src/util/AspectRatioPixmapLabel.h new file mode 100644 index 000000000..f04dc619a --- /dev/null +++ b/retroshare-gui/src/util/AspectRatioPixmapLabel.h @@ -0,0 +1,43 @@ +/******************************************************************************* + * retroshare-gui/src/util/AspectRatioPixmapLabel.h * + * * + * Copyright (C) 2019 Retroshare Team * + * * + * 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 ASPECTRATIOPIXMAPLABEL_H +#define ASPECTRATIOPIXMAPLABEL_H + +#include +#include +#include + +class AspectRatioPixmapLabel : public QLabel +{ + Q_OBJECT +public: + explicit AspectRatioPixmapLabel(QWidget *parent = 0); + virtual int heightForWidth( int width ) const; + virtual QSize sizeHint() const; + QPixmap scaledPixmap() const; +public slots: + void setPixmap ( const QPixmap & ); + void resizeEvent(QResizeEvent *); +private: + QPixmap pix; +}; + +#endif // ASPECTRATIOPIXMAPLABEL_H \ No newline at end of file From 69a2933590ccc9c9d35c1962689bdbf25ff928d8 Mon Sep 17 00:00:00 2001 From: hunbernd Date: Tue, 21 Jan 2020 20:02:08 +0100 Subject: [PATCH 31/44] Make pixmap resizing label work --- retroshare-gui/src/gui/Posted/PhotoView.ui | 37 +++++-------------- .../src/util/AspectRatioPixmapLabel.cpp | 3 ++ .../src/util/AspectRatioPixmapLabel.h | 11 +++--- 3 files changed, 18 insertions(+), 33 deletions(-) diff --git a/retroshare-gui/src/gui/Posted/PhotoView.ui b/retroshare-gui/src/gui/Posted/PhotoView.ui index 9c540bc28..82688978c 100644 --- a/retroshare-gui/src/gui/Posted/PhotoView.ui +++ b/retroshare-gui/src/gui/Posted/PhotoView.ui @@ -51,38 +51,15 @@ 0 - - - Qt::Horizontal - - - - 40 - 20 - - - - - - + + + Qt::AlignCenter + - - - - Qt::Horizontal - - - - 40 - 20 - - - - @@ -207,9 +184,13 @@
gui/common/AvatarWidget.h
1 + + AspectRatioPixmapLabel + QLabel +
util/aspectratiopixmaplabel.h
+
- diff --git a/retroshare-gui/src/util/AspectRatioPixmapLabel.cpp b/retroshare-gui/src/util/AspectRatioPixmapLabel.cpp index d8da057e6..d62a72a0d 100644 --- a/retroshare-gui/src/util/AspectRatioPixmapLabel.cpp +++ b/retroshare-gui/src/util/AspectRatioPixmapLabel.cpp @@ -19,6 +19,7 @@ *******************************************************************************/ #include "AspectRatioPixmapLabel.h" +#include AspectRatioPixmapLabel::AspectRatioPixmapLabel(QWidget *parent) : QLabel(parent) @@ -53,4 +54,6 @@ void AspectRatioPixmapLabel::resizeEvent(QResizeEvent * e) { if(!pix.isNull()) QLabel::setPixmap(scaledPixmap()); + QLabel::resizeEvent(e); + //std::cout << "Information resized: " << e->oldSize().width() << 'x' << e->oldSize().height() << " to " << e->size().width() << 'x' << e->size().height() << std::endl; } diff --git a/retroshare-gui/src/util/AspectRatioPixmapLabel.h b/retroshare-gui/src/util/AspectRatioPixmapLabel.h index f04dc619a..ad7c40e4c 100644 --- a/retroshare-gui/src/util/AspectRatioPixmapLabel.h +++ b/retroshare-gui/src/util/AspectRatioPixmapLabel.h @@ -29,15 +29,16 @@ class AspectRatioPixmapLabel : public QLabel { Q_OBJECT public: - explicit AspectRatioPixmapLabel(QWidget *parent = 0); - virtual int heightForWidth( int width ) const; - virtual QSize sizeHint() const; + explicit AspectRatioPixmapLabel(QWidget *parent = nullptr); + virtual int heightForWidth( int width ) const override; + virtual QSize sizeHint() const override; QPixmap scaledPixmap() const; public slots: void setPixmap ( const QPixmap & ); - void resizeEvent(QResizeEvent *); +protected: + void resizeEvent(QResizeEvent *event) override; private: QPixmap pix; }; -#endif // ASPECTRATIOPIXMAPLABEL_H \ No newline at end of file +#endif // ASPECTRATIOPIXMAPLABEL_H From 83b18509e25cd9d216483efb7b09ba6c979f075a Mon Sep 17 00:00:00 2001 From: hunbernd Date: Tue, 21 Jan 2020 21:23:42 +0100 Subject: [PATCH 32/44] Resize photoview to the size of embedded image --- retroshare-gui/src/gui/Posted/PhotoView.cpp | 1 + retroshare-gui/src/gui/Posted/PhotoView.ui | 11 ++++------- retroshare-gui/src/util/AspectRatioPixmapLabel.cpp | 5 ++--- 3 files changed, 7 insertions(+), 10 deletions(-) diff --git a/retroshare-gui/src/gui/Posted/PhotoView.cpp b/retroshare-gui/src/gui/Posted/PhotoView.cpp index fcfd374e1..3cbf261cd 100644 --- a/retroshare-gui/src/gui/Posted/PhotoView.cpp +++ b/retroshare-gui/src/gui/Posted/PhotoView.cpp @@ -62,6 +62,7 @@ void PhotoView::setPixmap(const QPixmap& pixmap) else{ ui->photoLabel->setPixmap(pixmap); } + this->adjustSize(); } void PhotoView::setTitle(const QString& text) diff --git a/retroshare-gui/src/gui/Posted/PhotoView.ui b/retroshare-gui/src/gui/Posted/PhotoView.ui index 82688978c..b7067eecf 100644 --- a/retroshare-gui/src/gui/Posted/PhotoView.ui +++ b/retroshare-gui/src/gui/Posted/PhotoView.ui @@ -6,8 +6,8 @@ 0 0 - 565 - 464 + 346 + 107 @@ -38,7 +38,7 @@ - + 0 0 @@ -55,9 +55,6 @@ - - Qt::AlignCenter - @@ -142,7 +139,7 @@ - 398 + 0 20 diff --git a/retroshare-gui/src/util/AspectRatioPixmapLabel.cpp b/retroshare-gui/src/util/AspectRatioPixmapLabel.cpp index d62a72a0d..49fc9697b 100644 --- a/retroshare-gui/src/util/AspectRatioPixmapLabel.cpp +++ b/retroshare-gui/src/util/AspectRatioPixmapLabel.cpp @@ -31,7 +31,7 @@ AspectRatioPixmapLabel::AspectRatioPixmapLabel(QWidget *parent) : void AspectRatioPixmapLabel::setPixmap ( const QPixmap & p) { pix = p; - QLabel::setPixmap(scaledPixmap()); + QLabel::setPixmap(pix); } int AspectRatioPixmapLabel::heightForWidth( int width ) const @@ -41,8 +41,7 @@ int AspectRatioPixmapLabel::heightForWidth( int width ) const QSize AspectRatioPixmapLabel::sizeHint() const { - int w = this->width(); - return QSize( w, heightForWidth(w) ); + return QSize(pix.width(), pix.height()); } QPixmap AspectRatioPixmapLabel::scaledPixmap() const From 91b03064b9c9f10eaec4d9dee9da1bc52c54d977 Mon Sep 17 00:00:00 2001 From: hunbernd Date: Tue, 21 Jan 2020 22:11:13 +0100 Subject: [PATCH 33/44] Removed size limit inside image viewer, because QT already limits the window size to the 2/3 of screen size --- retroshare-gui/src/gui/Posted/PhotoView.cpp | 12 +----------- retroshare-gui/src/util/AspectRatioPixmapLabel.cpp | 1 + 2 files changed, 2 insertions(+), 11 deletions(-) diff --git a/retroshare-gui/src/gui/Posted/PhotoView.cpp b/retroshare-gui/src/gui/Posted/PhotoView.cpp index 3cbf261cd..ee572dfac 100644 --- a/retroshare-gui/src/gui/Posted/PhotoView.cpp +++ b/retroshare-gui/src/gui/Posted/PhotoView.cpp @@ -51,17 +51,7 @@ PhotoView::~PhotoView() void PhotoView::setPixmap(const QPixmap& pixmap) { - QPixmap sqpixmap; - if(pixmap.width() > 800 ){ - QPixmap sqpixmap = pixmap.scaled(640,480, Qt::KeepAspectRatio, Qt::SmoothTransformation); - ui->photoLabel->setPixmap(sqpixmap); - }else if (pixmap.height() > 600){ - QPixmap sqpixmap = pixmap.scaled(480,640, Qt::KeepAspectRatio, Qt::SmoothTransformation); - ui->photoLabel->setPixmap(sqpixmap); - } - else{ - ui->photoLabel->setPixmap(pixmap); - } + ui->photoLabel->setPixmap(pixmap); this->adjustSize(); } diff --git a/retroshare-gui/src/util/AspectRatioPixmapLabel.cpp b/retroshare-gui/src/util/AspectRatioPixmapLabel.cpp index 49fc9697b..08ecf18c6 100644 --- a/retroshare-gui/src/util/AspectRatioPixmapLabel.cpp +++ b/retroshare-gui/src/util/AspectRatioPixmapLabel.cpp @@ -32,6 +32,7 @@ void AspectRatioPixmapLabel::setPixmap ( const QPixmap & p) { pix = p; QLabel::setPixmap(pix); + //std::cout << "Information size: " << pix.width() << 'x' << pix.height() << std::endl; } int AspectRatioPixmapLabel::heightForWidth( int width ) const From bd18f572c9b0683a7d088336a10f12c5b461a897 Mon Sep 17 00:00:00 2001 From: defnax Date: Fri, 24 Jan 2020 16:35:44 +0100 Subject: [PATCH 34/44] adding back spacer for PhotoView & fixed issue with centering --- retroshare-gui/src/gui/Posted/PhotoView.ui | 39 ++++++++++++++++++++-- 1 file changed, 37 insertions(+), 2 deletions(-) diff --git a/retroshare-gui/src/gui/Posted/PhotoView.ui b/retroshare-gui/src/gui/Posted/PhotoView.ui index b7067eecf..10fda92bb 100644 --- a/retroshare-gui/src/gui/Posted/PhotoView.ui +++ b/retroshare-gui/src/gui/Posted/PhotoView.ui @@ -6,8 +6,8 @@ 0 0 - 346 - 107 + 490 + 316 @@ -47,14 +47,49 @@ 0 + + 0 + 0 + + 0 + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + Qt::AlignCenter + From 54d0758bf2998f24d1b8a08fde47b0759914cb1b Mon Sep 17 00:00:00 2001 From: defnax Date: Fri, 24 Jan 2020 17:08:40 +0100 Subject: [PATCH 35/44] Enabled Min & Max feature for Photo View Dialog --- retroshare-gui/src/gui/Posted/PhotoView.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/retroshare-gui/src/gui/Posted/PhotoView.cpp b/retroshare-gui/src/gui/Posted/PhotoView.cpp index ee572dfac..839e5f4d3 100644 --- a/retroshare-gui/src/gui/Posted/PhotoView.cpp +++ b/retroshare-gui/src/gui/Posted/PhotoView.cpp @@ -32,7 +32,7 @@ /** Constructor */ PhotoView::PhotoView(QWidget *parent) -: QDialog(parent), +: QDialog(parent, Qt::WindowMinimizeButtonHint | Qt::WindowMaximizeButtonHint | Qt::WindowCloseButtonHint), ui(new Ui::PhotoView) { /* Invoke the Qt Designer generated object setup routine */ From 3758e37c7b98ba339490e3ef1f8d5577427cf0c1 Mon Sep 17 00:00:00 2001 From: defnax Date: Sat, 25 Jan 2020 15:17:21 +0100 Subject: [PATCH 36/44] fixed include --- retroshare-gui/src/gui/Posted/PhotoView.ui | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/retroshare-gui/src/gui/Posted/PhotoView.ui b/retroshare-gui/src/gui/Posted/PhotoView.ui index 10fda92bb..e0d4dce64 100644 --- a/retroshare-gui/src/gui/Posted/PhotoView.ui +++ b/retroshare-gui/src/gui/Posted/PhotoView.ui @@ -219,7 +219,7 @@ AspectRatioPixmapLabel QLabel -
util/aspectratiopixmaplabel.h
+
util/AspectRatioPixmapLabel.h
From fb9282f5887bec940139dd5969f78ee05b28c7e8 Mon Sep 17 00:00:00 2001 From: csoler Date: Sun, 26 Jan 2020 23:19:20 +0100 Subject: [PATCH 37/44] moved UserNotify to MainPage level, and added RsEvent handling code in Posted --- libretroshare/src/retroshare/rsgxschannels.h | 4 ++ libretroshare/src/retroshare/rsposted.h | 9 ++-- libretroshare/src/services/p3gxschannels.cc | 15 ++++-- libretroshare/src/services/p3postbase.cc | 47 ++++++++++++++----- plugins/FeedReader/gui/FeedReaderDialog.cpp | 2 +- plugins/FeedReader/gui/FeedReaderDialog.h | 3 +- retroshare-gui/src/gui/ChatLobbyWidget.cpp | 9 ++-- retroshare-gui/src/gui/ChatLobbyWidget.h | 4 +- .../src/gui/FileTransfer/TransfersDialog.cpp | 2 +- .../src/gui/FileTransfer/TransfersDialog.h | 2 +- retroshare-gui/src/gui/FriendsDialog.cpp | 2 +- retroshare-gui/src/gui/FriendsDialog.h | 2 +- retroshare-gui/src/gui/MainPage.cpp | 9 ++++ retroshare-gui/src/gui/MainWindow.cpp | 2 +- retroshare-gui/src/gui/NewsFeed.cpp | 2 +- retroshare-gui/src/gui/NewsFeed.h | 2 +- .../src/gui/Posted/PostedDialog.cpp | 31 +++++++++++- retroshare-gui/src/gui/Posted/PostedDialog.h | 6 ++- .../src/gui/Posted/PostedListWidget.cpp | 2 +- .../src/gui/gxs/GxsGroupFrameDialog.cpp | 2 + .../src/gui/gxs/GxsGroupFrameDialog.h | 3 +- .../src/gui/gxschannels/GxsChannelDialog.cpp | 8 +++- .../src/gui/gxschannels/GxsChannelDialog.h | 3 +- .../src/gui/gxsforums/GxsForumsDialog.cpp | 2 +- .../src/gui/gxsforums/GxsForumsDialog.h | 4 +- .../src/gui/msgs/MessagesDialog.cpp | 2 +- retroshare-gui/src/gui/msgs/MessagesDialog.h | 3 +- retroshare-gui/src/retroshare-gui/mainpage.h | 9 +++- 28 files changed, 140 insertions(+), 51 deletions(-) diff --git a/libretroshare/src/retroshare/rsgxschannels.h b/libretroshare/src/retroshare/rsgxschannels.h index 8e6939672..9fa2f8638 100644 --- a/libretroshare/src/retroshare/rsgxschannels.h +++ b/libretroshare/src/retroshare/rsgxschannels.h @@ -122,6 +122,10 @@ enum class RsChannelEventCode: uint8_t /// subscription for channel mChannelGroupId changed. SUBSCRIBE_STATUS_CHANGED = 0x06, + + /// existing message has been read or set to unread + READ_STATUS_CHANGED = 0x07, + }; struct RsGxsChannelEvent: RsEvent diff --git a/libretroshare/src/retroshare/rsposted.h b/libretroshare/src/retroshare/rsposted.h index 211f67bb1..c8f3a313a 100644 --- a/libretroshare/src/retroshare/rsposted.h +++ b/libretroshare/src/retroshare/rsposted.h @@ -70,9 +70,12 @@ std::ostream &operator<<(std::ostream &out, const RsPostedPost &post); enum class RsPostedEventCode: uint8_t { - UNKNOWN = 0x00, - NEW_POSTED_GROUP = 0x01, - NEW_MESSAGE = 0x02 + UNKNOWN = 0x00, + NEW_POSTED_GROUP = 0x01, + NEW_MESSAGE = 0x02, + SUBSCRIBE_STATUS_CHANGED = 0x03, + UPDATED_POSTED_GROUP = 0x04, + UPDATED_MESSAGE = 0x05, }; diff --git a/libretroshare/src/services/p3gxschannels.cc b/libretroshare/src/services/p3gxschannels.cc index 800c148f4..e97c2389c 100644 --- a/libretroshare/src/services/p3gxschannels.cc +++ b/libretroshare/src/services/p3gxschannels.cc @@ -369,8 +369,8 @@ void p3GxsChannels::notifyChanges(std::vector &changes) if(!unprocessedGroups.empty()) request_SpecificSubscribedGroups(unprocessedGroups); - // the call below deletes changes and its content. - RsGxsIfaceHelper::receiveChanges(changes); +// // the call below deletes changes and its content. +// RsGxsIfaceHelper::receiveChanges(changes); } void p3GxsChannels::service_tick() @@ -1764,8 +1764,17 @@ void p3GxsChannels::setMessageReadStatus( uint32_t& token, if (read) status = 0; setMsgStatusFlags(token, msgId, status, mask); -} + if (rsEvents) + { + auto ev = std::make_shared(); + + ev->mChannelMsgId = msgId.second; + ev->mChannelGroupId = msgId.first; + ev->mChannelEventCode = RsChannelEventCode::READ_STATUS_CHANGED; + rsEvents->postEvent(ev); + } +} /********************************************************************************************/ /********************************************************************************************/ diff --git a/libretroshare/src/services/p3postbase.cc b/libretroshare/src/services/p3postbase.cc index 12799c4f7..a7e4cd476 100644 --- a/libretroshare/src/services/p3postbase.cc +++ b/libretroshare/src/services/p3postbase.cc @@ -91,8 +91,8 @@ void p3PostBase::notifyChanges(std::vector &changes) for(it = changes.begin(); it != changes.end(); ++it) { - RsGxsGroupChange *groupChange = dynamic_cast(*it); RsGxsMsgChange *msgChange = dynamic_cast(*it); + if (msgChange) { #ifdef POSTBASE_DEBUG @@ -124,31 +124,54 @@ void p3PostBase::notifyChanges(std::vector &changes) } } + RsGxsGroupChange *grpChange = dynamic_cast(*it); + /* pass on Group Changes to GUI */ - if (groupChange) + if (grpChange && rsEvents) { #ifdef POSTBASE_DEBUG std::cerr << "p3PostBase::notifyChanges() Found Group Change Notification"; std::cerr << std::endl; #endif - std::list &groupList = groupChange->mGrpIdList; - - for(auto git = groupList.begin(); git != groupList.end(); ++git) + switch(grpChange->getType()) + { + default: + case RsGxsNotify::TYPE_PROCESSED: // happens when the group is subscribed { -#ifdef POSTBASE_DEBUG - std::cerr << "p3PostBase::notifyChanges() Incoming Group: " << *git; - std::cerr << std::endl; -#endif - - if (rsEvents && groupChange->getType() == RsGxsNotify::TYPE_RECEIVED_NEW) + std::list &grpList = grpChange->mGrpIdList; + std::list::iterator git; + for (git = grpList.begin(); git != grpList.end(); ++git) { + auto ev = std::make_shared(); + ev->mPostedGroupId = *git; + ev->mPostedEventCode = RsPostedEventCode::SUBSCRIBE_STATUS_CHANGED; + rsEvents->postEvent(ev); + } + + } + break; + + case RsGxsNotify::TYPE_PUBLISHED: + case RsGxsNotify::TYPE_RECEIVED_NEW: + { + /* group received */ + const std::list& grpList = grpChange->mGrpIdList; + + for (auto git = grpList.begin(); git != grpList.end(); ++git) + { +#ifdef POSTBASE_DEBUG + std::cerr << "p3PostBase::notifyChanges() Incoming Group: " << *git; + std::cerr << std::endl; +#endif auto ev = std::make_shared(); ev->mPostedGroupId = *git; ev->mPostedEventCode = RsPostedEventCode::NEW_POSTED_GROUP; rsEvents->postEvent(ev); } - } + } + break; + } } } receiveHelperChanges(changes); diff --git a/plugins/FeedReader/gui/FeedReaderDialog.cpp b/plugins/FeedReader/gui/FeedReaderDialog.cpp index ca86715e2..5a00cdd6d 100644 --- a/plugins/FeedReader/gui/FeedReaderDialog.cpp +++ b/plugins/FeedReader/gui/FeedReaderDialog.cpp @@ -133,7 +133,7 @@ FeedReaderDialog::~FeedReaderDialog() } } -UserNotify *FeedReaderDialog::getUserNotify(QObject *parent) +UserNotify *FeedReaderDialog::createUserNotify(QObject *parent) { return new FeedReaderUserNotify(this, mFeedReader, mNotify, parent); } diff --git a/plugins/FeedReader/gui/FeedReaderDialog.h b/plugins/FeedReader/gui/FeedReaderDialog.h index 80b6d25a3..a064df811 100644 --- a/plugins/FeedReader/gui/FeedReaderDialog.h +++ b/plugins/FeedReader/gui/FeedReaderDialog.h @@ -42,11 +42,10 @@ public: FeedReaderDialog(RsFeedReader *feedReader, FeedReaderNotify *notify, QWidget *parent = 0); ~FeedReaderDialog(); - virtual UserNotify *getUserNotify(QObject *parent); - static QIcon iconFromFeed(const FeedInfo &feedInfo); protected: + virtual UserNotify *createUserNotify(QObject *parent) override; virtual void showEvent(QShowEvent *event); bool eventFilter(QObject *obj, QEvent *ev); diff --git a/retroshare-gui/src/gui/ChatLobbyWidget.cpp b/retroshare-gui/src/gui/ChatLobbyWidget.cpp index 1c5201343..b139d0113 100644 --- a/retroshare-gui/src/gui/ChatLobbyWidget.cpp +++ b/retroshare-gui/src/gui/ChatLobbyWidget.cpp @@ -226,12 +226,11 @@ ChatLobbyWidget::~ChatLobbyWidget() } } -UserNotify *ChatLobbyWidget::getUserNotify(QObject *parent) +UserNotify *ChatLobbyWidget::createUserNotify(QObject *parent) { - if (!myChatLobbyUserNotify){ - myChatLobbyUserNotify = new ChatLobbyUserNotify(parent); - connect(myChatLobbyUserNotify, SIGNAL(countChanged(ChatLobbyId, unsigned int)), this, SLOT(updateNotify(ChatLobbyId, unsigned int))); - } + myChatLobbyUserNotify = new ChatLobbyUserNotify(parent); + connect(myChatLobbyUserNotify, SIGNAL(countChanged(ChatLobbyId, unsigned int)), this, SLOT(updateNotify(ChatLobbyId, unsigned int))); + return myChatLobbyUserNotify; } diff --git a/retroshare-gui/src/gui/ChatLobbyWidget.h b/retroshare-gui/src/gui/ChatLobbyWidget.h index 39422ec6a..8c6f07081 100644 --- a/retroshare-gui/src/gui/ChatLobbyWidget.h +++ b/retroshare-gui/src/gui/ChatLobbyWidget.h @@ -63,7 +63,7 @@ public: virtual QString pageName() const { return tr("Chats") ; } //MainPage virtual QString helpText() const { return ""; } //MainPage - virtual UserNotify *getUserNotify(QObject *parent); //MainPage + virtual UserNotify *createUserNotify(QObject *parent) override; //MainPage virtual void updateDisplay(); @@ -137,7 +137,7 @@ private: QAction* showTopicAct; int getNumColVisible(); - ChatLobbyUserNotify* myChatLobbyUserNotify; + ChatLobbyUserNotify* myChatLobbyUserNotify; // local copy that avoids dynamic casts QAbstractButton* myInviteYesButton; GxsIdChooser* myInviteIdChooser; diff --git a/retroshare-gui/src/gui/FileTransfer/TransfersDialog.cpp b/retroshare-gui/src/gui/FileTransfer/TransfersDialog.cpp index 15b57e6d8..855d74ecb 100644 --- a/retroshare-gui/src/gui/FileTransfer/TransfersDialog.cpp +++ b/retroshare-gui/src/gui/FileTransfer/TransfersDialog.cpp @@ -1114,7 +1114,7 @@ void TransfersDialog::activatePage(TransfersDialog::Page page) } } -UserNotify *TransfersDialog::getUserNotify(QObject *parent) +UserNotify *TransfersDialog::createUserNotify(QObject *parent) { return new TransferUserNotify(parent); } diff --git a/retroshare-gui/src/gui/FileTransfer/TransfersDialog.h b/retroshare-gui/src/gui/FileTransfer/TransfersDialog.h index eb39df9b9..83da19c5c 100644 --- a/retroshare-gui/src/gui/FileTransfer/TransfersDialog.h +++ b/retroshare-gui/src/gui/FileTransfer/TransfersDialog.h @@ -67,7 +67,7 @@ public: virtual QString pageName() const { return tr("Files") ; } //MainPage virtual QString helpText() const { return ""; } //MainPage - virtual UserNotify *getUserNotify(QObject *parent); + virtual UserNotify *createUserNotify(QObject *parent) override; void activatePage(TransfersDialog::Page page) ; diff --git a/retroshare-gui/src/gui/FriendsDialog.cpp b/retroshare-gui/src/gui/FriendsDialog.cpp index 152d3a96d..660f13fa7 100644 --- a/retroshare-gui/src/gui/FriendsDialog.cpp +++ b/retroshare-gui/src/gui/FriendsDialog.cpp @@ -163,7 +163,7 @@ void FriendsDialog::activatePage(FriendsDialog::Page page) } } -UserNotify *FriendsDialog::getUserNotify(QObject *parent) +UserNotify *FriendsDialog::createUserNotify(QObject *parent) { return new ChatUserNotify(parent); } diff --git a/retroshare-gui/src/gui/FriendsDialog.h b/retroshare-gui/src/gui/FriendsDialog.h index 6eb9cdf7a..bd8979224 100644 --- a/retroshare-gui/src/gui/FriendsDialog.h +++ b/retroshare-gui/src/gui/FriendsDialog.h @@ -55,7 +55,7 @@ public: virtual QString pageName() const { return tr("Network") ; } //MainPage virtual QString helpText() const { return ""; } //MainPage - virtual UserNotify *getUserNotify(QObject *parent); + virtual UserNotify *createUserNotify(QObject *parent) override; static bool isGroupChatActive(); static void groupChatActivate(); diff --git a/retroshare-gui/src/gui/MainPage.cpp b/retroshare-gui/src/gui/MainPage.cpp index 087655572..545f1270e 100644 --- a/retroshare-gui/src/gui/MainPage.cpp +++ b/retroshare-gui/src/gui/MainPage.cpp @@ -31,6 +31,15 @@ MainPage::MainPage(QWidget *parent , Qt::WindowFlags flags ) : QWidget(parent, f mIcon = QIcon(); mName = ""; mHelp = ""; + mUserNotify = nullptr; +} + +UserNotify *MainPage::getUserNotify() +{ + if(!mUserNotify) + mUserNotify = createUserNotify(this); + + return mUserNotify; } void MainPage::registerHelpButton(QToolButton *button, const QString& help_html_text, const QString &code_name) diff --git a/retroshare-gui/src/gui/MainWindow.cpp b/retroshare-gui/src/gui/MainWindow.cpp index 6ec0c22f7..63a563dc4 100644 --- a/retroshare-gui/src/gui/MainWindow.cpp +++ b/retroshare-gui/src/gui/MainWindow.cpp @@ -469,7 +469,7 @@ void MainWindow::initStackedPage() //List All notify before Setting was created QList > >::iterator notifyIt; for (notifyIt = notify.begin(); notifyIt != notify.end(); ++notifyIt) { - UserNotify *userNotify = notifyIt->first->getUserNotify(this); + UserNotify *userNotify = notifyIt->first->getUserNotify(); if (userNotify) { userNotify->initialize(ui->toolBarPage, notifyIt->second.first, notifyIt->second.second); connect(userNotify, SIGNAL(countChanged()), this, SLOT(updateTrayCombine())); diff --git a/retroshare-gui/src/gui/NewsFeed.cpp b/retroshare-gui/src/gui/NewsFeed.cpp index c64c758ea..2f70340be 100644 --- a/retroshare-gui/src/gui/NewsFeed.cpp +++ b/retroshare-gui/src/gui/NewsFeed.cpp @@ -141,7 +141,7 @@ NewsFeed::~NewsFeed() } } -UserNotify *NewsFeed::getUserNotify(QObject *parent) +UserNotify *NewsFeed::createUserNotify(QObject *parent) { return new NewsFeedUserNotify(this, parent); } diff --git a/retroshare-gui/src/gui/NewsFeed.h b/retroshare-gui/src/gui/NewsFeed.h index ec9aabcb5..9f43c0df8 100644 --- a/retroshare-gui/src/gui/NewsFeed.h +++ b/retroshare-gui/src/gui/NewsFeed.h @@ -70,7 +70,7 @@ public: virtual QString pageName() const { return tr("Log") ; } //MainPage virtual QString helpText() const { return ""; } //MainPage - virtual UserNotify *getUserNotify(QObject *parent); + virtual UserNotify *createUserNotify(QObject *parent) override; /* FeedHolder Functions (for FeedItem functionality) */ virtual QScrollArea *getScrollArea(); diff --git a/retroshare-gui/src/gui/Posted/PostedDialog.cpp b/retroshare-gui/src/gui/Posted/PostedDialog.cpp index edf09ff20..f4a59ad03 100644 --- a/retroshare-gui/src/gui/Posted/PostedDialog.cpp +++ b/retroshare-gui/src/gui/Posted/PostedDialog.cpp @@ -26,6 +26,7 @@ #include "gui/gxs/GxsGroupShareKey.h" #include "gui/settings/rsharesettings.h" #include "gui/common/GroupTreeWidget.h" +#include "util/qtthreadsutils.h" #include @@ -43,13 +44,41 @@ public: PostedDialog::PostedDialog(QWidget *parent) : GxsGroupFrameDialog(rsPosted, parent) { + mEventHandlerId = 0; + // Needs to be asynced because this function is likely to be called by another thread! + + rsEvents->registerEventsHandler(RsEventType::GXS_POSTED, [this](std::shared_ptr event) { RsQThreadUtils::postToObject( [=]() { handleEvent_main_thread(event); }, this ); }, mEventHandlerId ); } +void PostedDialog::handleEvent_main_thread(std::shared_ptr event) +{ + if(event->mType == RsEventType::GXS_POSTED) + { + const RsGxsPostedEvent *e = dynamic_cast(event.get()); + if(!e) return; + + switch(e->mPostedEventCode) + { + case RsPostedEventCode::NEW_MESSAGE: + case RsPostedEventCode::NEW_POSTED_GROUP: // [[fallthrough]]; + case RsPostedEventCode::UPDATED_MESSAGE: // [[fallthrough]]; + updateDisplay(false); + break; + + case RsPostedEventCode::SUBSCRIBE_STATUS_CHANGED: // [[fallthrough]]; + updateDisplay(true); + break; + default: break; + } + } +} + + PostedDialog::~PostedDialog() { } -UserNotify *PostedDialog::getUserNotify(QObject *parent) +UserNotify *PostedDialog::createUserNotify(QObject *parent) { return new PostedUserNotify(rsPosted, parent); } diff --git a/retroshare-gui/src/gui/Posted/PostedDialog.h b/retroshare-gui/src/gui/Posted/PostedDialog.h index e3f681aa8..7f23ee24f 100644 --- a/retroshare-gui/src/gui/Posted/PostedDialog.h +++ b/retroshare-gui/src/gui/Posted/PostedDialog.h @@ -40,9 +40,8 @@ public: virtual QString pageName() const { return tr("Links") ; } //MainPage virtual QString helpText() const { return ""; } //MainPage - virtual UserNotify *getUserNotify(QObject *parent); - protected: + virtual UserNotify *createUserNotify(QObject *parent) override; virtual QString getHelpString() const ; virtual RetroShareLink::enumType getLinkType() { return RetroShareLink::TYPE_POSTED; } virtual GroupFrameSettings::Type groupFrameSettingsType() { return GroupFrameSettings::Posted; } @@ -61,6 +60,9 @@ private: virtual QWidget *createCommentHeaderWidget(const RsGxsGroupId &grpId, const RsGxsMessageId &msgId); virtual uint32_t requestGroupSummaryType() { return GXS_REQUEST_TYPE_GROUP_DATA; } // request complete group data virtual void loadGroupSummaryToken(const uint32_t &token, std::list &groupInfo, RsUserdata* &userdata); + + void handleEvent_main_thread(std::shared_ptr event); + RsEventsHandlerId_t mEventHandlerId; }; #endif diff --git a/retroshare-gui/src/gui/Posted/PostedListWidget.cpp b/retroshare-gui/src/gui/Posted/PostedListWidget.cpp index 9c86a2f9a..1373c6d9b 100644 --- a/retroshare-gui/src/gui/Posted/PostedListWidget.cpp +++ b/retroshare-gui/src/gui/Posted/PostedListWidget.cpp @@ -23,6 +23,7 @@ #include "PostedListWidget.h" #include "ui_PostedListWidget.h" +#include "util/qtthreadsutils.h" #include "gui/gxs/GxsIdDetails.h" #include "PostedCreatePostDialog.h" #include "PostedItem.h" @@ -94,7 +95,6 @@ PostedListWidget::PostedListWidget(const RsGxsGroupId &postedId, QWidget *parent /* Initialize GUI */ setGroupId(postedId); } - PostedListWidget::~PostedListWidget() { // save settings diff --git a/retroshare-gui/src/gui/gxs/GxsGroupFrameDialog.cpp b/retroshare-gui/src/gui/gxs/GxsGroupFrameDialog.cpp index a3984ae53..c54f6171f 100644 --- a/retroshare-gui/src/gui/gxs/GxsGroupFrameDialog.cpp +++ b/retroshare-gui/src/gui/gxs/GxsGroupFrameDialog.cpp @@ -1173,6 +1173,8 @@ void GxsGroupFrameDialog::loadGroupStatistics(const uint32_t &token) } ui->groupTreeWidget->setUnreadCount(item, mCountChildMsgs ? (stats.mNumThreadMsgsUnread + stats.mNumChildMsgsUnread) : stats.mNumThreadMsgsUnread); + + getUserNotify()->updateIcon(); } /*********************** **** **** **** ***********************/ diff --git a/retroshare-gui/src/gui/gxs/GxsGroupFrameDialog.h b/retroshare-gui/src/gui/gxs/GxsGroupFrameDialog.h index 4e77ccb44..cc1fa7843 100644 --- a/retroshare-gui/src/gui/gxs/GxsGroupFrameDialog.h +++ b/retroshare-gui/src/gui/gxs/GxsGroupFrameDialog.h @@ -96,6 +96,8 @@ protected: virtual void groupInfoToGroupItemInfo(const RsGroupMetaData &groupInfo, GroupItemInfo &groupItemInfo, const RsUserdata *userdata); virtual void checkRequestGroup(const RsGxsGroupId& /* grpId */) {} // overload this one in order to retrieve full group data when the group is browsed + void updateMessageSummaryList(RsGxsGroupId groupId); + private slots: void todo(); @@ -153,7 +155,6 @@ private: void initUi(); - void updateMessageSummaryList(RsGxsGroupId groupId); void updateSearchResults(); void openGroupInNewTab(const RsGxsGroupId &groupId); diff --git a/retroshare-gui/src/gui/gxschannels/GxsChannelDialog.cpp b/retroshare-gui/src/gui/gxschannels/GxsChannelDialog.cpp index 2e1b6dc7e..67bbce334 100644 --- a/retroshare-gui/src/gui/gxschannels/GxsChannelDialog.cpp +++ b/retroshare-gui/src/gui/gxschannels/GxsChannelDialog.cpp @@ -64,7 +64,11 @@ void GxsChannelDialog::handleEvent_main_thread(std::shared_ptr ev switch(e->mChannelEventCode) { - case RsChannelEventCode::SUBSCRIBE_STATUS_CHANGED: updateDisplay(true); + case RsChannelEventCode::READ_STATUS_CHANGED: + updateMessageSummaryList(e->mChannelGroupId); + break; + case RsChannelEventCode::SUBSCRIBE_STATUS_CHANGED: + updateDisplay(true); break; default: break; @@ -92,7 +96,7 @@ QString GxsChannelDialog::getHelpString() const return hlp_str ; } -UserNotify *GxsChannelDialog::getUserNotify(QObject *parent) +UserNotify *GxsChannelDialog::createUserNotify(QObject *parent) { return new GxsChannelUserNotify(rsGxsChannels, parent); } diff --git a/retroshare-gui/src/gui/gxschannels/GxsChannelDialog.h b/retroshare-gui/src/gui/gxschannels/GxsChannelDialog.h index 5d80be518..4c9c6eb95 100644 --- a/retroshare-gui/src/gui/gxschannels/GxsChannelDialog.h +++ b/retroshare-gui/src/gui/gxschannels/GxsChannelDialog.h @@ -39,8 +39,6 @@ public: virtual QString pageName() const { return tr("Channels") ; } //MainPage virtual QString helpText() const { return ""; } //MainPage - virtual UserNotify *getUserNotify(QObject *parent); - void shareOnChannel(const RsGxsGroupId& channel_id, const QList& file_link) ; protected: @@ -54,6 +52,7 @@ protected: virtual TurtleRequestId distantSearch(const QString& search_string) ; virtual void checkRequestGroup(const RsGxsGroupId& grpId) ; + virtual UserNotify *createUserNotify(QObject *parent) override; private slots: void toggleAutoDownload(); void setDefaultDirectory(); diff --git a/retroshare-gui/src/gui/gxsforums/GxsForumsDialog.cpp b/retroshare-gui/src/gui/gxsforums/GxsForumsDialog.cpp index 2282db1bb..839908ba0 100644 --- a/retroshare-gui/src/gui/gxsforums/GxsForumsDialog.cpp +++ b/retroshare-gui/src/gui/gxsforums/GxsForumsDialog.cpp @@ -102,7 +102,7 @@ void GxsForumsDialog::shareInMessage(const RsGxsGroupId& forum_id,const QListshow(); } -UserNotify *GxsForumsDialog::getUserNotify(QObject *parent) +UserNotify *GxsForumsDialog::createUserNotify(QObject *parent) { return new GxsForumUserNotify(rsGxsForums, parent); } diff --git a/retroshare-gui/src/gui/gxsforums/GxsForumsDialog.h b/retroshare-gui/src/gui/gxsforums/GxsForumsDialog.h index 6a21c8de9..9b6da9d00 100644 --- a/retroshare-gui/src/gui/gxsforums/GxsForumsDialog.h +++ b/retroshare-gui/src/gui/gxsforums/GxsForumsDialog.h @@ -37,11 +37,11 @@ public: virtual QString pageName() const { return tr("Forums") ; } //MainPage virtual QString helpText() const { return ""; } //MainPage - virtual UserNotify *getUserNotify(QObject *parent); - void shareInMessage(const RsGxsGroupId& forum_id, const QList& file_link) ; protected: + virtual UserNotify *createUserNotify(QObject *parent) override; + virtual QString getHelpString() const ; virtual RetroShareLink::enumType getLinkType() { return RetroShareLink::TYPE_FORUM; } virtual GroupFrameSettings::Type groupFrameSettingsType() { return GroupFrameSettings::Forum; } diff --git a/retroshare-gui/src/gui/msgs/MessagesDialog.cpp b/retroshare-gui/src/gui/msgs/MessagesDialog.cpp index fca0e8cbf..62a027a51 100644 --- a/retroshare-gui/src/gui/msgs/MessagesDialog.cpp +++ b/retroshare-gui/src/gui/msgs/MessagesDialog.cpp @@ -325,7 +325,7 @@ MessagesDialog::~MessagesDialog() processSettings(false); } -UserNotify *MessagesDialog::getUserNotify(QObject *parent) +UserNotify *MessagesDialog::createUserNotify(QObject *parent) { return new MessageUserNotify(parent); } diff --git a/retroshare-gui/src/gui/msgs/MessagesDialog.h b/retroshare-gui/src/gui/msgs/MessagesDialog.h index 1671df268..a8115d466 100644 --- a/retroshare-gui/src/gui/msgs/MessagesDialog.h +++ b/retroshare-gui/src/gui/msgs/MessagesDialog.h @@ -50,8 +50,6 @@ public: virtual QString pageName() const { return tr("Mail") ; } //MainPage virtual QString helpText() const { return ""; } //MainPage - virtual UserNotify *getUserNotify(QObject *parent); - // replaced by shortcut // virtual void keyPressEvent(QKeyEvent *) ; @@ -64,6 +62,7 @@ signals: void messagesLoaded(); protected: + virtual UserNotify *createUserNotify(QObject *parent) override; bool eventFilter(QObject *obj, QEvent *ev); int getSelectedMessages(QList& mid); diff --git a/retroshare-gui/src/retroshare-gui/mainpage.h b/retroshare-gui/src/retroshare-gui/mainpage.h index dc1853556..c96706e7e 100644 --- a/retroshare-gui/src/retroshare-gui/mainpage.h +++ b/retroshare-gui/src/retroshare-gui/mainpage.h @@ -55,14 +55,19 @@ public: void setHelpText(QString help) { mHelp = help; } virtual void retranslateUi() {} - virtual UserNotify *getUserNotify(QObject */*parent*/) { return NULL; } + + // Override this if needed. + virtual UserNotify *createUserNotify(QObject */*parent*/) { return NULL; } // Call this to add some help info to the page. The way the info is // shown is handled by showHelp() below; // void registerHelpButton(QToolButton *button, const QString& help_html_text, const QString &code_name) ; + UserNotify *getUserNotify() ; + protected: + virtual void showEvent(QShowEvent *); private: @@ -71,6 +76,8 @@ private: QString mName; QString mHelp; QString mHelpCodeName; + + UserNotify *mUserNotify; }; #endif From 90bb6c0011f53a12b5afa6c200bc6b7a894e3ff3 Mon Sep 17 00:00:00 2001 From: csoler Date: Mon, 27 Jan 2020 21:38:57 +0100 Subject: [PATCH 38/44] fixed notifications in forums, posted and channels --- libretroshare/src/gxstrans/p3gxstrans.cc | 5 ++--- libretroshare/src/retroshare/rsgxsforums.h | 13 ++++--------- libretroshare/src/retroshare/rsposted.h | 1 + libretroshare/src/services/p3gxschannels.cc | 4 +--- libretroshare/src/services/p3gxscircles.cc | 6 +++--- libretroshare/src/services/p3gxsforums.cc | 15 +++++++++++---- libretroshare/src/services/p3idservice.cc | 4 ++-- libretroshare/src/services/p3postbase.cc | 16 ++++++++++++---- retroshare-gui/src/gui/Posted/PostedDialog.cpp | 13 ++++++++++--- .../src/gui/gxs/GxsGroupFrameDialog.cpp | 1 + .../src/gui/gxschannels/GxsChannelDialog.cpp | 13 ++++++++++++- .../src/gui/gxsforums/GxsForumsDialog.cpp | 16 +++++++++++++++- 12 files changed, 74 insertions(+), 33 deletions(-) diff --git a/libretroshare/src/gxstrans/p3gxstrans.cc b/libretroshare/src/gxstrans/p3gxstrans.cc index d6d6069b4..44ecccbd1 100644 --- a/libretroshare/src/gxstrans/p3gxstrans.cc +++ b/libretroshare/src/gxstrans/p3gxstrans.cc @@ -656,8 +656,7 @@ void p3GxsTrans::notifyChanges(std::vector& changes) #ifdef DEBUG_GXSTRANS std::cout << "p3GxsTrans::notifyChanges(...)" << std::endl; #endif - for( std::vector::const_iterator it = changes.begin(); - it != changes.end(); ++it ) + for( auto it = changes.begin(); it != changes.end(); ++it ) { RsGxsGroupChange* grpChange = dynamic_cast(*it); RsGxsMsgChange* msgChange = dynamic_cast(*it); @@ -697,8 +696,8 @@ void p3GxsTrans::notifyChanges(std::vector& changes) } #endif } + delete *it; } - RsGxsIfaceHelper::receiveChanges(changes); } uint32_t p3GxsTrans::AuthenPolicy() diff --git a/libretroshare/src/retroshare/rsgxsforums.h b/libretroshare/src/retroshare/rsgxsforums.h index 1ce658ab3..becddb329 100644 --- a/libretroshare/src/retroshare/rsgxsforums.h +++ b/libretroshare/src/retroshare/rsgxsforums.h @@ -110,15 +110,10 @@ enum class RsForumEventCode: uint8_t UNKNOWN = 0x00, NEW_FORUM = 0x01, /// emitted when new forum is received UPDATED_FORUM = 0x02, /// emitted when existing forum is updated - - /// new message reeived in a particular forum - NEW_MESSAGE = 0x03, - - /// existing message has been updated in a particular forum - UPDATED_MESSAGE = 0x04, - - /// forum was subscribed or unsubscribed - SUBSCRIBE_STATUS_CHANGED = 0x05, + NEW_MESSAGE = 0x03, /// new message reeived in a particular forum + UPDATED_MESSAGE = 0x04, /// existing message has been updated in a particular forum + SUBSCRIBE_STATUS_CHANGED = 0x05, /// forum was subscribed or unsubscribed + READ_STATUS_CHANGED = 0x06, /// msg was read or marked unread }; struct RsGxsForumEvent: RsEvent diff --git a/libretroshare/src/retroshare/rsposted.h b/libretroshare/src/retroshare/rsposted.h index c8f3a313a..a1dbdf83c 100644 --- a/libretroshare/src/retroshare/rsposted.h +++ b/libretroshare/src/retroshare/rsposted.h @@ -76,6 +76,7 @@ enum class RsPostedEventCode: uint8_t SUBSCRIBE_STATUS_CHANGED = 0x03, UPDATED_POSTED_GROUP = 0x04, UPDATED_MESSAGE = 0x05, + READ_STATUS_CHANGED = 0x06, }; diff --git a/libretroshare/src/services/p3gxschannels.cc b/libretroshare/src/services/p3gxschannels.cc index e97c2389c..0ccdafc03 100644 --- a/libretroshare/src/services/p3gxschannels.cc +++ b/libretroshare/src/services/p3gxschannels.cc @@ -364,13 +364,11 @@ void p3GxsChannels::notifyChanges(std::vector &changes) } /* shouldn't need to worry about groups - as they need to be subscribed to */ + delete *it; } if(!unprocessedGroups.empty()) request_SpecificSubscribedGroups(unprocessedGroups); - -// // the call below deletes changes and its content. -// RsGxsIfaceHelper::receiveChanges(changes); } void p3GxsChannels::service_tick() diff --git a/libretroshare/src/services/p3gxscircles.cc b/libretroshare/src/services/p3gxscircles.cc index b5b7ae9ad..3cdf50147 100644 --- a/libretroshare/src/services/p3gxscircles.cc +++ b/libretroshare/src/services/p3gxscircles.cc @@ -477,8 +477,8 @@ void p3GxsCircles::notifyChanges(std::vector &changes) #endif p3Notify *notify = RsServer::notify(); - std::vector::iterator it; - for(it = changes.begin(); it != changes.end(); ++it) + + for(auto it = changes.begin(); it != changes.end(); ++it) { RsGxsGroupChange *groupChange = dynamic_cast(*it); RsGxsMsgChange *msgChange = dynamic_cast(*it); @@ -605,8 +605,8 @@ void p3GxsCircles::notifyChanges(std::vector &changes) } } + delete *it; } - RsGxsIfaceHelper::receiveChanges(changes); // this clear up the vector and delete its elements } /********************************************************************************/ diff --git a/libretroshare/src/services/p3gxsforums.cc b/libretroshare/src/services/p3gxsforums.cc index 6ef0dae34..b8c414df0 100644 --- a/libretroshare/src/services/p3gxsforums.cc +++ b/libretroshare/src/services/p3gxsforums.cc @@ -315,9 +315,9 @@ void p3GxsForums::notifyChanges(std::vector &changes) } /* shouldn't need to worry about groups - as they need to be subscribed to */ - } - RsGxsIfaceHelper::receiveChanges(changes); + delete *it; + } } void p3GxsForums::service_tick() @@ -861,12 +861,19 @@ void p3GxsForums::setMessageReadStatus(uint32_t& token, const RsGxsGrpMsgIdPair& uint32_t mask = GXS_SERV::GXS_MSG_STATUS_GUI_NEW | GXS_SERV::GXS_MSG_STATUS_GUI_UNREAD; uint32_t status = GXS_SERV::GXS_MSG_STATUS_GUI_UNREAD; if (read) - { status = 0; - } setMsgStatusFlags(token, msgId, status, mask); + if (rsEvents) + { + auto ev = std::make_shared(); + + ev->mForumMsgId = msgId.second; + ev->mForumGroupId = msgId.first; + ev->mForumEventCode = RsForumEventCode::READ_STATUS_CHANGED; + rsEvents->postEvent(ev); + } } /********************************************************************************************/ diff --git a/libretroshare/src/services/p3idservice.cc b/libretroshare/src/services/p3idservice.cc index 85de0abcb..c75f8ee72 100644 --- a/libretroshare/src/services/p3idservice.cc +++ b/libretroshare/src/services/p3idservice.cc @@ -661,9 +661,9 @@ void p3IdService::notifyChanges(std::vector &changes) changes[i] = NULL ; } } - } - RsGxsIfaceHelper::receiveChanges(changes); + delete changes[i]; + } } /********************************************************************************/ diff --git a/libretroshare/src/services/p3postbase.cc b/libretroshare/src/services/p3postbase.cc index a7e4cd476..309c3ee16 100644 --- a/libretroshare/src/services/p3postbase.cc +++ b/libretroshare/src/services/p3postbase.cc @@ -87,9 +87,7 @@ void p3PostBase::notifyChanges(std::vector &changes) std::cerr << std::endl; #endif - std::vector::iterator it; - - for(it = changes.begin(); it != changes.end(); ++it) + for(auto it = changes.begin(); it != changes.end(); ++it) { RsGxsMsgChange *msgChange = dynamic_cast(*it); @@ -173,8 +171,9 @@ void p3PostBase::notifyChanges(std::vector &changes) break; } } + + delete *it; } - receiveHelperChanges(changes); #ifdef POSTBASE_DEBUG std::cerr << "p3PostBase::notifyChanges() -> receiveChanges()"; @@ -206,6 +205,15 @@ void p3PostBase::setMessageReadStatus(uint32_t& token, const RsGxsGrpMsgIdPair& setMsgStatusFlags(token, msgId, status, mask); + if (rsEvents) + { + auto ev = std::make_shared(); + + ev->mPostedMsgId = msgId.second; + ev->mPostedGroupId = msgId.first; + ev->mPostedEventCode = RsPostedEventCode::READ_STATUS_CHANGED; + rsEvents->postEvent(ev); + } } diff --git a/retroshare-gui/src/gui/Posted/PostedDialog.cpp b/retroshare-gui/src/gui/Posted/PostedDialog.cpp index f4a59ad03..5e743b957 100644 --- a/retroshare-gui/src/gui/Posted/PostedDialog.cpp +++ b/retroshare-gui/src/gui/Posted/PostedDialog.cpp @@ -60,14 +60,21 @@ void PostedDialog::handleEvent_main_thread(std::shared_ptr event) switch(e->mPostedEventCode) { case RsPostedEventCode::NEW_MESSAGE: - case RsPostedEventCode::NEW_POSTED_GROUP: // [[fallthrough]]; + updateMessageSummaryList(e->mPostedGroupId); + break; + case RsPostedEventCode::UPDATED_MESSAGE: // [[fallthrough]]; updateDisplay(false); break; + case RsPostedEventCode::READ_STATUS_CHANGED: // [[fallthrough]]; + updateMessageSummaryList(e->mPostedGroupId); + break; + + case RsPostedEventCode::NEW_POSTED_GROUP: // [[fallthrough]]; case RsPostedEventCode::SUBSCRIBE_STATUS_CHANGED: // [[fallthrough]]; - updateDisplay(true); - break; + updateDisplay(true); + break; default: break; } } diff --git a/retroshare-gui/src/gui/gxs/GxsGroupFrameDialog.cpp b/retroshare-gui/src/gui/gxs/GxsGroupFrameDialog.cpp index c54f6171f..d2aa30ce3 100644 --- a/retroshare-gui/src/gui/gxs/GxsGroupFrameDialog.cpp +++ b/retroshare-gui/src/gui/gxs/GxsGroupFrameDialog.cpp @@ -32,6 +32,7 @@ #include "gui/common/RSTreeWidget.h" #include "gui/notifyqt.h" #include "gui/common/UIStateHelper.h" +#include "gui/common/UserNotify.h" #include "GxsCommentDialog.h" //#define DEBUG_GROUPFRAMEDIALOG diff --git a/retroshare-gui/src/gui/gxschannels/GxsChannelDialog.cpp b/retroshare-gui/src/gui/gxschannels/GxsChannelDialog.cpp index 67bbce334..f031772b3 100644 --- a/retroshare-gui/src/gui/gxschannels/GxsChannelDialog.cpp +++ b/retroshare-gui/src/gui/gxschannels/GxsChannelDialog.cpp @@ -64,12 +64,23 @@ void GxsChannelDialog::handleEvent_main_thread(std::shared_ptr ev switch(e->mChannelEventCode) { - case RsChannelEventCode::READ_STATUS_CHANGED: + case RsChannelEventCode::NEW_MESSAGE: updateMessageSummaryList(e->mChannelGroupId); break; + + case RsChannelEventCode::UPDATED_MESSAGE: // [[fallthrough]]; + updateDisplay(false); + break; + + case RsChannelEventCode::READ_STATUS_CHANGED: + updateMessageSummaryList(e->mChannelGroupId); + break; + + case RsChannelEventCode::NEW_CHANNEL: // [[fallthrough]]; case RsChannelEventCode::SUBSCRIBE_STATUS_CHANGED: updateDisplay(true); break; + default: break; } diff --git a/retroshare-gui/src/gui/gxsforums/GxsForumsDialog.cpp b/retroshare-gui/src/gui/gxsforums/GxsForumsDialog.cpp index 839908ba0..7d5889e4d 100644 --- a/retroshare-gui/src/gui/gxsforums/GxsForumsDialog.cpp +++ b/retroshare-gui/src/gui/gxsforums/GxsForumsDialog.cpp @@ -59,7 +59,21 @@ void GxsForumsDialog::handleEvent_main_thread(std::shared_ptr eve switch(e->mForumEventCode) { - case RsForumEventCode::SUBSCRIBE_STATUS_CHANGED: updateDisplay(true); + case RsForumEventCode::NEW_MESSAGE: + updateMessageSummaryList(e->mForumGroupId); + break; + + case RsForumEventCode::UPDATED_MESSAGE: // [[fallthrough]]; + updateDisplay(false); + break; + + case RsForumEventCode::READ_STATUS_CHANGED: + updateMessageSummaryList(e->mForumGroupId); + break; + + case RsForumEventCode::NEW_FORUM: // [[fallthrough]]; + case RsForumEventCode::SUBSCRIBE_STATUS_CHANGED: + updateDisplay(true); break; default: break; From 424e7be52fa566ea59356efbc0eab427360876ca Mon Sep 17 00:00:00 2001 From: csoler Date: Mon, 27 Jan 2020 23:02:04 +0100 Subject: [PATCH 39/44] added notifications for identities --- libretroshare/src/retroshare/rsevents.h | 3 ++ libretroshare/src/retroshare/rsidentity.h | 26 +++++++++++ libretroshare/src/services/p3idservice.cc | 45 ++++++++++++------- .../src/gui/Circles/CirclesDialog.cpp | 13 +----- .../src/gui/Circles/CirclesDialog.h | 26 ----------- retroshare-gui/src/gui/Identity/IdDialog.cpp | 28 ++++++++++++ retroshare-gui/src/gui/Identity/IdDialog.h | 3 ++ 7 files changed, 92 insertions(+), 52 deletions(-) diff --git a/libretroshare/src/retroshare/rsevents.h b/libretroshare/src/retroshare/rsevents.h index 7d6d24505..d89846e1a 100644 --- a/libretroshare/src/retroshare/rsevents.h +++ b/libretroshare/src/retroshare/rsevents.h @@ -85,6 +85,9 @@ enum class RsEventType : uint32_t /// @see RsGxsPostedEvent GXS_POSTED = 11, + /// @see RsGxsPostedEvent + GXS_IDENTITY = 12, + MAX /// Used to detect invalid event type passed }; diff --git a/libretroshare/src/retroshare/rsidentity.h b/libretroshare/src/retroshare/rsidentity.h index 67844cde0..2874ccc91 100644 --- a/libretroshare/src/retroshare/rsidentity.h +++ b/libretroshare/src/retroshare/rsidentity.h @@ -304,6 +304,32 @@ private: RsIdentityUsage(); }; +enum class RsGxsIdentityEventCode: uint8_t +{ + UNKNOWN = 0x00, + NEW_IDENTITY = 0x01, + DELETED_IDENTITY = 0x02, +}; + +struct RsGxsIdentityEvent: public RsEvent +{ + RsGxsIdentityEvent() + : RsEvent(RsEventType::GXS_IDENTITY), + mIdentityEventCode(RsGxsIdentityEventCode::UNKNOWN) {} + + RsGxsIdentityEventCode mIdentityEventCode; + RsGxsGroupId mIdentityId; + + ///* @see RsEvent @see RsSerializable + void serial_process( RsGenericSerializer::SerializeJob j, RsGenericSerializer::SerializeContext& ctx ) override + { + RsEvent::serial_process(j, ctx); + RS_SERIAL_PROCESS(mIdentityEventCode); + RS_SERIAL_PROCESS(mIdentityId); + } + + ~RsGxsIdentityEvent() override = default; +}; struct RsIdentityDetails : RsSerializable { diff --git a/libretroshare/src/services/p3idservice.cc b/libretroshare/src/services/p3idservice.cc index c75f8ee72..861c5c224 100644 --- a/libretroshare/src/services/p3idservice.cc +++ b/libretroshare/src/services/p3idservice.cc @@ -603,7 +603,6 @@ void p3IdService::notifyChanges(std::vector &changes) for(uint32_t i = 0;i(changes[i]); RsGxsMsgChange *msgChange = dynamic_cast(changes[i]); if (msgChange && !msgChange->metaChange()) @@ -614,8 +613,8 @@ void p3IdService::notifyChanges(std::vector &changes) #endif std::map > &msgChangeMap = msgChange->msgChangeMap; - std::map >::iterator mit; - for(mit = msgChangeMap.begin(); mit != msgChangeMap.end(); ++mit) + + for(auto mit = msgChangeMap.begin(); mit != msgChangeMap.end(); ++mit) { #ifdef DEBUG_IDS std::cerr << "p3IdService::notifyChanges() Msgs for Group: " << mit->first; @@ -624,7 +623,8 @@ void p3IdService::notifyChanges(std::vector &changes) } } - /* shouldn't need to worry about groups - as they need to be subscribed to */ + RsGxsGroupChange *groupChange = dynamic_cast(changes[i]); + if (groupChange && !groupChange->metaChange()) { #ifdef DEBUG_IDS @@ -632,9 +632,8 @@ void p3IdService::notifyChanges(std::vector &changes) std::cerr << std::endl; #endif std::list &groupList = groupChange->mGrpIdList; - std::list::iterator git; - for(git = groupList.begin(); git != groupList.end();) + for(auto git = groupList.begin(); git != groupList.end();++git) { #ifdef DEBUG_IDS std::cerr << "p3IdService::notifyChanges() Auto Subscribe to Incoming Groups: " << *git; @@ -649,16 +648,24 @@ void p3IdService::notifyChanges(std::vector &changes) timeStampKey(RsGxsId(*git),RsIdentityUsage(serviceType(),RsIdentityUsage::IDENTITY_DATA_UPDATE)) ; - ++git; - } - else - git = groupList.erase(git) ; - } + // notify that a new identity is received, if needed - if(groupList.empty()) - { - delete changes[i] ; - changes[i] = NULL ; + switch(groupChange->getType()) + { + case RsGxsNotify::TYPE_PUBLISHED: + case RsGxsNotify::TYPE_RECEIVED_NEW: + { + auto ev = std::make_shared(); + ev->mIdentityId = *git; + ev->mIdentityEventCode = RsGxsIdentityEventCode::NEW_IDENTITY; + rsEvents->postEvent(ev); + } + break; + + default: + break; + } + } } } @@ -1070,6 +1077,14 @@ bool p3IdService::deleteIdentity(RsGxsId& id) return false; } + if(rsEvents) + { + auto ev = std::make_shared(); + ev->mIdentityId = grouId; + ev->mIdentityEventCode = RsGxsIdentityEventCode::DELETED_IDENTITY; + rsEvents->postEvent(ev); + } + return true; } diff --git a/retroshare-gui/src/gui/Circles/CirclesDialog.cpp b/retroshare-gui/src/gui/Circles/CirclesDialog.cpp index 8be03e718..64dff16df 100644 --- a/retroshare-gui/src/gui/Circles/CirclesDialog.cpp +++ b/retroshare-gui/src/gui/Circles/CirclesDialog.cpp @@ -62,9 +62,6 @@ CirclesDialog::CirclesDialog(QWidget *parent) mStateHelper->addWidget(CIRCLESDIALOG_GROUPMETA, ui.pushButton_editCircle); mStateHelper->addWidget(CIRCLESDIALOG_GROUPMETA, ui.treeWidget_membership, UISTATE_ACTIVE_ENABLED); -// mStateHelper->addWidget(CIRCLESDIALOG_GROUPMETA, ui.treeWidget_friends, UISTATE_ACTIVE_ENABLED); -// mStateHelper->addWidget(CIRCLESDIALOG_GROUPMETA, ui.treeWidget_category, UISTATE_ACTIVE_ENABLED); - mStateHelper->setWidgetEnabled(ui.pushButton_editCircle, false); /* Connect signals */ @@ -74,19 +71,13 @@ CirclesDialog::CirclesDialog(QWidget *parent) connect(ui.todoPushButton, SIGNAL(clicked()), this, SLOT(todo())); connect(ui.treeWidget_membership, SIGNAL(itemSelectionChanged()), this, SLOT(circle_selected())); -// connect(ui.treeWidget_friends, SIGNAL(itemSelectionChanged()), this, SLOT(friend_selected())); -// connect(ui.treeWidget_category, SIGNAL(itemSelectionChanged()), this, SLOT(category_selected())); /* Setup TokenQueue */ mCircleQueue = new TokenQueue(rsGxsCircles->getTokenService(), this); /* Set header resize modes and initial section sizes */ - QHeaderView * membership_header = ui.treeWidget_membership->header () ; - membership_header->resizeSection ( CIRCLEGROUP_CIRCLE_COL_GROUPNAME, 200 ); - -// QHeaderView * friends_header = ui.treeWidget_friends->header () ; -// friends_header->resizeSection ( CIRCLEGROUP_FRIEND_COL_NAME, 200 ); - + QHeaderView * membership_header = ui.treeWidget_membership->header () ; + membership_header->resizeSection ( CIRCLEGROUP_CIRCLE_COL_GROUPNAME, 200 ); } CirclesDialog::~CirclesDialog() diff --git a/retroshare-gui/src/gui/Circles/CirclesDialog.h b/retroshare-gui/src/gui/Circles/CirclesDialog.h index 7c96febad..ecaff3f29 100644 --- a/retroshare-gui/src/gui/Circles/CirclesDialog.h +++ b/retroshare-gui/src/gui/Circles/CirclesDialog.h @@ -58,35 +58,9 @@ private slots: void friend_selected(); void category_selected(); -#if 0 - void OpenOrShowAddPageDialog(); - void OpenOrShowAddGroupDialog(); - void OpenOrShowEditDialog(); - void OpenOrShowRepublishDialog(); - - void groupTreeChanged(); - - void newGroup(); - void showGroupDetails(); - void editGroupDetails(); - - void insertWikiGroups(); -#endif - private: void reloadAll(); -#if 0 - voidclearWikiPage(); - void clearGroupTree(); - - void updateWikiPage(const RsWikiSnapshot &page); - - bool getSelectedPage(std::string &groupId, std::string &pageId, std::string &origPageId); - std::string getSelectedPage(); - std::string getSelectedGroup(); -#endif - void requestGroupMeta(); void loadGroupMeta(const uint32_t &token); diff --git a/retroshare-gui/src/gui/Identity/IdDialog.cpp b/retroshare-gui/src/gui/Identity/IdDialog.cpp index 5d8c45804..a1dc6d06d 100644 --- a/retroshare-gui/src/gui/Identity/IdDialog.cpp +++ b/retroshare-gui/src/gui/Identity/IdDialog.cpp @@ -35,10 +35,12 @@ #include "gui/chat/ChatDialog.h" #include "gui/Circles/CreateCircleDialog.h" #include "gui/common/UIStateHelper.h" +#include "gui/common/UserNotify.h" #include "gui/gxs/GxsIdDetails.h" #include "gui/gxs/RsGxsUpdateBroadcastBase.h" #include "gui/msgs/MessageComposer.h" #include "gui/settings/rsharesettings.h" +#include "util/qtthreadsutils.h" #include "retroshare-gui/RsAutoUpdatePage.h" #include "util/misc.h" #include "util/QtVersion.h" @@ -148,6 +150,9 @@ IdDialog::IdDialog(QWidget *parent) : mIdQueue = NULL; + mEventHandlerId = 0; + rsEvents->registerEventsHandler(RsEventType::GXS_IDENTITY, [this](std::shared_ptr event) { RsQThreadUtils::postToObject( [=]() { handleEvent_main_thread(event); }, this ); }, mEventHandlerId ); + // This is used to grab the broadcast of changes from p3GxsCircles, which is discarded by the current dialog, since it expects data for p3Identity only. mCirclesBroadcastBase = new RsGxsUpdateBroadcastBase(rsGxsCircles, this); connect(mCirclesBroadcastBase, SIGNAL(fillDisplay(bool)), this, SLOT(updateCirclesDisplay(bool))); @@ -398,6 +403,29 @@ IdDialog::IdDialog(QWidget *parent) : tmer->start(10000) ; // update every 10 secs. } +void IdDialog::handleEvent_main_thread(std::shared_ptr event) +{ + if(event->mType != RsEventType::GXS_IDENTITY) + return; + + const RsGxsIdentityEvent *e = dynamic_cast(event.get()); + + if(!e) + return; + + switch(e->mIdentityEventCode) + { + case RsGxsIdentityEventCode::DELETED_IDENTITY: + case RsGxsIdentityEventCode::NEW_IDENTITY: + + requestIdList(); + getUserNotify()->updateIcon(); + + default: + break; + } +} + void IdDialog::clearPerson() { QFontMetricsF f(ui->avLabel_Person->font()) ; diff --git a/retroshare-gui/src/gui/Identity/IdDialog.h b/retroshare-gui/src/gui/Identity/IdDialog.h index 30f2d0641..92ba76ee1 100644 --- a/retroshare-gui/src/gui/Identity/IdDialog.h +++ b/retroshare-gui/src/gui/Identity/IdDialog.h @@ -158,6 +158,9 @@ private: RsGxsGroupId mIdToNavigate; int filter; + void handleEvent_main_thread(std::shared_ptr event); + RsEventsHandlerId_t mEventHandlerId; + /* UI - Designer */ Ui::IdDialog *ui; }; From 841ba9e579022994a4751cb8a12dd5a55b61bbc4 Mon Sep 17 00:00:00 2001 From: csoler Date: Tue, 28 Jan 2020 22:22:04 +0100 Subject: [PATCH 40/44] added some missing notifications in circles dialog --- libretroshare/src/retroshare/rsgxscircles.h | 6 ++- libretroshare/src/services/p3gxscircles.cc | 8 +++ retroshare-gui/src/gui/Identity/IdDialog.cpp | 57 ++++++++++++++------ retroshare-gui/src/gui/Identity/IdDialog.h | 3 +- 4 files changed, 54 insertions(+), 20 deletions(-) diff --git a/libretroshare/src/retroshare/rsgxscircles.h b/libretroshare/src/retroshare/rsgxscircles.h index 5ef69fda8..ed38f5c2d 100644 --- a/libretroshare/src/retroshare/rsgxscircles.h +++ b/libretroshare/src/retroshare/rsgxscircles.h @@ -182,9 +182,11 @@ enum class RsGxsCircleEventCode: uint8_t /// mCircleId contains the circle id and mGxsId is the id of the new member CIRCLE_MEMBERSHIP_JOIN = 0x04, - /** mCircleId contains the circle id and mGxsId is the id that was revoqued - * by admin */ + /** mCircleId contains the circle id and mGxsId is the id that was revoqued * by admin */ CIRCLE_MEMBERSHIP_REVOQUED= 0x05, + + /** mCircleId contains the circle id */ + NEW_CIRCLE = 0x06, }; struct RsGxsCircleEvent: RsEvent diff --git a/libretroshare/src/services/p3gxscircles.cc b/libretroshare/src/services/p3gxscircles.cc index 3cdf50147..9a9b1de34 100644 --- a/libretroshare/src/services/p3gxscircles.cc +++ b/libretroshare/src/services/p3gxscircles.cc @@ -547,6 +547,14 @@ void p3GxsCircles::notifyChanges(std::vector &changes) RsStackMutex stack(mCircleMtx); /********** STACK LOCKED MTX ******/ mCircleCache.erase(RsGxsCircleId(*git)); } + + if(rsEvents && (c->getType() == RsGxsNotify::TYPE_RECEIVED_NEW|| c->getType() == RsGxsNotify::TYPE_PUBLISHED) ) + { + auto ev = std::make_shared(); + ev->mCircleId = RsGxsCircleId(*git); + ev->mCircleEventType = RsGxsCircleEventCode::NEW_CIRCLE; + rsEvents->postEvent(ev); + } } } diff --git a/retroshare-gui/src/gui/Identity/IdDialog.cpp b/retroshare-gui/src/gui/Identity/IdDialog.cpp index a1dc6d06d..4da14d29b 100644 --- a/retroshare-gui/src/gui/Identity/IdDialog.cpp +++ b/retroshare-gui/src/gui/Identity/IdDialog.cpp @@ -150,8 +150,11 @@ IdDialog::IdDialog(QWidget *parent) : mIdQueue = NULL; - mEventHandlerId = 0; - rsEvents->registerEventsHandler(RsEventType::GXS_IDENTITY, [this](std::shared_ptr event) { RsQThreadUtils::postToObject( [=]() { handleEvent_main_thread(event); }, this ); }, mEventHandlerId ); + mEventHandlerId_identity = 0; + rsEvents->registerEventsHandler(RsEventType::GXS_IDENTITY, [this](std::shared_ptr event) { RsQThreadUtils::postToObject( [=]() { handleEvent_main_thread(event); }, this ); }, mEventHandlerId_identity ); + + mEventHandlerId_circles = 0; + rsEvents->registerEventsHandler(RsEventType::GXS_CIRCLES, [this](std::shared_ptr event) { RsQThreadUtils::postToObject( [=]() { handleEvent_main_thread(event); }, this ); }, mEventHandlerId_circles ); // This is used to grab the broadcast of changes from p3GxsCircles, which is discarded by the current dialog, since it expects data for p3Identity only. mCirclesBroadcastBase = new RsGxsUpdateBroadcastBase(rsGxsCircles, this); @@ -405,25 +408,45 @@ IdDialog::IdDialog(QWidget *parent) : void IdDialog::handleEvent_main_thread(std::shared_ptr event) { - if(event->mType != RsEventType::GXS_IDENTITY) - return; - - const RsGxsIdentityEvent *e = dynamic_cast(event.get()); - - if(!e) - return; - - switch(e->mIdentityEventCode) + if(event->mType == RsEventType::GXS_IDENTITY) { - case RsGxsIdentityEventCode::DELETED_IDENTITY: - case RsGxsIdentityEventCode::NEW_IDENTITY: + const RsGxsIdentityEvent *e = dynamic_cast(event.get()); - requestIdList(); - getUserNotify()->updateIcon(); + if(!e) + return; - default: - break; + switch(e->mIdentityEventCode) + { + case RsGxsIdentityEventCode::DELETED_IDENTITY: + case RsGxsIdentityEventCode::NEW_IDENTITY: + + requestIdList(); + default: + break; + } } + else if(event->mType == RsEventType::GXS_CIRCLES) + { + const RsGxsCircleEvent *e = dynamic_cast(event.get()); + + if(!e) + return; + + switch(e->mCircleEventType) + { + case RsGxsCircleEventCode::NEW_CIRCLE: + case RsGxsCircleEventCode::CIRCLE_MEMBERSHIP_REQUEST: + case RsGxsCircleEventCode::CIRCLE_MEMBERSHIP_INVITE: + case RsGxsCircleEventCode::CIRCLE_MEMBERSHIP_LEAVE: + case RsGxsCircleEventCode::CIRCLE_MEMBERSHIP_JOIN: + case RsGxsCircleEventCode::CIRCLE_MEMBERSHIP_REVOQUED: + + requestIdList(); + default: + break; + } + + } } void IdDialog::clearPerson() diff --git a/retroshare-gui/src/gui/Identity/IdDialog.h b/retroshare-gui/src/gui/Identity/IdDialog.h index 92ba76ee1..e4c73229d 100644 --- a/retroshare-gui/src/gui/Identity/IdDialog.h +++ b/retroshare-gui/src/gui/Identity/IdDialog.h @@ -159,7 +159,8 @@ private: int filter; void handleEvent_main_thread(std::shared_ptr event); - RsEventsHandlerId_t mEventHandlerId; + RsEventsHandlerId_t mEventHandlerId_identity; + RsEventsHandlerId_t mEventHandlerId_circles; /* UI - Designer */ Ui::IdDialog *ui; From b6366ac5bd0a709357a0eca9ea7be26bcd5d9956 Mon Sep 17 00:00:00 2001 From: csoler Date: Tue, 28 Jan 2020 22:47:30 +0100 Subject: [PATCH 41/44] fixed misplaced notification event in GxsCircles --- libretroshare/src/services/p3gxscircles.cc | 17 +++++++++-------- retroshare-gui/src/gui/Identity/IdDialog.cpp | 7 ++++--- 2 files changed, 13 insertions(+), 11 deletions(-) diff --git a/libretroshare/src/services/p3gxscircles.cc b/libretroshare/src/services/p3gxscircles.cc index 9a9b1de34..cf465d18c 100644 --- a/libretroshare/src/services/p3gxscircles.cc +++ b/libretroshare/src/services/p3gxscircles.cc @@ -547,14 +547,6 @@ void p3GxsCircles::notifyChanges(std::vector &changes) RsStackMutex stack(mCircleMtx); /********** STACK LOCKED MTX ******/ mCircleCache.erase(RsGxsCircleId(*git)); } - - if(rsEvents && (c->getType() == RsGxsNotify::TYPE_RECEIVED_NEW|| c->getType() == RsGxsNotify::TYPE_PUBLISHED) ) - { - auto ev = std::make_shared(); - ev->mCircleId = RsGxsCircleId(*git); - ev->mCircleEventType = RsGxsCircleEventCode::NEW_CIRCLE; - rsEvents->postEvent(ev); - } } } @@ -610,6 +602,15 @@ void p3GxsCircles::notifyChanges(std::vector &changes) } #endif + + if(rsEvents && (c->getType() == RsGxsNotify::TYPE_RECEIVED_NEW|| c->getType() == RsGxsNotify::TYPE_PUBLISHED) ) + { + auto ev = std::make_shared(); + ev->mCircleId = RsGxsCircleId(*git); + ev->mCircleEventType = RsGxsCircleEventCode::NEW_CIRCLE; + rsEvents->postEvent(ev); + } + } } diff --git a/retroshare-gui/src/gui/Identity/IdDialog.cpp b/retroshare-gui/src/gui/Identity/IdDialog.cpp index 4da14d29b..e0a38a9ed 100644 --- a/retroshare-gui/src/gui/Identity/IdDialog.cpp +++ b/retroshare-gui/src/gui/Identity/IdDialog.cpp @@ -57,6 +57,7 @@ /****** * #define ID_DEBUG 1 *****/ +#define ID_DEBUG 1 // Data Requests. #define IDDIALOG_IDLIST 1 @@ -441,7 +442,7 @@ void IdDialog::handleEvent_main_thread(std::shared_ptr event) case RsGxsCircleEventCode::CIRCLE_MEMBERSHIP_JOIN: case RsGxsCircleEventCode::CIRCLE_MEMBERSHIP_REVOQUED: - requestIdList(); + requestCircleGroupMeta(); default: break; } @@ -752,7 +753,7 @@ void IdDialog::loadCircleGroupMeta(const uint32_t &token) for(std::map::const_iterator it(details.mSubscriptionFlags.begin());it!=details.mSubscriptionFlags.end();++it) { #ifdef ID_DEBUG - std::cerr << " ID " << *it << ": " ; + std::cerr << " ID " << it->first << ": " ; #endif bool is_own_id = rsIdentity->isOwnId(it->first) ; bool invited ( it->second & GXS_EXTERNAL_CIRCLE_FLAGS_IN_ADMIN_LIST ); @@ -2146,7 +2147,7 @@ void IdDialog::modifyReputation() rsReputations->setOwnOpinion(id,op); #ifdef ID_DEBUG - std::cerr << "IdDialog::modifyReputation() ID: " << id << " Mod: " << op; + std::cerr << "IdDialog::modifyReputation() ID: " << id << " Mod: " << static_cast(op); std::cerr << std::endl; #endif From 06be689bef1dd38da0bc9ce3f4ed77c5f18d6831 Mon Sep 17 00:00:00 2001 From: csoler Date: Tue, 28 Jan 2020 22:53:43 +0100 Subject: [PATCH 42/44] fixed missing cache update in GxsCircles --- libretroshare/src/services/p3gxscircles.cc | 6 ++++++ retroshare-gui/src/gui/Identity/IdDialog.cpp | 1 - 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/libretroshare/src/services/p3gxscircles.cc b/libretroshare/src/services/p3gxscircles.cc index cf465d18c..cb3b4a3ff 100644 --- a/libretroshare/src/services/p3gxscircles.cc +++ b/libretroshare/src/services/p3gxscircles.cc @@ -611,6 +611,12 @@ void p3GxsCircles::notifyChanges(std::vector &changes) rsEvents->postEvent(ev); } + // reset circle from cache since the number of invitee may have changed. + { + RsStackMutex stack(mCircleMtx); /********** STACK LOCKED MTX ******/ + mCircleCache.erase(RsGxsCircleId(*git)); + } + } } diff --git a/retroshare-gui/src/gui/Identity/IdDialog.cpp b/retroshare-gui/src/gui/Identity/IdDialog.cpp index e0a38a9ed..ffb29664a 100644 --- a/retroshare-gui/src/gui/Identity/IdDialog.cpp +++ b/retroshare-gui/src/gui/Identity/IdDialog.cpp @@ -57,7 +57,6 @@ /****** * #define ID_DEBUG 1 *****/ -#define ID_DEBUG 1 // Data Requests. #define IDDIALOG_IDLIST 1 From 0efc6b00a1c395ca02b8d2aded907c0fb375960f Mon Sep 17 00:00:00 2001 From: csoler Date: Wed, 29 Jan 2020 21:02:46 +0100 Subject: [PATCH 43/44] fixed missing check in AvatarInfo against empty image data --- libretroshare/src/chat/p3chatservice.cc | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) diff --git a/libretroshare/src/chat/p3chatservice.cc b/libretroshare/src/chat/p3chatservice.cc index 2f5df22fe..28ade2674 100644 --- a/libretroshare/src/chat/p3chatservice.cc +++ b/libretroshare/src/chat/p3chatservice.cc @@ -156,9 +156,17 @@ class p3ChatService::AvatarInfo void init(const unsigned char *jpeg_data,int size) { - _image_size = size ; - _image_data = (unsigned char*)rs_malloc(size) ; - memcpy(_image_data,jpeg_data,size) ; + if(size == 0) + { + _image_size = 0; + _image_data = nullptr; + } + else + { + _image_size = size ; + _image_data = (unsigned char*)rs_malloc(size) ; + memcpy(_image_data,jpeg_data,size) ; + } } AvatarInfo(const unsigned char *jpeg_data,int size) { From 10bee9f26b2499650d4342d6195591e72cdd8eb3 Mon Sep 17 00:00:00 2001 From: csoler Date: Wed, 29 Jan 2020 22:04:29 +0100 Subject: [PATCH 44/44] added optional delay to check files after download in order to prevent skiping recently downloaded files --- libretroshare/src/file_sharing/directory_updater.cc | 9 ++++++--- libretroshare/src/file_sharing/directory_updater.h | 2 +- libretroshare/src/file_sharing/file_sharing_defaults.h | 2 +- libretroshare/src/file_sharing/p3filelists.cc | 6 +++--- libretroshare/src/file_sharing/p3filelists.h | 2 +- libretroshare/src/ft/ftcontroller.cc | 2 +- libretroshare/src/ft/ftserver.cc | 4 ++-- libretroshare/src/ft/ftserver.h | 2 +- libretroshare/src/retroshare/rsfiles.h | 3 ++- 9 files changed, 18 insertions(+), 14 deletions(-) diff --git a/libretroshare/src/file_sharing/directory_updater.cc b/libretroshare/src/file_sharing/directory_updater.cc index 254c9ebe3..406c44024 100644 --- a/libretroshare/src/file_sharing/directory_updater.cc +++ b/libretroshare/src/file_sharing/directory_updater.cc @@ -107,10 +107,13 @@ void LocalDirectoryUpdater::threadTick() } } -void LocalDirectoryUpdater::forceUpdate() +void LocalDirectoryUpdater::forceUpdate(bool add_safe_delay) { mForceUpdate = true ; - mLastSweepTime = 0 ; + mLastSweepTime = rstime_t(time(NULL)) - rstime_t(mDelayBetweenDirectoryUpdates) ; + + if(add_safe_delay) + mLastSweepTime += rstime_t(MIN_TIME_AFTER_LAST_MODIFICATION); if(mHashCache != NULL && mHashCache->hashingProcessPaused()) mHashCache->togglePauseHashingProcess(); @@ -363,7 +366,7 @@ void LocalDirectoryUpdater::setFollowSymLinks(bool b) mFollowSymLinks = b ; - forceUpdate(); + forceUpdate(false); } bool LocalDirectoryUpdater::followSymLinks() const diff --git a/libretroshare/src/file_sharing/directory_updater.h b/libretroshare/src/file_sharing/directory_updater.h index 4b95daabe..b7d72b3a9 100644 --- a/libretroshare/src/file_sharing/directory_updater.h +++ b/libretroshare/src/file_sharing/directory_updater.h @@ -35,7 +35,7 @@ public: LocalDirectoryUpdater(HashStorage *hash_cache,LocalDirectoryStorage *lds) ; virtual ~LocalDirectoryUpdater() {} - void forceUpdate(); + void forceUpdate(bool add_safe_delay); bool inDirectoryCheck() const ; void togglePauseHashingProcess(); bool hashingProcessPaused(); diff --git a/libretroshare/src/file_sharing/file_sharing_defaults.h b/libretroshare/src/file_sharing/file_sharing_defaults.h index 75f19075a..92ff43947 100644 --- a/libretroshare/src/file_sharing/file_sharing_defaults.h +++ b/libretroshare/src/file_sharing/file_sharing_defaults.h @@ -48,7 +48,7 @@ static const std::string LOCAL_SHARED_DIRS_FILE_NAME = "local_dir_hierarchy.bin" static const uint32_t MIN_INTERVAL_BETWEEN_HASH_CACHE_SAVE = 20 ; // never save hash cache more often than every 20 secs. static const uint32_t MIN_INTERVAL_BETWEEN_REMOTE_DIRECTORY_SAVE = 23 ; // never save remote directories more often than this -static const uint32_t MIN_TIME_AFTER_LAST_MODIFICATION = 20 ; // never hash a file that is just being modified, otherwise we end up with a corrupted hash +static const uint32_t MIN_TIME_AFTER_LAST_MODIFICATION = 10 ; // never hash a file that is just being modified, otherwise we end up with a corrupted hash static const uint32_t MAX_DIR_SYNC_RESPONSE_DATA_SIZE = 20000 ; // Maximum RsItem data size in bytes for serialised directory transmission static const uint32_t DEFAULT_HASH_STORAGE_DURATION_DAYS = 30 ; // remember deleted/inaccessible files for 30 days diff --git a/libretroshare/src/file_sharing/p3filelists.cc b/libretroshare/src/file_sharing/p3filelists.cc index e4ea57dc7..c7db78b0f 100644 --- a/libretroshare/src/file_sharing/p3filelists.cc +++ b/libretroshare/src/file_sharing/p3filelists.cc @@ -114,7 +114,7 @@ void p3FileDatabase::setSharedDirectories(const std::list& shared RS_STACK_MUTEX(mFLSMtx) ; mLocalSharedDirs->setSharedDirectoryList(shared_dirs) ; - mLocalDirWatcher->forceUpdate(); + mLocalDirWatcher->forceUpdate(false); } @@ -1231,9 +1231,9 @@ uint32_t p3FileDatabase::getType(void *ref,FileSearchFlags flags) const } } -void p3FileDatabase::forceDirectoryCheck() // Force re-sweep the directories and see what's changed +void p3FileDatabase::forceDirectoryCheck(bool add_safe_delay) // Force re-sweep the directories and see what's changed { - mLocalDirWatcher->forceUpdate(); + mLocalDirWatcher->forceUpdate(add_safe_delay); } void p3FileDatabase::togglePauseHashingProcess() { diff --git a/libretroshare/src/file_sharing/p3filelists.h b/libretroshare/src/file_sharing/p3filelists.h index 7ddc6d282..41e8cbeaf 100644 --- a/libretroshare/src/file_sharing/p3filelists.h +++ b/libretroshare/src/file_sharing/p3filelists.h @@ -168,7 +168,7 @@ class p3FileDatabase: public p3Service, public p3Config, public ftSearch //, pub // interfact for directory parsing - void forceDirectoryCheck(); // Force re-sweep the directories and see what's changed + void forceDirectoryCheck(bool add_safe_delay); // Force re-sweep the directories and see what's changed bool inDirectoryCheck(); void togglePauseHashingProcess(); bool hashingProcessPaused(); diff --git a/libretroshare/src/ft/ftcontroller.cc b/libretroshare/src/ft/ftcontroller.cc index d682caba7..45fc70845 100644 --- a/libretroshare/src/ft/ftcontroller.cc +++ b/libretroshare/src/ft/ftcontroller.cc @@ -821,7 +821,7 @@ bool ftController::completeFile(const RsFileHash& hash) RsServer::notify()->notifyDownloadComplete(hash.toStdString()); RsServer::notify()->notifyDownloadCompleteCount(completeCount); - rsFiles->ForceDirectoryCheck() ; + rsFiles->ForceDirectoryCheck(true) ; IndicateConfigChanged(); /* completed transfer -> save */ return true; diff --git a/libretroshare/src/ft/ftserver.cc b/libretroshare/src/ft/ftserver.cc index 293da6d51..256543da6 100644 --- a/libretroshare/src/ft/ftserver.cc +++ b/libretroshare/src/ft/ftserver.cc @@ -791,9 +791,9 @@ void ftServer::updateSinceGroupPermissionsChanged() { mFileDatabase->forceSyncWithPeers(); } -void ftServer::ForceDirectoryCheck() +void ftServer::ForceDirectoryCheck(bool add_safe_delay) { - mFileDatabase->forceDirectoryCheck(); + mFileDatabase->forceDirectoryCheck(add_safe_delay); return; } diff --git a/libretroshare/src/ft/ftserver.h b/libretroshare/src/ft/ftserver.h index 0cc88d6aa..6f719c04e 100644 --- a/libretroshare/src/ft/ftserver.h +++ b/libretroshare/src/ft/ftserver.h @@ -275,7 +275,7 @@ public: * Utility Functions ***/ virtual bool ConvertSharedFilePath(std::string path, std::string &fullpath); - virtual void ForceDirectoryCheck(); + virtual void ForceDirectoryCheck(bool add_safe_delay); virtual void updateSinceGroupPermissionsChanged() ; virtual bool InDirectoryCheck(); virtual bool copyFile(const std::string& source, const std::string& dest); diff --git a/libretroshare/src/retroshare/rsfiles.h b/libretroshare/src/retroshare/rsfiles.h index daa83d3bc..e0793d8b7 100644 --- a/libretroshare/src/retroshare/rsfiles.h +++ b/libretroshare/src/retroshare/rsfiles.h @@ -591,9 +591,10 @@ public: /** * @brief Force shared directories check + * @param[in] add_safe_delay Schedule the check 20 seconds from now, to ensure to capture files written just now. * @jsonapi{development} */ - virtual void ForceDirectoryCheck() = 0; + virtual void ForceDirectoryCheck(bool add_safe_delay=false) = 0; virtual void updateSinceGroupPermissionsChanged() = 0; virtual bool InDirectoryCheck() = 0;