- Added new base class for group feeds - GxsGroupFeedItem

- Added feed item for channel group
- Added test of feed items for channels and forums
- Reworked existing feed items

git-svn-id: http://svn.code.sf.net/p/retroshare/code/trunk@7689 b45a01b8-16f6-495d-af2f-9b41ad6348cc
This commit is contained in:
thunder2 2014-11-18 00:49:21 +00:00
parent fd20f629dc
commit 97968170d1
16 changed files with 1524 additions and 452 deletions

View File

@ -27,12 +27,12 @@
#include <retroshare/rsnotify.h>
#include <retroshare/rspeers.h>
//#include <retroshare/rschannels.h>
//#include <retroshare/rsforums.h>
#include <retroshare/rsgxschannels.h>
#include <retroshare/rsgxsforums.h>
#include <retroshare/rsmsgs.h>
#include <retroshare/rsplugin.h>
//#include "feeds/ChanNewItem.h"
#include "feeds/GxsChannelGroupItem.h"
#include "feeds/GxsChannelPostItem.h"
//#include "feeds/ForumNewItem.h"
//#include "feeds/ForumMsgItem.h"
@ -72,6 +72,9 @@ const uint32_t NEWSFEED_SECLIST = 0x000a;
#define ROLE_RECEIVED FEED_TREEWIDGET_SORTROLE
#define TOKEN_TYPE_GROUP 1
#define TOKEN_TYPE_MESSAGE 2
/*****
* #define NEWS_DEBUG 1
****/
@ -86,6 +89,9 @@ NewsFeed::NewsFeed(QWidget *parent) :
/* Invoke the Qt Designer generated object setup routine */
ui->setupUi(this);
mTokenQueueChannel = NULL;
mTokenQueueForum = NULL;
setUpdateWhenInvisible(true);
if (!instance) {
@ -123,6 +129,13 @@ NewsFeed::~NewsFeed()
if (instance == this) {
instance = NULL;
}
if (mTokenQueueChannel) {
delete(mTokenQueueChannel);
}
if (mTokenQueueForum) {
delete(mTokenQueueForum);
}
}
UserNotify *NewsFeed::getUserNotify(QObject *parent)
@ -300,117 +313,35 @@ void NewsFeed::testFeeds(uint notifyFlags)
instance->addFeedItemSecurityUnknownOut(fi);
break;
#if 0
case RS_FEED_TYPE_CHANNEL:
{
std::list<ChannelInfo> channelList;
rsChannels->getChannelList(channelList);
std::list<ChannelInfo>::iterator channelIt;
for (channelIt = channelList.begin(); channelIt != channelList.end(); ++channelIt) {
if (fi.mId1.empty()) {
/* store first channel */
fi.mId1 = channelIt->channelId;
}
if (!channelIt->channelDesc.empty()) {
/* take channel with description */
fi.mId1 = channelIt->channelId;
break;
}
if (!instance->mTokenQueueChannel) {
instance->mTokenQueueChannel = new TokenQueue(rsGxsChannels->getTokenService(), instance);
}
instance->addFeedItemChanNew(fi);
instance->addFeedItemChanUpdate(fi);
RsTokReqOptions opts;
opts.mReqType = GXS_REQUEST_TYPE_GROUP_DATA;
uint32_t token;
instance->mTokenQueueChannel->requestGroupInfo(token, RS_TOKREQ_ANSTYPE_SUMMARY, opts, TOKEN_TYPE_GROUP);
RsFeedItem fiMsg;
bool bFound = false;
for (channelIt = channelList.begin(); channelIt != channelList.end(); ++channelIt) {
std::list<ChannelMsgSummary> channelMsgs;
rsChannels->getChannelMsgList(channelIt->channelId, channelMsgs);
std::list<ChannelMsgSummary>::iterator msgIt;
for (msgIt = channelMsgs.begin(); msgIt != channelMsgs.end(); ++msgIt) {
if (fiMsg.mId2.empty()) {
/* store first channel message */
fiMsg.mId1 = msgIt->channelId;
fiMsg.mId2 = msgIt->msgId;
}
if (!msgIt->msg.empty()) {
/* take channel message with description */
fiMsg.mId1 = msgIt->channelId;
fiMsg.mId2 = msgIt->msgId;
bFound = true;
break;
}
}
if (bFound) {
break;
}
}
instance->addFeedItemChanMsg(fiMsg);
break;
}
case RS_FEED_TYPE_FORUM:
{
std::list<ForumInfo> forumList;
rsForums->getForumList(forumList);
std::list<ForumInfo>::iterator forumIt;
for (forumIt = forumList.begin(); forumIt != forumList.end(); ++forumIt) {
if (fi.mId1.empty()) {
/* store first forum */
fi.mId1 = forumIt->forumId;
}
if (!forumIt->forumDesc.empty()) {
/* take forum with description */
fi.mId1 = forumIt->forumId;
break;
}
if (!instance->mTokenQueueForum) {
instance->mTokenQueueForum = new TokenQueue(rsGxsForums->getTokenService(), instance);
}
instance->addFeedItemForumNew(fi);
instance->addFeedItemForumUpdate(fi);
RsTokReqOptions opts;
opts.mReqType = GXS_REQUEST_TYPE_GROUP_DATA;
uint32_t token;
instance->mTokenQueueForum->requestGroupInfo(token, RS_TOKREQ_ANSTYPE_SUMMARY, opts, TOKEN_TYPE_GROUP);
RsFeedItem fiMsg;
bool bFound = false;
for (forumIt = forumList.begin(); forumIt != forumList.end(); ++forumIt) {
std::list<ThreadInfoSummary> forumMsgs;
rsForums->getForumThreadList(forumIt->forumId, forumMsgs);
std::list<ThreadInfoSummary>::iterator msgIt;
for (msgIt = forumMsgs.begin(); msgIt != forumMsgs.end(); ++msgIt) {
if (fiMsg.mId2.empty()) {
/* store first forum message */
fiMsg.mId1 = msgIt->forumId;
fiMsg.mId2 = msgIt->msgId;
}
if (!msgIt->msg.empty()) {
/* take channel message with description */
fiMsg.mId1 = msgIt->forumId;
fiMsg.mId2 = msgIt->msgId;
bFound = true;
break;
}
}
if (bFound) {
break;
}
}
instance->addFeedItemForumMsg(fiMsg);
break;
}
#if 0
case RS_FEED_TYPE_BLOG:
// not used
// instance->addFeedItemBlogNew(fi);
@ -464,6 +395,191 @@ void NewsFeed::testFeeds(uint notifyFlags)
instance->sendNewsFeedChanged();
}
void NewsFeed::loadChannelGroup(const uint32_t &token)
{
std::vector<RsGxsChannelGroup> groups;
if (!rsGxsChannels->getGroupData(token, groups)) {
std::cerr << "NewsFeed::loadChannelGroup() ERROR getting data";
std::cerr << std::endl;
return;
}
RsFeedItem fi;
std::vector<RsGxsChannelGroup>::iterator channelIt;
for (channelIt = groups.begin(); channelIt != groups.end(); ++channelIt) {
if (fi.mId1.empty()) {
/* store first channel */
fi.mId1 = channelIt->mMeta.mGroupId.toStdString();
}
if (!channelIt->mDescription.empty()) {
/* take channel with description */
fi.mId1 = channelIt->mMeta.mGroupId.toStdString();
break;
}
}
if (fi.mId1.empty()) {
return;
}
instance->addFeedItemChannelNew(fi);
// instance->addFeedItemChanUpdate(fi);
/* Prepare group ids for message request */
std::list<RsGxsGroupId> grpIds;
for (channelIt = groups.begin(); channelIt != groups.end(); ++channelIt) {
grpIds.push_back(channelIt->mMeta.mGroupId);
}
RsTokReqOptions opts;
opts.mReqType = GXS_REQUEST_TYPE_MSG_DATA;
opts.mOptions = RS_TOKREQOPT_MSG_THREAD;
uint32_t msgToken;
instance->mTokenQueueChannel->requestMsgInfo(msgToken, RS_TOKREQ_ANSTYPE_SUMMARY, opts, grpIds, TOKEN_TYPE_MESSAGE);
}
void NewsFeed::loadChannelPost(const uint32_t &token)
{
std::vector<RsGxsChannelPost> posts;
if (!rsGxsChannels->getPostData(token, posts)) {
std::cerr << "NewsFeed::loadChannelPost() ERROR getting data";
std::cerr << std::endl;
return;
}
RsFeedItem fi;
std::vector<RsGxsChannelPost>::iterator postIt;
for (postIt = posts.begin(); postIt != posts.end(); ++postIt) {
if (fi.mId2.empty()) {
/* store first channel message */
fi.mId1 = postIt->mMeta.mGroupId.toStdString();
fi.mId2 = postIt->mMeta.mMsgId.toStdString();
}
if (!postIt->mMsg.empty()) {
/* take channel message with description */
fi.mId1 = postIt->mMeta.mGroupId.toStdString();
fi.mId2 = postIt->mMeta.mMsgId.toStdString();
break;
}
}
if (!fi.mId1.empty()) {
instance->addFeedItemChannelMsg(fi);
}
}
void NewsFeed::loadForumGroup(const uint32_t &token)
{
std::vector<RsGxsForumGroup> forums;
if (!rsGxsForums->getGroupData(token, forums)) {
std::cerr << "NewsFeed::loadForumGroup() ERROR getting data";
std::cerr << std::endl;
return;
}
RsFeedItem fi;
std::vector<RsGxsForumGroup>::iterator forumIt;
for (forumIt = forums.begin(); forumIt != forums.end(); ++forumIt) {
if (fi.mId1.empty()) {
/* store first forum */
fi.mId1 = forumIt->mMeta.mGroupId.toStdString();
}
if (!forumIt->mDescription.empty()) {
/* take forum with description */
fi.mId1 = forumIt->mMeta.mGroupId.toStdString();
break;
}
}
if (fi.mId1.empty()) {
return;
}
instance->addFeedItemForumNew(fi);
// instance->addFeedItemForumUpdate(fi);
/* Prepare group ids for message request */
std::list<RsGxsGroupId> grpIds;
for (forumIt = forums.begin(); forumIt != forums.end(); ++forumIt) {
grpIds.push_back(forumIt->mMeta.mGroupId);
}
RsTokReqOptions opts;
opts.mReqType = GXS_REQUEST_TYPE_MSG_DATA;
opts.mOptions = RS_TOKREQOPT_MSG_THREAD;
uint32_t msgToken;
instance->mTokenQueueForum->requestMsgInfo(msgToken, RS_TOKREQ_ANSTYPE_SUMMARY, opts, grpIds, TOKEN_TYPE_MESSAGE);
}
void NewsFeed::loadForumMessage(const uint32_t &token)
{
std::vector<RsGxsForumMsg> msgs;
if (!rsGxsForums->getMsgData(token, msgs)) {
std::cerr << "NewsFeed::loadChannelPost() ERROR getting data";
std::cerr << std::endl;
return;
}
RsFeedItem fi;
std::vector<RsGxsForumMsg>::iterator msgIt;
for (msgIt = msgs.begin(); msgIt != msgs.end(); ++msgIt) {
if (fi.mId2.empty()) {
/* store first forum message */
fi.mId1 = msgIt->mMeta.mGroupId.toStdString();
fi.mId2 = msgIt->mMeta.mMsgId.toStdString();
}
if (!msgIt->mMsg.empty()) {
/* take forum message with description */
fi.mId1 = msgIt->mMeta.mGroupId.toStdString();
fi.mId2 = msgIt->mMeta.mMsgId.toStdString();
break;
}
}
if (!fi.mId1.empty()) {
instance->addFeedItemForumMsg(fi);
}
}
void NewsFeed::loadRequest(const TokenQueue *queue, const TokenRequest &req)
{
if (queue == mTokenQueueChannel) {
switch (req.mUserType) {
case TOKEN_TYPE_GROUP:
loadChannelGroup(req.mToken);
break;
case TOKEN_TYPE_MESSAGE:
loadChannelPost(req.mToken);
break;
default:
std::cerr << "NewsFeed::loadRequest() ERROR: INVALID TYPE";
std::cerr << std::endl;
break;
}
}
if (queue == mTokenQueueForum) {
switch (req.mUserType) {
case TOKEN_TYPE_GROUP:
loadForumGroup(req.mToken);
break;
case TOKEN_TYPE_MESSAGE:
loadForumMessage(req.mToken);
break;
default:
std::cerr << "NewsFeed::loadRequest() ERROR: INVALID TYPE";
std::cerr << std::endl;
break;
}
}
}
void NewsFeed::testFeed(FeedNotify *feedNotify)
{
if (!instance) {
@ -484,7 +600,7 @@ void NewsFeed::testFeed(FeedNotify *feedNotify)
void NewsFeed::addFeedItem(FeedItem *item)
{
static const unsigned int MAX_FEEDITEM_COUNT = 500 ;
static const int MAX_FEEDITEM_COUNT = 500 ;
item->setAttribute(Qt::WA_DeleteOnClose, true);
@ -662,11 +778,17 @@ void NewsFeed::addFeedItemSecurityUnknownOut(const RsFeedItem &fi)
void NewsFeed::addFeedItemChannelNew(const RsFeedItem &fi)
{
RsGxsGroupId grpId(fi.mId1);
if (grpId.isNull()) {
return;
}
/* make new widget */
// ChanNewItem *cni = new ChanNewItem(this, NEWSFEED_CHANNEWLIST, fi.mId1, false, true);
GxsChannelGroupItem *item = new GxsChannelGroupItem(this, NEWSFEED_CHANNELNEWLIST, grpId, false, true);
/* add to layout */
// addFeedItem(cni);
addFeedItem(item);
#ifdef NEWS_DEBUG
std::cerr << "NewsFeed::addFeedItemChanNew()";

View File

@ -25,6 +25,7 @@
#include "mainpage.h"
#include "gui/feeds/FeedHolder.h"
#include "util/TokenQueue.h"
#include <retroshare-gui/RsAutoUpdatePage.h>
#define IMAGE_NEWSFEED ":/images/newsfeed/news-feed-32.png"
@ -37,7 +38,7 @@ class RsFeedItem;
class FeedNotify;
class FeedItem;
class NewsFeed : public RsAutoUpdatePage, public FeedHolder
class NewsFeed : public RsAutoUpdatePage, public FeedHolder, public TokenResponse
{
Q_OBJECT
@ -67,6 +68,10 @@ public:
signals:
void newsFeedChanged(int count);
protected:
/* TokenResponse */
virtual void loadRequest(const TokenQueue *queue, const TokenRequest &req);
private slots:
// void toggleChanMsgItems(bool on);
void feedoptions();
@ -103,7 +108,16 @@ private:
void addFeedItemMessage(const RsFeedItem &fi);
void addFeedItemFilesNew(const RsFeedItem &fi);
virtual void loadChannelGroup(const uint32_t &token);
virtual void loadChannelPost(const uint32_t &token);
virtual void loadForumGroup(const uint32_t &token);
virtual void loadForumMessage(const uint32_t &token);
private:
TokenQueue *mTokenQueueChannel;
TokenQueue *mTokenQueueForum;
/* UI - from Designer */
Ui::NewsFeed *ui;
};

View File

@ -38,18 +38,35 @@
/** Constructor */
PostedItem::PostedItem(FeedHolder *feedHolder, uint32_t feedId, const RsGxsGroupId &groupId, const RsGxsMessageId &messageId, bool isHome) :
GxsFeedItem(feedHolder, feedId, groupId, messageId, isHome, rsPosted, true, false)
GxsFeedItem(feedHolder, feedId, groupId, messageId, isHome, rsPosted, false)
{
setup();
requestGroup();
requestMessage();
}
PostedItem::PostedItem(FeedHolder *feedHolder, uint32_t feedId, const RsPostedGroup &group, const RsPostedPost &post, bool isHome) :
GxsFeedItem(feedHolder, feedId, post.mMeta.mGroupId, post.mMeta.mMsgId, isHome, rsPosted, false)
{
setup();
setGroup(group, false);
setPost(post);
}
PostedItem::PostedItem(FeedHolder *feedHolder, uint32_t feedId, const RsPostedPost &post, bool isHome) :
GxsFeedItem(feedHolder, feedId, post.mMeta.mGroupId, post.mMeta.mMsgId, isHome, rsPosted, false, false),
mPost(post)
GxsFeedItem(feedHolder, feedId, post.mMeta.mGroupId, post.mMeta.mMsgId, isHome, rsPosted, false)
{
setup();
setContent(mPost);
requestGroup();
setPost(post);
}
PostedItem::~PostedItem()
{
delete(ui);
}
void PostedItem::setup()
@ -58,10 +75,16 @@ void PostedItem::setup()
ui = new Ui::PostedItem;
ui->setupUi(this);
mInSetContent = false;
setAttribute(Qt::WA_DeleteOnClose, true);
mInFill = false;
/* clear ui */
ui->titleLabel->setText(tr("Loading"));
ui->dateLabel->clear();
ui->fromLabel->clear();
ui->siteLabel->clear();
connect(ui->commentButton, SIGNAL( clicked()), this, SLOT(loadComments()));
connect(ui->voteUpButton, SIGNAL(clicked()), this, SLOT(makeUpVote()));
connect(ui->voteDownButton, SIGNAL(clicked()), this, SLOT( makeDownVote()));
@ -69,6 +92,60 @@ void PostedItem::setup()
connect(ui->readButton, SIGNAL(toggled(bool)), this, SLOT(readToggled(bool)));
}
bool PostedItem::setGroup(const RsPostedGroup &group, bool doFill)
{
if (groupId() != group.mMeta.mGroupId) {
std::cerr << "PostedItem::setGroup() - Wrong id, cannot set post";
std::cerr << std::endl;
return false;
}
mGroup = group;
if (doFill) {
fill();
}
return true;
}
bool PostedItem::setPost(const RsPostedPost &post, bool doFill)
{
if (groupId() != post.mMeta.mGroupId || messageId() != post.mMeta.mMsgId) {
std::cerr << "PostedItem::setPost() - Wrong id, cannot set post";
std::cerr << std::endl;
return false;
}
mPost = post;
if (doFill) {
fill();
}
return true;
}
void PostedItem::loadGroup(const uint32_t &token)
{
std::vector<RsPostedGroup> groups;
if (!rsPosted->getGroupData(token, groups))
{
std::cerr << "PostedItem::loadGroup() ERROR getting data";
std::cerr << std::endl;
return;
}
if (groups.size() != 1)
{
std::cerr << "PostedItem::loadGroup() Wrong number of Items";
std::cerr << std::endl;
return;
}
setGroup(groups[0]);
}
void PostedItem::loadMessage(const uint32_t &token)
{
std::vector<RsPostedPost> posts;
@ -86,48 +163,40 @@ void PostedItem::loadMessage(const uint32_t &token)
return;
}
mPost = posts[0];
setContent(mPost);
setPost(posts[0]);
}
void PostedItem::setContent(const QVariant &content)
void PostedItem::fill()
{
if (!content.canConvert<RsPostedPost>()) {
if (isLoading()) {
/* Wait for all requests */
return;
}
RsPostedPost post = content.value<RsPostedPost>();
setContent(post);
}
void PostedItem::setContent(const RsPostedPost &post)
{
mInSetContent = true;
mPost = post;
mInFill = true;
QDateTime qtime;
qtime.setTime_t(mPost.mMeta.mPublishTs);
QString timestamp = qtime.toString("dd.MMMM yyyy hh:mm");
ui->dateLabel->setText(timestamp);
ui->fromLabel->setId(post.mMeta.mAuthorId);
ui->titleLabel->setText("<a href=" + QString::fromStdString(post.mLink) +
ui->fromLabel->setId(mPost.mMeta.mAuthorId);
ui->titleLabel->setText("<a href=" + QString::fromStdString(mPost.mLink) +
"><span style=\" text-decoration: underline; color:#2255AA;\">" +
QString::fromStdString(post.mMeta.mMsgName) + "</span></a>");
ui->siteLabel->setText("<a href=" + QString::fromStdString(post.mLink) +
messageName() + "</span></a>");
ui->siteLabel->setText("<a href=" + QString::fromStdString(mPost.mLink) +
"><span style=\" text-decoration: underline; color:#2255AA;\">" +
QString::fromStdString(post.mLink) + "</span></a>");
QString::fromStdString(mPost.mLink) + "</span></a>");
//QString score = "Hot" + QString::number(post.mHotScore);
//score += " Top" + QString::number(post.mTopScore);
//score += " New" + QString::number(post.mNewScore);
QString score = QString::number(post.mTopScore);
QString score = QString::number(mPost.mTopScore);
ui->scoreLabel->setText(score);
// FIX THIS UP LATER.
ui->notes->setText(QString::fromUtf8(post.mNotes.c_str()));
ui->notes->setText(QString::fromUtf8(mPost.mNotes.c_str()));
// differences between Feed or Top of Comment.
if (mFeedHolder)
{
@ -136,9 +205,9 @@ void PostedItem::setContent(const RsPostedPost &post)
//frame_comment->show();
ui->commentButton->show();
if (post.mComments)
if (mPost.mComments)
{
QString commentText = QString::number(post.mComments);
QString commentText = QString::number(mPost.mComments);
commentText += " ";
commentText += tr("Comments");
ui->commentButton->setText(commentText);
@ -148,7 +217,7 @@ void PostedItem::setContent(const RsPostedPost &post)
ui->commentButton->setText(tr("Comment"));
}
setReadStatus(IS_MSG_NEW(post.mMeta.mMsgStatus), IS_MSG_UNREAD(post.mMeta.mMsgStatus) || IS_MSG_NEW(post.mMeta.mMsgStatus));
setReadStatus(IS_MSG_NEW(mPost.mMeta.mMsgStatus), IS_MSG_UNREAD(mPost.mMeta.mMsgStatus) || IS_MSG_NEW(mPost.mMeta.mMsgStatus));
}
else
{
@ -169,7 +238,7 @@ void PostedItem::setContent(const RsPostedPost &post)
}
// disable voting buttons - if they have already voted.
if (post.mMeta.mMsgStatus & GXS_SERV::GXS_MSG_STATUS_VOTE_MASK)
if (mPost.mMeta.mMsgStatus & GXS_SERV::GXS_MSG_STATUS_VOTE_MASK)
{
ui->voteUpButton->setEnabled(false);
ui->voteDownButton->setEnabled(false);
@ -193,7 +262,7 @@ void PostedItem::setContent(const RsPostedPost &post)
}
#endif
mInSetContent = false;
mInFill = false;
}
const RsPostedPost &PostedItem::getPost() const
@ -206,6 +275,11 @@ RsPostedPost &PostedItem::post()
return mPost;
}
QString PostedItem::groupName()
{
return QString::fromUtf8(mGroup.mMeta.mGroupName.c_str());
}
QString PostedItem::messageName()
{
return QString::fromUtf8(mPost.mMeta.mMsgName.c_str());
@ -276,7 +350,7 @@ void PostedItem::setReadStatus(bool isNew, bool isUnread)
void PostedItem::readToggled(bool checked)
{
if (mInSetContent) {
if (mInFill) {
return;
}

View File

@ -41,12 +41,15 @@ class PostedItem : public GxsFeedItem
public:
PostedItem(FeedHolder *parent, uint32_t feedId, const RsGxsGroupId &groupId, const RsGxsMessageId &messageId, bool isHome);
PostedItem(FeedHolder *parent, uint32_t feedId, const RsPostedGroup &group, const RsPostedPost &post, bool isHome);
PostedItem(FeedHolder *parent, uint32_t feedId, const RsPostedPost &post, bool isHome);
virtual ~PostedItem();
bool setGroup(const RsPostedGroup& group, bool doFill = true);
bool setPost(const RsPostedPost& post, bool doFill = true);
const RsPostedPost &getPost() const;
RsPostedPost &post();
void setContent(const RsPostedPost& post);
virtual void setContent(const QVariant &content);
/* FeedItem */
virtual void expand(bool /*open*/) {}
@ -61,18 +64,24 @@ signals:
void vote(const RsGxsGrpMsgIdPair& msgId, bool up);
protected:
virtual void loadMessage(const uint32_t &token);
/* GxsGroupFeedItem */
virtual QString groupName();
virtual void loadGroup(const uint32_t &token);
virtual RetroShareLink::enumType getLinkType() { return RetroShareLink::TYPE_UNKNOWN; }
/* GxsFeedItem */
virtual void loadMessage(const uint32_t &token);
virtual QString messageName();
private:
void setup();
void fill();
void setReadStatus(bool isNew, bool isUnread);
bool mInSetContent;
private:
bool mInFill;
uint32_t mType;
bool mSelected;
RsPostedGroup mGroup;
RsPostedPost mPost;
/** Qt Designer generated object */

View File

@ -330,7 +330,11 @@ void PostedListWidget::insertPostedDetails(const RsPostedGroup &group)
void PostedListWidget::loadPost(const RsPostedPost &post)
{
PostedItem *item = new PostedItem(this, 0, post, true);
/* Group is not always available because of the TokenQueue */
RsPostedGroup dummyGroup;
dummyGroup.mMeta.mGroupId = groupId();
PostedItem *item = new PostedItem(this, 0, dummyGroup, post, true);
connect(item, SIGNAL(vote(RsGxsGrpMsgIdPair,bool)), this, SLOT(submitVote(RsGxsGrpMsgIdPair,bool)));
mPosts.insert(post.mMeta.mMsgId, item);
//QLayout *alayout = ui.scrollAreaWidgetContents->layout();
@ -573,7 +577,7 @@ void PostedListWidget::insertRelatedPosts(const uint32_t &token)
std::cerr << "PostedListWidget::updateCurrentDisplayComplete() updating MsgId: " << p.mMeta.mMsgId;
std::cerr << std::endl;
mPosts[p.mMeta.mMsgId]->setContent(p);
mPosts[p.mMeta.mMsgId]->setPost(p);
}
else
{

View File

@ -0,0 +1,205 @@
/****************************************************************
* RetroShare is distributed under the following license:
*
* Copyright (C) 2008 Robert Fernie
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* 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 General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor,
* Boston, MA 02110-1301, USA.
****************************************************************/
#include "GxsChannelGroupItem.h"
#include "ui_GxsChannelGroupItem.h"
#include "FeedHolder.h"
#include "gui/RetroShareLink.h"
/****
* #define DEBUG_ITEM 1
****/
GxsChannelGroupItem::GxsChannelGroupItem(FeedHolder *feedHolder, uint32_t feedId, const RsGxsGroupId &groupId, bool isHome, bool autoUpdate) :
GxsGroupFeedItem(feedHolder, feedId, groupId, isHome, rsGxsChannels, autoUpdate)
{
setup();
requestGroup();
}
GxsChannelGroupItem::GxsChannelGroupItem(FeedHolder *feedHolder, uint32_t feedId, const RsGxsChannelGroup &group, bool isHome, bool autoUpdate) :
GxsGroupFeedItem(feedHolder, feedId, group.mMeta.mGroupId, isHome, rsGxsChannels, autoUpdate)
{
setup();
setGroup(group);
}
GxsChannelGroupItem::~GxsChannelGroupItem()
{
delete(ui);
}
void GxsChannelGroupItem::setup()
{
/* Invoke the Qt Designer generated object setup routine */
ui = new(Ui::GxsChannelGroupItem);
ui->setupUi(this);
setAttribute(Qt::WA_DeleteOnClose, true);
/* clear ui */
ui->nameLabel->setText(tr("Loading"));
ui->titleLabel->clear();
ui->descLabel->clear();
/* general ones */
connect(ui->expandButton, SIGNAL(clicked()), this, SLOT(toggle()));
connect(ui->clearButton, SIGNAL(clicked()), this, SLOT(removeItem()));
/* specific */
connect(ui->subscribeButton, SIGNAL(clicked()), this, SLOT(subscribeChannel()));
connect(ui->copyLinkButton, SIGNAL(clicked()), this, SLOT(copyGroupLink()));
ui->expandFrame->hide();
}
bool GxsChannelGroupItem::setGroup(const RsGxsChannelGroup &group)
{
if (groupId() != group.mMeta.mGroupId) {
std::cerr << "GxsChannelGroupItem::setContent() - Wrong id, cannot set post";
std::cerr << std::endl;
return false;
}
mGroup = group;
fill();
return true;
}
void GxsChannelGroupItem::loadGroup(const uint32_t &token)
{
#ifdef DEBUG_ITEM
std::cerr << "GxsChannelGroupItem::loadGroup()";
std::cerr << std::endl;
#endif
std::vector<RsGxsChannelGroup> groups;
if (!rsGxsChannels->getGroupData(token, groups))
{
std::cerr << "GxsChannelGroupItem::loadGroup() ERROR getting data";
std::cerr << std::endl;
return;
}
if (groups.size() != 1)
{
std::cerr << "GxsChannelGroupItem::loadGroup() Wrong number of Items";
std::cerr << std::endl;
return;
}
setGroup(groups[0]);
}
QString GxsChannelGroupItem::groupName()
{
return QString::fromUtf8(mGroup.mMeta.mGroupName.c_str());
}
void GxsChannelGroupItem::fill()
{
/* fill in */
#ifdef DEBUG_ITEM
std::cerr << "GxsChannelGroupItem::fill()";
std::cerr << std::endl;
#endif
RetroShareLink link;
link.createGxsGroupLink(RetroShareLink::TYPE_CHANNEL, mGroup.mMeta.mGroupId, groupName());
ui->nameLabel->setText(link.toHtml());
ui->descLabel->setText(QString::fromUtf8(mGroup.mDescription.c_str()));
if (mGroup.mImage.mData != NULL) {
QPixmap chanImage;
chanImage.loadFromData(mGroup.mImage.mData, mGroup.mImage.mSize, "PNG");
ui->logoLabel->setPixmap(QPixmap(chanImage));
}
if (IS_GROUP_SUBSCRIBED(mGroup.mMeta.mSubscribeFlags)) {
ui->subscribeButton->setEnabled(false);
} else {
ui->subscribeButton->setEnabled(true);
}
// if (mIsNew)
// {
ui->titleLabel->setText(tr("New Channel"));
// }
// else
// {
// ui->titleLabel->setText(tr("Updated Channel"));
// }
if (mIsHome)
{
/* disable buttons */
ui->clearButton->setEnabled(false);
}
}
void GxsChannelGroupItem::toggle()
{
expand(ui->expandFrame->isHidden());
}
void GxsChannelGroupItem::expand(bool open)
{
if (mFeedHolder)
{
mFeedHolder->lockLayout(this, true);
}
if (open)
{
ui->expandFrame->show();
ui->expandButton->setIcon(QIcon(QString(":/images/edit_remove24.png")));
ui->expandButton->setToolTip(tr("Hide"));
}
else
{
ui->expandFrame->hide();
ui->expandButton->setIcon(QIcon(QString(":/images/edit_add24.png")));
ui->expandButton->setToolTip(tr("Expand"));
}
emit sizeChanged(this);
if (mFeedHolder)
{
mFeedHolder->lockLayout(this, false);
}
}
void GxsChannelGroupItem::subscribeChannel()
{
#ifdef DEBUG_ITEM
std::cerr << "GxsChannelGroupItem::subscribeChannel()";
std::cerr << std::endl;
#endif
subscribe();
}

View File

@ -0,0 +1,77 @@
/****************************************************************
* RetroShare is distributed under the following license:
*
* Copyright (C) 2008 Robert Fernie
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* 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 General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor,
* Boston, MA 02110-1301, USA.
****************************************************************/
#ifndef _GXSCHANNELGROUPITEM_H
#define _GXSCHANNELGROUPITEM_H
#include <QMetaType>
#include <retroshare/rsgxschannels.h>
#include "gui/gxs/GxsGroupFeedItem.h"
#include <stdint.h>
namespace Ui {
class GxsChannelGroupItem;
}
class FeedHolder;
class GxsChannelGroupItem : public GxsGroupFeedItem
{
Q_OBJECT
public:
/** Default Constructor */
GxsChannelGroupItem(FeedHolder *feedHolder, uint32_t feedId, const RsGxsGroupId &groupId, bool isHome, bool autoUpdate);
GxsChannelGroupItem(FeedHolder *feedHolder, uint32_t feedId, const RsGxsChannelGroup &group, bool isHome, bool autoUpdate);
~GxsChannelGroupItem();
bool setGroup(const RsGxsChannelGroup &group);
/* FeedItem */
virtual void expand(bool open);
protected:
/* GxsGroupFeedItem */
virtual QString groupName();
virtual void loadGroup(const uint32_t &token);
virtual RetroShareLink::enumType getLinkType() { return RetroShareLink::TYPE_CHANNEL; }
private slots:
/* default stuff */
void toggle();
void subscribeChannel();
private:
void fill();
void setup();
private:
RsGxsChannelGroup mGroup;
/** Qt Designer generated object */
Ui::GxsChannelGroupItem *ui;
};
Q_DECLARE_METATYPE(RsGxsChannelGroup)
#endif

View File

@ -0,0 +1,325 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>GxsChannelGroupItem</class>
<widget class="QWidget" name="GxsChannelGroupItem">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>643</width>
<height>157</height>
</rect>
</property>
<layout class="QGridLayout">
<property name="leftMargin">
<number>0</number>
</property>
<property name="topMargin">
<number>0</number>
</property>
<property name="rightMargin">
<number>0</number>
</property>
<property name="bottomMargin">
<number>0</number>
</property>
<item row="0" column="0">
<widget class="QFrame" name="frame">
<property name="sizePolicy">
<sizepolicy hsizetype="Expanding" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="palette">
<palette>
<active>
<colorrole role="Window">
<brush brushstyle="SolidPattern">
<color alpha="255">
<red>248</red>
<green>248</green>
<blue>248</blue>
</color>
</brush>
</colorrole>
</active>
<inactive>
<colorrole role="Window">
<brush brushstyle="SolidPattern">
<color alpha="255">
<red>248</red>
<green>248</green>
<blue>248</blue>
</color>
</brush>
</colorrole>
</inactive>
<disabled>
<colorrole role="Window">
<brush brushstyle="SolidPattern">
<color alpha="255">
<red>248</red>
<green>248</green>
<blue>248</blue>
</color>
</brush>
</colorrole>
</disabled>
</palette>
</property>
<property name="autoFillBackground">
<bool>true</bool>
</property>
<property name="frameShape">
<enum>QFrame::Box</enum>
</property>
<property name="frameShadow">
<enum>QFrame::Sunken</enum>
</property>
<layout class="QGridLayout">
<item row="0" column="0" rowspan="2">
<layout class="QGridLayout">
<item row="0" column="0" rowspan="2">
<widget class="QLabel" name="logoLabel">
<property name="minimumSize">
<size>
<width>70</width>
<height>70</height>
</size>
</property>
<property name="maximumSize">
<size>
<width>70</width>
<height>70</height>
</size>
</property>
<property name="pixmap">
<pixmap resource="../images.qrc">:/images/channels.png</pixmap>
</property>
<property name="scaledContents">
<bool>false</bool>
</property>
</widget>
</item>
<item row="0" column="1">
<widget class="QLabel" name="nameLabel">
<property name="text">
<string notr="true">name</string>
</property>
<property name="alignment">
<set>Qt::AlignLeading|Qt::AlignLeft|Qt::AlignTop</set>
</property>
<property name="openExternalLinks">
<bool>true</bool>
</property>
</widget>
</item>
<item row="1" column="1">
<widget class="QLabel" name="titleLabel">
<property name="sizePolicy">
<sizepolicy hsizetype="Minimum" vsizetype="Minimum">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="font">
<font>
<weight>75</weight>
<italic>true</italic>
<bold>true</bold>
</font>
</property>
<property name="text">
<string notr="true">New Channel</string>
</property>
</widget>
</item>
</layout>
</item>
<item row="0" column="1">
<layout class="QHBoxLayout" name="horizontalLayout">
<item>
<spacer>
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeType">
<enum>QSizePolicy::Expanding</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>338</width>
<height>28</height>
</size>
</property>
</spacer>
</item>
<item>
<widget class="QPushButton" name="copyLinkButton">
<property name="maximumSize">
<size>
<width>24</width>
<height>16777215</height>
</size>
</property>
<property name="focusPolicy">
<enum>Qt::NoFocus</enum>
</property>
<property name="toolTip">
<string>Copy RetroShare Link</string>
</property>
<property name="icon">
<iconset resource="../images.qrc">
<normaloff>:/images/copyrslink.png</normaloff>:/images/copyrslink.png</iconset>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="subscribeButton">
<property name="sizePolicy">
<sizepolicy hsizetype="Fixed" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="focusPolicy">
<enum>Qt::NoFocus</enum>
</property>
<property name="toolTip">
<string>Subscribe to Channel</string>
</property>
<property name="icon">
<iconset resource="../images.qrc">
<normaloff>:/images/directoryadd_24x24_shadow.png</normaloff>:/images/directoryadd_24x24_shadow.png</iconset>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="expandButton">
<property name="sizePolicy">
<sizepolicy hsizetype="Fixed" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="focusPolicy">
<enum>Qt::NoFocus</enum>
</property>
<property name="toolTip">
<string>Expand</string>
</property>
<property name="icon">
<iconset resource="../images.qrc">
<normaloff>:/images/edit_add24.png</normaloff>:/images/edit_add24.png</iconset>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="clearButton">
<property name="sizePolicy">
<sizepolicy hsizetype="Fixed" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="focusPolicy">
<enum>Qt::NoFocus</enum>
</property>
<property name="toolTip">
<string>Remove Item</string>
</property>
<property name="icon">
<iconset resource="../images.qrc">
<normaloff>:/images/close_normal.png</normaloff>:/images/close_normal.png</iconset>
</property>
</widget>
</item>
</layout>
</item>
<item row="1" column="1">
<spacer name="horizontalSpacer">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>455</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
<item row="2" column="0" colspan="2">
<widget class="QFrame" name="expandFrame">
<layout class="QVBoxLayout">
<property name="spacing">
<number>0</number>
</property>
<property name="leftMargin">
<number>0</number>
</property>
<property name="topMargin">
<number>0</number>
</property>
<property name="rightMargin">
<number>0</number>
</property>
<property name="bottomMargin">
<number>0</number>
</property>
<item>
<widget class="QGroupBox" name="groupBox">
<property name="title">
<string>Channel Description</string>
</property>
<layout class="QGridLayout">
<item row="0" column="0">
<widget class="QLabel" name="iconLabel">
<property name="text">
<string/>
</property>
<property name="pixmap">
<pixmap resource="../images.qrc">:/images/contacts24.png</pixmap>
</property>
</widget>
</item>
<item row="0" column="1">
<widget class="QLabel" name="descLabel">
<property name="sizePolicy">
<sizepolicy hsizetype="MinimumExpanding" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="text">
<string notr="true">Description
of Channel</string>
</property>
<property name="wordWrap">
<bool>true</bool>
</property>
<property name="openExternalLinks">
<bool>true</bool>
</property>
<property name="textInteractionFlags">
<set>Qt::LinksAccessibleByMouse|Qt::TextSelectableByKeyboard|Qt::TextSelectableByMouse</set>
</property>
</widget>
</item>
</layout>
</widget>
</item>
</layout>
</widget>
</item>
</layout>
</widget>
</item>
</layout>
</widget>
<resources>
<include location="../images.qrc"/>
</resources>
<connections/>
</ui>

View File

@ -30,7 +30,6 @@
#include "FeedHolder.h"
#include "SubFileItem.h"
//#include "gui/notifyqt.h"
#include "util/misc.h"
#include "gui/RetroShareLink.h"
#include "util/HandleRichText.h"
@ -45,54 +44,41 @@
#define COLOR_NORMAL QColor(248, 248, 248)
#define COLOR_NEW QColor(220, 236, 253)
#define SELF_LOAD 1
#define DATA_PROVIDED 2
GxsChannelPostItem::GxsChannelPostItem(FeedHolder *feedHolder, uint32_t feedId, const RsGxsGroupId &groupId, const RsGxsMessageId &messageId, bool isHome, bool autoUpdate) :
GxsFeedItem(feedHolder, feedId, groupId, messageId, isHome, rsGxsChannels, true, autoUpdate)
GxsFeedItem(feedHolder, feedId, groupId, messageId, isHome, rsGxsChannels, autoUpdate)
{
mMode = SELF_LOAD;
setup();
requestGroup();
requestMessage();
}
/** Constructor */
GxsChannelPostItem::GxsChannelPostItem(FeedHolder *feedHolder, uint32_t feedId, const RsGxsChannelPost &post, uint32_t subFlags, bool isHome, bool autoUpdate) :
GxsFeedItem(feedHolder, feedId, post.mMeta.mGroupId, post.mMeta.mMsgId, isHome, rsGxsChannels, false, autoUpdate)
GxsChannelPostItem::GxsChannelPostItem(FeedHolder *feedHolder, uint32_t feedId, const RsGxsChannelGroup &group, const RsGxsChannelPost &post, bool isHome, bool autoUpdate) :
GxsFeedItem(feedHolder, feedId, post.mMeta.mGroupId, post.mMeta.mMsgId, isHome, rsGxsChannels, autoUpdate)
{
#ifdef DEBUG_ITEM
std::cerr << "GxsChannelPostItem::GxsChannelPostItem() Direct Load";
std::cerr << std::endl;
mMode = DATA_PROVIDED;
mGroupMeta.mSubscribeFlags = subFlags;
#endif
setup();
// is it because we are in the constructor?
loadPost(post);
setGroup(group, false);
setPost(post);
}
void GxsChannelPostItem::setContent(const QVariant &content)
GxsChannelPostItem::GxsChannelPostItem(FeedHolder *feedHolder, uint32_t feedId, const RsGxsChannelPost &post, bool isHome, bool autoUpdate) :
GxsFeedItem(feedHolder, feedId, post.mMeta.mGroupId, post.mMeta.mMsgId, isHome, rsGxsChannels, autoUpdate)
{
if (!content.canConvert<RsGxsChannelPost>()) {
return;
}
#ifdef DEBUG_ITEM
std::cerr << "GxsChannelPostItem::GxsChannelPostItem() Direct Load";
std::cerr << std::endl;
#endif
RsGxsChannelPost post = content.value<RsGxsChannelPost>();
setContent(post);
}
setup();
bool GxsChannelPostItem::setContent(const RsGxsChannelPost &post)
{
if (groupId() != post.mMeta.mGroupId || messageId() != post.mMeta.mMsgId) {
std::cerr << "GxsChannelPostItem::setPost() - Wrong id, cannot set post";
std::cerr << std::endl;
return false;
}
loadPost(post);
return true;
requestGroup();
setPost(post);
}
GxsChannelPostItem::~GxsChannelPostItem()
@ -106,24 +92,30 @@ void GxsChannelPostItem::setup()
ui = new Ui::GxsChannelPostItem;
ui->setupUi(this);
setAttribute ( Qt::WA_DeleteOnClose, true );
setAttribute(Qt::WA_DeleteOnClose, true);
mInUpdateItemStatic = false;
mInFill = false;
/* clear ui */
ui->titleLabel->setText(tr("Loading"));
ui->subjectLabel->clear();
ui->datetimelabel->clear();
ui->filelabel->clear();
/* general ones */
connect(ui->expandButton, SIGNAL(clicked(void)), this, SLOT(toggle(void)));
connect(ui->clearButton, SIGNAL(clicked(void)), this, SLOT(removeItem(void)));
connect(ui->expandButton, SIGNAL(clicked()), this, SLOT(toggle()));
connect(ui->clearButton, SIGNAL(clicked()), this, SLOT(removeItem()));
/* specific */
connect(ui->readAndClearButton, SIGNAL(clicked()), this, SLOT(readAndClearItem()));
connect(ui->unsubscribeButton, SIGNAL(clicked(void)), this, SLOT(unsubscribeChannel(void)));
connect(ui->unsubscribeButton, SIGNAL(clicked()), this, SLOT(unsubscribeChannel()));
connect(ui->downloadButton, SIGNAL(clicked(void)), this, SLOT(download(void)));
connect(ui->downloadButton, SIGNAL(clicked()), this, SLOT(download()));
// HACK FOR NOW.
connect(ui->commentButton, SIGNAL(clicked(void)), this, SLOT(loadComments(void)));
connect(ui->commentButton, SIGNAL(clicked()), this, SLOT(loadComments()));
connect(ui->playButton, SIGNAL(clicked(void)), this, SLOT( play(void)));
connect(ui->copyLinkButton, SIGNAL(clicked(void)), this, SLOT(copyLink(void)));
connect(ui->playButton, SIGNAL(clicked()), this, SLOT(play(void)));
connect(ui->copyLinkButton, SIGNAL(clicked()), this, SLOT(copyMessageLink()));
connect(ui->readButton, SIGNAL(toggled(bool)), this, SLOT(readToggled(bool)));
//connect(NotifyQt::getInstance(), SIGNAL(channelMsgReadSatusChanged(QString,QString,int)), this, SLOT(channelMsgReadSatusChanged(QString,QString,int)), Qt::QueuedConnection);
@ -148,16 +140,84 @@ void GxsChannelPostItem::setup()
ui->expandFrame->hide();
}
bool GxsChannelPostItem::setGroup(const RsGxsChannelGroup &group, bool doFill)
{
if (groupId() != group.mMeta.mGroupId) {
std::cerr << "GxsChannelPostItem::setGroup() - Wrong id, cannot set post";
std::cerr << std::endl;
return false;
}
mGroup = group;
if (doFill) {
fill();
}
return true;
}
bool GxsChannelPostItem::setPost(const RsGxsChannelPost &post, bool doFill)
{
if (groupId() != post.mMeta.mGroupId || messageId() != post.mMeta.mMsgId) {
std::cerr << "GxsChannelPostItem::setPost() - Wrong id, cannot set post";
std::cerr << std::endl;
return false;
}
mPost = post;
if (doFill) {
fill();
}
updateItem();
return true;
}
QString GxsChannelPostItem::groupName()
{
return QString::fromUtf8(mGroup.mMeta.mGroupName.c_str());
}
void GxsChannelPostItem::loadComments()
{
QString title = QString::fromUtf8(mPost.mMeta.mMsgName.c_str());
comments(title);
}
void GxsChannelPostItem::loadGroup(const uint32_t &token)
{
#ifdef DEBUG_ITEM
std::cerr << "GxsChannelGroupItem::loadGroup()";
std::cerr << std::endl;
#endif
std::vector<RsGxsChannelGroup> groups;
if (!rsGxsChannels->getGroupData(token, groups))
{
std::cerr << "GxsChannelGroupItem::loadGroup() ERROR getting data";
std::cerr << std::endl;
return;
}
if (groups.size() != 1)
{
std::cerr << "GxsChannelGroupItem::loadGroup() Wrong number of Items";
std::cerr << std::endl;
return;
}
setGroup(groups[0]);
}
void GxsChannelPostItem::loadMessage(const uint32_t &token)
{
#ifdef DEBUG_ITEM
std::cerr << "GxsChannelPostItem::loadMessage()";
std::cerr << std::endl;
#endif
std::vector<RsGxsChannelPost> posts;
if (!rsGxsChannels->getPostData(token, posts))
@ -174,23 +234,24 @@ void GxsChannelPostItem::loadMessage(const uint32_t &token)
return;
}
loadPost(posts[0]);
updateItem();
setPost(posts[0]);
}
void GxsChannelPostItem::loadPost(const RsGxsChannelPost &post)
void GxsChannelPostItem::fill()
{
/* fill in */
if (isLoading()) {
/* Wait for all requests */
return;
}
#ifdef DEBUG_ITEM
std::cerr << "GxsChannelPostItem::loadPost()";
std::cerr << "GxsChannelPostItem::fill()";
std::cerr << std::endl;
#endif
mInUpdateItemStatic = true;
mPost = post;
mInFill = true;
QString title;
@ -198,14 +259,15 @@ void GxsChannelPostItem::loadPost(const RsGxsChannelPost &post)
{
title = tr("Channel Feed") + ": ";
RetroShareLink link;
link.createGxsGroupLink(RetroShareLink::TYPE_CHANNEL, post.mMeta.mGroupId, "");
link.createGxsGroupLink(RetroShareLink::TYPE_CHANNEL, mPost.mMeta.mGroupId, groupName());
title += link.toHtml();
ui->titleLabel->setText(title);
RetroShareLink msgLink;
msgLink.createGxsMessageLink(RetroShareLink::TYPE_CHANNEL, post.mMeta.mGroupId, post.mMeta.mMsgId, QString::fromUtf8(post.mMeta.mMsgName.c_str()));
msgLink.createGxsMessageLink(RetroShareLink::TYPE_CHANNEL, mPost.mMeta.mGroupId, mPost.mMeta.mMsgId, messageName());
ui->subjectLabel->setText(msgLink.toHtml());
if (IS_GROUP_SUBSCRIBED(mSubscribeFlags) || IS_GROUP_ADMIN(mSubscribeFlags))
if (IS_GROUP_SUBSCRIBED(mGroup.mMeta.mSubscribeFlags) || IS_GROUP_ADMIN(mGroup.mMeta.mSubscribeFlags))
{
ui->unsubscribeButton->setEnabled(true);
}
@ -220,8 +282,8 @@ void GxsChannelPostItem::loadPost(const RsGxsChannelPost &post)
else
{
/* subject */
ui->titleLabel->setText(QString::fromUtf8(post.mMeta.mMsgName.c_str()));
ui->subjectLabel->setText(RsHtml().formatText(NULL, QString::fromUtf8(post.mMsg.c_str()), RSHTML_FORMATTEXT_EMBED_SMILEYS | RSHTML_FORMATTEXT_EMBED_LINKS));
ui->titleLabel->setText(QString::fromUtf8(mPost.mMeta.mMsgName.c_str()));
ui->subjectLabel->setText(RsHtml().formatText(NULL, QString::fromUtf8(mPost.mMsg.c_str()), RSHTML_FORMATTEXT_EMBED_SMILEYS | RSHTML_FORMATTEXT_EMBED_LINKS));
//QString score = QString::number(post.mTopScore);
// scoreLabel->setText(score);
@ -234,11 +296,11 @@ void GxsChannelPostItem::loadPost(const RsGxsChannelPost &post)
ui->unsubscribeButton->hide();
ui->copyLinkButton->show();
if (IS_GROUP_SUBSCRIBED(mGroupMeta.mSubscribeFlags) || IS_GROUP_ADMIN(mGroupMeta.mSubscribeFlags))
if (IS_GROUP_SUBSCRIBED(mGroup.mMeta.mSubscribeFlags) || IS_GROUP_ADMIN(mGroup.mMeta.mSubscribeFlags))
{
ui->readButton->setVisible(true);
setReadStatus(IS_MSG_NEW(post.mMeta.mMsgStatus), IS_MSG_UNREAD(post.mMeta.mMsgStatus) || IS_MSG_NEW(post.mMeta.mMsgStatus));
setReadStatus(IS_MSG_NEW(mPost.mMeta.mMsgStatus), IS_MSG_UNREAD(mPost.mMeta.mMsgStatus) || IS_MSG_NEW(mPost.mMeta.mMsgStatus));
}
else
{
@ -250,7 +312,11 @@ void GxsChannelPostItem::loadPost(const RsGxsChannelPost &post)
// differences between Feed or Top of Comment.
if (mFeedHolder)
{
ui->commentButton->show();
if (mIsHome) {
ui->commentButton->show();
} else {
ui->commentButton->hide();
}
// THIS CODE IS doesn't compile - disabling until fixed.
#if 0
@ -280,12 +346,12 @@ void GxsChannelPostItem::loadPost(const RsGxsChannelPost &post)
voteDownButton->setEnabled(false);
}*/
ui->msgLabel->setText(RsHtml().formatText(NULL, QString::fromUtf8(post.mMsg.c_str()), RSHTML_FORMATTEXT_EMBED_SMILEYS | RSHTML_FORMATTEXT_EMBED_LINKS));
ui->msgFrame->setVisible(!post.mMsg.empty());
ui->msgLabel->setText(RsHtml().formatText(NULL, QString::fromUtf8(mPost.mMsg.c_str()), RSHTML_FORMATTEXT_EMBED_SMILEYS | RSHTML_FORMATTEXT_EMBED_LINKS));
ui->msgFrame->setVisible(!mPost.mMsg.empty());
ui->datetimelabel->setText(DateTime::formatLongDateTime(post.mMeta.mPublishTs));
ui->datetimelabel->setText(DateTime::formatLongDateTime(mPost.mMeta.mPublishTs));
ui->filelabel->setText(QString("(%1 %2) %3").arg(post.mCount).arg(tr("Files")).arg(misc::friendlyUnit(post.mSize)));
ui->filelabel->setText(QString("(%1 %2) %3").arg(mPost.mCount).arg(tr("Files")).arg(misc::friendlyUnit(mPost.mSize)));
if (mFileItems.empty() == false) {
std::list<SubFileItem *>::iterator it;
@ -297,7 +363,7 @@ void GxsChannelPostItem::loadPost(const RsGxsChannelPost &post)
}
std::list<RsGxsFile>::const_iterator it;
for(it = post.mFiles.begin(); it != post.mFiles.end(); ++it)
for(it = mPost.mFiles.begin(); it != mPost.mFiles.end(); ++it)
{
/* add file */
std::string path;
@ -312,15 +378,15 @@ void GxsChannelPostItem::loadPost(const RsGxsChannelPost &post)
layout->addWidget(fi);
}
if(post.mThumbnail.mData != NULL)
if(mPost.mThumbnail.mData != NULL)
{
QPixmap thumbnail;
thumbnail.loadFromData(post.mThumbnail.mData, post.mThumbnail.mSize, "PNG");
thumbnail.loadFromData(mPost.mThumbnail.mData, mPost.mThumbnail.mSize, "PNG");
// Wiping data - as its been passed to thumbnail.
ui->logoLabel->setPixmap(thumbnail);
}
mInUpdateItemStatic = false;
mInFill = false;
}
QString GxsChannelPostItem::messageName()
@ -379,6 +445,7 @@ void GxsChannelPostItem::updateItem()
std::cerr << "GxsChannelPostItem::updateItem()";
std::cerr << std::endl;
#endif
int msec_rate = 10000;
int downloadCount = 0;
@ -503,7 +570,6 @@ void GxsChannelPostItem::unsubscribeChannel()
#endif
unsubscribe();
updateItemStatic();
}
void GxsChannelPostItem::download()
@ -531,7 +597,7 @@ void GxsChannelPostItem::play()
void GxsChannelPostItem::readToggled(bool checked)
{
if (mInUpdateItemStatic) {
if (mInFill) {
return;
}

View File

@ -43,13 +43,13 @@ class GxsChannelPostItem : public GxsFeedItem
Q_OBJECT
public:
/** Default Constructor */
GxsChannelPostItem(FeedHolder *feedHolder, uint32_t feedId, const RsGxsGroupId &groupId, const RsGxsMessageId &messageId, bool isHome, bool autoUpdate);
GxsChannelPostItem(FeedHolder *feedHolder, uint32_t feedId, const RsGxsChannelPost &post, uint32_t subscribeFlags, bool isHome, bool autoUpdate);
GxsChannelPostItem(FeedHolder *feedHolder, uint32_t feedId, const RsGxsChannelGroup &group, const RsGxsChannelPost &post, bool isHome, bool autoUpdate);
GxsChannelPostItem(FeedHolder *feedHolder, uint32_t feedId, const RsGxsChannelPost &post, bool isHome, bool autoUpdate);
virtual ~GxsChannelPostItem();
virtual void setContent(const QVariant &content);
bool setContent(const RsGxsChannelPost &post);
bool setGroup(const RsGxsChannelGroup &group, bool doFill = true);
bool setPost(const RsGxsChannelPost &post, bool doFill = true);
void setFileCleanUpWarning(uint32_t time_left);
@ -61,8 +61,13 @@ public:
virtual void expand(bool open);
protected:
virtual void loadMessage(const uint32_t &token);
/* GxsGroupFeedItem */
virtual QString groupName();
virtual void loadGroup(const uint32_t &token);
virtual RetroShareLink::enumType getLinkType() { return RetroShareLink::TYPE_CHANNEL; }
/* GxsFeedItem */
virtual void loadMessage(const uint32_t &token);
virtual QString messageName();
private slots:
@ -87,14 +92,13 @@ signals:
private:
void setup();
void loadPost(const RsGxsChannelPost &post);
void fill();
void setReadStatus(bool isNew, bool isUnread);
bool mInUpdateItemStatic;
private:
bool mInFill;
uint32_t mMode;
uint32_t mSubscribeFlags;
RsGxsChannelGroup mGroup;
RsGxsChannelPost mPost;
std::list<SubFileItem*> mFileItems;

View File

@ -26,34 +26,32 @@
#include "gui/gxs/RsGxsUpdateBroadcastBase.h"
#include <iostream>
#include <algorithm>
//#include <algorithm>
/**
* #define DEBUG_ITEM 1
**/
#define GXSFEEDITEM_GROUPMETA 5
#define GXSFEEDITEM_MESSAGE 6
void GxsFeedItem::removeItem()
GxsFeedItem::GxsFeedItem(FeedHolder *feedHolder, uint32_t feedId, const RsGxsGroupId &groupId, const RsGxsMessageId &messageId, bool isHome, RsGxsIfaceHelper *iface, bool autoUpdate) :
GxsGroupFeedItem(feedHolder, feedId, groupId, isHome, iface, autoUpdate)
{
#ifdef DEBUG_ITEM
std::cerr << "GxsFeedItem::removeItem()";
std::cerr << "GxsFeedItem::GxsFeedItem()";
std::cerr << std::endl;
#endif
if (mFeedHolder)
{
mFeedHolder->lockLayout(this, true);
}
/* load data if we can */
mMessageId = messageId;
hide();
mTokenTypeMessage = nextTokenType();
}
if (mFeedHolder)
{
mFeedHolder->lockLayout(this, false);
mFeedHolder->deleteFeedItem(this, mFeedId);
}
GxsFeedItem::~GxsFeedItem()
{
#ifdef DEBUG_ITEM
std::cerr << "GxsFeedItem::~GxsFeedItem()";
std::cerr << std::endl;
#endif
}
void GxsFeedItem::comments(const QString &title)
@ -65,41 +63,13 @@ void GxsFeedItem::comments(const QString &title)
if (mFeedHolder)
{
mFeedHolder->openComments(mFeedId, mGroupId, mMessageId, title);
mFeedHolder->openComments(feedId(), groupId(), messageId(), title);
}
}
void GxsFeedItem::unsubscribe()
void GxsFeedItem::copyMessageLink()
{
#ifdef DEBUG_ITEM
std::cerr << "GxsFeedItem::unsubscribe()";
std::cerr << std::endl;
#endif
if (mGxsIface)
{
uint32_t token;
mGxsIface->subscribeToGroup(token, mGroupId, false);
}
}
void GxsFeedItem::subscribe()
{
#ifdef DEBUG_ITEM
std::cerr << "GxsFeedItem::subscribe()";
std::cerr << std::endl;
#endif
if (mGxsIface)
{
uint32_t token;
mGxsIface->subscribeToGroup(token, mGroupId, true);
}
}
void GxsFeedItem::copyLink()
{
if (mGroupId.isNull() || mMessageId.isNull()) {
if (groupId().isNull() || mMessageId.isNull()) {
return;
}
@ -108,84 +78,29 @@ void GxsFeedItem::copyLink()
}
RetroShareLink link;
if (link.createGxsMessageLink(getLinkType(), mGroupId, mMessageId, messageName())) {
if (link.createGxsMessageLink(getLinkType(), groupId(), mMessageId, messageName())) {
QList<RetroShareLink> urls;
urls.push_back(link);
RSLinkClipboard::copyLinks(urls);
}
}
void GxsFeedItem::updateItemStatic()
//void GxsFeedItem::updateItemStatic()
//{
//#ifdef DEBUG_ITEM
// std::cerr << "GxsFeedItem::updateItemStatic()";
// std::cerr << std::endl;
//#endif
// requestMessage();
//}
void GxsFeedItem::fillDisplay(RsGxsUpdateBroadcastBase *updateBroadcastBase, bool complete)
{
std::cerr << "GxsFeedItem::updateItemStatic()";
std::cerr << std::endl;
GxsGroupFeedItem::fillDisplay(updateBroadcastBase, complete);
requestMessage();
}
void GxsFeedItem::updateItem()
{
std::cerr << "GxsFeedItem::updateItem() EMPTY";
std::cerr << std::endl;
}
/***********************************************************/
GxsFeedItem::GxsFeedItem(FeedHolder *feedHolder, uint32_t feedId, const RsGxsGroupId &groupId, const RsGxsMessageId &messageId, bool isHome, RsGxsIfaceHelper *iface, bool loadData, bool autoUpdate) :
FeedItem(NULL)
{
std::cerr << "GxsFeedItem::GxsFeedItem()";
std::cerr << std::endl;
/* this are just generally useful for all children */
mFeedHolder = feedHolder;
mFeedId = feedId;
mIsHome = isHome;
/* load data if we can */
mGroupId = groupId;
mMessageId = messageId;
mGxsIface = iface;
if (loadData && iface)
{
mLoadQueue = new TokenQueue(iface->getTokenService(), this);
requestGroupMeta();
}
else
{
mLoadQueue = NULL;
}
if (mGxsIface && autoUpdate) {
/* Connect to update broadcast */
mUpdateBroadcastBase = new RsGxsUpdateBroadcastBase(mGxsIface);
connect(mUpdateBroadcastBase, SIGNAL(fillDisplay(bool)), this, SLOT(fillDisplay(bool)));
} else {
mUpdateBroadcastBase = NULL;
}
}
GxsFeedItem::~GxsFeedItem()
{
std::cerr << "GxsFeedItem::~GxsFeedItem()";
std::cerr << std::endl;
if (mUpdateBroadcastBase)
{
delete(mUpdateBroadcastBase);
}
if (mLoadQueue)
{
delete mLoadQueue;
}
}
void GxsFeedItem::fillDisplay(bool /*complete*/)
{
std::map<RsGxsGroupId, std::vector<RsGxsMessageId> > msgs;
mUpdateBroadcastBase->getAllMsgIds(msgs);
updateBroadcastBase->getAllMsgIds(msgs);
if (!msgs.empty())
{
@ -200,31 +115,12 @@ void GxsFeedItem::fillDisplay(bool /*complete*/)
}
}
void GxsFeedItem::requestGroupMeta()
{
std::cerr << "GxsFeedItem::requestGroup()";
std::cerr << std::endl;
if (!mLoadQueue)
{
return;
}
std::list<RsGxsGroupId> ids;
ids.push_back(mGroupId);
RsTokReqOptions opts;
opts.mReqType = GXS_REQUEST_TYPE_GROUP_META;
uint32_t token;
mLoadQueue->requestGroupInfo(token, RS_TOKREQ_ANSTYPE_SUMMARY, opts, ids, GXSFEEDITEM_GROUPMETA);
updateItemStatic();
}
void GxsFeedItem::requestMessage()
{
#ifdef DEBUG_ITEM
std::cerr << "GxsFeedItem::requestMessage()";
std::cerr << std::endl;
#endif
if (!mLoadQueue)
{
@ -240,59 +136,39 @@ void GxsFeedItem::requestMessage()
opts.mReqType = GXS_REQUEST_TYPE_MSG_DATA;
GxsMsgReq msgIds;
std::vector<RsGxsMessageId> &vect_msgIds = msgIds[mGroupId];
std::vector<RsGxsMessageId> &vect_msgIds = msgIds[groupId()];
vect_msgIds.push_back(mMessageId);
uint32_t token;
mLoadQueue->requestMsgInfo(token, RS_TOKREQ_ANSTYPE_DATA, opts, msgIds, GXSFEEDITEM_MESSAGE);
}
void GxsFeedItem::loadGroupMeta(const uint32_t &token)
{
std::cerr << "GxsFeedItem::loadGroupMeta()";
std::cerr << std::endl;
std::list<RsGroupMetaData> groupMeta;
if (!mGxsIface->getGroupSummary(token, groupMeta))
{
std::cerr << "GxsFeedItem::loadGroupMeta() Error getting GroupMeta";
std::cerr << std::endl;
return;
}
if (groupMeta.size() == 1)
{
mGroupMeta = *groupMeta.begin();
}
else
{
std::cerr << "GxsFeedItem::loadGroupMeta() ERROR Should be ONE GroupMeta";
std::cerr << std::endl;
}
mLoadQueue->requestMsgInfo(token, RS_TOKREQ_ANSTYPE_DATA, opts, msgIds, mTokenTypeMessage);
}
void GxsFeedItem::loadRequest(const TokenQueue *queue, const TokenRequest &req)
{
#ifdef DEBUG_ITEM
std::cerr << "GxsFeedItem::loadRequest()";
std::cerr << std::endl;
#endif
if (queue == mLoadQueue)
{
switch(req.mUserType)
{
case GXSFEEDITEM_GROUPMETA:
loadGroupMeta(req.mToken);
break;
case GXSFEEDITEM_MESSAGE:
if (queue == mLoadQueue) {
if (req.mUserType == mTokenTypeMessage) {
loadMessage(req.mToken);
break;
default:
std::cerr << "GxsFeedItem::loadRequest() ERROR: INVALID TYPE";
std::cerr << std::endl;
break;
return;
}
}
GxsGroupFeedItem::loadRequest(queue, req);
}
bool GxsFeedItem::isLoading()
{
if (GxsGroupFeedItem::isLoading()) {
return true;
}
if (mLoadQueue && mLoadQueue->activeRequestExist(mTokenTypeMessage)) {
return true;
}
return false;
}

View File

@ -24,78 +24,42 @@
#ifndef _GXS_GENERIC_FEED_ITEM_H
#define _GXS_GENERIC_FEED_ITEM_H
#include <QMetaType>
#include "GxsGroupFeedItem.h"
#include <retroshare/rsgxsifacehelper.h>
#include "gui/feeds/FeedItem.h"
#include "util/TokenQueue.h"
#include "gui/RetroShareLink.h"
#include <stdint.h>
class FeedHolder;
class RsGxsUpdateBroadcastBase;
class GxsFeedItem : public FeedItem, public TokenResponse
class GxsFeedItem : public GxsGroupFeedItem
{
Q_OBJECT
public:
/** Note parent can = NULL */
GxsFeedItem(FeedHolder *feedHolder, uint32_t feedId, const RsGxsGroupId &groupId, const RsGxsMessageId &messageId, bool isHome, RsGxsIfaceHelper *iface, bool loadData, bool autoUpdate);
GxsFeedItem(FeedHolder *feedHolder, uint32_t feedId, const RsGxsGroupId &groupId, const RsGxsMessageId &messageId, bool isHome, RsGxsIfaceHelper *iface, bool autoUpdate);
virtual ~GxsFeedItem();
RsGxsGroupId groupId() { return mGroupId; }
RsGxsMessageId messageId() { return mMessageId; }
virtual void setContent(const QVariant &content) = 0;
protected:
// generic Fns - to be overloaded.
virtual void updateItemStatic();
virtual void updateItem();
virtual void loadMessage(const uint32_t &token) = 0;
/* load message data */
void requestMessage();
virtual void loadGroupMeta(const uint32_t &token);
virtual void loadRequest(const TokenQueue *queue, const TokenRequest &req);
virtual RetroShareLink::enumType getLinkType() = 0;
virtual void loadMessage(const uint32_t &token) = 0;
virtual QString messageName() = 0;
// general fns that can be implemented here.
/* GxsGroupFeedItem */
virtual bool isLoading();
virtual void fillDisplay(RsGxsUpdateBroadcastBase *updateBroadcastBase, bool complete);
/* TokenResponse */
virtual void loadRequest(const TokenQueue *queue, const TokenRequest &req);
protected slots:
void comments(const QString &title);
void subscribe();
void unsubscribe();
void removeItem();
void copyLink();
private slots:
/* RsGxsUpdateBroadcastBase */
void fillDisplay(bool complete);
protected:
FeedHolder *mFeedHolder;
uint32_t mFeedId;
bool mIsHome;
RsGxsGroupId mGroupId;
RsGxsMessageId mMessageId;
RsGroupMetaData mGroupMeta;
void copyMessageLink();
private:
void requestGroupMeta();
RsGxsIfaceHelper *mGxsIface;
TokenQueue *mLoadQueue;
RsGxsUpdateBroadcastBase *mUpdateBroadcastBase;
RsGxsMessageId mMessageId;
uint32_t mTokenTypeMessage;
};
Q_DECLARE_METATYPE(RsGxsGroupId)
Q_DECLARE_METATYPE(RsGxsMessageId)
#endif

View File

@ -0,0 +1,232 @@
/*
* Retroshare Gxs Feed Item
*
* Copyright 2012-2013 by Robert Fernie.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
* License Version 2.1 as published by the Free Software Foundation.
*
* This library 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
* Library General Public License for more details.
*
* You should have received a copy of the GNU Library General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
* USA.
*
* Please report all bugs and problems to "retroshare@lunamutt.com".
*
*/
#include <QTimer>
#include "gui/gxs/GxsGroupFeedItem.h"
#include "gui/feeds/FeedHolder.h"
#include "gui/gxs/RsGxsUpdateBroadcastBase.h"
#include <iostream>
//#include <algorithm>
/**
* #define DEBUG_ITEM 1
**/
GxsGroupFeedItem::GxsGroupFeedItem(FeedHolder *feedHolder, uint32_t feedId, const RsGxsGroupId &groupId, bool isHome, RsGxsIfaceHelper *iface, bool autoUpdate) :
FeedItem(NULL)
{
#ifdef DEBUG_ITEM
std::cerr << "GxsGroupFeedItem::GxsGroupFeedItem()";
std::cerr << std::endl;
#endif
/* this are just generally useful for all children */
mFeedHolder = feedHolder;
mFeedId = feedId;
mIsHome = isHome;
/* load data if we can */
mGroupId = groupId;
mGxsIface = iface;
mTokenTypeGroup = nextTokenType();
mLoadQueue = NULL;
if (mGxsIface && autoUpdate) {
/* Connect to update broadcast */
mUpdateBroadcastBase = new RsGxsUpdateBroadcastBase(mGxsIface);
connect(mUpdateBroadcastBase, SIGNAL(fillDisplay(bool)), this, SLOT(fillDisplaySlot(bool)));
} else {
mUpdateBroadcastBase = NULL;
}
}
GxsGroupFeedItem::~GxsGroupFeedItem()
{
#ifdef DEBUG_ITEM
std::cerr << "GxsGroupFeedItem::~GxsGroupFeedItem()";
std::cerr << std::endl;
#endif
if (mLoadQueue) {
delete mLoadQueue;
}
if (mUpdateBroadcastBase)
{
delete(mUpdateBroadcastBase);
}
}
void GxsGroupFeedItem::removeItem()
{
#ifdef DEBUG_ITEM
std::cerr << "GxsGroupFeedItem::removeItem()";
std::cerr << std::endl;
#endif
if (mFeedHolder)
{
mFeedHolder->lockLayout(this, true);
}
hide();
if (mFeedHolder)
{
mFeedHolder->lockLayout(this, false);
mFeedHolder->deleteFeedItem(this, mFeedId);
}
}
void GxsGroupFeedItem::unsubscribe()
{
#ifdef DEBUG_ITEM
std::cerr << "GxsGroupFeedItem::unsubscribe()";
std::cerr << std::endl;
#endif
if (mGxsIface)
{
uint32_t token;
mGxsIface->subscribeToGroup(token, mGroupId, false);
}
}
void GxsGroupFeedItem::subscribe()
{
#ifdef DEBUG_ITEM
std::cerr << "GxsGroupFeedItem::subscribe()";
std::cerr << std::endl;
#endif
if (mGxsIface)
{
uint32_t token;
mGxsIface->subscribeToGroup(token, mGroupId, true);
}
}
void GxsGroupFeedItem::copyGroupLink()
{
if (mGroupId.isNull()) {
return;
}
if (getLinkType() == RetroShareLink::TYPE_UNKNOWN) {
return;
}
RetroShareLink link;
if (link.createGxsGroupLink(getLinkType(), mGroupId, groupName())) {
QList<RetroShareLink> urls;
urls.push_back(link);
RSLinkClipboard::copyLinks(urls);
}
}
//void GxsGroupFeedItem::updateItemStatic()
//{
//#ifdef DEBUG_ITEM
// std::cerr << "GxsGroupFeedItem::updateItemStatic()";
// std::cerr << std::endl;
//#endif
//}
//void GxsGroupFeedItem::updateItem()
//{
//#ifdef DEBUG_ITEM
// std::cerr << "GxsGroupFeedItem::updateItem() EMPTY";
// std::cerr << std::endl;
//#endif
//}
void GxsGroupFeedItem::fillDisplaySlot(bool complete)
{
fillDisplay(mUpdateBroadcastBase, complete);
}
void GxsGroupFeedItem::fillDisplay(RsGxsUpdateBroadcastBase *updateBroadcastBase, bool /*complete*/)
{
std::list<RsGxsGroupId> grpIds;
updateBroadcastBase->getAllGrpIds(grpIds);
if (std::find(grpIds.begin(), grpIds.end(), groupId()) != grpIds.end()) {
requestGroup();
}
}
/***********************************************************/
void GxsGroupFeedItem::requestGroup()
{
#ifdef DEBUG_ITEM
std::cerr << "GxsGroupFeedItem::requestGroup()";
std::cerr << std::endl;
#endif
if (!mLoadQueue) {
if (mGxsIface) {
mLoadQueue = new TokenQueue(mGxsIface->getTokenService(), this);
} else {
return;
}
}
std::list<RsGxsGroupId> ids;
ids.push_back(mGroupId);
RsTokReqOptions opts;
opts.mReqType = GXS_REQUEST_TYPE_GROUP_DATA;
uint32_t token;
mLoadQueue->requestGroupInfo(token, RS_TOKREQ_ANSTYPE_SUMMARY, opts, ids, mTokenTypeGroup);
}
void GxsGroupFeedItem::loadRequest(const TokenQueue *queue, const TokenRequest &req)
{
#ifdef DEBUG_ITEM
std::cerr << "GxsGroupFeedItem::loadRequest()";
std::cerr << std::endl;
#endif
if (queue == mLoadQueue) {
if (req.mUserType == mTokenTypeGroup) {
loadGroup(req.mToken);
} else {
std::cerr << "GxsGroupFeedItem::loadRequest() ERROR: INVALID TYPE";
std::cerr << std::endl;
}
}
}
bool GxsGroupFeedItem::isLoading()
{
if (mLoadQueue && mLoadQueue->activeRequestExist(mTokenTypeGroup)) {
return true;
}
return false;
}

View File

@ -0,0 +1,92 @@
/*
* Retroshare Gxs Feed Item
*
* Copyright 2012-2013 by Robert Fernie.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
* License Version 2.1 as published by the Free Software Foundation.
*
* This library 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
* Library General Public License for more details.
*
* You should have received a copy of the GNU Library General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
* USA.
*
* Please report all bugs and problems to "retroshare@lunamutt.com".
*
*/
#ifndef _GXS_GROUPFEEDITEM_H
#define _GXS_GROUPFEEDITEM_H
#include <QMetaType>
#include <retroshare/rsgxsifacehelper.h>
#include "gui/feeds/FeedItem.h"
#include "util/TokenQueue.h"
#include "gui/RetroShareLink.h"
#include <stdint.h>
class FeedHolder;
class RsGxsUpdateBroadcastBase;
class GxsGroupFeedItem : public FeedItem, public TokenResponse
{
Q_OBJECT
public:
/** Note parent can = NULL */
GxsGroupFeedItem(FeedHolder *feedHolder, uint32_t feedId, const RsGxsGroupId &groupId, bool isHome, RsGxsIfaceHelper *iface, bool autoUpdate);
virtual ~GxsGroupFeedItem();
RsGxsGroupId groupId() { return mGroupId; }
uint32_t feedId() { return mFeedId; }
protected:
uint32_t nextTokenType() { return ++mNextTokenType; }
/* load group data */
void requestGroup();
virtual bool isLoading();
virtual void loadGroup(const uint32_t &token) = 0;
virtual RetroShareLink::enumType getLinkType() = 0;
virtual QString groupName() = 0;
virtual void fillDisplay(RsGxsUpdateBroadcastBase *updateBroadcastBase, bool complete);
/* TokenResponse */
virtual void loadRequest(const TokenQueue *queue, const TokenRequest &req);
protected slots:
void subscribe();
void unsubscribe();
void removeItem();
void copyGroupLink();
protected:
FeedHolder *mFeedHolder;
uint32_t mFeedId;
bool mIsHome;
RsGxsIfaceHelper *mGxsIface;
TokenQueue *mLoadQueue;
private slots:
/* RsGxsUpdateBroadcastBase */
void fillDisplaySlot(bool complete);
private:
RsGxsGroupId mGroupId;
RsGxsUpdateBroadcastBase *mUpdateBroadcastBase;
uint32_t mNextTokenType;
uint32_t mTokenTypeGroup;
};
Q_DECLARE_METATYPE(RsGxsGroupId)
#endif

View File

@ -329,11 +329,14 @@ void GxsChannelPostsWidget::createPostItem(const RsGxsChannelPost &post, bool re
item = dynamic_cast<GxsChannelPostItem*>(feedItem);
}
if (item) {
item->setContent(post);
item->setPost(post);
ui->feedWidget->setSort(item, ROLE_PUBLISH, QDateTime::fromTime_t(post.mMeta.mPublishTs));
} else {
uint32_t subscribeFlags = 0xffffffff;
GxsChannelPostItem *item = new GxsChannelPostItem(this, 0, post, subscribeFlags, true, false);
/* Group is not always available because of the TokenQueue */
RsGxsChannelGroup dummyGroup;
dummyGroup.mMeta.mGroupId = groupId();
dummyGroup.mMeta.mSubscribeFlags = 0xffffffff;
GxsChannelPostItem *item = new GxsChannelPostItem(this, 0, dummyGroup, post, true, false);
ui->feedWidget->addFeedItem(item, ROLE_PUBLISH, QDateTime::fromTime_t(post.mMeta.mPublishTs));
}

View File

@ -1192,6 +1192,7 @@ gxschannels {
gui/gxschannels/GxsChannelPostsWidget.h \
gui/gxschannels/GxsChannelFilesWidget.h \
gui/gxschannels/GxsChannelFilesStatusWidget.h \
gui/feeds/GxsChannelGroupItem.h \
gui/feeds/GxsChannelPostItem.h \
gui/gxschannels/GxsChannelUserNotify.h
@ -1199,6 +1200,7 @@ gxschannels {
gui/gxschannels/GxsChannelFilesWidget.ui \
gui/gxschannels/GxsChannelFilesStatusWidget.ui \
gui/gxschannels/CreateGxsChannelMsg.ui \
gui/feeds/GxsChannelGroupItem.ui \
gui/feeds/GxsChannelPostItem.ui
SOURCES += gui/gxschannels/GxsChannelDialog.cpp \
@ -1207,6 +1209,7 @@ gxschannels {
gui/gxschannels/GxsChannelFilesStatusWidget.cpp \
gui/gxschannels/GxsChannelGroupDialog.cpp \
gui/gxschannels/CreateGxsChannelMsg.cpp \
gui/feeds/GxsChannelGroupItem.cpp \
gui/feeds/GxsChannelPostItem.cpp \
gui/gxschannels/GxsChannelUserNotify.cpp
}
@ -1264,6 +1267,7 @@ gxsgui {
gui/gxs/GxsGroupFrameDialog.h \
gui/gxs/GxsMessageFrameWidget.h \
gui/gxs/GxsMessageFramePostWidget.h \
gui/gxs/GxsGroupFeedItem.h \
gui/gxs/GxsFeedItem.h \
gui/gxs/RsGxsUpdateBroadcastBase.h \
gui/gxs/RsGxsUpdateBroadcastWidget.h \
@ -1301,6 +1305,7 @@ gxsgui {
gui/gxs/GxsGroupFrameDialog.cpp \
gui/gxs/GxsMessageFrameWidget.cpp \
gui/gxs/GxsMessageFramePostWidget.cpp \
gui/gxs/GxsGroupFeedItem.cpp \
gui/gxs/GxsFeedItem.cpp \
gui/gxs/RsGxsUpdateBroadcastBase.cpp \
gui/gxs/RsGxsUpdateBroadcastWidget.cpp \