From 54d0d8ab8bac01fc32bf14467231cc4fbc731e7f Mon Sep 17 00:00:00 2001 From: defnax Date: Wed, 25 Dec 2019 17:16:58 +0100 Subject: [PATCH 01/36] 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 zcmY+GX*kqt8^HfFjj?8?X0jzFnHX6@7)b`rv5c`xS>~V|*-04df9&faos7L?&2n&Z z?1Pb=LK~M|qe$74B}?!0p7Y^-KRx$z-}m*qf6sG0AD$RQ1^T|Q0vrH<&Z~}t>;>kc zP1Xh=kR?MI$3*~uuDj~$ni}ZpVodLP|K{r93;_7SG;47X!gunIBwo>D&``oMo<~9bdqj>s zVgj}d2NLQ`H3+mZZ2PqiO+{ssjuFfBhyehdf)tPlMLKcax3jT?BMjki2wV=X6>Au4 z#fK0o7A_Q8RJ`h}blc6LxvR2csxLI7JJwn3g0j2n7b{h%dh)W&va&i1e_8#edQMYj z(?nxalhmgEhU`a`1p1-9L+F7@sP!yZTD zT7M^f=EUJ1TqV}*7kbZwo_6wTmYAxo%vS-7YxwI_h5WGrwqvo51(T zsmjPJv|$|sSPMn9{lgYnuRpx@R4P!ac=ns~T7OeU@55@!oW%{hOD(%T{gX-wcQX>7 z4+L4cRQwqI{H}Y<#0@{X+cKVyZS|*sli&C|jMu8RS36tz!nP0nQQPDLt#Mz&FKGy{kknTXCqX9XM>eWIzuPlIPxjpC?9>NHuky7-3Ih4>?lcjiKw^n z%xOOCG@iAu*!Ec_&judQzIP1iR;TWsnGUr(xVF+SRoXi2p)M8DcKE!MZMyg$zzh5q{e{hQLr;kCAfu#lZ| zKNjO=yTP`@itj(f0eQYNNy#C%BGS$Zg78-c*R(CEl$E?mcS$0;M_E&OI&Yk+jplIP zfJSmXXX!BVxn!gxS&7ZH%>!^jblBI(t5oh8y1hNx5*hRDdGAh1E9&ZU z6vB;Vw6nF9JZoT#;c-8oRla)JYH{baRk}e*%g|VaZn$wavUcKxxcZ0cvLn%KCXFXOJTiMe7*KiK9Nb! zleij;5C-w0Z2{-!QCrH4h2z0;h#-@TP+kujG9SI4n?^Z2%;Nfb(|KMzlBM^oj1=BU3~ zLlRpi;qCiHYZRs}q-H~_i+#Id6RNw@yqmK7eJ&@c7ih2UY$5rmyn%s64@%VLz0Z88 z3Z!On6=>8;CyGz5Y|A3ZL`9*k313F(5G?I{~`iykS^;eg*68D_`BI0*

vZWmH%(fUwXLo6%YY>?MaB0vvZ6c&eueY4e)S<^x#9l>UI8^{p(9Nb^gjCwC%UYomikg z6@W)|7>f3Wc)D<_pc=WA!s*VB-+G2Zd$f2rm@eiSP+w?%LhNK1mi*>R(9-}U;)Mm= zynstGnC68h4taLqkKw%Br4505ao<8(<;0gOd2=VDz}F0#5M-pQ%6b2CUPVx!x{sIj zDWb3C11`xRnqh62M)9=QY*bWcF(DclwFBGRnf8kvO=5HwN3I}1{(u>tB^I^j#N~1> z2Kzo*Tq7YPUhm z9W@BT9&FUgYMgzy3rhy&SrI1o6rNl(Ko&y(aQgmuc%1~>VEPxn`s8d)oGa)2Whoe3Yeh;gb0VxAhffN+MoACdmY!hON{@ z=?Ci2oo9`|s)r}cWrMvcvv^nf$ej3bIip1B0<~o_lO_^P-oA%O zPwK@8JS4xh3N0{aKbG))c6(%T{w52R&P|g~7R#zCV2jqEEh(V|hKP}mdL`*Uo_uCk zxoGG-=W*1ORXsq`cJ7v{XDrkxhiM?&&S6Lfchyk^)fWh^ z{KPkbw%t?qq?>Xo-_+{DqExL*!3in8z^Rtv_Q?OhDDdQOg!g;Vn$q}yJ!eh zda!fKvIOS0C#3fKEi%x!KRjQegv}(m50h@72xjP6AB(J$FFuY*0~G?WoCk7?%r=m{c%Bhs9u46~w@7dhz1pun9xq%cWXp7{ZCsOUeNUiWgiu z)WakE>@L}>jZ|>z1VG8sWRIKlQfi;N!vXemPeXzbq9&rEA3J$UH);nsJp!w)s*?8` z6TWV3O~+2}osLHV5Vd_ZwY(><;)AEqG5Qec1tboL77P&R0?ZH&{2FG}&Xzy~c+LX2 zWe+uaB8Kr{ZwsLpyQ#8w<*k5-b5?)|OhiYMF!vOI>XiT@#|1NhmoS-4B#!pphsw=H z%MK1U;dsi#2!W8;5$sRE!U)DREsp137MJKL8csw627gJdgqp$%pckWyQ*~_gIFNW5 zz~T-c@`?-y5XB@oM%?Pc=S!5YnQdKABmScjD>R&}0yq8e1j?rT8pvi(-Y75x1Cw0tel5*$e4tHrIn;3@w|e2R4= zjwcP8|7>|BU>_goUMf4N;Ct_e&04>X2a-#{=VV-Wcsm#zRunuJa}>SttG8;7g26!* z@O(loR$2-91%g)o?`XC>jcEpfrTot^{}ufIlD4w)R|E=Ej@_=Rnq&X)00W}&wJIHl 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/36] 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/36] 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/36] 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/36] 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/36] 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/36] 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/36] 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/36] 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/36] 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/36] 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/36] 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/36] 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/36] 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/36] 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/36] 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/36] 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/36] 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/36] 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/36] 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/36] 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/36] 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/36] 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/36] 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/36] 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/36] 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/36] 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/36] 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/36] 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/36] 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/36] 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/36] 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/36] 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/36] 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/36] 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/36] 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