diff --git a/retroshare-gui/src/gui/NewsFeed.cpp b/retroshare-gui/src/gui/NewsFeed.cpp index ec4ef272f..bdf0954d4 100644 --- a/retroshare-gui/src/gui/NewsFeed.cpp +++ b/retroshare-gui/src/gui/NewsFeed.cpp @@ -34,6 +34,7 @@ #include "util/misc.h" #include "util/qtthreadsutils.h" #include "feeds/BoardsCommentsItem.h" +#include "feeds/BoardsPostItem.h" #include "feeds/ChatMsgItem.h" #include "feeds/GxsCircleItem.h" #include "feeds/ChannelsCommentsItem.h" @@ -243,7 +244,7 @@ void NewsFeed::handlePostedEvent(std::shared_ptr event) addFeedItem( new PostedGroupItem(this, NEWSFEED_POSTEDNEWLIST, pe->mPostedGroupId, false, true)); break; case RsPostedEventCode::NEW_MESSAGE: - addFeedItem( new PostedItem(this, NEWSFEED_POSTEDMSGLIST, pe->mPostedGroupId, pe->mPostedMsgId, false, true)); + addFeedItem( new BoardsPostItem(this, NEWSFEED_POSTEDMSGLIST, pe->mPostedGroupId, pe->mPostedMsgId, false, true)); break; case RsPostedEventCode::NEW_COMMENT: addFeedItem( new BoardsCommentsItem(this, NEWSFEED_POSTEDMSGLIST, pe->mPostedGroupId, pe->mPostedMsgId, false, true)); @@ -530,6 +531,14 @@ void NewsFeed::testFeeds(RsFeedTypeFlags /*notifyFlags*/) if (flags & RS_FEED_TYPE_CIRCLE) instance->addFeedItemIfUnique(new GxsCircleItem(instance, NEWSFEED_CIRCLELIST, RsGxsCircleId(""), RsGxsId(""), RS_FEED_ITEM_CIRCLE_MEMB_JOIN),true);; + auto feedItem2 = new BoardsPostItem(instance, + NEWSFEED_CHANNELNEWLIST, + RsGxsGroupId ("00000000000000000000000000000000"), + RsGxsMessageId("0000000000000000000000000000000000000000") + , false, true); + + instance->addFeedItem(feedItem2); + #ifdef TO_REMOVE if (!instance) { return; diff --git a/retroshare-gui/src/gui/Posted/PostedCardView.cpp b/retroshare-gui/src/gui/Posted/PostedCardView.cpp index 5f7c6c286..c63996b3a 100644 --- a/retroshare-gui/src/gui/Posted/PostedCardView.cpp +++ b/retroshare-gui/src/gui/Posted/PostedCardView.cpp @@ -45,14 +45,14 @@ PostedCardView::PostedCardView(FeedHolder *feedHolder, uint32_t feedId, const RsGroupMetaData &group_meta, const RsGxsMessageId &post_id, bool isHome, bool autoUpdate) : BasePostedItem(feedHolder, feedId, group_meta, post_id, isHome, autoUpdate) { - setup(); + PostedCardView::setup(); } PostedCardView::PostedCardView(FeedHolder *feedHolder, uint32_t feedId, const RsGxsGroupId &groupId, const RsGxsMessageId& post_id, bool isHome, bool autoUpdate) : BasePostedItem(feedHolder, feedId, groupId, post_id, isHome, autoUpdate) { - setup(); - loadGroup(); + PostedCardView::setup(); + PostedCardView::loadGroup(); } void PostedCardView::setCommentsSize(int comNb) diff --git a/retroshare-gui/src/gui/Posted/PostedItem.cpp b/retroshare-gui/src/gui/Posted/PostedItem.cpp index aa5aea9c4..a592b0058 100644 --- a/retroshare-gui/src/gui/Posted/PostedItem.cpp +++ b/retroshare-gui/src/gui/Posted/PostedItem.cpp @@ -367,14 +367,14 @@ void BasePostedItem::showAuthorInPeople() PostedItem::PostedItem(FeedHolder *feedHolder, uint32_t feedId, const RsGroupMetaData &group_meta, const RsGxsMessageId& post_id, bool isHome, bool autoUpdate) : BasePostedItem(feedHolder, feedId, group_meta, post_id, isHome, autoUpdate) { - setup(); + PostedItem::setup(); } PostedItem::PostedItem(FeedHolder *feedHolder, uint32_t feedId, const RsGxsGroupId &groupId, const RsGxsMessageId& post_id, bool isHome, bool autoUpdate) : BasePostedItem(feedHolder, feedId, groupId, post_id, isHome, autoUpdate) { - setup(); - loadGroup(); + PostedItem::setup(); + PostedItem::loadGroup(); } diff --git a/retroshare-gui/src/gui/Posted/PostedItem.h b/retroshare-gui/src/gui/Posted/PostedItem.h index a2f432dc0..2f1bc51b1 100644 --- a/retroshare-gui/src/gui/Posted/PostedItem.h +++ b/retroshare-gui/src/gui/Posted/PostedItem.h @@ -24,7 +24,7 @@ #include #include -#include "gui/gxs/GxsFeedItem.h" +#include "gui/feeds/GxsFeedItem.h" namespace Ui { class PostedItem; diff --git a/retroshare-gui/src/gui/feeds/BoardsCommentsItem.cpp b/retroshare-gui/src/gui/feeds/BoardsCommentsItem.cpp index 8081c0e99..59082a8fd 100644 --- a/retroshare-gui/src/gui/feeds/BoardsCommentsItem.cpp +++ b/retroshare-gui/src/gui/feeds/BoardsCommentsItem.cpp @@ -143,6 +143,7 @@ void BaseBoardsCommentsItem::loadGroup() { RsErr() << "GxsPostedGroupItem::loadGroup() ERROR getting data" << std::endl; mIsLoadingGroup = false; + deferred_update(); return; } @@ -150,7 +151,8 @@ void BaseBoardsCommentsItem::loadGroup() { std::cerr << "GxsPostedGroupItem::loadGroup() Wrong number of Items" << std::endl; mIsLoadingGroup = false; - return; + deferred_update(); + return; } RsPostedGroup group(groups[0]); @@ -182,7 +184,8 @@ void BaseBoardsCommentsItem::loadMessage() { RsErr() << "BaseBoardsCommentsItem::loadMessage() ERROR getting data" << std::endl; mIsLoadingMessage = false; - return; + deferred_update(); + return; } if (posts.size() == 1) @@ -243,7 +246,8 @@ void BaseBoardsCommentsItem::loadComment() { RsErr() << "BaseBoardsCommentsItem::loadGroup() ERROR getting data" << std::endl; mIsLoadingComment = false; - return; + deferred_update(); + return; } int comNb = comments.size(); diff --git a/retroshare-gui/src/gui/feeds/BoardsCommentsItem.h b/retroshare-gui/src/gui/feeds/BoardsCommentsItem.h index d5bff44b7..bffbf5bf6 100644 --- a/retroshare-gui/src/gui/feeds/BoardsCommentsItem.h +++ b/retroshare-gui/src/gui/feeds/BoardsCommentsItem.h @@ -24,7 +24,7 @@ #include #include -#include "gui/gxs/GxsFeedItem.h" +#include "gui/feeds/GxsFeedItem.h" namespace Ui { class BoardsCommentsItem; diff --git a/retroshare-gui/src/gui/feeds/BoardsPostItem.cpp b/retroshare-gui/src/gui/feeds/BoardsPostItem.cpp new file mode 100644 index 000000000..9fcf15bff --- /dev/null +++ b/retroshare-gui/src/gui/feeds/BoardsPostItem.cpp @@ -0,0 +1,536 @@ +/******************************************************************************* + * gui/feeds/BoardsPostItem.cpp * + * * + * Copyright (c) 2012, Robert Fernie * + * * + * This program is free software: you can redistribute it and/or modify * + * it under the terms of the GNU Affero General Public License as * + * published by the Free Software Foundation, either version 3 of the * + * License, or (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU Affero General Public License for more details. * + * * + * You should have received a copy of the GNU Affero General Public License * + * along with this program. If not, see . * + * * + *******************************************************************************/ + +#include +#include +#include + +#include "gui/gxs/GxsIdDetails.h" +#include "gui/common/FilesDefs.h" +#include "gui/Posted/PhotoView.h" +#include "rshare.h" +#include "BoardsPostItem.h" +#include "ui_BoardsPostItem.h" + +#include "FeedHolder.h" +#include "SubFileItem.h" +#include "util/misc.h" +#include "util/qtthreadsutils.h" +#include "gui/RetroShareLink.h" +#include "util/HandleRichText.h" +#include "util/DateTime.h" +#include "util/stringutil.h" + +#include +#include + +/**** + * #define DEBUG_ITEM 1 + ****/ + +BoardsPostItem::BoardsPostItem(FeedHolder *feedHolder, uint32_t feedId, const RsGxsGroupId& groupId, const RsGxsMessageId &messageId, bool isHome, bool autoUpdate,const std::set& older_versions) : + GxsFeedItem(feedHolder, feedId, groupId, messageId, isHome, rsPosted, autoUpdate) // this one should be in GxsFeedItem +{ + QVector v; + //bool self = false; + + for(std::set::const_iterator it(older_versions.begin());it!=older_versions.end();++it) + v.push_back(*it) ; + + if(older_versions.find(messageId) == older_versions.end()) + v.push_back(messageId); + + mLoadingStatus = LOADING_STATUS_NO_DATA; + mLoadingMessage = false; + mLoadingGroup = false; + + setMessageVersions(v) ; + setup(); +} + +void BoardsPostItem::paintEvent(QPaintEvent *e) +{ + /* This method employs a trick to trigger a deferred loading. The post and group is requested only + * when actually displayed on the screen. */ + + if(mLoadingStatus != LOADING_STATUS_FILLED && !mGroupMeta.mGroupId.isNull() && !mPost.mMeta.mMsgId.isNull() ) + mLoadingStatus = LOADING_STATUS_HAS_DATA; + + if(mGroupMeta.mGroupId.isNull() && !mLoadingGroup) + requestGroup(); + + if(mPost.mMeta.mMsgId.isNull() && !mLoadingMessage) + requestMessage(); + + switch(mLoadingStatus) + { + case LOADING_STATUS_FILLED: + case LOADING_STATUS_NO_DATA: + default: + break; + + case LOADING_STATUS_HAS_DATA: + fill(); + mLoadingStatus = LOADING_STATUS_FILLED; + break; + } + + GxsFeedItem::paintEvent(e) ; +} + +BoardsPostItem::~BoardsPostItem() +{ + auto timeout = std::chrono::steady_clock::now() + std::chrono::milliseconds(GROUP_ITEM_LOADING_TIMEOUT_ms); + + while( (mLoadingGroup || mLoadingMessage) + && std::chrono::steady_clock::now() < timeout) + { + RsDbg() << __PRETTY_FUNCTION__ << " is Waiting for " + << (mLoadingGroup ? "Group " : "") + << (mLoadingMessage ? "Message " : "") + << "loading." << std::endl; + std::this_thread::sleep_for(std::chrono::milliseconds(100)); + } + + delete(ui); +} + +bool BoardsPostItem::isUnread() const +{ + return IS_MSG_UNREAD(mPost.mMeta.mMsgStatus) ; +} + +void BoardsPostItem::setup() +{ + /* Invoke the Qt Designer generated object setup routine */ + + ui = new Ui::BoardsPostItem; + ui->setupUi(this); + + // Manually set icons to allow to use clever resource sharing that is missing in Qt for Icons loaded from Qt resource file. + // This is particularly important here because a channel may contain many posts, so duplicating the QImages here is deadly for the + // memory. + + ui->logoLabel->setPixmap(FilesDefs::getPixmapFromQtResourcePath(":/images/thumb-default-video.png")); + //ui->warn_image_label->setPixmap(FilesDefs::getPixmapFromQtResourcePath(":/images/status_unknown.png")); + //ui->readButton->setIcon(FilesDefs::getIconFromQtResourcePath(":/images/message-state-unread.png")); + //ui->voteUpButton->setIcon(FilesDefs::getIconFromQtResourcePath(":/images/vote_up.png")); + //ui->voteDownButton->setIcon(FilesDefs::getIconFromQtResourcePath(":/images/vote_down.png")); + //ui->downloadButton->setIcon(FilesDefs::getIconFromQtResourcePath(":/icons/png/download.png")); + //ui->playButton->setIcon(FilesDefs::getIconFromQtResourcePath(":/icons/png/play.png")); + ui->commentButton->setIcon(FilesDefs::getIconFromQtResourcePath(":/icons/png/comment.png")); + //ui->editButton->setIcon(FilesDefs::getIconFromQtResourcePath(":/icons/png/pencil-edit-button.png")); + //ui->copyLinkButton->setIcon(FilesDefs::getIconFromQtResourcePath(":/icons/png/copy.png")); + ui->expandButton->setIcon(FilesDefs::getIconFromQtResourcePath(":/icons/png/down-arrow.png")); + ui->readAndClearButton->setIcon(FilesDefs::getIconFromQtResourcePath(":/icons/png/correct.png")); + ui->clearButton->setIcon(FilesDefs::getIconFromQtResourcePath(":/icons/png/exit2.png")); + + setAttribute(Qt::WA_DeleteOnClose, true); + + mCloseOnRead = false; + + /* clear ui */ + ui->titleLabel->setText(tr("Loading...")); + ui->datetimelabel->clear(); + //ui->filelabel->hide(); + //ui->newCommentLabel->hide(); + //ui->commLabel->hide(); + + /* general ones */ + connect(ui->expandButton, SIGNAL(clicked()), this, SLOT(toggle())); + connect(ui->clearButton, SIGNAL(clicked()), this, SLOT(removeItem())); + connect(ui->logoLabel, SIGNAL(clicked()), this, SLOT(viewPicture())); + + /* specific */ + connect(ui->readAndClearButton, SIGNAL(clicked()), this, SLOT(readAndClearItem())); + //connect(ui->unsubscribeButton, SIGNAL(clicked()), this, SLOT(unsubscribeChannel())); + + //connect(ui->downloadButton, SIGNAL(clicked()), this, SLOT(download())); + // HACK FOR NOW. + ui->commentButton->hide();// hidden until properly enabled. +// connect(ui->commentButton, SIGNAL(clicked()), this, SLOT(loadComments())); + + //connect(ui->playButton, SIGNAL(clicked()), this, SLOT(play(void))); + //connect(ui->editButton, SIGNAL(clicked()), this, SLOT(edit(void))); + //connect(ui->copyLinkButton, SIGNAL(clicked()), this, SLOT(copyMessageLink())); + + //connect(ui->readButton, SIGNAL(toggled(bool)), this, SLOT(readToggled(bool))); + + // hide voting buttons, backend is not implemented yet + //ui->voteUpButton->hide(); + //ui->voteDownButton->hide(); + + //ui->scoreLabel->hide(); + + // hide unsubscribe button not necessary + //ui->unsubscribeButton->hide(); + + //ui->downloadButton->hide(); + //ui->playButton->hide(); + //ui->warn_image_label->hide(); + //ui->warning_label->hide(); + + ui->titleLabel->setMinimumWidth(100); + //ui->subjectLabel->setMinimumWidth(100); + //ui->warning_label->setMinimumWidth(100); + + ui->feedFrame->setProperty("new", false); + ui->feedFrame->style()->unpolish(ui->feedFrame); + ui->feedFrame->style()->polish( ui->feedFrame); + + ui->expandFrame->hide(); +} + +QString BoardsPostItem::groupName() +{ + return QString::fromUtf8(mGroupMeta.mGroupName.c_str()); +} + +void BoardsPostItem::loadGroup() +{ + std::cerr << "BoardsGroupItem::loadGroup()" << std::endl; + + mLoadingGroup = true; + + RsThread::async([this]() + { + // 1 - get group data + + std::vector groups; + const std::list groupIds = { groupId() }; + + if(!rsPosted->getBoardsInfo(groupIds,groups)) // would be better to call channel Summaries for a single group + { + RsErr() << "BoardsPostItem::loadGroup() ERROR getting data for group " << groupId() << std::endl; + mLoadingGroup = false; + deferred_update(); + return; + } + + if (groups.size() != 1) + { + std::cerr << "BoardsPostItem::loadGroup() Wrong number of Items for group " << groupId() ; + std::cerr << std::endl; + mLoadingGroup = false; + deferred_update(); + return; + } + RsPostedGroup group(groups[0]); + + RsQThreadUtils::postToObject( [group,this]() + { + /* Here it goes any code you want to be executed on the Qt Gui + * thread, for example to update the data model with new information + * after a blocking call to RetroShare API complete */ + + mGroupMeta = group.mMeta; + mLoadingGroup = false; + + update(); // this triggers a paintEvent if needed. + + }, this ); + }); +} +void BoardsPostItem::loadMessage() +{ +#ifdef DEBUG_ITEM + std::cerr << "BoardsPostItem::loadMessage()"; + std::cerr << std::endl; +#endif + mLoadingMessage = true; + + RsThread::async([this]() + { + // 1 - get group data + + std::vector posts; + std::vector comments; + std::vector votes; + + if(! rsPosted->getBoardContent( groupId(), std::set( { messageId() } ),posts,comments,votes)) + { + RsErr() << "BoardsPostedItem::loadMessage() ERROR getting data" << std::endl; + mLoadingMessage = false; + deferred_update(); + return; + } + + if (posts.size() == 1) + { +#ifdef DEBUG_ITEM + std::cerr << (void*)this << ": Obtained post, with msgId = " << posts[0].mMeta.mMsgId << std::endl; +#endif + const RsPostedPost& post(posts[0]); + + RsQThreadUtils::postToObject( [post,this]() + { + mPost = post; + mLoadingMessage = false; + update(); // this triggers a paintEvent if needed. + + }, this ); + } + else + { +#ifdef DEBUG_ITEM + std::cerr << "BoardsPostItem::loadMessage() Wrong number of Items. Remove It."; + std::cerr << std::endl; +#endif + + RsQThreadUtils::postToObject( [this]() + { + removeItem(); + mLoadingMessage = false; + update(); // this triggers a paintEvent if needed. + }, this ); + } + }); +} + +void BoardsPostItem::fill() +{ +#ifdef DEBUG_ITEM + std::cerr << "BoardsPostItem::fill()"; + std::cerr << std::endl; +#endif + + QString title; + QString msgText; + //float f = QFontMetricsF(font()).height()/14.0 ; + + ui->logoLabel->setEnableZoom(false); + int desired_height = QFontMetricsF(font()).height() * ITEM_HEIGHT_FACTOR; + ui->logoLabel->setFixedSize(ITEM_PICTURE_FORMAT_RATIO*desired_height,desired_height); + + if(mPost.mImage.mData != NULL) + { + QPixmap thumbnail; + GxsIdDetails::loadPixmapFromData(mPost.mImage.mData, mPost.mImage.mSize, thumbnail,GxsIdDetails::ORIGINAL); + // Wiping data - as its been passed to thumbnail. + + ui->logoLabel->setPicture(thumbnail); + } + else + ui->logoLabel->setPicture( FilesDefs::getPixmapFromQtResourcePath(":/images/thumb-default-video.png") ); + + //if( !IS_GROUP_PUBLISHER(mGroupMeta.mSubscribeFlags) ) + //ui->editButton->hide() ; // never show this button. Feeds are not the place to edit posts. + + if(mPost.mNotes.empty()) + ui->expandButton->hide() ; // never show this button. + + if (mCloseOnRead && !IS_MSG_NEW(mPost.mMeta.mMsgStatus)) { + removeItem(); + } + + title = tr("Board") + ": "; + RetroShareLink link = RetroShareLink::createGxsGroupLink(RetroShareLink::TYPE_POSTED, mPost.mMeta.mGroupId, groupName()); + title += link.toHtml(); + ui->titleLabel->setText(title); + + msgText = tr("Post") + ": "; + RetroShareLink msgLink = RetroShareLink::createGxsMessageLink(RetroShareLink::TYPE_POSTED, mPost.mMeta.mGroupId, mPost.mMeta.mMsgId, messageName()); + msgText += msgLink.toHtml(); + msgText += " By: "; + + RsIdentityDetails detail; + rsIdentity->getIdDetails(mPost.mMeta.mAuthorId,detail); + msgText += GxsIdDetails::getName(detail); + + ui->subjectLabel->setText(msgText); + + //std::cerr << "Copying 1 line from \"" << mPost.mNotes << "\"" << std::endl; + //ui->newCommentLabel->setText(RsStringUtil::CopyLines(QString::fromUtf8(mPost.mNotes.c_str()), 1)) ; + //ui->newCommentLabel->setText(RsHtml().formatText(NULL, QString::fromUtf8(mPost.mNotes.c_str()), /* RSHTML_FORMATTEXT_EMBED_SMILEYS |*/ RSHTML_FORMATTEXT_EMBED_LINKS)); + +// if (IS_GROUP_SUBSCRIBED(mGroupMeta.mSubscribeFlags) || IS_GROUP_ADMIN(mGroupMeta.mSubscribeFlags)) +// { +// ui->unsubscribeButton->setEnabled(true); +// } +// else +// { +// ui->unsubscribeButton->setEnabled(false); +// } + //ui->readButton->hide(); + ui->newLabel->hide(); + //ui->copyLinkButton->hide(); + + if (IS_MSG_NEW(mPost.mMeta.mMsgStatus)) + mCloseOnRead = true; + + // differences between Feed or Top of Comment. + if(mFeedHolder) + { + if (mIsHome) { + ui->commentButton->show(); + } else if (ui->commentButton->icon().isNull()){ + //Icon is seted if a comment received. + ui->commentButton->hide(); + } + } + else + { + ui->commentButton->hide(); + } + + // disable voting buttons - if they have already voted. + /*if (post.mMeta.mMsgStatus & GXS_SERV::GXS_MSG_STATUS_VOTE_MASK) + { + voteUpButton->setEnabled(false); + voteDownButton->setEnabled(false); + }*/ + + { + QTextDocument doc; + doc.setHtml( QString::fromUtf8(mPost.mNotes.c_str()) ); + + ui->msgFrame->setVisible(doc.toPlainText().length() > 0); + } + + ui->datetimelabel->setText(DateTime::formatLongDateTime(mPost.mMeta.mPublishTs)); +} + +QString BoardsPostItem::messageName() +{ + return QString::fromUtf8(mPost.mMeta.mMsgName.c_str()); +} + +void BoardsPostItem::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(messageId()); + + PView->show(); + + /* window will destroy itself! */ +} +void BoardsPostItem::setReadStatus(bool isNew, bool isUnread) +{ +#ifdef TODO + if (isNew) + mPost.mMeta.mMsgStatus |= GXS_SERV::GXS_MSG_STATUS_GUI_NEW; + else + mPost.mMeta.mMsgStatus &= ~GXS_SERV::GXS_MSG_STATUS_GUI_NEW; + + if (isUnread) + { + mPost.mMeta.mMsgStatus |= GXS_SERV::GXS_MSG_STATUS_GUI_UNREAD; + whileBlocking(ui->readButton)->setChecked(true); + ui->readButton->setIcon(FilesDefs::getIconFromQtResourcePath(":/images/message-state-unread.png")); + } + else + { + mPost.mMeta.mMsgStatus &= ~GXS_SERV::GXS_MSG_STATUS_GUI_UNREAD; + whileBlocking(ui->readButton)->setChecked(false); + ui->readButton->setIcon(FilesDefs::getIconFromQtResourcePath(":/images/message-state-read.png")); + } + + ui->newLabel->setVisible(isNew); + + ui->feedFrame->setProperty("new", isNew); + ui->feedFrame->style()->unpolish(ui->feedFrame); + ui->feedFrame->style()->polish( ui->feedFrame); +#endif +} +void BoardsPostItem::toggle() +{ + expand(ui->expandFrame->isHidden()); +} + +/*********** SPECIFIC FUNCTIONS ***********************/ + +void BoardsPostItem::readAndClearItem() +{ +#ifdef DEBUG_ITEM + std::cerr << "BoardsPostItem::readAndClearItem()"; + std::cerr << std::endl; +#endif + readToggled(false); + removeItem(); +} + +void BoardsPostItem::readToggled(bool /*checked*/) +{ + mCloseOnRead = false; + + RsGxsGrpMsgIdPair msgPair = std::make_pair(groupId(), messageId()); + + rsPosted->setPostReadStatus(msgPair, isUnread()); +} + +void BoardsPostItem::fillExpandFrame() +{ + ui->msgLabel->setText(RsHtml().formatText(NULL, QString::fromUtf8(mPost.mNotes.c_str()), /* RSHTML_FORMATTEXT_EMBED_SMILEYS |*/ RSHTML_FORMATTEXT_EMBED_LINKS)); +} + +void BoardsPostItem::doExpand(bool open) +{ + if (mFeedHolder) + { + mFeedHolder->lockLayout(this, true); + } + + if (open) + { + ui->expandFrame->show(); + ui->expandButton->setIcon(FilesDefs::getIconFromQtResourcePath(QString(":/icons/png/up-arrow.png"))); + ui->expandButton->setToolTip(tr("Hide")); + + readToggled(false); + } + else + { + ui->expandFrame->hide(); + ui->expandButton->setIcon(FilesDefs::getIconFromQtResourcePath(QString(":/icons/png/down-arrow.png"))); + ui->expandButton->setToolTip(tr("Expand")); + } + + emit sizeChanged(this); + + if (mFeedHolder) + { + mFeedHolder->lockLayout(this, false); + } +} + +void BoardsPostItem::expandFill(bool first) +{ + GxsFeedItem::expandFill(first); + + if (first) { + fillExpandFrame(); + } +} + diff --git a/retroshare-gui/src/gui/feeds/BoardsPostItem.h b/retroshare-gui/src/gui/feeds/BoardsPostItem.h new file mode 100644 index 000000000..3b8845f63 --- /dev/null +++ b/retroshare-gui/src/gui/feeds/BoardsPostItem.h @@ -0,0 +1,106 @@ +/******************************************************************************* + * gui/feeds/BoardsPostItem.h * + * * + * Copyright (c) 2012, Robert Fernie * + * * + * This program is free software: you can redistribute it and/or modify * + * it under the terms of the GNU Affero General Public License as * + * published by the Free Software Foundation, either version 3 of the * + * License, or (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU Affero General Public License for more details. * + * * + * You should have received a copy of the GNU Affero General Public License * + * along with this program. If not, see . * + * * + *******************************************************************************/ + +#ifndef _BOARDS_POST_ITEM_H +#define _BOARDS_POST_ITEM_H + +#include + +#include +#include "gui/feeds/GxsFeedItem.h" + +namespace Ui { +class BoardsPostItem; +} + +class FeedHolder; +class SubFileItem; + +class BoardsPostItem : public GxsFeedItem +{ + Q_OBJECT + +public: + // This one is used in NewFeed for incoming channel posts. Only the group and msg ids are known at this point. + // It can be used for all apparences of channel posts. But in rder to merge comments from the previous versions of the post, the list of + // previous posts should be supplied. It's optional. If not supplied only the comments of the new version will be displayed. + + BoardsPostItem(FeedHolder *feedHolder, uint32_t feedId, const RsGxsGroupId& groupId, const RsGxsMessageId &messageId, bool isHome, bool autoUpdate, const std::set& older_versions = std::set()); + virtual ~BoardsPostItem(); + + uint64_t uniqueIdentifier() const override { return hash_64bits("BoardsPostItem " + messageId().toStdString()) ; } + +protected: + + bool isUnread() const ; + void setReadStatus(bool isNew, bool isUnread); + + static uint64_t computeIdentifier(const RsGxsMessageId& msgid) { return hash64("BoardsPostItem " + msgid.toStdString()) ; } + + /* FeedItem */ + virtual void doExpand(bool open) override ; + virtual void expandFill(bool first) override ; + + // This does nothing except triggering the loading of the post data and comments. This function is mainly used to detect + // when the post is actually made visible. + + virtual void paintEvent(QPaintEvent *) override; + + /* GxsGroupFeedItem */ + virtual QString groupName() override; + virtual void loadGroup() override; + virtual RetroShareLink::enumType getLinkType() override{ return RetroShareLink::TYPE_CHANNEL; } + + /* GxsFeedItem */ + virtual QString messageName() override; + virtual void loadMessage() override; + virtual void loadComment() override {} + +private slots: + /* default stuff */ + void toggle() override; + void readAndClearItem(); + void readToggled(bool checked); + void viewPicture(); + +signals: + void vote(const RsGxsGrpMsgIdPair& msgId, bool up); + +private: + void setup(); + void fill(); + void fillExpandFrame(); + +private: + bool mCloseOnRead; + + LoadingStatus mLoadingStatus; + + bool mLoadingMessage; + bool mLoadingGroup; + + RsGroupMetaData mGroupMeta; + RsPostedPost mPost; + + /** Qt Designer generated object */ + Ui::BoardsPostItem *ui; +}; + +#endif diff --git a/retroshare-gui/src/gui/feeds/BoardsPostItem.ui b/retroshare-gui/src/gui/feeds/BoardsPostItem.ui new file mode 100644 index 000000000..3a7a890f6 --- /dev/null +++ b/retroshare-gui/src/gui/feeds/BoardsPostItem.ui @@ -0,0 +1,334 @@ + + + BoardsPostItem + + + + 0 + 0 + 803 + 175 + + + + + 1 + + + 1 + + + 1 + + + 1 + + + 6 + + + 1 + + + + + + 0 + 0 + + + + true + + + QFrame::StyledPanel + + + QFrame::Raised + + + + + + + + + + + 0 + 0 + + + + + + + false + + + Qt::AlignCenter + + + + + + + + + + + + + + 0 + 0 + + + + + 11 + 75 + true + true + + + + Board label + + + false + + + true + + + + + + + + 75 + true + + + + DateTime + + + + + + + New + + + + + + + + + Qt::Vertical + + + + 20 + 40 + + + + + + + + 0 + + + + + + 11 + 75 + false + true + + + + TextLabel + + + true + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + Comments + + + + + + + + 0 + 0 + + + + Qt::NoFocus + + + Expand + + + + + + + + 0 + 0 + + + + Qt::NoFocus + + + Set as read and remove item + + + + + + + + 0 + 0 + + + + Qt::NoFocus + + + Remove Item + + + + + + + + + + + + + + 0 + + + 0 + + + 0 + + + 0 + + + + + QFrame::Box + + + QFrame::Sunken + + + + 5 + + + 5 + + + 5 + + + 5 + + + + + + 0 + 0 + + + + true + + + 6 + + + -1 + + + true + + + Qt::LinksAccessibleByMouse|Qt::TextSelectableByKeyboard|Qt::TextSelectableByMouse + + + + + + + + + + + + + Qt::Vertical + + + + 20 + 0 + + + + + + + + + + + + ZoomableLabel + QLabel +
gui/gxschannels/GxsChannelPostThumbnail.h
+
+
+ + + + +
diff --git a/retroshare-gui/src/gui/feeds/ChannelsCommentsItem.cpp b/retroshare-gui/src/gui/feeds/ChannelsCommentsItem.cpp index 88425975d..75a6106fc 100644 --- a/retroshare-gui/src/gui/feeds/ChannelsCommentsItem.cpp +++ b/retroshare-gui/src/gui/feeds/ChannelsCommentsItem.cpp @@ -211,6 +211,7 @@ void ChannelsCommentsItem::loadGroupData() { RsErr() << "GxsGxsChannelGroupItem::loadGroup() ERROR getting data for group " << groupId() << std::endl; mLoadingGroup = false; + deferred_update(); return; } @@ -219,6 +220,7 @@ void ChannelsCommentsItem::loadGroupData() std::cerr << "GxsGxsChannelGroupItem::loadGroup() Wrong number of Items for group " << groupId() ; std::cerr << std::endl; mLoadingGroup = false; + deferred_update(); return; } RsGxsChannelGroup group(groups[0]); @@ -257,6 +259,7 @@ void ChannelsCommentsItem::loadMessageData() { RsErr() << "GxsGxsChannelGroupItem::loadMessage() ERROR getting data" << std::endl; mLoadingMessage = false; + deferred_update(); return; } @@ -303,11 +306,13 @@ void ChannelsCommentsItem::loadCommentData() { RsErr() << "GxsGxsChannelGroupItem::loadComment() ERROR getting data" << std::endl; mLoadingComment = false; + deferred_update(); return; } if(comments.size()!=1) { mLoadingComment = false; + deferred_update(); return; } diff --git a/retroshare-gui/src/gui/feeds/ChannelsCommentsItem.h b/retroshare-gui/src/gui/feeds/ChannelsCommentsItem.h index 6cd25154e..87192c7d0 100644 --- a/retroshare-gui/src/gui/feeds/ChannelsCommentsItem.h +++ b/retroshare-gui/src/gui/feeds/ChannelsCommentsItem.h @@ -24,7 +24,7 @@ #include #include -#include "gui/gxs/GxsFeedItem.h" +#include "gui/feeds/GxsFeedItem.h" namespace Ui { class ChannelsCommentsItem; diff --git a/retroshare-gui/src/gui/feeds/FeedItem.cpp b/retroshare-gui/src/gui/feeds/FeedItem.cpp index fbaa7226d..df8c82c5d 100644 --- a/retroshare-gui/src/gui/feeds/FeedItem.cpp +++ b/retroshare-gui/src/gui/feeds/FeedItem.cpp @@ -22,6 +22,11 @@ #include "FeedItem.h" #include "FeedHolder.h" +// Height of feed items as a factor of font size height. + +const int FeedItem::ITEM_HEIGHT_FACTOR = 8; +const float FeedItem::ITEM_PICTURE_FORMAT_RATIO = 16.0/9.0; + /** Constructor */ FeedItem::FeedItem(FeedHolder *fh, uint32_t feedId, QWidget *parent) : QWidget(parent),mFeedHolder(fh),mFeedId(feedId),mHash(0) { diff --git a/retroshare-gui/src/gui/feeds/FeedItem.h b/retroshare-gui/src/gui/feeds/FeedItem.h index f2bb92e9f..f11424520 100644 --- a/retroshare-gui/src/gui/feeds/FeedItem.h +++ b/retroshare-gui/src/gui/feeds/FeedItem.h @@ -120,6 +120,9 @@ protected: FeedHolder *mFeedHolder; uint32_t mFeedId; + static const int ITEM_HEIGHT_FACTOR ; + static const float ITEM_PICTURE_FORMAT_RATIO ; + signals: void sizeChanged(FeedItem *feedItem); void feedItemNeedsClosing(qulonglong); diff --git a/retroshare-gui/src/gui/feeds/GxsChannelGroupItem.cpp b/retroshare-gui/src/gui/feeds/GxsChannelGroupItem.cpp index 56c10508a..0adafe8e9 100644 --- a/retroshare-gui/src/gui/feeds/GxsChannelGroupItem.cpp +++ b/retroshare-gui/src/gui/feeds/GxsChannelGroupItem.cpp @@ -150,6 +150,7 @@ void GxsChannelGroupItem::loadGroup() { RsErr() << "PostedItem::loadGroup() ERROR getting data" << std::endl; mLoadingGroup = false; + deferred_update(); return; } @@ -157,6 +158,7 @@ void GxsChannelGroupItem::loadGroup() { std::cerr << "GxsGxsChannelGroupItem::loadGroup() Wrong number of Items"; std::cerr << std::endl; + deferred_update(); mLoadingGroup = false; return; } @@ -192,11 +194,16 @@ void GxsChannelGroupItem::fill() RetroShareLink link = RetroShareLink::createGxsGroupLink(RetroShareLink::TYPE_CHANNEL, mGroup.mMeta.mGroupId, groupName()); ui->nameLabel->setText(link.toHtml()); - ui->descLabel->setText(QString::fromUtf8(mGroup.mDescription.c_str())); + ui->logoLabel->setEnableZoom(false); + int desired_height = QFontMetricsF(font()).height() * ITEM_HEIGHT_FACTOR; + ui->logoLabel->setFixedSize(ITEM_PICTURE_FORMAT_RATIO*desired_height,desired_height); + + ui->descLabel->setText(QString::fromUtf8(mGroup.mDescription.c_str())); if (mGroup.mImage.mData != NULL) { QPixmap chanImage; GxsIdDetails::loadPixmapFromData(mGroup.mImage.mData, mGroup.mImage.mSize, chanImage,GxsIdDetails::ORIGINAL); + ui->logoLabel->setPixmap(chanImage); } diff --git a/retroshare-gui/src/gui/feeds/GxsChannelGroupItem.h b/retroshare-gui/src/gui/feeds/GxsChannelGroupItem.h index 604145941..ab9aaf088 100644 --- a/retroshare-gui/src/gui/feeds/GxsChannelGroupItem.h +++ b/retroshare-gui/src/gui/feeds/GxsChannelGroupItem.h @@ -22,7 +22,7 @@ #define _GXSCHANNELGROUPITEM_H #include -#include "gui/gxs/GxsGroupFeedItem.h" +#include "gui/feeds/GxsGroupFeedItem.h" namespace Ui { class GxsChannelGroupItem; diff --git a/retroshare-gui/src/gui/feeds/GxsChannelGroupItem.ui b/retroshare-gui/src/gui/feeds/GxsChannelGroupItem.ui index 43537d061..d828571b0 100644 --- a/retroshare-gui/src/gui/feeds/GxsChannelGroupItem.ui +++ b/retroshare-gui/src/gui/feeds/GxsChannelGroupItem.ui @@ -143,7 +143,7 @@ - + 70 @@ -391,6 +391,13 @@ + + + ZoomableLabel + QLabel +
gui/gxschannels/GxsChannelPostThumbnail.h
+
+
diff --git a/retroshare-gui/src/gui/feeds/GxsChannelPostItem.cpp b/retroshare-gui/src/gui/feeds/GxsChannelPostItem.cpp index abd10ed2b..9d6a9992f 100644 --- a/retroshare-gui/src/gui/feeds/GxsChannelPostItem.cpp +++ b/retroshare-gui/src/gui/feeds/GxsChannelPostItem.cpp @@ -219,6 +219,7 @@ void GxsChannelPostItem::loadGroup() { RsErr() << "GxsGxsChannelGroupItem::loadGroup() ERROR getting data for group " << groupId() << std::endl; mLoadingGroup = false; + deferred_update(); return; } @@ -227,6 +228,7 @@ void GxsChannelPostItem::loadGroup() std::cerr << "GxsGxsChannelGroupItem::loadGroup() Wrong number of Items for group " << groupId() ; std::cerr << std::endl; mLoadingGroup = false; + deferred_update(); return; } RsGxsChannelGroup group(groups[0]); @@ -265,6 +267,7 @@ void GxsChannelPostItem::loadMessage() { RsErr() << "GxsGxsChannelGroupItem::loadGroup() ERROR getting data" << std::endl; mLoadingMessage = false; + deferred_update(); return; } @@ -312,8 +315,8 @@ void GxsChannelPostItem::fill() //float f = QFontMetricsF(font()).height()/14.0 ; ui->logoLabel->setEnableZoom(false); - int desired_height = QFontMetricsF(font()).height() * 8; - ui->logoLabel->setFixedSize(4/3.0*desired_height,desired_height); + int desired_height = QFontMetricsF(font()).height() * ITEM_HEIGHT_FACTOR; + ui->logoLabel->setFixedSize(ITEM_PICTURE_FORMAT_RATIO*desired_height,desired_height); if(mPost.mThumbnail.mData != NULL) { @@ -373,7 +376,7 @@ void GxsChannelPostItem::fill() ui->subjectLabel->setText(RsStringUtil::CopyLines(QString::fromUtf8(mPost.mMsg.c_str()), 2)) ; - //QString score = QString::number(post.mTopScore); + //QString score = QString::number(post.mTopScore); // scoreLabel->setText(score); /* disable buttons: deletion facility not enabled with cache services yet */ diff --git a/retroshare-gui/src/gui/feeds/GxsChannelPostItem.h b/retroshare-gui/src/gui/feeds/GxsChannelPostItem.h index cdcd56088..4c4503ec0 100644 --- a/retroshare-gui/src/gui/feeds/GxsChannelPostItem.h +++ b/retroshare-gui/src/gui/feeds/GxsChannelPostItem.h @@ -24,7 +24,7 @@ #include #include -#include "gui/gxs/GxsFeedItem.h" +#include "gui/feeds/GxsFeedItem.h" namespace Ui { class GxsChannelPostItem; diff --git a/retroshare-gui/src/gui/gxs/GxsFeedItem.cpp b/retroshare-gui/src/gui/feeds/GxsFeedItem.cpp similarity index 98% rename from retroshare-gui/src/gui/gxs/GxsFeedItem.cpp rename to retroshare-gui/src/gui/feeds/GxsFeedItem.cpp index b9f2e68ee..524ecc578 100644 --- a/retroshare-gui/src/gui/gxs/GxsFeedItem.cpp +++ b/retroshare-gui/src/gui/feeds/GxsFeedItem.cpp @@ -18,7 +18,7 @@ * * *******************************************************************************/ -#include "gui/gxs/GxsFeedItem.h" +#include "gui/feeds/GxsFeedItem.h" #include "gui/feeds/FeedHolder.h" #include "gui/gxs/RsGxsUpdateBroadcastBase.h" diff --git a/retroshare-gui/src/gui/gxs/GxsFeedItem.h b/retroshare-gui/src/gui/feeds/GxsFeedItem.h similarity index 97% rename from retroshare-gui/src/gui/gxs/GxsFeedItem.h rename to retroshare-gui/src/gui/feeds/GxsFeedItem.h index bc75d1837..b33db7f18 100644 --- a/retroshare-gui/src/gui/gxs/GxsFeedItem.h +++ b/retroshare-gui/src/gui/feeds/GxsFeedItem.h @@ -1,5 +1,5 @@ /******************************************************************************* - * retroshare-gui/src/gui/gxs/GxsFeedItem.h * + * retroshare-gui/src/gui/feeds/GxsFeedItem.h * * * * Copyright 2012-2013 by Robert Fernie * * * diff --git a/retroshare-gui/src/gui/feeds/GxsForumGroupItem.cpp b/retroshare-gui/src/gui/feeds/GxsForumGroupItem.cpp index 7e0fdca71..c3592b958 100644 --- a/retroshare-gui/src/gui/feeds/GxsForumGroupItem.cpp +++ b/retroshare-gui/src/gui/feeds/GxsForumGroupItem.cpp @@ -161,6 +161,7 @@ void GxsForumGroupItem::loadGroup() { RsErr() << "GxsForumGroupItem::loadGroup() ERROR getting data" << std::endl; mLoadingGroup = false; + deferred_update(); return; } @@ -169,6 +170,7 @@ void GxsForumGroupItem::loadGroup() std::cerr << "GxsForumGroupItem::loadGroup() Wrong number of Items"; std::cerr << std::endl; mLoadingGroup = false; + deferred_update(); return; } RsGxsForumGroup group(groups[0]);// no reference to teporary accross threads! @@ -205,7 +207,11 @@ void GxsForumGroupItem::fill() ui->descLabel->setText(QString::fromUtf8(mGroup.mDescription.c_str())); - if (IS_GROUP_PUBLISHER(mGroup.mMeta.mSubscribeFlags)) { + ui->forumlogo_label->setEnableZoom(false); + int desired_height = QFontMetricsF(font()).height() * ITEM_HEIGHT_FACTOR; + ui->forumlogo_label->setFixedSize(ITEM_PICTURE_FORMAT_RATIO*desired_height,desired_height); + + if (IS_GROUP_PUBLISHER(mGroup.mMeta.mSubscribeFlags)) { ui->forumlogo_label->setPixmap(FilesDefs::getPixmapFromQtResourcePath(":/icons/png/forums.png")); } else { ui->forumlogo_label->setPixmap(FilesDefs::getPixmapFromQtResourcePath(":/icons/png/forums-default.png")); diff --git a/retroshare-gui/src/gui/feeds/GxsForumGroupItem.h b/retroshare-gui/src/gui/feeds/GxsForumGroupItem.h index 4a70a215d..31026f18c 100644 --- a/retroshare-gui/src/gui/feeds/GxsForumGroupItem.h +++ b/retroshare-gui/src/gui/feeds/GxsForumGroupItem.h @@ -23,7 +23,7 @@ #include #include -#include "gui/gxs/GxsGroupFeedItem.h" +#include "gui/feeds/GxsGroupFeedItem.h" namespace Ui { class GxsForumGroupItem; diff --git a/retroshare-gui/src/gui/feeds/GxsForumGroupItem.ui b/retroshare-gui/src/gui/feeds/GxsForumGroupItem.ui index aee325282..ff344158a 100644 --- a/retroshare-gui/src/gui/feeds/GxsForumGroupItem.ui +++ b/retroshare-gui/src/gui/feeds/GxsForumGroupItem.ui @@ -135,7 +135,7 @@ - + 70 @@ -406,6 +406,13 @@ + + + ZoomableLabel + QLabel +
gui/gxschannels/GxsChannelPostThumbnail.h
+
+
diff --git a/retroshare-gui/src/gui/feeds/GxsForumMsgItem.cpp b/retroshare-gui/src/gui/feeds/GxsForumMsgItem.cpp index 9e07c6de8..333a6a577 100644 --- a/retroshare-gui/src/gui/feeds/GxsForumMsgItem.cpp +++ b/retroshare-gui/src/gui/feeds/GxsForumMsgItem.cpp @@ -167,6 +167,7 @@ void GxsForumMsgItem::loadGroup() { RsErr() << "GxsForumGroupItem::loadGroup() ERROR getting data" << std::endl; mLoadingGroup = false; + deferred_update(); return; } @@ -175,6 +176,7 @@ void GxsForumMsgItem::loadGroup() std::cerr << "GxsForumGroupItem::loadGroup() Wrong number of Items"; std::cerr << std::endl; mLoadingGroup = false; + deferred_update(); return; } RsGxsForumGroup group(groups[0]); @@ -229,6 +231,7 @@ void GxsForumMsgItem::loadMessage() { std::cerr << "GxsForumMsgItem::loadMessage() ERROR getting message data"; mLoadingMessage = false; + deferred_update(); return; } // now load the parent message. If not found, it's not a problem. @@ -420,7 +423,9 @@ void GxsForumMsgItem::unsubscribeForum() void GxsForumMsgItem::setAsRead(bool doUpdate) { mCloseOnRead = false; - mLoadingSetAsRead = true; + + if(doUpdate) + mLoadingSetAsRead = true; RsThread::async( [this, doUpdate]() { RsGxsGrpMsgIdPair msgPair = std::make_pair(groupId(), messageId()); diff --git a/retroshare-gui/src/gui/feeds/GxsForumMsgItem.h b/retroshare-gui/src/gui/feeds/GxsForumMsgItem.h index e6dc533d5..2c8e55292 100644 --- a/retroshare-gui/src/gui/feeds/GxsForumMsgItem.h +++ b/retroshare-gui/src/gui/feeds/GxsForumMsgItem.h @@ -22,7 +22,7 @@ #define _GXSFORUMMSGITEM_H #include -#include "gui/gxs/GxsFeedItem.h" +#include "gui/feeds/GxsFeedItem.h" namespace Ui { class GxsForumMsgItem; diff --git a/retroshare-gui/src/gui/gxs/GxsGroupFeedItem.cpp b/retroshare-gui/src/gui/feeds/GxsGroupFeedItem.cpp similarity index 84% rename from retroshare-gui/src/gui/gxs/GxsGroupFeedItem.cpp rename to retroshare-gui/src/gui/feeds/GxsGroupFeedItem.cpp index 72f08ae8e..523f41076 100644 --- a/retroshare-gui/src/gui/gxs/GxsGroupFeedItem.cpp +++ b/retroshare-gui/src/gui/feeds/GxsGroupFeedItem.cpp @@ -1,5 +1,5 @@ /******************************************************************************* - * retroshare-gui/src/gui/gxs/GxsGroupFeedItem.cpp * + * retroshare-gui/src/gui/feeds/GxsGroupFeedItem.cpp * * * * Copyright 2012-2013 by Robert Fernie * * * @@ -20,10 +20,13 @@ #include -#include "gui/gxs/GxsGroupFeedItem.h" +#include "GxsGroupFeedItem.h" + #include "gui/feeds/FeedHolder.h" #include "gui/gxs/RsGxsUpdateBroadcastBase.h" +#include "util/qtthreadsutils.h" + #include #include @@ -43,6 +46,7 @@ GxsGroupFeedItem::GxsGroupFeedItem(FeedHolder *feedHolder, uint32_t feedId, cons /* this are just generally useful for all children */ mIsHome = isHome; + mLastDelay = 300; // re-update after 300ms on fail. See deferred_update() /* load data if we can */ mGroupId = groupId; @@ -116,3 +120,19 @@ void GxsGroupFeedItem::requestGroup() loadGroup(); } +void GxsGroupFeedItem::deferred_update() +{ + mLastDelay = (int)(float(mLastDelay)*1.2); + mLastDelay += 100.0*RsRandom::random_f32(); + + if(mLastDelay < 10000.0) + { + std::cerr << "Launching deferred update at " << mLastDelay << " ms." << std::endl; + RsQThreadUtils::postToObject( [this]() { QTimer::singleShot(mLastDelay,this,SLOT(update())); }, this ); + } +} + + + + + diff --git a/retroshare-gui/src/gui/gxs/GxsGroupFeedItem.h b/retroshare-gui/src/gui/feeds/GxsGroupFeedItem.h similarity index 92% rename from retroshare-gui/src/gui/gxs/GxsGroupFeedItem.h rename to retroshare-gui/src/gui/feeds/GxsGroupFeedItem.h index 9bb21b6d0..c70879bbd 100644 --- a/retroshare-gui/src/gui/gxs/GxsGroupFeedItem.h +++ b/retroshare-gui/src/gui/feeds/GxsGroupFeedItem.h @@ -1,5 +1,5 @@ /******************************************************************************* - * retroshare-gui/src/gui/gxs/GxsGroupFeedItem.h * + * retroshare-gui/src/gui/feeds/GxsGroupFeedItem.h * * * * Copyright 2012-2013 by Robert Fernie * * * @@ -58,6 +58,9 @@ protected: virtual RetroShareLink::enumType getLinkType() = 0; virtual QString groupName() = 0; + // This triggers an update in the main thread after a short waiting period. Help loading objects that havn't loaded yet. + void deferred_update(); + protected slots: void subscribe(); void unsubscribe(); @@ -74,6 +77,7 @@ private slots: private: RsGxsGroupId mGroupId; + int mLastDelay; }; Q_DECLARE_METATYPE(RsGxsGroupId) diff --git a/retroshare-gui/src/gui/feeds/PostedGroupItem.cpp b/retroshare-gui/src/gui/feeds/PostedGroupItem.cpp index e4e416faa..2e341a00a 100644 --- a/retroshare-gui/src/gui/feeds/PostedGroupItem.cpp +++ b/retroshare-gui/src/gui/feeds/PostedGroupItem.cpp @@ -127,6 +127,7 @@ void PostedGroupItem::loadGroup() { RsErr() << "GxsPostedGroupItem::loadGroup() ERROR getting data" << std::endl; mLoadingGroup = false; + deferred_update(); return; } @@ -135,6 +136,7 @@ void PostedGroupItem::loadGroup() std::cerr << "GxsPostedGroupItem::loadGroup() Wrong number of Items"; std::cerr << std::endl; mLoadingGroup = false; + deferred_update(); return; } RsPostedGroup group(groups[0]); @@ -173,7 +175,11 @@ void PostedGroupItem::fill() ui->descLabel->setText(QString::fromUtf8(mGroup.mDescription.c_str())); - if (mGroup.mGroupImage.mData != NULL) { + ui->logoLabel->setEnableZoom(false); + int desired_height = QFontMetricsF(font()).height() * ITEM_HEIGHT_FACTOR; + ui->logoLabel->setFixedSize(ITEM_PICTURE_FORMAT_RATIO*desired_height,desired_height); + + if (mGroup.mGroupImage.mData != NULL) { QPixmap postedImage; GxsIdDetails::loadPixmapFromData(mGroup.mGroupImage.mData, mGroup.mGroupImage.mSize, postedImage,GxsIdDetails::ORIGINAL); ui->logoLabel->setPixmap(QPixmap(postedImage)); diff --git a/retroshare-gui/src/gui/feeds/PostedGroupItem.h b/retroshare-gui/src/gui/feeds/PostedGroupItem.h index 835c7ce19..fdda04922 100644 --- a/retroshare-gui/src/gui/feeds/PostedGroupItem.h +++ b/retroshare-gui/src/gui/feeds/PostedGroupItem.h @@ -22,7 +22,7 @@ #define _POSTEDGROUPITEM_H #include -#include "gui/gxs/GxsGroupFeedItem.h" +#include "gui/feeds/GxsGroupFeedItem.h" namespace Ui { class PostedGroupItem; diff --git a/retroshare-gui/src/gui/feeds/PostedGroupItem.ui b/retroshare-gui/src/gui/feeds/PostedGroupItem.ui index 6c043972f..b037b767a 100644 --- a/retroshare-gui/src/gui/feeds/PostedGroupItem.ui +++ b/retroshare-gui/src/gui/feeds/PostedGroupItem.ui @@ -135,7 +135,7 @@ - + 70 @@ -396,6 +396,13 @@ + + + ZoomableLabel + QLabel +
gui/gxschannels/GxsChannelPostThumbnail.h
+
+
diff --git a/retroshare-gui/src/retroshare-gui.pro b/retroshare-gui/src/retroshare-gui.pro index 32aa52360..e8362a885 100644 --- a/retroshare-gui/src/retroshare-gui.pro +++ b/retroshare-gui/src/retroshare-gui.pro @@ -596,10 +596,13 @@ HEADERS += rshare.h \ gui/elastic/elnode.h \ gui/NewsFeed.h \ gui/feeds/BoardsCommentsItem.h \ + gui/feeds/BoardsPostItem.h \ gui/feeds/FeedItem.h \ gui/feeds/FeedHolder.h \ + gui/feeds/GxsGroupFeedItem.h \ gui/feeds/GxsCircleItem.h \ gui/feeds/ChannelsCommentsItem.h \ + gui/feeds/GxsFeedItem.h \ gui/feeds/PeerItem.h \ gui/feeds/MsgItem.h \ gui/feeds/ChatMsgItem.h \ @@ -691,6 +694,7 @@ FORMS += gui/StartDialog.ui \ gui/advsearch/expressionwidget.ui \ gui/NewsFeed.ui \ gui/feeds/BoardsCommentsItem.ui \ + gui/feeds/BoardsPostItem.ui \ gui/feeds/GxsCircleItem.ui \ gui/feeds/ChannelsCommentsItem.ui \ gui/feeds/PeerItem.ui \ @@ -942,10 +946,13 @@ SOURCES += main.cpp \ gui/elastic/elnode.cpp \ gui/NewsFeed.cpp \ gui/feeds/BoardsCommentsItem.cpp \ + gui/feeds/BoardsPostItem.cpp \ gui/feeds/FeedItem.cpp \ + gui/feeds/GxsGroupFeedItem.cpp \ gui/feeds/FeedHolder.cpp \ gui/feeds/GxsCircleItem.cpp \ gui/feeds/ChannelsCommentsItem.cpp \ + gui/feeds/GxsFeedItem.cpp \ gui/feeds/PeerItem.cpp \ gui/feeds/MsgItem.cpp \ gui/feeds/ChatMsgItem.cpp \ @@ -1424,11 +1431,9 @@ gxsgui { gui/gxs/GxsGroupFrameDialog.h \ gui/gxs/GxsMessageFrameWidget.h \ gui/gxs/GxsMessageFramePostWidget.h \ - gui/gxs/GxsGroupFeedItem.h \ - gui/gxs/GxsFeedItem.h \ gui/gxs/GxsGroupShareKey.h \ gui/gxs/GxsUserNotify.h \ - gui/gxs/GxsFeedWidget.h \ +# gui/gxs/GxsFeedWidget.h \ util/TokenQueue.h \ util/RsGxsUpdateBroadcast.h \ @@ -1458,10 +1463,8 @@ gxsgui { gui/gxs/GxsGroupFrameDialog.cpp \ gui/gxs/GxsMessageFrameWidget.cpp \ gui/gxs/GxsMessageFramePostWidget.cpp \ - gui/gxs/GxsGroupFeedItem.cpp \ - gui/gxs/GxsFeedItem.cpp \ gui/gxs/GxsUserNotify.cpp \ - gui/gxs/GxsFeedWidget.cpp \ +# gui/gxs/GxsFeedWidget.cpp \ util/TokenQueue.cpp \ util/RsGxsUpdateBroadcast.cpp \