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 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)
+ {
+ 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));
+
+ QTextDocument doc;
+ doc.setHtml(ui->notes->text());
+
+ if(doc.toPlainText().trimmed().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..7fc303680
--- /dev/null
+++ b/retroshare-gui/src/gui/Posted/PostedCardView.h
@@ -0,0 +1,98 @@
+/*******************************************************************************
+ * 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();
+
+ uint64_t uniqueIdentifier() const override { return hash_64bits("PostedItem " + mMessageId.toStdString()); }
+
+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..8cbbd4d56
--- /dev/null
+++ b/retroshare-gui/src/gui/Posted/PostedCardView.ui
@@ -0,0 +1,526 @@
+
+
+ PostedCardView
+
+
+
+ 0
+ 0
+ 614
+ 182
+
+
+
+
+
+
+
+
+
+
+ 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
+
+
+
+ -
+
+
+
+ 0
+
+
+ 0
+
+
+ 0
+
+
+ 0
+
+
-
+
+
+ PictureLabel
+
+
+ true
+
+
+
+ -
+
+
+ Qt::Horizontal
+
+
+
+ 268
+ 17
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ StyledLabel
+ QLabel
+
+
+
+ GxsIdLabel
+ QLabel
+
+
+
+
+
+
+
+
+
+
diff --git a/retroshare-gui/src/gui/Posted/PostedCreatePostDialog.cpp b/retroshare-gui/src/gui/Posted/PostedCreatePostDialog.cpp
index c822bb492..ddacd4895 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),
@@ -44,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"));
@@ -52,19 +58,59 @@ 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)));
+ 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());
+
+ 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 +131,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 +160,66 @@ 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->addPicButton->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;
+ }
+
+ 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();
+ 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->addPicButton->setEnabled(false);
+ QStringList files;
+ files.append(imagefilename);
+ ui->hashBox->addAttachments(files,RS_FILE_REQ_ANONYMOUS_ROUTING);
+ }
+
- // to show the selected
- ui->imageLabel->setPixmap(picture);
}
void PostedCreatePostDialog::on_postButton_clicked()
@@ -151,3 +236,13 @@ 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();
+ ui->stackedWidgetPicture->setCurrentIndex(0);
+}
diff --git a/retroshare-gui/src/gui/Posted/PostedCreatePostDialog.h b/retroshare-gui/src/gui/Posted/PostedCreatePostDialog.h
index de13358fb..5aed59950 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 = 199000;
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..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
- 429
+ 518
@@ -48,6 +48,427 @@
QFrame::Raised
+ -
+
+
+ 0
+
+
+
+
+ 0
+
+
+ 0
+
+
+ 0
+
+
+ 0
+
+
-
+
+
+
+
+
+
+
+ 0
+
+
+ 0
+
+
+ 0
+
+
+ 0
+
+ -
+
+
+
+ 0
+ 0
+
+
+
+ true
+
+
+
+ -
+
+
+ Preview
+
+
+
+ 0
+
+
+ 0
+
+
+ 0
+
+
-
+
+
+ Qt::Horizontal
+
+
+
+ 40
+ 20
+
+
+
+
+ -
+
+
+ Qt::Horizontal
+
+
+
+ 40
+ 20
+
+
+
+
+ -
+
+
+ 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
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 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 +549,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 +565,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 +599,12 @@
QLabel
+
+ HashBox
+ QScrollArea
+
+ 1
+
HeaderFrame
QFrame
@@ -475,7 +625,6 @@
-
diff --git a/retroshare-gui/src/gui/Posted/PostedItem.cpp b/retroshare-gui/src/gui/Posted/PostedItem.cpp
index 5d4e00a93..b09452a8e 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"
@@ -28,7 +29,7 @@
#include "gui/gxs/GxsIdDetails.h"
#include "util/misc.h"
#include "util/HandleRichText.h"
-
+#include "PhotoView.h"
#include "ui_PostedItem.h"
#include
@@ -109,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));
@@ -302,6 +304,11 @@ void PostedItem::fill()
}
+ if (urlarray.isEmpty())
+ {
+ ui->siteLabel->hide();
+ }
+
ui->siteLabel->setText(sitestr);
if(mPost.mImage.mData != NULL)
@@ -312,7 +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 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))
{
@@ -337,7 +352,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)
@@ -569,3 +587,28 @@ 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->setGroupId(groupId());
+ PView->setMessageId(mMessageId);
+
+ 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 aa855d72b..97b6974d0 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() override;
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
+
+ ClickableLabel
+ QLabel
+
+
-
-
+
+
diff --git a/retroshare-gui/src/gui/Posted/PostedListWidget.cpp b/retroshare-gui/src/gui/Posted/PostedListWidget.cpp
index 1373c6d9b..0d7960804 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"
@@ -27,10 +28,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"
@@ -42,6 +45,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),
@@ -64,6 +71,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;
@@ -103,17 +116,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()
@@ -143,6 +162,12 @@ QScrollArea *PostedListWidget::getScrollArea()
return ui->scrollArea;
}
+// Overloaded from FeedHolder.
+/*QScrollArea *PostedListWidget::getScrollArea()
+{
+ return ui->scrollAreaCardView;
+}*/
+
void PostedListWidget::deleteFeedItem(FeedItem *, uint32_t /*type*/)
{
#ifdef DEBUG_POSTED_LIST_WIDGET
@@ -414,11 +439,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);
@@ -471,6 +508,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 */
@@ -491,6 +580,7 @@ void PostedListWidget::applyRanking()
std::cerr << std::endl;
#endif
qSort(mPostItems.begin(), mPostItems.end(), CmpPIHot);
+ qSort(mPostCardView.begin(), mPostCardView.end(), CVHot);
break;
case RsPosted::NewRankType:
#ifdef DEBUG_POSTED_LIST_WIDGET
@@ -498,6 +588,7 @@ void PostedListWidget::applyRanking()
std::cerr << std::endl;
#endif
qSort(mPostItems.begin(), mPostItems.end(), CmpPINew);
+ qSort(mPostCardView.begin(), mPostCardView.end(), CVNew);
break;
case RsPosted::TopRankType:
#ifdef DEBUG_POSTED_LIST_WIDGET
@@ -505,6 +596,7 @@ void PostedListWidget::applyRanking()
std::cerr << std::endl;
#endif
qSort(mPostItems.begin(), mPostItems.end(), CmpPITop);
+ qSort(mPostCardView.begin(), mPostCardView.end(), CVTop);
break;
}
mLastSortMethod = mSortMethod;
@@ -516,8 +608,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)
{
#ifdef DEBUG_POSTED_LIST_WIDGET
@@ -564,6 +659,46 @@ void PostedListWidget::applyRanking()
++counter;
}
+ // Card View
+ counter = 0;
+ 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;
+ }
+
#ifdef DEBUG_POSTED_LIST_WIDGET
std::cerr << "PostedListWidget::applyRanking() Loaded New Order";
std::cerr << std::endl;
@@ -571,6 +706,8 @@ void PostedListWidget::applyRanking()
// trigger a redraw.
ui->scrollAreaWidgetContents->update();
+ ui->scrollAreaWidgetContentsCardView->update();
+
}
void PostedListWidget::blank()
@@ -580,10 +717,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();
}
@@ -641,6 +785,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)
@@ -668,6 +851,7 @@ void PostedListWidget::insertAllPosts(const uint32_t &token, GxsMessageFramePost
{
RsPostedPost& p = *vit;
loadPost(p);
+ loadPostCardView(p);
}
applyRanking();
@@ -701,6 +885,7 @@ void PostedListWidget::insertPosts(const uint32_t &token)
#endif
/* insert new entry */
loadPost(p);
+ loadPostCardView(p);
}
}
@@ -767,3 +952,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 cf05e9d4c..fa9f25c8e 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..9c2be0db4 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
@@ -21,7 +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/card.png b/retroshare-gui/src/gui/Posted/images/card.png
new file mode 100644
index 000000000..47cc72d0a
Binary files /dev/null and b/retroshare-gui/src/gui/Posted/images/card.png differ
diff --git a/retroshare-gui/src/gui/Posted/images/classic.png b/retroshare-gui/src/gui/Posted/images/classic.png
new file mode 100644
index 000000000..b85e0a119
Binary files /dev/null and b/retroshare-gui/src/gui/Posted/images/classic.png differ
diff --git a/retroshare-gui/src/gui/Posted/images/down-arrow.png b/retroshare-gui/src/gui/Posted/images/down-arrow.png
index b6c7fcc06..1e531f03d 100644
Binary files a/retroshare-gui/src/gui/Posted/images/down-arrow.png and b/retroshare-gui/src/gui/Posted/images/down-arrow.png differ
diff --git a/retroshare-gui/src/gui/Posted/images/down-hover.png b/retroshare-gui/src/gui/Posted/images/down-hover.png
new file mode 100644
index 000000000..b822a0d87
Binary files /dev/null and b/retroshare-gui/src/gui/Posted/images/down-hover.png differ
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 000000000..8fa5953a0
Binary files /dev/null and b/retroshare-gui/src/gui/Posted/images/linkext.png differ
diff --git a/retroshare-gui/src/gui/Posted/images/notes.png b/retroshare-gui/src/gui/Posted/images/notes.png
index a73a03968..800eec492 100644
Binary files a/retroshare-gui/src/gui/Posted/images/notes.png and b/retroshare-gui/src/gui/Posted/images/notes.png differ
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 000000000..d812bcfe5
Binary files /dev/null and b/retroshare-gui/src/gui/Posted/images/trashcan.png differ
diff --git a/retroshare-gui/src/gui/Posted/images/up-arrow.png b/retroshare-gui/src/gui/Posted/images/up-arrow.png
index 728ccf068..7f276af8f 100644
Binary files a/retroshare-gui/src/gui/Posted/images/up-arrow.png and b/retroshare-gui/src/gui/Posted/images/up-arrow.png differ
diff --git a/retroshare-gui/src/gui/Posted/images/up-hover.png b/retroshare-gui/src/gui/Posted/images/up-hover.png
new file mode 100644
index 000000000..6e1144f96
Binary files /dev/null and b/retroshare-gui/src/gui/Posted/images/up-hover.png differ
diff --git a/retroshare-gui/src/gui/qss/stylesheet/Standard.qss b/retroshare-gui/src/gui/qss/stylesheet/Standard.qss
index 282f4917f..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,22 @@ 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;
+}
+
GxsCommentDialog QComboBox#sortBox {
font: bold;
color: #0099cc;
diff --git a/retroshare-gui/src/gui/settings/JsonApiPage.cc b/retroshare-gui/src/gui/settings/JsonApiPage.cc
index 6c6dee018..5f1bb225f 100644
--- a/retroshare-gui/src/gui/settings/JsonApiPage.cc
+++ b/retroshare-gui/src/gui/settings/JsonApiPage.cc
@@ -112,28 +112,41 @@ QString JsonApiPage::helpText() const { return ""; }
bool JsonApiPage::checkStartJsonApi()
{
- if(!Settings->getJsonApiEnabled())
- return false;
+ if(!Settings->getJsonApiEnabled()) return false;
rsJsonApi->setListeningPort(Settings->getJsonApiPort());
rsJsonApi->setBindingAddress(Settings->getJsonApiListenAddress().toStdString());
- rsJsonApi->restart();
+
+ const auto rErr = rsJsonApi->restart();
+ if(rErr == RsJsonApiErrorNum::NOT_A_MACHINE_GUN)
+ {
+ RsDbg() << __PRETTY_FUNCTION__ << " apparently the user is attempting "
+ << "to restart JSON API service in a burst. Re-scheduling "
+ << "restart in a while..." << std::endl;
+ RsThread::async([]()
+ {
+ std::this_thread::sleep_for(std::chrono::seconds(10));
+ rsJsonApi->restart();
+ });
+ }
+ else if(rErr)
+ {
+ RsErr() << __PRETTY_FUNCTION__ << rErr << std::endl;
+ return false;
+ }
return true;
}
/*static*/ void JsonApiPage::checkShutdownJsonApi()
{
- if(!rsJsonApi->isRunning()) return;
rsJsonApi->fullstop(); // this is a blocks until the thread is terminated.
}
void JsonApiPage::onApplyClicked()
{
- // restart
-
- checkShutdownJsonApi();
- checkStartJsonApi();
+ // restart
+ checkStartJsonApi();
}
void JsonApiPage::checkToken(QString s)
diff --git a/retroshare-gui/src/qss/qdarkstyle-v2.qss b/retroshare-gui/src/qss/qdarkstyle-v2.qss
index 90324f9ab..c9e951921 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,95 @@ 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;
+
+}
+
+PostedItem QLabel#thumbnailLabel{
+ border: 2px solid #CCCCCC;
+ border-radius: 3px;
+}
+
+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..ef8495956 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,85 @@ 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;
+}
+
+PostedItem QLabel#thumbnailLabel{
+ border: 2px solid #CCCCCC;
+ border-radius: 3px;
+}
+
+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 8f49a1525..59f1cb458 100644
--- a/retroshare-gui/src/retroshare-gui.pro
+++ b/retroshare-gui/src/retroshare-gui.pro
@@ -469,6 +469,8 @@ HEADERS += rshare.h \
util/QtVersion.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 \
@@ -828,6 +830,8 @@ SOURCES += main.cpp \
util/ObjectPainter.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 \
@@ -1344,9 +1348,11 @@ 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 \
+ gui/Posted/PhotoView.h \
gui/Posted/PostedUserNotify.h
#gui/Posted/PostedCreateCommentDialog.h \
@@ -1355,8 +1361,9 @@ posted {
FORMS += gui/Posted/PostedListWidget.ui \
gui/feeds/PostedGroupItem.ui \
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
@@ -1365,8 +1372,10 @@ 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/PhotoView.cpp \
gui/Posted/PostedUserNotify.cpp
#gui/Posted/PostedDialog.cpp \
diff --git a/retroshare-gui/src/util/AspectRatioPixmapLabel.cpp b/retroshare-gui/src/util/AspectRatioPixmapLabel.cpp
new file mode 100644
index 000000000..08ecf18c6
--- /dev/null
+++ b/retroshare-gui/src/util/AspectRatioPixmapLabel.cpp
@@ -0,0 +1,59 @@
+/*******************************************************************************
+ * 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"
+#include
+
+AspectRatioPixmapLabel::AspectRatioPixmapLabel(QWidget *parent) :
+ QLabel(parent)
+{
+ this->setMinimumSize(1,1);
+ setScaledContents(false);
+}
+
+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
+{
+ return pix.isNull() ? this->height() : ((qreal)pix.height()*width)/pix.width();
+}
+
+QSize AspectRatioPixmapLabel::sizeHint() const
+{
+ return QSize(pix.width(), pix.height());
+}
+
+QPixmap AspectRatioPixmapLabel::scaledPixmap() const
+{
+ return pix.scaled(this->size(), Qt::KeepAspectRatio, Qt::SmoothTransformation);
+}
+
+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
new file mode 100644
index 000000000..ad7c40e4c
--- /dev/null
+++ b/retroshare-gui/src/util/AspectRatioPixmapLabel.h
@@ -0,0 +1,44 @@
+/*******************************************************************************
+ * 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 = nullptr);
+ virtual int heightForWidth( int width ) const override;
+ virtual QSize sizeHint() const override;
+ QPixmap scaledPixmap() const;
+public slots:
+ void setPixmap ( const QPixmap & );
+protected:
+ void resizeEvent(QResizeEvent *event) override;
+private:
+ QPixmap pix;
+};
+
+#endif // ASPECTRATIOPIXMAPLABEL_H
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..ec1c66b8d
--- /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: 2px solid #CCCCCC; border-radius: 3px; }");}
+
+};
+
+#endif // CLICKABLELABEL_H
\ No newline at end of file
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/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);
diff --git a/retroshare-gui/src/util/imageutil.cpp b/retroshare-gui/src/util/imageutil.cpp
index c507bfa05..47029505e 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, QString file)
}
}
-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)) {
- int s = checkSize(html, optimized, maxBytes);
+ int s = checkSize(bytearray, optimized);
if((maxBytes <= 0) || (s <= maxBytes)) {
return true;
}
@@ -92,7 +92,7 @@ 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;
}
@@ -100,9 +100,9 @@ bool ImageUtil::optimizeSize(QString &html, const QImage& original, QImage &opti
quantization(original, ct);
//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;
@@ -115,7 +115,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;
@@ -137,34 +137,41 @@ 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(maxBytes < 1) maxBytes = 1;
+ }
+
+ 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();
} 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 a6ff19b88..1a9658e13 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, QString file = "");
- 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);