From da4c1e0f7f4ae2938dbbdc01d6da76b43d6c29ed Mon Sep 17 00:00:00 2001 From: drbob Date: Mon, 11 Mar 2013 20:53:15 +0000 Subject: [PATCH] Added New Services to GUI. - Added GxsChannels - Added New Common Comments GUI elements. - Moved Posted over to use Comments. Lots done, but lots to do! git-svn-id: http://svn.code.sf.net/p/retroshare/code/trunk@6212 b45a01b8-16f6-495d-af2f-9b41ad6348cc --- retroshare-gui/src/gui/ChannelFeed.cpp | 4 + retroshare-gui/src/gui/ChannelFeed.h | 1 + retroshare-gui/src/gui/NewsFeed.cpp | 9 + retroshare-gui/src/gui/NewsFeed.h | 1 + .../src/gui/Posted/PostedCreatePostDialog.cpp | 2 +- retroshare-gui/src/gui/Posted/PostedDialog.h | 52 +- .../src/gui/Posted/PostedGroupDialog.cpp | 68 +- .../src/gui/Posted/PostedGroupDialog.h | 26 +- retroshare-gui/src/gui/Posted/PostedItem.cpp | 2 + .../src/gui/Posted/PostedListDialog.cpp | 856 ++++++------- .../src/gui/Posted/PostedListDialog.h | 12 +- retroshare-gui/src/gui/feeds/FeedHolder.h | 3 + .../src/gui/feeds/GxsChannelPostItem.cpp | 663 ++++++++++ .../src/gui/feeds/GxsChannelPostItem.h | 83 ++ .../src/gui/feeds/GxsChannelPostItem.ui | 481 ++++++++ .../src/gui/gxs/GxsCommentContainer.cpp | 91 ++ .../src/gui/gxs/GxsCommentContainer.h | 97 ++ .../src/gui/gxs/GxsCommentContainer.ui | 88 ++ .../src/gui/gxs/GxsCommentDialog.cpp | 90 ++ retroshare-gui/src/gui/gxs/GxsCommentDialog.h | 51 + .../src/gui/gxs/GxsCommentDialog.ui | 367 ++++++ .../src/gui/gxs/GxsCommentTreeWidget.cpp | 30 +- .../src/gui/gxs/GxsCommentTreeWidget.h | 6 +- .../src/gui/gxs/GxsCreateCommentDialog.cpp | 32 + .../src/gui/gxs/GxsCreateCommentDialog.h | 34 + .../src/gui/gxs/GxsCreateCommentDialog.ui | 82 ++ .../src/gui/gxschannels/ChannelDialog.h | 69 ++ .../gui/gxschannels/CreateGxsChannelMsg.cpp | 656 ++++++++++ .../src/gui/gxschannels/CreateGxsChannelMsg.h | 91 ++ .../gui/gxschannels/CreateGxsChannelMsg.ui | 365 ++++++ .../src/gui/gxschannels/GxsChannelDialog.cpp | 1092 +++++++++++++++++ .../src/gui/gxschannels/GxsChannelDialog.h | 182 +++ .../src/gui/gxschannels/GxsChannelDialog.ui | 366 ++++++ .../gui/gxschannels/GxsChannelGroupDialog.cpp | 95 ++ .../gui/gxschannels/GxsChannelGroupDialog.h | 42 + .../gui/gxsforums/GxsForumThreadWidget.cpp | 19 +- .../src/gui/unfinished/ApplicationWindow.cpp | 9 +- retroshare-gui/src/retroshare-gui.pro | 58 +- 38 files changed, 5725 insertions(+), 550 deletions(-) create mode 100644 retroshare-gui/src/gui/feeds/GxsChannelPostItem.cpp create mode 100644 retroshare-gui/src/gui/feeds/GxsChannelPostItem.h create mode 100644 retroshare-gui/src/gui/feeds/GxsChannelPostItem.ui create mode 100644 retroshare-gui/src/gui/gxs/GxsCommentContainer.cpp create mode 100644 retroshare-gui/src/gui/gxs/GxsCommentContainer.h create mode 100644 retroshare-gui/src/gui/gxs/GxsCommentContainer.ui create mode 100644 retroshare-gui/src/gui/gxs/GxsCommentDialog.cpp create mode 100644 retroshare-gui/src/gui/gxs/GxsCommentDialog.h create mode 100644 retroshare-gui/src/gui/gxs/GxsCommentDialog.ui create mode 100644 retroshare-gui/src/gui/gxs/GxsCreateCommentDialog.cpp create mode 100644 retroshare-gui/src/gui/gxs/GxsCreateCommentDialog.h create mode 100644 retroshare-gui/src/gui/gxs/GxsCreateCommentDialog.ui create mode 100644 retroshare-gui/src/gui/gxschannels/ChannelDialog.h create mode 100644 retroshare-gui/src/gui/gxschannels/CreateGxsChannelMsg.cpp create mode 100644 retroshare-gui/src/gui/gxschannels/CreateGxsChannelMsg.h create mode 100644 retroshare-gui/src/gui/gxschannels/CreateGxsChannelMsg.ui create mode 100644 retroshare-gui/src/gui/gxschannels/GxsChannelDialog.cpp create mode 100644 retroshare-gui/src/gui/gxschannels/GxsChannelDialog.h create mode 100644 retroshare-gui/src/gui/gxschannels/GxsChannelDialog.ui create mode 100644 retroshare-gui/src/gui/gxschannels/GxsChannelGroupDialog.cpp create mode 100644 retroshare-gui/src/gui/gxschannels/GxsChannelGroupDialog.h diff --git a/retroshare-gui/src/gui/ChannelFeed.cpp b/retroshare-gui/src/gui/ChannelFeed.cpp index 4c42874e3..c12f73e02 100644 --- a/retroshare-gui/src/gui/ChannelFeed.cpp +++ b/retroshare-gui/src/gui/ChannelFeed.cpp @@ -246,6 +246,10 @@ void ChannelFeed::openChat(std::string /*peerId*/) { } +void ChannelFeed::openComments(uint32_t /*type*/ , const RsGxsGroupId & /*grpId */, const RsGxsMessageId & /*msgId*/) +{ +} + void ChannelFeed::editChannelDetail(){ EditChanDetails editUi(this, mChannelId); diff --git a/retroshare-gui/src/gui/ChannelFeed.h b/retroshare-gui/src/gui/ChannelFeed.h index a785c4301..4609c2602 100644 --- a/retroshare-gui/src/gui/ChannelFeed.h +++ b/retroshare-gui/src/gui/ChannelFeed.h @@ -54,6 +54,7 @@ public: virtual QScrollArea *getScrollArea(); virtual void deleteFeedItem(QWidget *item, uint32_t type); virtual void openChat(std::string peerId); + virtual void openComments(uint32_t /*type*/ , const RsGxsGroupId & /*grpId */, const RsGxsMessageId & /*msgId*/); bool navigate(const std::string& channelId, const std::string& msgId); diff --git a/retroshare-gui/src/gui/NewsFeed.cpp b/retroshare-gui/src/gui/NewsFeed.cpp index 6707ea0c9..183504763 100644 --- a/retroshare-gui/src/gui/NewsFeed.cpp +++ b/retroshare-gui/src/gui/NewsFeed.cpp @@ -810,6 +810,15 @@ void NewsFeed::openChat(std::string peerId) ChatDialog::chatFriend(peerId); } + +void NewsFeed::openComments(uint32_t type, const RsGxsGroupId &groupId, const RsGxsMessageId &msgId) +{ + std::cerr << "NewsFeed::openComments() Not Handled Yet"; + std::cerr << std::endl; +} + + + void NewsFeed::itemDestroyed(QObject *item) { widgets.remove(item); diff --git a/retroshare-gui/src/gui/NewsFeed.h b/retroshare-gui/src/gui/NewsFeed.h index afca54975..352eddbef 100644 --- a/retroshare-gui/src/gui/NewsFeed.h +++ b/retroshare-gui/src/gui/NewsFeed.h @@ -47,6 +47,7 @@ public: virtual QScrollArea *getScrollArea(); virtual void deleteFeedItem(QWidget *item, uint32_t type); virtual void openChat(std::string peerId); + virtual void openComments(uint32_t type, const RsGxsGroupId &groupId, const RsGxsMessageId &msgId); static void testFeeds(uint notifyFlags); static void testFeed(FeedNotify *feedNotify); diff --git a/retroshare-gui/src/gui/Posted/PostedCreatePostDialog.cpp b/retroshare-gui/src/gui/Posted/PostedCreatePostDialog.cpp index c9eebf008..aa611f178 100644 --- a/retroshare-gui/src/gui/Posted/PostedCreatePostDialog.cpp +++ b/retroshare-gui/src/gui/Posted/PostedCreatePostDialog.cpp @@ -18,7 +18,7 @@ void PostedCreatePostDialog::createPost() post.mMeta.mMsgName = ui->titleEdit->text().toStdString(); uint32_t token; - mPosted->submitPost(token, post); + mPosted->createPost(token, post); mTokenQueue->queueRequest(token, TOKENREQ_MSGINFO, RS_TOKREQ_ANSTYPE_ACK, TOKEN_USER_TYPE_POST); close(); } diff --git a/retroshare-gui/src/gui/Posted/PostedDialog.h b/retroshare-gui/src/gui/Posted/PostedDialog.h index 4b491770d..cb5c6710f 100644 --- a/retroshare-gui/src/gui/Posted/PostedDialog.h +++ b/retroshare-gui/src/gui/Posted/PostedDialog.h @@ -24,43 +24,43 @@ #ifndef MRK_POSTED_DIALOG_H #define MRK_POSTED_DIALOG_H -#include "retroshare-gui/mainpage.h" -#include "ui_PostedDialog.h" - #include -#include +#include "gui/gxs/GxsCommentContainer.h" +#include "gui/Posted/PostedListDialog.h" -class CommentHolder -{ -public: - - /*! - * This should be used for loading comments of a message on a main comment viewing page - * @param msgId the message id for which comments will be requested - */ - virtual void commentLoad(const RsPostedPost&) = 0; -}; - -class PostedListDialog; -class PostedComments; - -class PostedDialog : public MainPage, public CommentHolder +class PostedDialog : public GxsCommentContainer { Q_OBJECT public: - PostedDialog(QWidget *parent = 0); - void commentLoad(const RsPostedPost &); + PostedDialog(QWidget *parent = 0) + :GxsCommentContainer(parent) { return; } -private: + virtual GxsServiceDialog *createServiceDialog() + { + return new PostedListDialog(this); + } - PostedListDialog *mPostedList; - PostedComments *mPostedComments; + virtual QString getServiceName() + { + return tr("Posted"); + } - /* UI - from Designer */ - Ui::PostedDialog ui; + virtual RsTokenService *getTokenService() + { + return rsPosted->getTokenService(); + } + virtual RsGxsCommentService *getCommentService() + { + return rsPosted; + } + + virtual GxsCommentHeader *createHeaderWidget() + { + return NULL; + } }; #endif diff --git a/retroshare-gui/src/gui/Posted/PostedGroupDialog.cpp b/retroshare-gui/src/gui/Posted/PostedGroupDialog.cpp index bccabdb6b..f4168284c 100644 --- a/retroshare-gui/src/gui/Posted/PostedGroupDialog.cpp +++ b/retroshare-gui/src/gui/Posted/PostedGroupDialog.cpp @@ -20,35 +20,49 @@ ****************************************************************/ #include "PostedGroupDialog.h" -#include "util/TokenQueue.h" -#include +#include #include -#define POSTED_ENABLE_FLAG ( GXS_GROUP_FLAGS_ICON | \ - GXS_GROUP_FLAGS_DESCRIPTION | \ - GXS_GROUP_FLAGS_DISTRIBUTION | \ - GXS_GROUP_FLAGS_PUBLISHSIGN | \ - GXS_GROUP_FLAGS_SHAREKEYS | \ - GXS_GROUP_FLAGS_PERSONALSIGN | \ - GXS_GROUP_FLAGS_COMMENTS | \ - 0) +const uint32_t PostedCreateEnabledFlags = ( // GXS_GROUP_FLAGS_ICON | + GXS_GROUP_FLAGS_DESCRIPTION | + GXS_GROUP_FLAGS_DISTRIBUTION | + // GXS_GROUP_FLAGS_PUBLISHSIGN | + GXS_GROUP_FLAGS_SHAREKEYS | + // GXS_GROUP_FLAGS_PERSONALSIGN | + // GXS_GROUP_FLAGS_COMMENTS | + 0); -#define POSTED_CREATE_DEFAULT_FLAG ( GXS_GROUP_DEFAULTS_DISTRIB_LOCAL | \ - GXS_GROUP_DEFAULTS_PUBLISH_REQUIRED | \ - GXS_GROUP_DEFAULTS_PERSONAL_IFNOPUB | \ - GXS_GROUP_DEFAULTS_COMMENTS_NO | \ - 0) +uint32_t PostedCreateDefaultsFlags = ( GXS_GROUP_DEFAULTS_DISTRIB_PUBLIC | + //GXS_GROUP_DEFAULTS_DISTRIB_GROUP | + //GXS_GROUP_DEFAULTS_DISTRIB_LOCAL | -PostedGroupDialog::PostedGroupDialog(TokenQueue* tokenQueue, RsPosted* posted, QWidget *parent) - :GxsGroupDialog(tokenQueue, POSTED_ENABLE_FLAG, POSTED_CREATE_DEFAULT_FLAG, parent), - mPosted(posted) + GXS_GROUP_DEFAULTS_PUBLISH_OPEN | + //GXS_GROUP_DEFAULTS_PUBLISH_THREADS | + //GXS_GROUP_DEFAULTS_PUBLISH_REQUIRED | + //GXS_GROUP_DEFAULTS_PUBLISH_ENCRYPTED | + + //GXS_GROUP_DEFAULTS_PERSONAL_GPG | + GXS_GROUP_DEFAULTS_PERSONAL_REQUIRED | + //GXS_GROUP_DEFAULTS_PERSONAL_IFNOPUB | + + //GXS_GROUP_DEFAULTS_COMMENTS_YES | + GXS_GROUP_DEFAULTS_COMMENTS_NO | + 0); + + +PostedGroupDialog::PostedGroupDialog(TokenQueue *tokenQueue, QWidget *parent) + :GxsGroupDialog(tokenQueue, PostedCreateEnabledFlags, PostedCreateDefaultsFlags, parent) { + + } -PostedGroupDialog::PostedGroupDialog(const RsPostedGroup& grp, Mode mode, QWidget *parent) - :GxsGroupDialog(grp.mMeta, mode, parent), mGrp(grp) +PostedGroupDialog::PostedGroupDialog(const RsPostedGroup &group, QWidget *parent) + :GxsGroupDialog(group.mMeta, MODE_SHOW, parent) { + + } void PostedGroupDialog::initUi() @@ -65,20 +79,26 @@ void PostedGroupDialog::initUi() setUiText(UITYPE_SERVICE_HEADER, tr("Edit Posted Topic")); break; } + + setUiText(UITYPE_KEY_SHARE_CHECKBOX, tr("Add Topic Admins")); + setUiText(UITYPE_CONTACTS_DOCK, tr("Select Topic Admins")); } QPixmap PostedGroupDialog::serviceImage() { - return QPixmap(":/images/posted_add_64.png"); + return QPixmap(":/images/resource-group_64.png"); } bool PostedGroupDialog::service_CreateGroup(uint32_t &token, const RsGroupMetaData &meta) { // Specific Function. - RsPostedGroup grp; - grp.mDescription = getDescription().toStdString(); + RsPostedGroup grp; grp.mMeta = meta; + grp.mDescription = getDescription().toStdString(); + std::cerr << "PostedGroupDialog::service_CreateGroup() storing to Queue"; + std::cerr << std::endl; + + rsPosted->createGroup(token, grp); - rsPosted->submitGroup(token, grp); return true; } diff --git a/retroshare-gui/src/gui/Posted/PostedGroupDialog.h b/retroshare-gui/src/gui/Posted/PostedGroupDialog.h index 2cd592eb1..3096a5732 100644 --- a/retroshare-gui/src/gui/Posted/PostedGroupDialog.h +++ b/retroshare-gui/src/gui/Posted/PostedGroupDialog.h @@ -24,32 +24,26 @@ #define _POSTED_GROUP_DIALOG_H #include "gui/gxs/GxsGroupDialog.h" -#include "retroshare/rsposted.h" +#include class PostedGroupDialog : public GxsGroupDialog { Q_OBJECT public: - - /*! - * This constructs a create dialog - */ - PostedGroupDialog(TokenQueue* tokenQueue, RsPosted* posted, QWidget *parent = NULL); - - /*! - * This constructs a show dialog which displays an already existing group - */ - PostedGroupDialog(const RsPostedGroup& grp, Mode mode, QWidget *parent = NULL); + PostedGroupDialog(TokenQueue *tokenQueue, QWidget *parent); + PostedGroupDialog(const RsPostedGroup &topic, QWidget *parent); protected: - virtual void initUi(); - virtual QPixmap serviceImage(); - bool service_CreateGroup(uint32_t &token, const RsGroupMetaData &meta); + virtual void initUi(); + virtual QPixmap serviceImage(); + virtual bool service_CreateGroup(uint32_t &token, const RsGroupMetaData &meta); private: - RsPostedGroup mGrp; - RsPosted* mPosted; + + RsPostedGroup mTopic; + }; #endif + diff --git a/retroshare-gui/src/gui/Posted/PostedItem.cpp b/retroshare-gui/src/gui/Posted/PostedItem.cpp index d4c99dfff..996e157dc 100644 --- a/retroshare-gui/src/gui/Posted/PostedItem.cpp +++ b/retroshare-gui/src/gui/Posted/PostedItem.cpp @@ -69,6 +69,7 @@ void PostedItem::setContent(const RsPostedPost &post) uint32_t up, down, nComments; +#if 0 bool ok = rsPosted->retrieveScores(mPost.mMeta.mServiceString, up, down, nComments); if(ok) @@ -82,6 +83,7 @@ void PostedItem::setContent(const RsPostedPost &post) "style=\" font-size:8pt; font-weight:600;\"> Comments: " + QString::number(nComments) + "

"); } +#endif } diff --git a/retroshare-gui/src/gui/Posted/PostedListDialog.cpp b/retroshare-gui/src/gui/Posted/PostedListDialog.cpp index 80d9ae9d0..729c79b01 100644 --- a/retroshare-gui/src/gui/Posted/PostedListDialog.cpp +++ b/retroshare-gui/src/gui/Posted/PostedListDialog.cpp @@ -44,213 +44,222 @@ //#define DEBUG_FORUMS /* Images for context menu icons */ -#define IMAGE_MESSAGE ":/images/folder-draft.png" +#define IMAGE_MESSAGE ":/images/folder-draft.png" #define IMAGE_MESSAGEREPLY ":/images/mail_reply.png" #define IMAGE_MESSAGEREMOVE ":/images/mail_delete.png" -#define IMAGE_DOWNLOAD ":/images/start.png" -#define IMAGE_DOWNLOADALL ":/images/startall.png" +#define IMAGE_DOWNLOAD ":/images/start.png" +#define IMAGE_DOWNLOADALL ":/images/startall.png" /* Images for TreeWidget */ -#define IMAGE_FOLDER ":/images/folder16.png" -#define IMAGE_FOLDERGREEN ":/images/folder_green.png" -#define IMAGE_FOLDERRED ":/images/folder_red.png" +#define IMAGE_FOLDER ":/images/folder16.png" +#define IMAGE_FOLDERGREEN ":/images/folder_green.png" +#define IMAGE_FOLDERRED ":/images/folder_red.png" #define IMAGE_FOLDERYELLOW ":/images/folder_yellow.png" -#define IMAGE_FORUM ":/images/konversation16.png" -#define IMAGE_SUBSCRIBE ":/images/edit_add24.png" -#define IMAGE_UNSUBSCRIBE ":/images/cancel.png" -#define IMAGE_INFO ":/images/info16.png" -#define IMAGE_NEWFORUM ":/images/new_forum16.png" -#define IMAGE_FORUMAUTHD ":/images/konv_message2.png" -#define IMAGE_COPYLINK ":/images/copyrslink.png" +#define IMAGE_FORUM ":/images/konversation16.png" +#define IMAGE_SUBSCRIBE ":/images/edit_add24.png" +#define IMAGE_UNSUBSCRIBE ":/images/cancel.png" +#define IMAGE_INFO ":/images/info16.png" +#define IMAGE_NEWFORUM ":/images/new_forum16.png" +#define IMAGE_FORUMAUTHD ":/images/konv_message2.png" +#define IMAGE_COPYLINK ":/images/copyrslink.png" // token types to deal with /** Constructor */ -PostedListDialog::PostedListDialog(CommentHolder *commentHolder, QWidget *parent) -: RsAutoUpdatePage(1000,parent), mCommentHolder(commentHolder) +PostedListDialog::PostedListDialog(QWidget *parent) +: RsAutoUpdatePage(1000,parent), GxsServiceDialog(dynamic_cast(parent)) { - /* Invoke the Qt Designer generated object setup routine */ - ui.setupUi(this); + /* Invoke the Qt Designer generated object setup routine */ + ui.setupUi(this); - /* Setup Queue */ - mPostedQueue = new TokenQueue(rsPosted->getTokenService(), this); + /* Setup Queue */ + mPostedQueue = new TokenQueue(rsPosted->getTokenService(), this); - connect( ui.groupTreeWidget, SIGNAL( treeCustomContextMenuRequested( QPoint ) ), this, SLOT( groupListCustomPopupMenu( QPoint ) ) ); + connect( ui.groupTreeWidget, SIGNAL( treeCustomContextMenuRequested( QPoint ) ), this, SLOT( groupListCustomPopupMenu( QPoint ) ) ); - connect( ui.groupTreeWidget, SIGNAL( treeCurrentItemChanged(QString) ), this, SLOT( changedTopic(QString) ) ); + connect( ui.groupTreeWidget, SIGNAL( treeCurrentItemChanged(QString) ), this, SLOT( changedTopic(QString) ) ); - connect(ui.hotSortButton, SIGNAL(clicked()), this, SLOT(getRankings())); - connect(ui.newSortButton, SIGNAL(clicked()), this, SLOT(getRankings())); - connect(ui.topSortButton, SIGNAL(clicked()), this, SLOT(getRankings())); + connect(ui.hotSortButton, SIGNAL(clicked()), this, SLOT(getRankings())); + connect(ui.newSortButton, SIGNAL(clicked()), this, SLOT(getRankings())); + connect(ui.topSortButton, SIGNAL(clicked()), this, SLOT(getRankings())); - /* create posted tree */ - yourTopics = ui.groupTreeWidget->addCategoryItem(tr("My Topics"), QIcon(IMAGE_FOLDER), true); - subscribedTopics = ui.groupTreeWidget->addCategoryItem(tr("Subscribed Topics"), QIcon(IMAGE_FOLDERRED), true); - popularTopics = ui.groupTreeWidget->addCategoryItem(tr("Popular Topics"), QIcon(IMAGE_FOLDERGREEN), false); - otherTopics = ui.groupTreeWidget->addCategoryItem(tr("Other Topics"), QIcon(IMAGE_FOLDERYELLOW), false); + /* create posted tree */ + yourTopics = ui.groupTreeWidget->addCategoryItem(tr("My Topics"), QIcon(IMAGE_FOLDER), true); + subscribedTopics = ui.groupTreeWidget->addCategoryItem(tr("Subscribed Topics"), QIcon(IMAGE_FOLDERRED), true); + popularTopics = ui.groupTreeWidget->addCategoryItem(tr("Popular Topics"), QIcon(IMAGE_FOLDERGREEN), false); + otherTopics = ui.groupTreeWidget->addCategoryItem(tr("Other Topics"), QIcon(IMAGE_FOLDERYELLOW), false); - ui.hotSortButton->setChecked(true); + ui.hotSortButton->setChecked(true); - connect( ui.newTopicButton, SIGNAL( clicked() ), this, SLOT( newTopic() ) ); - connect(ui.refreshButton, SIGNAL(clicked()), this, SLOT(refreshTopics())); - connect(ui.submitPostButton, SIGNAL(clicked()), this, SLOT(newPost())); + connect( ui.newTopicButton, SIGNAL( clicked() ), this, SLOT( newTopic() ) ); + connect(ui.refreshButton, SIGNAL(clicked()), this, SLOT(refreshTopics())); + connect(ui.submitPostButton, SIGNAL(clicked()), this, SLOT(newPost())); } void PostedListDialog::getRankings() { +#if 0 + if(mCurrTopicId.empty()) + return; - if(mCurrTopicId.empty()) - return; + std::cerr << "PostedListDialog::getHotRankings()"; + std::cerr << std::endl; - std::cerr << "PostedListDialog::getHotRankings()"; - std::cerr << std::endl; + RsTokReqOptions opts; + opts.mReqType = GXS_REQUEST_TYPE_GROUP_META; + uint32_t token; - RsTokReqOptions opts; - opts.mReqType = GXS_REQUEST_TYPE_GROUP_META; - uint32_t token; + QObject* button = sender(); + if(button == ui.hotSortButton) + { + rsPosted->requestPostRankings(token, RsPosted::HotRankType, mCurrTopicId); + }else if(button == ui.topSortButton) + { + rsPosted->requestPostRankings(token, RsPosted::TopRankType, mCurrTopicId); + }else if(button == ui.newSortButton) + { + rsPosted->requestPostRankings(token, RsPosted::NewRankType, mCurrTopicId); + }else{ + return; + } - QObject* button = sender(); - if(button == ui.hotSortButton) - { - rsPosted->requestPostRankings(token, RsPosted::HotRankType, mCurrTopicId); - }else if(button == ui.topSortButton) - { - rsPosted->requestPostRankings(token, RsPosted::TopRankType, mCurrTopicId); - }else if(button == ui.newSortButton) - { - rsPosted->requestPostRankings(token, RsPosted::NewRankType, mCurrTopicId); - }else{ - return; - } - - mPostedQueue->queueRequest(token, TOKENREQ_GROUPINFO, RS_TOKREQ_ANSTYPE_DATA, TOKEN_USER_TYPE_POST_RANKINGS); + mPostedQueue->queueRequest(token, TOKENREQ_GROUPINFO, RS_TOKREQ_ANSTYPE_DATA, TOKEN_USER_TYPE_POST_RANKINGS); +#endif } +#if 0 void PostedListDialog::loadRankings(const uint32_t &token) { + RsPostedPostRanking rankings; - RsPostedPostRanking rankings; + if(!rsPosted->getPostRanking(token, rankings)) + return; - if(!rsPosted->getPostRanking(token, rankings)) - return; + if(rankings.grpId != mCurrTopicId) + return; - if(rankings.grpId != mCurrTopicId) - return; - - applyRanking(rankings.ranking); + applyRanking(rankings.ranking); } +#endif +#if 0 void PostedListDialog::applyRanking(const PostedRanking& ranks) { - std::cerr << "PostedListDialog::loadGroupThreadData_InsertThreads()"; - std::cerr << std::endl; + std::cerr << "PostedListDialog::loadGroupThreadData_InsertThreads()"; + std::cerr << std::endl; - shallowClearPosts(); + shallowClearPosts(); - QLayout *alayout = ui.scrollAreaWidgetContents->layout(); + QLayout *alayout = ui.scrollAreaWidgetContents->layout(); - PostedRanking::const_iterator mit = ranks.begin(); + PostedRanking::const_iterator mit = ranks.begin(); - for(; mit != ranks.end(); mit++) - { - const RsGxsMessageId& msgId = mit->second; + for(; mit != ranks.end(); mit++) + { + const RsGxsMessageId& msgId = mit->second; - if(mPosts.find(msgId) != mPosts.end()) - alayout->addWidget(mPosts[msgId]); - } + if(mPosts.find(msgId) != mPosts.end()) + alayout->addWidget(mPosts[msgId]); + } - return; + return; } +#endif void PostedListDialog::refreshTopics() { - std::cerr << "PostedListDialog::requestGroupSummary()"; - std::cerr << std::endl; + std::cerr << "PostedListDialog::requestGroupSummary()"; + std::cerr << std::endl; - RsTokReqOptions opts; - opts.mReqType = GXS_REQUEST_TYPE_GROUP_META; - uint32_t token; - mPostedQueue->requestGroupInfo(token, RS_TOKREQ_ANSTYPE_SUMMARY, opts, TOKEN_USER_TYPE_TOPIC); + RsTokReqOptions opts; + opts.mReqType = GXS_REQUEST_TYPE_GROUP_META; + uint32_t token; + mPostedQueue->requestGroupInfo(token, RS_TOKREQ_ANSTYPE_SUMMARY, opts, TOKEN_USER_TYPE_TOPIC); } void PostedListDialog::groupListCustomPopupMenu( QPoint /*point*/ ) { - QMenu contextMnu( this ); + QMenu contextMnu( this ); - QAction *action = contextMnu.addAction(QIcon(IMAGE_MESSAGE), tr("Submit Post"), this, SLOT(newPost())); - action->setDisabled (mCurrTopicId.empty()); + QAction *action = contextMnu.addAction(QIcon(IMAGE_MESSAGE), tr("Submit Post"), this, SLOT(newPost())); + action->setDisabled (mCurrTopicId.empty()); - contextMnu.exec(QCursor::pos()); + contextMnu.exec(QCursor::pos()); } void PostedListDialog::newPost() { - if(mCurrTopicId.empty()) - return; + if(mCurrTopicId.empty()) + return; - PostedCreatePostDialog cp(mPostedQueue, rsPosted, mCurrTopicId, this); - cp.exec(); + PostedCreatePostDialog cp(mPostedQueue, rsPosted, mCurrTopicId, this); + cp.exec(); } void PostedListDialog::submitVote(const RsGxsGrpMsgIdPair &msgId, bool up) { - uint32_t token; - RsPostedVote vote; +#if 0 + uint32_t token; + RsPostedVote vote; - vote.mMeta.mGroupId = msgId.first; - vote.mMeta.mParentId = msgId.second; - vote.mDirection = (uint8_t)up; - rsPosted->submitVote(token, vote); + vote.mMeta.mGroupId = msgId.first; + vote.mMeta.mParentId = msgId.second; + vote.mDirection = (uint8_t)up; + rsPosted->submitVote(token, vote); - mPostedQueue->queueRequest(token, 0 , RS_TOKREQ_ANSTYPE_ACK, TOKEN_USER_TYPE_VOTE); -} + mPostedQueue->queueRequest(token, 0 , RS_TOKREQ_ANSTYPE_ACK, TOKEN_USER_TYPE_VOTE); +#endif +} void PostedListDialog::showComments(const RsPostedPost& post) { - mCommentHolder->commentLoad(post); + commentLoad(post.mMeta.mGroupId, post.mMeta.mMsgId); + //mCommentHolder->commentLoad(post); } + + void PostedListDialog::updateDisplay() { - if (!rsPosted) - return; + if (!rsPosted) + return; - std::list groupIds; - std::map > msgs; + std::list groupIds; + std::map > msgs; - if (rsPosted->updated(true, true)) - { - /* update Forums List */ + if (rsPosted->updated(true, true)) + { + /* update Forums List */ - rsPosted->groupsChanged(groupIds); - if(!groupIds.empty()) - { - std::list::iterator it = std::find(groupIds.begin(), groupIds.end(), mCurrTopicId); + rsPosted->groupsChanged(groupIds); + if(!groupIds.empty()) + { + std::list::iterator it = std::find(groupIds.begin(), groupIds.end(), mCurrTopicId); - if(it != groupIds.end()){ - requestGroupSummary(); - return; - } - } + if(it != groupIds.end()){ + requestGroupSummary(); + return; + } + } - rsPosted->msgsChanged(msgs); + rsPosted->msgsChanged(msgs); - if(!msgs.empty()) - { + if(!msgs.empty()) + { - std::map >::iterator mit = msgs.find(mCurrTopicId); - if(mit != msgs.end()) - { - updateDisplayedItems(mit->second); - } - } - } + std::map >::iterator mit = msgs.find(mCurrTopicId); + if(mit != msgs.end()) + { + updateDisplayedItems(mit->second); + } + } + } } @@ -258,20 +267,20 @@ void PostedListDialog::updateDisplay() void PostedListDialog::updateDisplayedItems(const std::vector &msgIds) { - RsTokReqOptions opts; + RsTokReqOptions opts; - opts.mReqType = GXS_REQUEST_TYPE_MSG_DATA; - opts.mOptions = RS_TOKREQOPT_MSG_LATEST; + opts.mReqType = GXS_REQUEST_TYPE_MSG_DATA; + opts.mOptions = RS_TOKREQOPT_MSG_LATEST; - GxsMsgReq msgs; - msgs[mCurrTopicId] = msgIds; + GxsMsgReq msgs; + msgs[mCurrTopicId] = msgIds; - std::cerr << "PostedListDialog::updateDisplayedItems(" << mCurrTopicId << ")"; - std::cerr << std::endl; + std::cerr << "PostedListDialog::updateDisplayedItems(" << mCurrTopicId << ")"; + std::cerr << std::endl; - uint32_t token; - mPostedQueue->requestMsgInfo(token, RS_TOKREQ_ANSTYPE_DATA, opts, msgs, TOKEN_USER_TYPE_POST_MOD); + uint32_t token; + mPostedQueue->requestMsgInfo(token, RS_TOKREQ_ANSTYPE_DATA, opts, msgs, TOKEN_USER_TYPE_POST_MOD); } @@ -279,18 +288,18 @@ void PostedListDialog::updateDisplayedItems(const std::vector &m void PostedListDialog::changedTopic(const QString &id) { - mCurrTopicId = id.toStdString(); - insertThreads(); + mCurrTopicId = id.toStdString(); + insertThreads(); } /*********************** **** **** **** ***********************/ -/** New / Edit Groups ********************************/ +/** New / Edit Groups ********************************/ /*********************** **** **** **** ***********************/ void PostedListDialog::newTopic() { - PostedGroupDialog cf (mPostedQueue, rsPosted, this); + PostedGroupDialog cf (mPostedQueue, this); cf.exec (); } @@ -301,7 +310,7 @@ void PostedListDialog::showGroupDetails() return; } - PostedGroupDialog cf(mGroups[mCurrTopicId], GxsGroupDialog::MODE_SHOW, this); + PostedGroupDialog cf(mGroups[mCurrTopicId], this); cf.exec (); } @@ -313,72 +322,72 @@ void PostedListDialog::insertGroups() void PostedListDialog::requestGroupSummary() { - std::cerr << "PostedListDialog::requestGroupSummary()"; - std::cerr << std::endl; + std::cerr << "PostedListDialog::requestGroupSummary()"; + std::cerr << std::endl; - RsTokReqOptions opts; - opts.mReqType = GXS_REQUEST_TYPE_GROUP_META; + RsTokReqOptions opts; + opts.mReqType = GXS_REQUEST_TYPE_GROUP_META; uint32_t token; - mPostedQueue->requestGroupInfo(token, RS_TOKREQ_ANSTYPE_SUMMARY, opts, TOKEN_USER_TYPE_TOPIC); + mPostedQueue->requestGroupInfo(token, RS_TOKREQ_ANSTYPE_SUMMARY, opts, TOKEN_USER_TYPE_TOPIC); } void PostedListDialog::acknowledgeGroup(const uint32_t &token) { - RsGxsGroupId grpId; - rsPosted->acknowledgeGrp(token, grpId); + RsGxsGroupId grpId; + rsPosted->acknowledgeGrp(token, grpId); - if(!grpId.empty()) - { + if(!grpId.empty()) + { - RsTokReqOptions opts; - opts.mReqType = GXS_REQUEST_TYPE_GROUP_META; - uint32_t reqToken; - mPostedQueue->requestGroupInfo(reqToken, RS_TOKREQ_ANSTYPE_SUMMARY, opts, TOKEN_USER_TYPE_TOPIC); - } + RsTokReqOptions opts; + opts.mReqType = GXS_REQUEST_TYPE_GROUP_META; + uint32_t reqToken; + mPostedQueue->requestGroupInfo(reqToken, RS_TOKREQ_ANSTYPE_SUMMARY, opts, TOKEN_USER_TYPE_TOPIC); + } } void PostedListDialog::acknowledgePostMsg(const uint32_t &token) { - RsGxsGrpMsgIdPair msgId; + RsGxsGrpMsgIdPair msgId; - // just acknowledge, don't load anything - rsPosted->acknowledgeMsg(token, msgId); + // just acknowledge, don't load anything + rsPosted->acknowledgeMsg(token, msgId); } void PostedListDialog::loadGroupSummary(const uint32_t &token) { - std::cerr << "PostedListDialog::loadGroupSummary()"; - std::cerr << std::endl; + std::cerr << "PostedListDialog::loadGroupSummary()"; + std::cerr << std::endl; - std::list groupInfo; - rsPosted->getGroupSummary(token, groupInfo); + std::list groupInfo; + rsPosted->getGroupSummary(token, groupInfo); - if (groupInfo.size() > 0) - { + if (groupInfo.size() > 0) + { insertGroupData(groupInfo); - } - else - { - std::cerr << "PostedListDialog::loadGroupSummary() ERROR No Groups..."; - std::cerr << std::endl; - } + } + else + { + std::cerr << "PostedListDialog::loadGroupSummary() ERROR No Groups..."; + std::cerr << std::endl; + } } void PostedListDialog::loadPostData(const uint32_t &token) { - loadGroupThreadData_InsertThreads(token); + loadGroupThreadData_InsertThreads(token); } void PostedListDialog::acknowledgeVoteMsg(const uint32_t &token) { - RsGxsGrpMsgIdPair msgId; + RsGxsGrpMsgIdPair msgId; - rsPosted->acknowledgeMsg(token, msgId); + rsPosted->acknowledgeMsg(token, msgId); } void PostedListDialog::loadVoteData(const uint32_t &token) { - return; + return; } /*********************** **** **** **** ***********************/ @@ -388,13 +397,13 @@ void PostedListDialog::loadVoteData(const uint32_t &token) void PostedListDialog::requestGroupSummary_CurrentForum(const std::string &forumId) { - RsTokReqOptions opts; + RsTokReqOptions opts; std::list grpIds; grpIds.push_back(forumId); - std::cerr << "PostedListDialog::requestGroupSummary_CurrentForum(" << forumId << ")"; - std::cerr << std::endl; + std::cerr << "PostedListDialog::requestGroupSummary_CurrentForum(" << forumId << ")"; + std::cerr << std::endl; uint32_t token; mPostedQueue->requestGroupInfo(token, RS_TOKREQ_ANSTYPE_SUMMARY, opts, grpIds, POSTEDDIALOG_CURRENTFORUM); @@ -402,22 +411,22 @@ void PostedListDialog::requestGroupSummary_CurrentForum(const std::string &forum void PostedListDialog::loadGroupSummary_CurrentForum(const uint32_t &token) { - std::cerr << "PostedListDialog::loadGroupSummary_CurrentForum()"; - std::cerr << std::endl; + std::cerr << "PostedListDialog::loadGroupSummary_CurrentForum()"; + std::cerr << std::endl; - std::list groupInfo; - rsPosted->getGroupSummary(token, groupInfo); + std::list groupInfo; + rsPosted->getGroupSummary(token, groupInfo); - if (groupInfo.size() == 1) - { + if (groupInfo.size() == 1) + { RsGroupMetaData fi = groupInfo.front(); //insertForumThreads(fi); - } - else - { - std::cerr << "PostedListDialog::loadGroupSummary_CurrentForum() ERROR Invalid Number of Groups..."; - std::cerr << std::endl; - } + } + else + { + std::cerr << "PostedListDialog::loadGroupSummary_CurrentForum() ERROR Invalid Number of Groups..."; + std::cerr << std::endl; + } } /*********************** **** **** **** ***********************/ @@ -428,189 +437,182 @@ void PostedListDialog::loadGroupSummary_CurrentForum(const uint32_t &token) void PostedListDialog::insertThreads() { - loadCurrentTopicThreads(mCurrTopicId); + loadCurrentTopicThreads(mCurrTopicId); } void PostedListDialog::loadCurrentTopicThreads(const std::string &topicId) { - std::cerr << "PostedListDialog::loadCurrentForumThreads(" << topicId << ")"; - std::cerr << std::endl; + std::cerr << "PostedListDialog::loadCurrentForumThreads(" << topicId << ")"; + std::cerr << std::endl; - if (topicId.empty()) + if (topicId.empty()) { - std::cerr << "PostedListDialog::loadCurrentForumThreads() Empty GroupId .. ignoring Req"; - std::cerr << std::endl; + std::cerr << "PostedListDialog::loadCurrentForumThreads() Empty GroupId .. ignoring Req"; + std::cerr << std::endl; return; - } + } clearPosts(); - /* initiate loading */ - requestGroupThreadData_InsertThreads(topicId); + /* initiate loading */ + requestGroupThreadData_InsertThreads(topicId); } void PostedListDialog::requestGroupThreadData_InsertThreads(const std::string &groupId) { - RsTokReqOptions opts; + RsTokReqOptions opts; - opts.mReqType = GXS_REQUEST_TYPE_MSG_DATA; - opts.mOptions = RS_TOKREQOPT_MSG_LATEST; + opts.mReqType = GXS_REQUEST_TYPE_MSG_DATA; + opts.mOptions = RS_TOKREQOPT_MSG_LATEST; - std::list grpIds; + std::list grpIds; grpIds.push_back(groupId); - std::cerr << "PostedListDialog::requestGroupThreadData_InsertThreads(" << groupId << ")"; - std::cerr << std::endl; + std::cerr << "PostedListDialog::requestGroupThreadData_InsertThreads(" << groupId << ")"; + std::cerr << std::endl; uint32_t token; - mPostedQueue->requestMsgInfo(token, RS_TOKREQ_ANSTYPE_DATA, opts, grpIds, TOKEN_USER_TYPE_POST); + mPostedQueue->requestMsgInfo(token, RS_TOKREQ_ANSTYPE_DATA, opts, grpIds, TOKEN_USER_TYPE_POST); } void PostedListDialog::loadGroupThreadData_InsertThreads(const uint32_t &token) { - std::cerr << "PostedListDialog::loadGroupThreadData_InsertThreads()"; - std::cerr << std::endl; + std::cerr << "PostedListDialog::loadGroupThreadData_InsertThreads()"; + std::cerr << std::endl; - clearPosts(); + clearPosts(); - PostedPostResult result; - rsPosted->getPost(token, result); - std::vector& posts = result[mCurrTopicId]; - std::vector::iterator vit = posts.begin(); + std::vector posts; + rsPosted->getPostData(token, posts); + std::vector::iterator vit; + + for(vit = posts.begin(); vit != posts.end(); vit++) + { + RsPostedPost& p = *vit; + loadPost(p); + } - for(; vit != posts.end(); vit++) - { - RsPostedPost& p = *vit; - loadPost(p); - } } void PostedListDialog::loadPost(const RsPostedPost &post) { - PostedItem *item = new PostedItem(this, post); - connect(item, SIGNAL(vote(RsGxsGrpMsgIdPair,bool)), this, SLOT(submitVote(RsGxsGrpMsgIdPair,bool))); - QLayout *alayout = ui.scrollAreaWidgetContents->layout(); - mPosts.insert(post.mMeta.mMsgId, item); - alayout->addWidget(item); + PostedItem *item = new PostedItem(this, post); + connect(item, SIGNAL(vote(RsGxsGrpMsgIdPair,bool)), this, SLOT(submitVote(RsGxsGrpMsgIdPair,bool))); + QLayout *alayout = ui.scrollAreaWidgetContents->layout(); + mPosts.insert(post.mMeta.mMsgId, item); + alayout->addWidget(item); } void PostedListDialog::clearPosts() { - std::cerr << "PostedListDialog::clearPosts()" << std::endl; + std::cerr << "PostedListDialog::clearPosts()" << std::endl; - std::list postedItems; - std::list::iterator pit; + std::list postedItems; + std::list::iterator pit; - QLayout *alayout = ui.scrollAreaWidgetContents->layout(); - int count = alayout->count(); - for(int i = 0; i < count; i++) - { - QLayoutItem *litem = alayout->itemAt(i); - if (!litem) - { - std::cerr << "PostedListDialog::clearPosts() missing litem"; - std::cerr << std::endl; - continue; - } + QLayout *alayout = ui.scrollAreaWidgetContents->layout(); + int count = alayout->count(); + for(int i = 0; i < count; i++) + { + QLayoutItem *litem = alayout->itemAt(i); + if (!litem) + { + std::cerr << "PostedListDialog::clearPosts() missing litem"; + std::cerr << std::endl; + continue; + } - PostedItem *item = dynamic_cast(litem->widget()); - if (item) - { - std::cerr << "PostedListDialog::clearPosts() item: " << item; - std::cerr << std::endl; + PostedItem *item = dynamic_cast(litem->widget()); + if (item) + { + std::cerr << "PostedListDialog::clearPosts() item: " << item; + std::cerr << std::endl; - postedItems.push_back(item); - } - else - { - std::cerr << "PostedListDialog::clearPosts() Found Child, which is not a PostedItem???"; - std::cerr << std::endl; - } - } + postedItems.push_back(item); + } + else + { + std::cerr << "PostedListDialog::clearPosts() Found Child, which is not a PostedItem???"; + std::cerr << std::endl; + } + } - for(pit = postedItems.begin(); pit != postedItems.end(); pit++) - { - PostedItem *item = *pit; - alayout->removeWidget(item); - delete item; - } + for(pit = postedItems.begin(); pit != postedItems.end(); pit++) + { + PostedItem *item = *pit; + alayout->removeWidget(item); + delete item; + } - mPosts.clear(); + mPosts.clear(); } void PostedListDialog::shallowClearPosts() { - std::cerr << "PostedListDialog::clearPosts()" << std::endl; + std::cerr << "PostedListDialog::clearPosts()" << std::endl; - std::list postedItems; - std::list::iterator pit; + std::list postedItems; + std::list::iterator pit; - QLayout *alayout = ui.scrollAreaWidgetContents->layout(); - int count = alayout->count(); - for(int i = 0; i < count; i++) - { - QLayoutItem *litem = alayout->itemAt(i); - if (!litem) - { - std::cerr << "PostedListDialog::clearPosts() missing litem"; - std::cerr << std::endl; - continue; - } + QLayout *alayout = ui.scrollAreaWidgetContents->layout(); + int count = alayout->count(); + for(int i = 0; i < count; i++) + { + QLayoutItem *litem = alayout->itemAt(i); + if (!litem) + { + std::cerr << "PostedListDialog::clearPosts() missing litem"; + std::cerr << std::endl; + continue; + } - PostedItem *item = dynamic_cast(litem->widget()); - if (item) - { - std::cerr << "PostedListDialog::clearPosts() item: " << item; - std::cerr << std::endl; + PostedItem *item = dynamic_cast(litem->widget()); + if (item) + { + std::cerr << "PostedListDialog::clearPosts() item: " << item; + std::cerr << std::endl; - postedItems.push_back(item); - } - else - { - std::cerr << "PostedListDialog::clearPosts() Found Child, which is not a PostedItem???"; - std::cerr << std::endl; - } - } + postedItems.push_back(item); + } + else + { + std::cerr << "PostedListDialog::clearPosts() Found Child, which is not a PostedItem???"; + std::cerr << std::endl; + } + } - for(pit = postedItems.begin(); pit != postedItems.end(); pit++) - { - PostedItem *item = *pit; - alayout->removeWidget(item); - } + for(pit = postedItems.begin(); pit != postedItems.end(); pit++) + { + PostedItem *item = *pit; + alayout->removeWidget(item); + } } void PostedListDialog::updateCurrentDisplayComplete(const uint32_t &token) { - std::cerr << "PostedListDialog::loadGroupThreadData_InsertThreads()"; - std::cerr << std::endl; + std::cerr << "PostedListDialog::loadGroupThreadData_InsertThreads()"; + std::cerr << std::endl; - PostedPostResult result; - rsPosted->getPost(token, result); + std::vector posts; + rsPosted->getPostData(token, posts); + std::vector::iterator vit; + for(vit = posts.begin(); vit != posts.end(); vit++) + { - if(result.find(mCurrTopicId) == result.end()) - return; + RsPostedPost& p = *vit; - std::vector& posts = result[mCurrTopicId]; - std::vector::iterator vit = posts.begin(); - - for(; vit != posts.end(); vit++) - { - - RsPostedPost& p = *vit; - - // modify post content - if(mPosts.find(p.mMeta.mMsgId) != mPosts.end()) - mPosts[p.mMeta.mMsgId]->setContent(p); - - } + // modify post content + if(mPosts.find(p.mMeta.mMsgId) != mPosts.end()) + mPosts[p.mMeta.mMsgId]->setContent(p); + } } /*********************** **** **** **** ***********************/ @@ -623,88 +625,88 @@ void PostedListDialog::loadRequest(const TokenQueue *queue, const TokenRequest & std::cerr << std::endl; if (queue == mPostedQueue) - { - /* now switch on req */ - switch(req.mUserType) + { + /* now switch on req */ + switch(req.mUserType) { - case TOKEN_USER_TYPE_TOPIC: - switch(req.mAnsType) - { - case RS_TOKREQ_ANSTYPE_SUMMARY: - loadGroupSummary(req.mToken); - break; - default: - std::cerr << "Error, unexpected anstype:" << req.mAnsType << std::endl; - break; - } - break; - case TOKEN_USER_TYPE_POST: - switch(req.mAnsType) - { - case RS_TOKREQ_ANSTYPE_ACK: - acknowledgePostMsg(req.mToken); - break; - case RS_TOKREQ_ANSTYPE_DATA: - loadPostData(req.mToken); - break; - default: - std::cerr << "Error, unexpected anstype:" << req.mAnsType << std::endl; - break; - } - break; - case TOKEN_USER_TYPE_VOTE: - switch(req.mAnsType) - { - case RS_TOKREQ_ANSTYPE_ACK: - acknowledgeVoteMsg(req.mToken); - break; - default: - std::cerr << "Error, unexpected anstype:" << req.mAnsType << std::endl; - break; - } - break; - case TOKEN_USER_TYPE_POST_MOD: - switch(req.mAnsType) - { - case RS_TOKREQ_ANSTYPE_DATA: - updateCurrentDisplayComplete(req.mToken); - break; - default: - std::cerr << "Error, unexpected anstype:" << req.mAnsType << std::endl; - break; - } - break; - case TOKEN_USER_TYPE_POST_RANKINGS: - switch(req.mAnsType) - { - case RS_TOKREQ_ANSTYPE_DATA: - loadRankings(req.mToken); - break; - default: - std::cerr << "Error, unexpected anstype:" << req.mAnsType << std::endl; - break; - } - break; - default: - std::cerr << "PostedListDialog::loadRequest() ERROR: INVALID TYPE"; - std::cerr << std::endl; - break; + case TOKEN_USER_TYPE_TOPIC: + switch(req.mAnsType) + { + case RS_TOKREQ_ANSTYPE_SUMMARY: + loadGroupSummary(req.mToken); + break; + default: + std::cerr << "Error, unexpected anstype:" << req.mAnsType << std::endl; + break; + } + break; + case TOKEN_USER_TYPE_POST: + switch(req.mAnsType) + { + case RS_TOKREQ_ANSTYPE_ACK: + acknowledgePostMsg(req.mToken); + break; + case RS_TOKREQ_ANSTYPE_DATA: + loadPostData(req.mToken); + break; + default: + std::cerr << "Error, unexpected anstype:" << req.mAnsType << std::endl; + break; + } + break; + case TOKEN_USER_TYPE_VOTE: + switch(req.mAnsType) + { + case RS_TOKREQ_ANSTYPE_ACK: + acknowledgeVoteMsg(req.mToken); + break; + default: + std::cerr << "Error, unexpected anstype:" << req.mAnsType << std::endl; + break; + } + break; + case TOKEN_USER_TYPE_POST_MOD: + switch(req.mAnsType) + { + case RS_TOKREQ_ANSTYPE_DATA: + updateCurrentDisplayComplete(req.mToken); + break; + default: + std::cerr << "Error, unexpected anstype:" << req.mAnsType << std::endl; + break; + } + break; + case TOKEN_USER_TYPE_POST_RANKINGS: + switch(req.mAnsType) + { + case RS_TOKREQ_ANSTYPE_DATA: + //loadRankings(req.mToken); + break; + default: + std::cerr << "Error, unexpected anstype:" << req.mAnsType << std::endl; + break; + } + break; + default: + std::cerr << "PostedListDialog::loadRequest() ERROR: INVALID TYPE"; + std::cerr << std::endl; + break; } } - /* now switch on req */ - switch(req.mType) - { - case TOKENREQ_GROUPINFO: - switch(req.mAnsType) - { - case RS_TOKREQ_ANSTYPE_ACK: - acknowledgeGroup(req.mToken); - break; - } - break; - } + /* now switch on req */ + switch(req.mType) + { + case TOKENREQ_GROUPINFO: + switch(req.mAnsType) + { + case RS_TOKREQ_ANSTYPE_ACK: + acknowledgeGroup(req.mToken); + break; + } + break; + } } @@ -717,11 +719,11 @@ void PostedListDialog::loadRequest(const TokenQueue *queue, const TokenRequest & void PostedListDialog::groupInfoToGroupItemInfo(const RsGroupMetaData &groupInfo, GroupItemInfo &groupItemInfo) { - groupItemInfo.id = QString::fromStdString(groupInfo.mGroupId); - groupItemInfo.name = QString::fromUtf8(groupInfo.mGroupName.c_str()); - //groupItemInfo.description = QString::fromUtf8(groupInfo.forumDesc); - groupItemInfo.popularity = groupInfo.mPop; - groupItemInfo.lastpost = QDateTime::fromTime_t(groupInfo.mLastPost); + groupItemInfo.id = QString::fromStdString(groupInfo.mGroupId); + groupItemInfo.name = QString::fromUtf8(groupInfo.mGroupName.c_str()); + //groupItemInfo.description = QString::fromUtf8(groupInfo.forumDesc); + groupItemInfo.popularity = groupInfo.mPop; + groupItemInfo.lastpost = QDateTime::fromTime_t(groupInfo.mLastPost); } @@ -729,60 +731,60 @@ void PostedListDialog::groupInfoToGroupItemInfo(const RsGroupMetaData &groupInfo void PostedListDialog::insertGroupData(const std::list &groupList) { - std::list::const_iterator it; + std::list::const_iterator it; - QList adminList; - QList subList; - QList popList; - QList otherList; - std::multimap popMap; + QList adminList; + QList subList; + QList popList; + QList otherList; + std::multimap popMap; - for (it = groupList.begin(); it != groupList.end(); it++) { - /* sort it into Publish (Own), Subscribed, Popular and Other */ - uint32_t flags = it->mSubscribeFlags; + for (it = groupList.begin(); it != groupList.end(); it++) { + /* sort it into Publish (Own), Subscribed, Popular and Other */ + uint32_t flags = it->mSubscribeFlags; - GroupItemInfo groupItemInfo; - groupInfoToGroupItemInfo(*it, groupItemInfo); + GroupItemInfo groupItemInfo; + groupInfoToGroupItemInfo(*it, groupItemInfo); // if (flags & GXS_SERV::GROUP_SUBSCRIBE_ADMIN) { - adminList.push_back(groupItemInfo); + adminList.push_back(groupItemInfo); // } else if (flags & GXS_SERV::GROUP_SUBSCRIBE_SUBSCRIBED) { - /* subscribed forum */ + /* subscribed forum */ // subList.push_back(groupItemInfo); // } else { - /* rate the others by popularity */ -// popMap.insert(std::make_pair(it->mPop, groupItemInfo)); - } -// } + /* rate the others by popularity */ +// popMap.insert(std::make_pair(it->mPop, groupItemInfo)); + } +// } - /* iterate backwards through popMap - take the top 5 or 10% of list */ - uint32_t popCount = 5; - if (popCount < popMap.size() / 10) - { - popCount = popMap.size() / 10; - } + /* iterate backwards through popMap - take the top 5 or 10% of list */ + uint32_t popCount = 5; + if (popCount < popMap.size() / 10) + { + popCount = popMap.size() / 10; + } - uint32_t i = 0; - uint32_t popLimit = 0; - std::multimap::reverse_iterator rit; - for(rit = popMap.rbegin(); ((rit != popMap.rend()) && (i < popCount)); rit++, i++) ; - if (rit != popMap.rend()) { - popLimit = rit->first; - } + uint32_t i = 0; + uint32_t popLimit = 0; + std::multimap::reverse_iterator rit; + for(rit = popMap.rbegin(); ((rit != popMap.rend()) && (i < popCount)); rit++, i++) ; + if (rit != popMap.rend()) { + popLimit = rit->first; + } - for (rit = popMap.rbegin(); rit != popMap.rend(); rit++) { - if (rit->second.popularity < (int) popLimit) { - otherList.append(rit->second); - } else { - popList.append(rit->second); - } - } + for (rit = popMap.rbegin(); rit != popMap.rend(); rit++) { + if (rit->second.popularity < (int) popLimit) { + otherList.append(rit->second); + } else { + popList.append(rit->second); + } + } - /* now we can add them in as a tree! */ - ui.groupTreeWidget->fillGroupItems(yourTopics, adminList); - ui.groupTreeWidget->fillGroupItems(subscribedTopics, subList); - ui.groupTreeWidget->fillGroupItems(popularTopics, popList); - ui.groupTreeWidget->fillGroupItems(otherTopics, otherList); + /* now we can add them in as a tree! */ + ui.groupTreeWidget->fillGroupItems(yourTopics, adminList); + ui.groupTreeWidget->fillGroupItems(subscribedTopics, subList); + ui.groupTreeWidget->fillGroupItems(popularTopics, popList); + ui.groupTreeWidget->fillGroupItems(otherTopics, otherList); } /**************************************************************************************/ diff --git a/retroshare-gui/src/gui/Posted/PostedListDialog.h b/retroshare-gui/src/gui/Posted/PostedListDialog.h index e2554dcd1..fb047bf8c 100644 --- a/retroshare-gui/src/gui/Posted/PostedListDialog.h +++ b/retroshare-gui/src/gui/Posted/PostedListDialog.h @@ -39,8 +39,8 @@ #include "retroshare-gui/RsAutoUpdatePage.h" #include "PostedUserTypes.h" +#include "gui/gxs/GxsCommentContainer.h" -class CommentHolder; /*********************** **** **** **** ***********************/ /** Request / Response of Data ********************************/ @@ -53,12 +53,12 @@ class CommentHolder; #define POSTEDDIALOG_INSERT_POST 5 #define POSTEDDIALOG_REPLY_MESSAGE 6 -class PostedListDialog : public RsAutoUpdatePage, public PostedHolder, public TokenResponse +class PostedListDialog : public RsAutoUpdatePage, public PostedHolder, public TokenResponse, public GxsServiceDialog { Q_OBJECT public: - PostedListDialog(CommentHolder* commentHolder, QWidget *parent = 0); + PostedListDialog(QWidget *parent = 0); void showComments(const RsPostedPost& post); @@ -112,8 +112,8 @@ private: // ranking - void loadRankings(const uint32_t& token); - void applyRanking(const PostedRanking& ranks); + //void loadRankings(const uint32_t& token); + //void applyRanking(const PostedRanking& ranks); // update displayed item @@ -141,7 +141,7 @@ private: QMap mPosts; TokenQueue *mPostedQueue; - CommentHolder* mCommentHolder; + //CommentHolder* mCommentHolder; /* UI - from Designer */ Ui::PostedListDialog ui; diff --git a/retroshare-gui/src/gui/feeds/FeedHolder.h b/retroshare-gui/src/gui/feeds/FeedHolder.h index a5fe28b3b..3823e3430 100644 --- a/retroshare-gui/src/gui/feeds/FeedHolder.h +++ b/retroshare-gui/src/gui/feeds/FeedHolder.h @@ -25,6 +25,8 @@ #include #include +#include // WRONG ONE - BUT IT'LL DO FOR NOW. + class QScrollArea; class FeedHolder @@ -35,6 +37,7 @@ public: virtual QScrollArea *getScrollArea() = 0; virtual void deleteFeedItem(QWidget *item, uint32_t type) = 0; virtual void openChat(std::string peerId) = 0; + virtual void openComments(uint32_t type, const RsGxsGroupId &groupId, const RsGxsMessageId &msgId) = 0; // Workaround for QTBUG-3372 void lockLayout(QWidget *feedItem, bool lock); diff --git a/retroshare-gui/src/gui/feeds/GxsChannelPostItem.cpp b/retroshare-gui/src/gui/feeds/GxsChannelPostItem.cpp new file mode 100644 index 000000000..9aba39c30 --- /dev/null +++ b/retroshare-gui/src/gui/feeds/GxsChannelPostItem.cpp @@ -0,0 +1,663 @@ +/**************************************************************** + * 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 +#include +#include + +#include "rshare.h" +#include "GxsChannelPostItem.h" + +#include "FeedHolder.h" +#include "SubFileItem.h" +#include "gui/notifyqt.h" +#include "util/misc.h" +#include "gui/RetroShareLink.h" +#include "util/HandleRichText.h" +#include "util/DateTime.h" + +#include + +/**** + * #define DEBUG_ITEM 1 + ****/ + +#define COLOR_NORMAL QColor(248, 248, 248) +#define COLOR_NEW QColor(220, 236, 253) + +#define SELF_LOAD 1 +#define DATA_PROVIDED 2 + +/** Constructor */ +GxsChannelPostItem::GxsChannelPostItem(FeedHolder *parent, uint32_t feedId, const std::string &chanId, const std::string &msgId, bool isHome) +:QWidget(NULL), mParent(parent), mFeedId(feedId), + mChanId(chanId), mMsgId(msgId), mIsHome(isHome) +{ + mMode = SELF_LOAD; + mSubscribeFlags = 0; + + setup(); + + // THIS IS JUST SO WE REMEMBER TO DO IT. + updateItemStatic(); + updateItem(); +} + +/** Constructor */ +GxsChannelPostItem::GxsChannelPostItem(FeedHolder *parent, uint32_t feedId, const RsGxsChannelPost &post, uint32_t subFlags, bool isHome) +:QWidget(NULL), mParent(parent), mFeedId(feedId), + mChanId(post.mMeta.mGroupId), mMsgId(post.mMeta.mMsgId), mIsHome(isHome) +{ + mMode = DATA_PROVIDED; + mSubscribeFlags = subFlags; + + setup(); + + loadPost(post); + updateItem(); +} + + +void GxsChannelPostItem::setup() +{ + /* Invoke the Qt Designer generated object setup routine */ + setupUi(this); + + setAttribute ( Qt::WA_DeleteOnClose, true ); + + m_inUpdateItemStatic = false; + + /* general ones */ + connect( expandButton, SIGNAL( clicked( void ) ), this, SLOT( toggle ( void ) ) ); + connect( clearButton, SIGNAL( clicked( void ) ), this, SLOT( removeItem ( void ) ) ); + + /* specific */ + connect(readAndClearButton, SIGNAL(clicked()), this, SLOT(readAndClearItem())); + connect( unsubscribeButton, SIGNAL( clicked( void ) ), this, SLOT( unsubscribeChannel ( void ) ) ); + + //connect( downloadButton, SIGNAL( clicked( void ) ), this, SLOT( download ( void ) ) ); + // HACK FOR NOW. + connect( downloadButton, SIGNAL( clicked( void ) ), this, SLOT( comments ( void ) ) ); + + connect( playButton, SIGNAL( clicked( void ) ), this, SLOT( play ( void ) ) ); + connect( copyLinkButton, SIGNAL( clicked( void ) ), this, SLOT( copyLink ( void ) ) ); + + connect( readButton, SIGNAL( toggled(bool) ), this, SLOT( readToggled(bool) ) ); + connect( NotifyQt::getInstance(), SIGNAL(channelMsgReadSatusChanged(QString,QString,int)), this, SLOT(channelMsgReadSatusChanged(QString,QString,int)), Qt::QueuedConnection); + + downloadButton->hide(); + playButton->hide(); + warn_image_label->hide(); + warning_label->hide(); + + titleLabel->setMinimumWidth(100); + subjectLabel->setMinimumWidth(100); + warning_label->setMinimumWidth(100); + + frame->setProperty("state", ""); + QPalette palette = frame->palette(); + palette.setColor(frame->backgroundRole(), COLOR_NORMAL); + frame->setPalette(palette); + + expandFrame->hide(); +} + + + +void GxsChannelPostItem::updateItemStatic() +{ + /* fill in */ +#ifdef DEBUG_ITEM + std::cerr << "GxsChannelPostItem::updateItemStatic()"; + std::cerr << std::endl; +#endif + + ChannelMsgInfo cmi; + + if (!rsChannels) + return; + + if (!rsChannels->getChannelMessage(mChanId, mMsgId, cmi)) + return; + + m_inUpdateItemStatic = true; + + QString title; + + ChannelInfo ci; + rsChannels->getChannelInfo(mChanId, ci); + + if (!mIsHome) + { + title = tr("Channel Feed") + ": "; + RetroShareLink link; + link.createChannel(ci.channelId, ""); + title += link.toHtml(); + titleLabel->setText(title); + RetroShareLink msgLink; + msgLink.createChannel(cmi.channelId, cmi.msgId); + subjectLabel->setText(msgLink.toHtml()); + + if ((ci.channelFlags & RS_DISTRIB_SUBSCRIBED) || (ci.channelFlags & RS_DISTRIB_ADMIN)) { + unsubscribeButton->setEnabled(true); + } else { + unsubscribeButton->setEnabled(false); + } + readButton->hide(); + newLabel->hide(); + copyLinkButton->hide(); + } + else + { + /* subject */ + titleLabel->setText(QString::fromStdWString(cmi.subject)); + subjectLabel->setText(RsHtml().formatText(NULL, QString::fromStdWString(cmi.msg), RSHTML_FORMATTEXT_EMBED_SMILEYS | RSHTML_FORMATTEXT_EMBED_LINKS)); + + /* disable buttons: deletion facility not enabled with cache services yet */ + clearButton->setEnabled(false); + unsubscribeButton->setEnabled(false); + clearButton->hide(); + readAndClearButton->hide(); + unsubscribeButton->hide(); + copyLinkButton->show(); + + if ((ci.channelFlags & RS_DISTRIB_SUBSCRIBED) || (ci.channelFlags & RS_DISTRIB_ADMIN)) { + readButton->setVisible(true); + + uint32_t status = 0; + rsChannels->getMessageStatus(mChanId, mMsgId, status); + + if ((status & CHANNEL_MSG_STATUS_READ) == 0 || (status & CHANNEL_MSG_STATUS_UNREAD_BY_USER)) { + readButton->setChecked(true); + readButton->setIcon(QIcon(":/images/message-state-unread.png")); + } else { + readButton->setChecked(false); + readButton->setIcon(QIcon(":/images/message-state-read.png")); + } + + bool newState; + QColor color; + if (status & CHANNEL_MSG_STATUS_READ) { + newLabel->setVisible(false); + newState = false; + color = COLOR_NORMAL; + } else { + newLabel->setVisible(true); + newState = true; + color = COLOR_NEW; + } + + /* unpolish widget to clear the stylesheet's palette cache */ + frame->style()->unpolish(frame); + + QPalette palette = frame->palette(); + palette.setColor(frame->backgroundRole(), color); + frame->setPalette(palette); + + frame->setProperty("new", newState); + Rshare::refreshStyleSheet(frame, false); + } else { + readButton->setVisible(false); + newLabel->setVisible(false); + } + } + + msgLabel->setText(RsHtml().formatText(NULL, QString::fromStdWString(cmi.msg), RSHTML_FORMATTEXT_EMBED_SMILEYS | RSHTML_FORMATTEXT_EMBED_LINKS)); + msgFrame->setVisible(!cmi.msg.empty()); + + datetimelabel->setText(DateTime::formatLongDateTime(cmi.ts)); + + filelabel->setText(QString("(%1 %2) %3").arg(cmi.count).arg(tr("Files")).arg(misc::friendlyUnit(cmi.size))); + + if (mFileItems.empty() == false) { + std::list::iterator it; + for(it = mFileItems.begin(); it != mFileItems.end(); it++) + { + delete(*it); + } + mFileItems.clear(); + } + + std::list::iterator it; + for(it = cmi.files.begin(); it != cmi.files.end(); it++) + { + /* add file */ + SubFileItem *fi = new SubFileItem(it->hash, it->fname, it->path, it->size, + SFI_STATE_REMOTE | SFI_TYPE_CHANNEL, ""); + mFileItems.push_back(fi); + + /* check if the file is a media file */ + if (!misc::isPreviewable(QFileInfo(QString::fromUtf8(it->fname.c_str())).suffix())) + fi->mediatype(); + + + QLayout *layout = expandFrame->layout(); + layout->addWidget(fi); + } + + if(cmi.thumbnail.image_thumbnail != NULL) + { + QPixmap thumbnail; + thumbnail.loadFromData(cmi.thumbnail.image_thumbnail, cmi.thumbnail.im_thumbnail_size, "PNG"); + + logoLabel->setPixmap(thumbnail); + } + + m_inUpdateItemStatic = false; +} + + + + + +void GxsChannelPostItem::loadPost(const RsGxsChannelPost &post) +{ + /* fill in */ +#ifdef DEBUG_ITEM + std::cerr << "GxsChannelPostItem::loadPost()"; + std::cerr << std::endl; +#endif + + QString title; + + if (!mIsHome) + { + title = tr("Channel Feed") + ": "; + RetroShareLink link; + link.createChannel(post.mMeta.mGroupId, ""); + title += link.toHtml(); + titleLabel->setText(title); + RetroShareLink msgLink; + msgLink.createChannel(post.mMeta.mGroupId, post.mMeta.mMsgId); + subjectLabel->setText(msgLink.toHtml()); + + if (IS_GROUP_SUBSCRIBED(mSubscribeFlags) || IS_GROUP_ADMIN(mSubscribeFlags)) + { + unsubscribeButton->setEnabled(true); + } + else + { + unsubscribeButton->setEnabled(false); + } + readButton->hide(); + newLabel->hide(); + copyLinkButton->hide(); + } + else + { + /* subject */ + titleLabel->setText(QString::fromUtf8(post.mMeta.mMsgName.c_str())); + subjectLabel->setText(RsHtml().formatText(NULL, QString::fromUtf8(post.mMsg.c_str()), RSHTML_FORMATTEXT_EMBED_SMILEYS | RSHTML_FORMATTEXT_EMBED_LINKS)); + + /* disable buttons: deletion facility not enabled with cache services yet */ + clearButton->setEnabled(false); + unsubscribeButton->setEnabled(false); + clearButton->hide(); + readAndClearButton->hide(); + unsubscribeButton->hide(); + copyLinkButton->show(); + + if (IS_GROUP_SUBSCRIBED(mSubscribeFlags) || IS_GROUP_ADMIN(mSubscribeFlags)) + { + + readButton->setVisible(true); + + uint32_t status = 0; + rsChannels->getMessageStatus(mChanId, mMsgId, status); + + if (IS_MSG_UNREAD(post.mMeta.mMsgStatus) || IS_MSG_NEW(post.mMeta.mMsgStatus)) + { + readButton->setChecked(true); + readButton->setIcon(QIcon(":/images/message-state-unread.png")); + } + else + { + readButton->setChecked(false); + readButton->setIcon(QIcon(":/images/message-state-read.png")); + } + + bool newState; + QColor color; + if (!IS_MSG_UNREAD(post.mMeta.mMsgStatus)) + { + newLabel->setVisible(false); + newState = false; + color = COLOR_NORMAL; + } + else + { + newLabel->setVisible(true); + newState = true; + color = COLOR_NEW; + } + + /* unpolish widget to clear the stylesheet's palette cache */ + frame->style()->unpolish(frame); + + QPalette palette = frame->palette(); + palette.setColor(frame->backgroundRole(), color); + frame->setPalette(palette); + + frame->setProperty("new", newState); + Rshare::refreshStyleSheet(frame, false); + } + else + { + readButton->setVisible(false); + newLabel->setVisible(false); + } + } + + msgLabel->setText(RsHtml().formatText(NULL, QString::fromUtf8(post.mMsg.c_str()), RSHTML_FORMATTEXT_EMBED_SMILEYS | RSHTML_FORMATTEXT_EMBED_LINKS)); + msgFrame->setVisible(!post.mMsg.empty()); + + datetimelabel->setText(DateTime::formatLongDateTime(post.mMeta.mPublishTs)); + + filelabel->setText(QString("(%1 %2) %3").arg(post.mCount).arg(tr("Files")).arg(misc::friendlyUnit(post.mSize))); + + if (mFileItems.empty() == false) { + std::list::iterator it; + for(it = mFileItems.begin(); it != mFileItems.end(); it++) + { + delete(*it); + } + mFileItems.clear(); + } + +#if 0 + std::list::iterator it; + for(it = cmi.files.begin(); it != cmi.files.end(); it++) + { + /* add file */ + SubFileItem *fi = new SubFileItem(it->hash, it->fname, it->path, it->size, + SFI_STATE_REMOTE | SFI_TYPE_CHANNEL, ""); + mFileItems.push_back(fi); + + /* check if the file is a media file */ + if (!misc::isPreviewable(QFileInfo(QString::fromUtf8(it->fname.c_str())).suffix())) + fi->mediatype(); + + + QLayout *layout = expandFrame->layout(); + layout->addWidget(fi); + } + + if(cmi.thumbnail.image_thumbnail != NULL) + { + QPixmap thumbnail; + thumbnail.loadFromData(cmi.thumbnail.image_thumbnail, cmi.thumbnail.im_thumbnail_size, "PNG"); + + logoLabel->setPixmap(thumbnail); + } +#endif + +} + +void GxsChannelPostItem::setFileCleanUpWarning(uint32_t time_left) +{ + int hours = (int)time_left/3600; + int minutes = (time_left - hours*3600)%60; + + warning_label->setText(tr("Warning! You have less than %1 hours and %2 minute before this file is deleted Consider saving it.").arg( + QString::number(hours)).arg(QString::number(minutes))); + + QFont warnFont = warning_label->font(); + warnFont.setBold(true); + warning_label->setFont(warnFont); + + warn_image_label->setVisible(true); + warning_label->setVisible(true); + return; + +} + +void GxsChannelPostItem::updateItem() +{ + /* fill in */ +#ifdef DEBUG_ITEM + std::cerr << "GxsChannelPostItem::updateItem()"; + std::cerr << std::endl; +#endif + int msec_rate = 10000; + + int downloadCount = 0; + int downloadStartable = 0; + int playCount = 0; + int playStartable = 0; + bool startable; + bool loopAgain = false; + + /* Very slow Tick to check when all files are downloaded */ + std::list::iterator it; + for(it = mFileItems.begin(); it != mFileItems.end(); it++) + { + SubFileItem *item = *it; + + if (item->isDownloadable(startable)) { + downloadCount++; + if (startable) { + downloadStartable++; + } + } + if (item->isPlayable(startable)) { + playCount++; + if (startable) { + playStartable++; + } + } + + if (!item->done()) + { + /* loop again */ + loopAgain = true; + } + } + + if (downloadCount) { + downloadButton->show(); + + if (downloadStartable) { + downloadButton->setEnabled(true); + } else { + downloadButton->setEnabled(false); + } + } else { + downloadButton->hide(); + } + if (playCount) { + /* one file is playable */ + playButton->show(); + + if (playStartable == 1) { + playButton->setEnabled(true); + } else { + playButton->setEnabled(false); + } + } else { + playButton->hide(); + } + + if (loopAgain) { + QTimer::singleShot( msec_rate, this, SLOT(updateItem( void ) )); + } + + // HACK TO DISPLAY COMMENT BUTTON FOR NOW. + downloadButton->show(); + downloadButton->setEnabled(true); +} + +void GxsChannelPostItem::toggle() +{ + mParent->lockLayout(this, true); + + if (expandFrame->isHidden()) + { + expandFrame->show(); + expandButton->setIcon(QIcon(QString(":/images/edit_remove24.png"))); + expandButton->setToolTip(tr("Hide")); + + readToggled(false); + } + else + { + expandFrame->hide(); + expandButton->setIcon(QIcon(QString(":/images/edit_add24.png"))); + expandButton->setToolTip(tr("Expand")); + } + + mParent->lockLayout(this, false); +} + +void GxsChannelPostItem::removeItem() +{ +#ifdef DEBUG_ITEM + std::cerr << "GxsChannelPostItem::removeItem()"; + std::cerr << std::endl; +#endif + + mParent->lockLayout(this, true); + hide(); + mParent->lockLayout(this, false); + + if (mParent) + { + mParent->deleteFeedItem(this, mFeedId); + } +} + + +void GxsChannelPostItem::comments() +{ +#ifdef DEBUG_ITEM + std::cerr << "GxsChannelPostItem::comments()"; + std::cerr << std::endl; +#endif + + if (mParent) + { + mParent->openComments(mFeedId, mChanId, mMsgId); + } +} + +/*********** SPECIFIC FUNCTIONS ***********************/ + +void GxsChannelPostItem::readAndClearItem() +{ +#ifdef DEBUG_ITEM + std::cerr << "GxsChannelPostItem::readAndClearItem()"; + std::cerr << std::endl; +#endif + + readToggled(false); + removeItem(); +} + +void GxsChannelPostItem::unsubscribeChannel() +{ +#ifdef DEBUG_ITEM + std::cerr << "GxsChannelPostItem::unsubscribeChannel()"; + std::cerr << std::endl; +#endif + + if (rsChannels) + { + rsChannels->channelSubscribe(mChanId, false, false); + } + updateItemStatic(); +} + +void GxsChannelPostItem::download() +{ + std::list::iterator it; + for(it = mFileItems.begin(); it != mFileItems.end(); it++) + { + (*it)->download(); + } + + updateItem(); +} + +void GxsChannelPostItem::play() +{ + std::list::iterator it; + for(it = mFileItems.begin(); it != mFileItems.end(); it++) + { + bool startable; + if ((*it)->isPlayable(startable) && startable) { + (*it)->play(); + } + } +} + +void GxsChannelPostItem::readToggled(bool checked) +{ + if (m_inUpdateItemStatic) { + return; + } + + /* set always as read ... */ + uint32_t statusNew = CHANNEL_MSG_STATUS_READ; + if (checked) { + /* ... and as unread by user */ + statusNew |= CHANNEL_MSG_STATUS_UNREAD_BY_USER; + } else { + /* ... and as read by user */ + statusNew &= ~CHANNEL_MSG_STATUS_UNREAD_BY_USER; + } + + if (!mIsHome) { + disconnect( NotifyQt::getInstance(), SIGNAL(channelMsgReadSatusChanged(QString,QString,int)), this, SLOT(channelMsgReadSatusChanged(QString,QString,int))); + } + rsChannels->setMessageStatus(mChanId, mMsgId, statusNew, CHANNEL_MSG_STATUS_READ | CHANNEL_MSG_STATUS_UNREAD_BY_USER); + if (!mIsHome) { + connect( NotifyQt::getInstance(), SIGNAL(channelMsgReadSatusChanged(QString,QString,int)), this, SLOT(channelMsgReadSatusChanged(QString,QString,int)), Qt::QueuedConnection); + } +} + +void GxsChannelPostItem::channelMsgReadSatusChanged(const QString& channelId, const QString& msgId, int status) +{ + if (channelId.toStdString() == mChanId && msgId.toStdString() == mMsgId) { + if (!mIsHome) { + if (status & CHANNEL_MSG_STATUS_READ) { + close(); + return; + } + } + updateItemStatic(); + } +} + +void GxsChannelPostItem::copyLink() +{ + if (mChanId.empty() || mMsgId.empty()) { + return; + } + + ChannelMsgInfo cmi; + if (rsChannels->getChannelMessage(mChanId, mMsgId, cmi)) { + RetroShareLink link; + if (link.createChannel(cmi.channelId, cmi.msgId)) { + QList urls; + urls.push_back(link); + RSLinkClipboard::copyLinks(urls); + } + } +} diff --git a/retroshare-gui/src/gui/feeds/GxsChannelPostItem.h b/retroshare-gui/src/gui/feeds/GxsChannelPostItem.h new file mode 100644 index 000000000..6ede57f06 --- /dev/null +++ b/retroshare-gui/src/gui/feeds/GxsChannelPostItem.h @@ -0,0 +1,83 @@ +/**************************************************************** + * 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 _GXS_CHANNEL_POST_ITEM_H +#define _GXS_CHANNEL_POST_ITEM_H + +#include +#include "ui_GxsChannelPostItem.h" +#include + +class FeedHolder; +class SubFileItem; + +class GxsChannelPostItem : public QWidget, private Ui::GxsChannelPostItem +{ + Q_OBJECT + +public: + /** Default Constructor */ + GxsChannelPostItem(FeedHolder *parent, uint32_t feedId, const std::string &chanId, const std::string &msgId, bool isHome); + GxsChannelPostItem(FeedHolder *parent, uint32_t feedId, const RsGxsChannelPost &post, uint32_t subscribeFlags, bool isHome); + void updateItemStatic(); + void setFileCleanUpWarning(uint32_t time_left); + + const std::string &msgId() { return mMsgId; } + +private slots: + /* default stuff */ + void removeItem(); + void toggle(); + + void readAndClearItem(); + void unsubscribeChannel(); + void download(); + void play(); + void copyLink(); + void comments(); + + void readToggled(bool checked); + void channelMsgReadSatusChanged(const QString& channelId, const QString& msgId, int status); + + void updateItem(); + +private: + void setup(); + void loadPost(const RsGxsChannelPost &post); + + + FeedHolder *mParent; + uint32_t mFeedId; + + std::string mChanId; + std::string mMsgId; + + bool mIsHome; + bool m_inUpdateItemStatic; + + uint32_t mMode; + uint32_t mSubscribeFlags; + + std::list mFileItems; +}; + +#endif + diff --git a/retroshare-gui/src/gui/feeds/GxsChannelPostItem.ui b/retroshare-gui/src/gui/feeds/GxsChannelPostItem.ui new file mode 100644 index 000000000..2feb080ba --- /dev/null +++ b/retroshare-gui/src/gui/feeds/GxsChannelPostItem.ui @@ -0,0 +1,481 @@ + + + GxsChannelPostItem + + + + 0 + 0 + 629 + 172 + + + + + 6 + + + 1 + + + 1 + + + + + + 0 + 0 + + + + true + + + QFrame::Box + + + QFrame::Sunken + + + + + + + + + 156 + 107 + + + + + + + :/images/thumb-default-video.png + + + true + + + + + + + + + + + + 0 + 0 + + + + + 11 + 75 + true + true + PreferAntialias + + + + <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> +<html><head><meta name="qrichtext" content="1" /><style type="text/css"> +p, li { white-space: pre-wrap; } +</style></head><body style=" font-family:'MS Shell Dlg 2'; font-size:11pt; font-weight:600; font-style:italic;"> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-style:normal; color:#656565;">Channel Subject</span></p></body></html> + + + false + + + true + + + + + + + + 75 + true + PreferAntialias + + + + <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> +<html><head><meta name="qrichtext" content="1" /><style type="text/css"> +p, li { white-space: pre-wrap; } +</style></head><body style=" font-family:'MS Shell Dlg 2'; font-size:8.25pt; font-weight:600; font-style:normal;"> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:8pt; color:#666666;">DateTime</span></p></body></html> + + + + + + + + + + + + 0 + 0 + + + + + 16777215 + 60 + + + + <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> +<html><head><meta name="qrichtext" content="1" /><style type="text/css"> +p, li { white-space: pre-wrap; } +</style></head><body style=" font-family:'MS Shell Dlg 2'; font-size:8.25pt; font-weight:400; font-style:normal;"> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:8pt; color:#666666;">Short Description</span></p></body></html> + + + true + + + true + + + + + + + + PreferAntialias + + + + fileLabel + + + Qt::AlignRight|Qt::AlignTop|Qt::AlignTrailing + + + + + + + + + + + + 24 + 16777215 + + + + + + + :/images/status_unknown.png + + + + + + + TextLabel + + + + + + + + + 8 + + + + + + 24 + 16777215 + + + + Qt::NoFocus + + + Toggle Message Read Status + + + + :/images/message-state-unread.png:/images/message-state-unread.png + + + true + + + false + + + false + + + + + + + + 16777215 + 21 + + + + New + + + + + + + + + + Qt::NoFocus + + + Download + + + + :/images/download16.png:/images/download16.png + + + + + + + + + + Qt::NoFocus + + + Play + + + + :/images/player_play.png:/images/player_play.png + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + 0 + 0 + + + + + 24 + 16777215 + + + + Qt::NoFocus + + + Copy RetroShare Link + + + + :/images/copyrslink.png:/images/copyrslink.png + + + + + + + + 0 + 0 + + + + + 24 + 16777215 + + + + Qt::NoFocus + + + Unsubscribe From Channel + + + + :/images/mail_delete.png:/images/mail_delete.png + + + + + + + + 0 + 0 + + + + + 24 + 16777215 + + + + Qt::NoFocus + + + Expand + + + + :/images/edit_add24.png:/images/edit_add24.png + + + + + + + + 0 + 0 + + + + + 24 + 16777215 + + + + Qt::NoFocus + + + Set as read and remove item + + + + :/images/cancel.png:/images/cancel.png + + + + + + + + 0 + 0 + + + + + 24 + 16777215 + + + + Qt::NoFocus + + + Remove Item + + + + :/images/close_normal.png:/images/close_normal.png + + + + + + + + + + + + + + 0 + + + + + QFrame::Box + + + QFrame::Sunken + + + + 5 + + + + + + 0 + 0 + + + + true + + + 6 + + + -1 + + + true + + + Qt::LinksAccessibleByMouse|Qt::TextSelectableByKeyboard|Qt::TextSelectableByMouse + + + + + + + + + + + + + + + + + + + diff --git a/retroshare-gui/src/gui/gxs/GxsCommentContainer.cpp b/retroshare-gui/src/gui/gxs/GxsCommentContainer.cpp new file mode 100644 index 000000000..777ba4c9d --- /dev/null +++ b/retroshare-gui/src/gui/gxs/GxsCommentContainer.cpp @@ -0,0 +1,91 @@ +/* + * Retroshare Posted List + * + * Copyright 2012-2012 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 "gui/gxs/GxsCommentContainer.h" +#include "gui/gxs/GxsCommentDialog.h" + +#include +#include + +#include +#include + +/****** + * #define PHOTO_DEBUG 1 + *****/ + + +/**************************************************************** + * Posted Dialog + * + */ + +GxsCommentContainer::GxsCommentContainer(QWidget *parent) +: MainPage(parent) +{ + ui.setupUi(this); +} + + +void GxsCommentContainer::setup() +{ + mServiceDialog = createServiceDialog(); + QString name = getServiceName(); + + QString list(name); + QWidget *widget = dynamic_cast(mServiceDialog); + ui.tabWidget->addTab(widget, name); +} + + +void GxsCommentContainer::commentLoad(const RsGxsGroupId &grpId, const RsGxsMessageId &msgId) +{ + QString comments(tr("Comments")); + GxsCommentDialog *commentDialog = new GxsCommentDialog(this, getTokenService(), getCommentService()); + + GxsCommentHeader *commentHeader = createHeaderWidget(); + commentDialog->setCommentHeader(commentHeader); + + commentDialog->commentLoad(grpId, msgId); + //commentHeader->commentLoad(grpId, msgId); + + ui.tabWidget->addTab(commentDialog, comments); +} + + + + + + + + + + + + + + + + + + diff --git a/retroshare-gui/src/gui/gxs/GxsCommentContainer.h b/retroshare-gui/src/gui/gxs/GxsCommentContainer.h new file mode 100644 index 000000000..56af66e47 --- /dev/null +++ b/retroshare-gui/src/gui/gxs/GxsCommentContainer.h @@ -0,0 +1,97 @@ +/* + * Retroshare Comment Container Dialog + * + * Copyright 2012-2012 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 MRK_COMMENT_CONTAINER_DIALOG_H +#define MRK_COMMENT_CONTAINER_DIALOG_H + +#include "retroshare-gui/mainpage.h" +#include "ui_GxsCommentContainer.h" + +#include +#include + +#include + +class GxsCommentHeader +{ +public: + + /*! + * This should be used for loading comments of a message on a main comment viewing page + * @param msgId the message id for which comments will be requested + */ + virtual void commentLoad(const RsGxsGroupId &grpId, const RsGxsMessageId &msgId) = 0; +}; + +class GxsServiceDialog; + + +class GxsCommentContainer : public MainPage +{ + Q_OBJECT + +public: + GxsCommentContainer(QWidget *parent = 0); + void setup(); + + void commentLoad(const RsGxsGroupId &grpId, const RsGxsMessageId &msgId); + + virtual GxsServiceDialog *createServiceDialog() = 0; + virtual QString getServiceName() = 0; + virtual RsTokenService *getTokenService() = 0; + virtual RsGxsCommentService *getCommentService() = 0; + virtual GxsCommentHeader *createHeaderWidget() = 0; + +private: + + GxsServiceDialog *mServiceDialog; + + /* UI - from Designer */ + Ui::GxsCommentContainer ui; + +}; + + + +class GxsServiceDialog +{ + +public: + GxsServiceDialog(GxsCommentContainer *container) + :mContainer(container) { return; } + +virtual ~GxsServiceDialog() { return; } + + void commentLoad(const RsGxsGroupId &grpId, const RsGxsMessageId &msgId) + { + mContainer->commentLoad(grpId, msgId); + } +private: + GxsCommentContainer *mContainer; + +}; + + + +#endif + diff --git a/retroshare-gui/src/gui/gxs/GxsCommentContainer.ui b/retroshare-gui/src/gui/gxs/GxsCommentContainer.ui new file mode 100644 index 000000000..a270afa44 --- /dev/null +++ b/retroshare-gui/src/gui/gxs/GxsCommentContainer.ui @@ -0,0 +1,88 @@ + + + GxsCommentContainer + + + + 0 + 0 + 726 + 557 + + + + + 1 + + + + + QFrame::StyledPanel + + + QFrame::Raised + + + + 2 + + + + + + 24 + 24 + + + + + + + :/images/posted_24.png + + + + + + + + 10 + 75 + true + + + + Comment Container + + + + + + + Qt::Horizontal + + + + 573 + 20 + + + + + + + + + + + -1 + + + + + + + + + + diff --git a/retroshare-gui/src/gui/gxs/GxsCommentDialog.cpp b/retroshare-gui/src/gui/gxs/GxsCommentDialog.cpp new file mode 100644 index 000000000..2a9537eeb --- /dev/null +++ b/retroshare-gui/src/gui/gxs/GxsCommentDialog.cpp @@ -0,0 +1,90 @@ +/* + * Retroshare Comment Dialog + * + * Copyright 2012-2012 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 "gui/gxs/GxsCommentDialog.h" + +//#include "gxs/GxsCreateComment.h" +//#include + + +#include +#include + +#include +#include +#include + + + +/** Constructor */ +GxsCommentDialog::GxsCommentDialog(QWidget *parent, RsTokenService *token_service, RsGxsCommentService *comment_service) +:QWidget(parent) +{ + ui.setupUi(this); + //ui.postFrame->setVisible(false); + + ui.treeWidget->setup(token_service, comment_service); +} + +void GxsCommentDialog::commentLoad(const RsGxsGroupId &grpId, const RsGxsMessageId &msgId) +{ + std::cerr << "GxsCommentDialog::commentLoad(" << grpId << ", " << msgId << ")"; + std::cerr << std::endl; + + mGrpId = grpId; + mMsgId = msgId; + + RsGxsGrpMsgIdPair threadId; + + threadId.first = grpId; + threadId.second = msgId; + + ui.treeWidget->requestComments(threadId); +} + + +void GxsCommentDialog::setCommentHeader(GxsCommentHeader *header) +{ + +#if 0 + ui.postFrame->setVisible(true); + + QDateTime qtime; + qtime.setTime_t(mCurrentPost.mMeta.mPublishTs); + QString timestamp = qtime.toString("dd.MMMM yyyy hh:mm"); + ui.dateLabel->setText(timestamp); + ui.fromLabel->setText(QString::fromUtf8(mCurrentPost.mMeta.mAuthorId.c_str())); + ui.titleLabel->setText("" + + QString::fromStdString(mCurrentPost.mMeta.mMsgName) + ""); + ui.siteLabel->setText("" + + QString::fromStdString(mCurrentPost.mLink) + ""); + + ui.scoreLabel->setText(QString("0")); + + ui.notesBrowser->setPlainText(QString::fromStdString(mCurrentPost.mNotes)); +#endif + +} + diff --git a/retroshare-gui/src/gui/gxs/GxsCommentDialog.h b/retroshare-gui/src/gui/gxs/GxsCommentDialog.h new file mode 100644 index 000000000..5f653bde9 --- /dev/null +++ b/retroshare-gui/src/gui/gxs/GxsCommentDialog.h @@ -0,0 +1,51 @@ +/* + * Retroshare Comment Dialog + * + * Copyright 2012-2012 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 MRK_GXS_COMMENT_DIALOG_H +#define MRK_GXS_COMMENT_DIALOG_H + +#include "ui_GxsCommentDialog.h" +#include "gui/gxs/GxsCommentContainer.h" + + +class GxsCommentDialog: public QWidget +{ + Q_OBJECT + +public: + GxsCommentDialog(QWidget *parent, RsTokenService *token_service, RsGxsCommentService *comment_service); + + void setCommentHeader(GxsCommentHeader *header); + void commentLoad(const RsGxsGroupId &grpId, const RsGxsMessageId &msgId); + +private: + + RsGxsGroupId mGrpId; + RsGxsMessageId mMsgId; + + /* UI - from Designer */ + Ui::GxsCommentDialog ui; +}; + +#endif + diff --git a/retroshare-gui/src/gui/gxs/GxsCommentDialog.ui b/retroshare-gui/src/gui/gxs/GxsCommentDialog.ui new file mode 100644 index 000000000..f11ffaf81 --- /dev/null +++ b/retroshare-gui/src/gui/gxs/GxsCommentDialog.ui @@ -0,0 +1,367 @@ + + + GxsCommentDialog + + + + 0 + 0 + 632 + 398 + + + + Form + + + + + + + 0 + 0 + + + + background-color: rgb(203, 203, 203); + + + QFrame::StyledPanel + + + QFrame::Raised + + + + + + + + + 20 + + + + 1 + + + + + + + + + /\ + + + + + + + score + + + + + + + \/ + + + + + + + + + + 0 + 0 + + + + + 12 + 75 + true + + + + Title this is a very very very very loooooooooooooooonnnnnnnnnnnnnnnnng title dont you think? yes it is and should wrap around I hope + + + true + + + true + + + + + + + + + + + + + + 0 + 0 + + + + + 9 + 75 + true + + + + Date + + + + + + + + 0 + 0 + + + + + 9 + + + + You eyes only + + + true + + + + + + + + + + + + 0 + 0 + + + + + 9 + 75 + true + + + + From + + + + + + + + 0 + 0 + + + + + 9 + + + + Signed by + + + true + + + + + + + + + + + + 0 + 0 + + + + + 9 + 75 + true + + + + Site + + + + + + + + 0 + 0 + + + + + 9 + + + + Signed by + + + true + + + + + + + + + + + + + + background-color: rgb(203, 203, 203); + + + + + + + + + false + + + + 6 + + + 0 + + + + + Hot + + + true + + + true + + + + + + + New + + + true + + + true + + + + + + + Top + + + true + + + false + + + true + + + + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + Refresh + + + + + + + + + + Comment + + + + + Author + + + + + Date + + + + + Points + + + + + + + + + GxsCommentTreeWidget + QTreeWidget +
gui/gxs/GxsCommentTreeWidget.h
+
+
+ + +
diff --git a/retroshare-gui/src/gui/gxs/GxsCommentTreeWidget.cpp b/retroshare-gui/src/gui/gxs/GxsCommentTreeWidget.cpp index 5332e57e6..ee6a70771 100644 --- a/retroshare-gui/src/gui/gxs/GxsCommentTreeWidget.cpp +++ b/retroshare-gui/src/gui/gxs/GxsCommentTreeWidget.cpp @@ -24,7 +24,7 @@ #include #include "gui/gxs/GxsCommentTreeWidget.h" -#include "gui/Posted/PostedCreateCommentDialog.h" +#include "gui/gxs/GxsCreateCommentDialog.h" #include @@ -37,14 +37,12 @@ #define GXSCOMMENTS_LOADTHREAD 1 -// Temporarily make this specific. -#include "retroshare/rsposted.h" /* Images for context menu icons */ #define IMAGE_MESSAGE ":/images/folder-draft.png" GxsCommentTreeWidget::GxsCommentTreeWidget(QWidget *parent) - :QTreeWidget(parent), mRsService(NULL), mTokenQueue(NULL) + :QTreeWidget(parent), mRsTokenService(NULL), mCommentService(NULL), mTokenQueue(NULL) { // QTreeWidget* widget = this; @@ -88,7 +86,7 @@ void GxsCommentTreeWidget::customPopUpMenu(const QPoint& point) void GxsCommentTreeWidget::makeComment() { - PostedCreateCommentDialog pcc(mTokenQueue, mThreadId, mThreadId.second, this); + GxsCreateCommentDialog pcc(mTokenQueue, mCommentService, mThreadId, mThreadId.second, this); pcc.exec(); } @@ -97,14 +95,15 @@ void GxsCommentTreeWidget::replyToComment() RsGxsGrpMsgIdPair msgId; msgId.first = mThreadId.first; msgId.second = mCurrentMsgId; - PostedCreateCommentDialog pcc(mTokenQueue, msgId, mThreadId.second, this); + GxsCreateCommentDialog pcc(mTokenQueue, mCommentService, msgId, mThreadId.second, this); pcc.exec(); } -void GxsCommentTreeWidget::setup(RsTokenService *service) +void GxsCommentTreeWidget::setup(RsTokenService *token_service, RsGxsCommentService *comment_service) { - mRsService = service; - mTokenQueue = new TokenQueue(service, this); + mRsTokenService = token_service; + mCommentService = comment_service; + mTokenQueue = new TokenQueue(token_service, this); connect(this, SIGNAL(customContextMenuRequested(QPoint)), this, SLOT(customPopUpMenu(QPoint))); connect(this, SIGNAL(currentItemChanged(QTreeWidgetItem*,QTreeWidgetItem*)), this, SLOT(setCurrentMsgId(QTreeWidgetItem*, QTreeWidgetItem*))); @@ -259,7 +258,7 @@ void GxsCommentTreeWidget::loadThread(const uint32_t &token) void GxsCommentTreeWidget::acknowledgeComment(const uint32_t &token) { RsGxsGrpMsgIdPair msgId; - rsPosted->acknowledgeMsg(token, msgId); + mCommentService->acknowledgeComment(token, msgId); // simply reload data service_requestComments(mThreadId); @@ -271,15 +270,14 @@ void GxsCommentTreeWidget::service_loadThread(const uint32_t &token) std::cerr << "GxsCommentTreeWidget::service_loadThread() ERROR must be overloaded!"; std::cerr << std::endl; - PostedRelatedCommentResult commentResult; - rsPosted->getRelatedComment(token, commentResult); + std::vector comments; + mCommentService->getRelatedComments(token, comments); - std::vector& commentV = commentResult[mThreadId]; - std::vector::iterator vit = commentV.begin(); + std::vector::iterator vit; - for(; vit != commentV.end(); vit++) + for(vit = comments.begin(); vit != comments.end(); vit++) { - RsPostedComment& comment = *vit; + RsGxsComment &comment = *vit; /* convert to a QTreeWidgetItem */ std::cerr << "GxsCommentTreeWidget::service_loadThread() Got Comment: " << comment.mMeta.mMsgId; std::cerr << std::endl; diff --git a/retroshare-gui/src/gui/gxs/GxsCommentTreeWidget.h b/retroshare-gui/src/gui/gxs/GxsCommentTreeWidget.h index f494e25e3..918668bb3 100644 --- a/retroshare-gui/src/gui/gxs/GxsCommentTreeWidget.h +++ b/retroshare-gui/src/gui/gxs/GxsCommentTreeWidget.h @@ -25,6 +25,7 @@ #include #include "util/TokenQueue.h" +#include class GxsCommentTreeWidget : public QTreeWidget, public TokenResponse { @@ -32,7 +33,7 @@ class GxsCommentTreeWidget : public QTreeWidget, public TokenResponse public: GxsCommentTreeWidget(QWidget *parent = 0); - void setup(RsTokenService *service); + void setup(RsTokenService *token_service, RsGxsCommentService *comment_service); void requestComments(const RsGxsGrpMsgIdPair& threadId); void getCurrentMsgId(RsGxsMessageId& parentId); @@ -73,7 +74,8 @@ protected: std::multimap mPendingInsertMap; TokenQueue *mTokenQueue; - RsTokenService *mRsService; + RsTokenService *mRsTokenService; + RsGxsCommentService *mCommentService; }; diff --git a/retroshare-gui/src/gui/gxs/GxsCreateCommentDialog.cpp b/retroshare-gui/src/gui/gxs/GxsCreateCommentDialog.cpp new file mode 100644 index 000000000..439f95218 --- /dev/null +++ b/retroshare-gui/src/gui/gxs/GxsCreateCommentDialog.cpp @@ -0,0 +1,32 @@ + +#include "GxsCreateCommentDialog.h" +#include "ui_GxsCreateCommentDialog.h" + +GxsCreateCommentDialog::GxsCreateCommentDialog(TokenQueue *tokQ, RsGxsCommentService *service, + const RsGxsGrpMsgIdPair &parentId, const RsGxsMessageId& threadId, QWidget *parent) : + QDialog(parent), + ui(new Ui::GxsCreateCommentDialog), mTokenQueue(tokQ), mCommentService(service), mParentId(parentId), mThreadId(threadId) +{ + ui->setupUi(this); + connect(ui->buttonBox, SIGNAL(accepted()), this, SLOT(createComment())); +} + +void GxsCreateCommentDialog::createComment() +{ + RsGxsComment comment; + + comment.mComment = ui->commentTextEdit->document()->toPlainText().toStdString(); + comment.mMeta.mParentId = mParentId.second; + comment.mMeta.mGroupId = mParentId.first; + comment.mMeta.mThreadId = mThreadId; + + uint32_t token; + mCommentService->createComment(token, comment); + mTokenQueue->queueRequest(token, TOKENREQ_MSGINFO, RS_TOKREQ_ANSTYPE_ACK, 0); + close(); +} + +GxsCreateCommentDialog::~GxsCreateCommentDialog() +{ + delete ui; +} diff --git a/retroshare-gui/src/gui/gxs/GxsCreateCommentDialog.h b/retroshare-gui/src/gui/gxs/GxsCreateCommentDialog.h new file mode 100644 index 000000000..72a53e975 --- /dev/null +++ b/retroshare-gui/src/gui/gxs/GxsCreateCommentDialog.h @@ -0,0 +1,34 @@ +#ifndef _MRK_GXS_CREATE_COMMENT_DIALOG_H +#define _MRK_GXS_CREATE_COMMENT_DIALOG_H + +#include +#include "retroshare/rsgxscommon.h" +#include "util/TokenQueue.h" + +namespace Ui { + class GxsCreateCommentDialog; +} + +class GxsCreateCommentDialog : public QDialog +{ + Q_OBJECT + +public: + explicit GxsCreateCommentDialog(TokenQueue* tokQ, RsGxsCommentService *service, + const RsGxsGrpMsgIdPair& parentId, const RsGxsMessageId& threadId, QWidget *parent = 0); + ~GxsCreateCommentDialog(); + +private slots: + + void createComment(); + +private: + Ui::GxsCreateCommentDialog *ui; + TokenQueue *mTokenQueue; + RsGxsCommentService *mCommentService; + + RsGxsGrpMsgIdPair mParentId; + RsGxsMessageId mThreadId; +}; + +#endif // _MRK_GXS_CREATE_COMMENT_DIALOG_H diff --git a/retroshare-gui/src/gui/gxs/GxsCreateCommentDialog.ui b/retroshare-gui/src/gui/gxs/GxsCreateCommentDialog.ui new file mode 100644 index 000000000..980b4c85e --- /dev/null +++ b/retroshare-gui/src/gui/gxs/GxsCreateCommentDialog.ui @@ -0,0 +1,82 @@ + + + GxsCreateCommentDialog + + + + 0 + 0 + 372 + 145 + + + + Make Comment + + + + + + + + <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> +<html><head><meta name="qrichtext" content="1" /><style type="text/css"> +p, li { white-space: pre-wrap; } +</style></head><body style=" font-family:'MS Shell Dlg 2'; font-size:8.25pt; font-weight:400; font-style:normal;"> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:12pt; font-weight:600;">Comment</span></p></body></html> + + + + + + + + + + + + Qt::Horizontal + + + QDialogButtonBox::Cancel|QDialogButtonBox::Ok + + + + + + + + + buttonBox + accepted() + PostedCreateCommentDialog + accept() + + + 248 + 254 + + + 157 + 274 + + + + + buttonBox + rejected() + PostedCreateCommentDialog + reject() + + + 316 + 260 + + + 286 + 274 + + + + + diff --git a/retroshare-gui/src/gui/gxschannels/ChannelDialog.h b/retroshare-gui/src/gui/gxschannels/ChannelDialog.h new file mode 100644 index 000000000..a7a844e84 --- /dev/null +++ b/retroshare-gui/src/gui/gxschannels/ChannelDialog.h @@ -0,0 +1,69 @@ +/* + * Retroshare Channel Dialog + * + * Copyright 2012-2012 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 MRK_CHANNEL_DIALOG_H +#define MRK_CHANNEL_DIALOG_H + + +#include + +#include "gui/gxs/GxsCommentContainer.h" +#include "gui/gxschannels/GxsChannelDialog.h" + + +class ChannelDialog : public GxsCommentContainer +{ + //Q_OBJECT + +public: + ChannelDialog(QWidget *parent = 0) + :GxsCommentContainer(parent) { return; } + + virtual GxsServiceDialog *createServiceDialog() + { + return new GxsChannelDialog(this); + } + + virtual QString getServiceName() + { + return tr("GxsChannels"); + } + + virtual RsTokenService *getTokenService() + { + return rsGxsChannels->getTokenService(); + } + + virtual RsGxsCommentService *getCommentService() + { + return rsGxsChannels; + } + + virtual GxsCommentHeader *createHeaderWidget() + { + return NULL; + } +}; + +#endif + diff --git a/retroshare-gui/src/gui/gxschannels/CreateGxsChannelMsg.cpp b/retroshare-gui/src/gui/gxschannels/CreateGxsChannelMsg.cpp new file mode 100644 index 000000000..40883cc72 --- /dev/null +++ b/retroshare-gui/src/gui/gxschannels/CreateGxsChannelMsg.cpp @@ -0,0 +1,656 @@ +/**************************************************************** + * 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 +#include +#include +#include +#include +#include +#include + +#include +#include "CreateGxsChannelMsg.h" +#include "gui/feeds/SubFileItem.h" +#include "util/misc.h" + +#include +#include + +#include + +/** Constructor */ +CreateGxsChannelMsg::CreateGxsChannelMsg(std::string cId) +: QDialog (NULL, Qt::WindowSystemMenuHint | Qt::WindowTitleHint | Qt::WindowMinMaxButtonsHint | Qt::WindowCloseButtonHint), mChannelId(cId) ,mCheckAttachment(true), mAutoMediaThumbNail(false) +{ + /* Invoke the Qt Designer generated object setup routine */ + setupUi(this); + + headerFrame->setHeaderImage(QPixmap(":/images/channels.png")); + headerFrame->setHeaderText(tr("New GxsChannel Post")); + + setAttribute ( Qt::WA_DeleteOnClose, true ); + + connect(buttonBox, SIGNAL(accepted()), this, SLOT(sendMsg())); + connect(buttonBox, SIGNAL(rejected()), this, SLOT(cancelMsg())); + + connect(addFileButton, SIGNAL(clicked() ), this , SLOT(addExtraFile())); + connect(addfilepushButton, SIGNAL(clicked() ), this , SLOT(addExtraFile())); + connect(addThumbnailButton, SIGNAL(clicked() ), this , SLOT(addThumbnail())); + connect(thumbNailCb, SIGNAL(toggled(bool)), this, SLOT(allowAutoMediaThumbNail(bool))); + connect(tabWidget, SIGNAL(customContextMenuRequested(QPoint)), this, SLOT(contextMenu(QPoint))); + + thumbNailCb->setVisible(false); + thumbNailCb->setEnabled(false); +#ifdef CHANNELS_FRAME_CATCHER + fCatcher = new framecatcher(); + thumbNailCb->setVisible(true); + thumbNailCb->setEnabled(true); +#endif + //buttonBox->button(QDialogButtonBox::Ok)->setEnabled(false); + + setAcceptDrops(true); + + newChannelMsg(); +} + +void CreateGxsChannelMsg::contextMenu(QPoint /*point*/) +{ + QList links ; + RSLinkClipboard::pasteLinks(links) ; + + int n_file = 0 ; + + for(QList::const_iterator it(links.begin());it!=links.end();++it) + if((*it).type() == RetroShareLink::TYPE_FILE) + n_file++ ; + + QMenu contextMnu(this) ; + + QAction *action ; + + if(n_file > 1) + action = contextMnu.addAction(QIcon(":/images/pasterslink.png"), tr("Paste RetroShare Links"), this, SLOT(pasteLink())); + else + action = contextMnu.addAction(QIcon(":/images/pasterslink.png"), tr("Paste RetroShare Link"), this, SLOT(pasteLink())); + + action->setDisabled(n_file < 1) ; + contextMnu.exec(QCursor::pos()); +} + +void CreateGxsChannelMsg::pasteLink() +{ + std::cerr << "Pasting links: " << std::endl; + + QList links,not_have ; + RSLinkClipboard::pasteLinks(links) ; + + for(QList::const_iterator it(links.begin());it!=links.end();++it) + if((*it).type() == RetroShareLink::TYPE_FILE) + { + // 0 - check that we actually have the file! + // + + std::cerr << "Pasting " << (*it).toString().toStdString() << std::endl; + + FileInfo info ; + if(rsFiles->alreadyHaveFile( (*it).hash().toStdString(),info ) ) + addAttachment((*it).hash().toStdString(), (*it).name().toUtf8().constData(), (*it).size(), true, "") ; + else + not_have.push_back( *it ) ; + } + + if(!not_have.empty()) + { + QString msg = tr("GxsChannel security policy prevents you from posting files that you don't have. If you have these files, you need to share them before, or attach them explicitly:")+"

" ; + + for(QList::const_iterator it(not_have.begin());it!=not_have.end();++it) + msg += (*it).toString() + "
" ; + + QMessageBox::warning(NULL,tr("You can only post files that you do have"),msg) ; + } +} + +CreateGxsChannelMsg::~CreateGxsChannelMsg(){ + +#ifdef CHANNELS_FRAME_CATCHER + delete fCatcher; +#endif + +} + +/* Dropping */ + +void CreateGxsChannelMsg::dragEnterEvent(QDragEnterEvent *event) +{ + /* print out mimeType */ + std::cerr << "CreateGxsChannelMsg::dragEnterEvent() Formats"; + std::cerr << std::endl; + QStringList formats = event->mimeData()->formats(); + QStringList::iterator it; + for(it = formats.begin(); it != formats.end(); it++) + { + std::cerr << "Format: " << (*it).toStdString(); + std::cerr << std::endl; + } + + if (event->mimeData()->hasFormat("text/plain")) + { + std::cerr << "CreateGxsChannelMsg::dragEnterEvent() Accepting PlainText"; + std::cerr << std::endl; + event->acceptProposedAction(); + } + else if (event->mimeData()->hasUrls()) + { + std::cerr << "CreateGxsChannelMsg::dragEnterEvent() Accepting Urls"; + std::cerr << std::endl; + event->acceptProposedAction(); + } + else if (event->mimeData()->hasFormat("application/x-rsfilelist")) + { + std::cerr << "CreateGxsChannelMsg::dragEnterEvent() accepting Application/x-qabs..."; + std::cerr << std::endl; + event->acceptProposedAction(); + } + else + { + std::cerr << "CreateGxsChannelMsg::dragEnterEvent() No PlainText/Urls"; + std::cerr << std::endl; + } +} + +void CreateGxsChannelMsg::dropEvent(QDropEvent *event) +{ + if (!(Qt::CopyAction & event->possibleActions())) + { + std::cerr << "CreateGxsChannelMsg::dropEvent() Rejecting uncopyable DropAction"; + std::cerr << std::endl; + + /* can't do it */ + return; + } + + std::cerr << "CreateGxsChannelMsg::dropEvent() Formats" << std::endl; + QStringList formats = event->mimeData()->formats(); + QStringList::iterator it; + for(it = formats.begin(); it != formats.end(); it++) + { + std::cerr << "Format: " << (*it).toStdString(); + std::cerr << std::endl; + } + + if (event->mimeData()->hasText()) + { + std::cerr << "CreateGxsChannelMsg::dropEvent() Plain Text:"; + std::cerr << std::endl; + std::cerr << event->mimeData()->text().toStdString(); + std::cerr << std::endl; + } + + if (event->mimeData()->hasUrls()) + { + std::cerr << "CreateGxsChannelMsg::dropEvent() Urls:" << std::endl; + + QList urls = event->mimeData()->urls(); + QList::iterator uit; + for(uit = urls.begin(); uit != urls.end(); uit++) + { + QString localpath = uit->toLocalFile(); + std::cerr << "Whole URL: " << uit->toString().toStdString() << std::endl; + std::cerr << "or As Local File: " << localpath.toStdString() << std::endl; + + if (localpath.isEmpty() == false) + { + // Check that the file does exist and is not a directory + QDir dir(localpath); + if (dir.exists()) { + std::cerr << "CreateGxsChannelMsg::dropEvent() directory not accepted."<< std::endl; + QMessageBox mb(tr("Drop file error."), tr("Directory can't be dropped, only files are accepted."),QMessageBox::Information,QMessageBox::Ok,0,0,this); + mb.exec(); + } else if (QFile::exists(localpath)) { + addAttachment(localpath.toUtf8().constData()); + } else { + std::cerr << "CreateGxsChannelMsg::dropEvent() file does not exists."<< std::endl; + QMessageBox mb(tr("Drop file error."), tr("File not found or file name not accepted."),QMessageBox::Information,QMessageBox::Ok,0,0,this); + mb.exec(); + } + } + } + } + else if (event->mimeData()->hasFormat("application/x-rsfilelist")) + { + std::cerr << "CreateGxsChannelMsg::dropEvent() Application/x-rsfilelist"; + std::cerr << std::endl; + + QByteArray data = event->mimeData()->data("application/x-rsfilelist"); + std::cerr << "Data Len:" << data.length(); + std::cerr << std::endl; + std::cerr << "Data is:" << data.data(); + std::cerr << std::endl; + + std::string newattachments(data.data()); + parseRsFileListAttachments(newattachments); + } + + event->setDropAction(Qt::CopyAction); + event->accept(); +} + +void CreateGxsChannelMsg::parseRsFileListAttachments(const std::string &attachList) +{ + /* split into lines */ + QString input = QString::fromStdString(attachList); + + QStringList attachItems = input.split("\n"); + QStringList::iterator it; + QStringList::iterator it2; + + for(it = attachItems.begin(); it != attachItems.end(); it++) + { + std::cerr << "CreateGxsChannelMsg::parseRsFileListAttachments() Entry: "; + + QStringList parts = (*it).split("/"); + + bool ok = false; + quint64 qsize = 0; + + std::string fname; + std::string hash; + uint64_t size = 0; + std::string source; + + int i = 0; + for(it2 = parts.begin(); it2 != parts.end(); it2++, i++) + { + std::cerr << "\"" << it2->toStdString() << "\" "; + switch(i) + { + case 0: + fname = it2->toStdString(); + break; + case 1: + hash = it2->toStdString(); + break; + case 2: + qsize = it2->toULongLong(&ok, 10); + size = qsize; + break; + case 3: + source = it2->toStdString(); + break; + } + } + + std::cerr << std::endl; + + std::cerr << "\tfname: " << fname << std::endl; + std::cerr << "\thash: " << hash << std::endl; + std::cerr << "\tsize: " << size << std::endl; + std::cerr << "\tsource: " << source << std::endl; + + /* basic error checking */ + if ((ok) && (hash.size() == 40)) + { + std::cerr << "Item Ok" << std::endl; + if (source == "Local") + { + addAttachment(hash, fname, size, true, ""); + } + else + { + // TEMP NOT ALLOWED UNTIL FT WORKING. + addAttachment(hash, fname, size, false, source); + } + + } + else + { + std::cerr << "Error Decode: Hash size: " << hash.size() << std::endl; + } + + } +} + + +void CreateGxsChannelMsg::addAttachment(const std::string &hash, const std::string &fname, uint64_t size, bool local, const std::string &srcId) +{ + /* add a SubFileItem to the attachment section */ + std::cerr << "CreateGxsChannelMsg::addAttachment()"; + std::cerr << std::endl; + + /* add widget in for new destination */ + + uint32_t flags = SFI_TYPE_CHANNEL; + if (local) + { + flags |= SFI_STATE_LOCAL; + } + else + { + flags |= SFI_STATE_REMOTE; + } + + SubFileItem *file = new SubFileItem(hash, fname, "", size, flags, srcId); // destroyed when fileFrame (this subfileitem) is destroyed + + mAttachments.push_back(file); + QLayout *layout = fileFrame->layout(); + layout->addWidget(file); + + if (mCheckAttachment) + { + checkAttachmentReady(); + } + + return; +} + + +void CreateGxsChannelMsg::addExtraFile() +{ + /* add a SubFileItem to the attachment section */ + std::cerr << "CreateGxsChannelMsg::addExtraFile() opening file dialog"; + std::cerr << std::endl; + + QStringList files; + if (misc::getOpenFileNames(this, RshareSettings::LASTDIR_EXTRAFILE, tr("Add Extra File"), "", files)) { + for (QStringList::iterator fileIt = files.begin(); fileIt != files.end(); fileIt++) { + addAttachment((*fileIt).toUtf8().constData()); + } + } +} + + +void CreateGxsChannelMsg::addAttachment(const std::string &path) +{ + /* add a SubFileItem to the attachment section */ + std::cerr << "CreateGxsChannelMsg::addAttachment()"; + std::cerr << std::endl; + + if(mAutoMediaThumbNail) + setThumbNail(path, 2000); + + /* add widget in for new destination */ + uint32_t flags = SFI_TYPE_CHANNEL | SFI_STATE_EXTRA | SFI_FLAG_CREATE; + + // check attachment if hash exists already + std::list::iterator it; + + for(it= mAttachments.begin(); it != mAttachments.end(); it++){ + + if((*it)->FilePath() == path){ + QMessageBox::warning(this, tr("RetroShare"), + tr("File already Added and Hashed"), + QMessageBox::Ok, QMessageBox::Ok); + + return; + } + + } + + // channels creates copy of file into channels directory and shares this + + FileInfo fInfo; +#if 0 + rsGxsChannels->channelExtraFileHash(path, mChannelId, fInfo); +#endif + + // file is not innitial + SubFileItem *file = new SubFileItem(fInfo.hash, fInfo.fname, fInfo.path, fInfo.size, + flags, mChannelId); // destroyed when fileFrame (this subfileitem) is destroyed + + mAttachments.push_back(file); + QLayout *layout = fileFrame->layout(); + layout->addWidget(file); + + if (mCheckAttachment) + { + checkAttachmentReady(); + } + + return; +} + +bool CreateGxsChannelMsg::setThumbNail(const std::string& path, int frame){ + +#ifdef CHANNELS_FRAME_CATCHER + unsigned char* imageBuffer = NULL; + int width = 0, height = 0, errCode = 0; + int length; + std::string errString; + + if(1 != (errCode = fCatcher->open(path))){ + fCatcher->getError(errCode, errString); + std::cerr << errString << std::endl; + return false; + } + + length = fCatcher->getLength(); + + // make sure frame chosen is at lease a quarter length of video length if not choose quarter length + if(frame < (int) (0.25 * length)) + frame = 0.25 * length; + + if(1 != (errCode = fCatcher->getRGBImage(frame, imageBuffer, width, height))){ + fCatcher->getError(errCode, errString); + std::cerr << errString << std::endl; + return false; + } + + if(imageBuffer == NULL) + return false; + + QImage tNail(imageBuffer, width, height, QImage::Format_RGB32); + QByteArray ba; + QBuffer buffer(&ba); + buffer.open(QIODevice::WriteOnly); + tNail.save(&buffer, "PNG"); + QPixmap img; + img.loadFromData(ba, "PNG"); + img = img.scaled(thumbnail_label->width(), thumbnail_label->height(), Qt::KeepAspectRatio); + thumbnail_label->setPixmap(img); + + delete[] imageBuffer; +#else + Q_UNUSED(path); + Q_UNUSED(frame); +#endif + + return true; +} + +void CreateGxsChannelMsg::allowAutoMediaThumbNail(bool allowThumbNail){ + + mAutoMediaThumbNail = allowThumbNail; +} + +void CreateGxsChannelMsg::checkAttachmentReady() +{ + std::list::iterator fit; + + mCheckAttachment = false; + + for(fit = mAttachments.begin(); fit != mAttachments.end(); fit++) + { + if (!(*fit)->isHidden()) + { + if (!(*fit)->ready()) + { + /* ensure file is hashed or file will be hashed, thus + * recognized by librs but not correctly by gui (can't + * formally remove it) + */ + buttonBox->button(QDialogButtonBox::Ok)->setEnabled(false); + buttonBox->button(QDialogButtonBox::Cancel)->setEnabled(false); + break; + } + } + } + + if (fit == mAttachments.end()) + { + buttonBox->button(QDialogButtonBox::Ok)->setEnabled(true); + buttonBox->button(QDialogButtonBox::Cancel)->setEnabled(true); + } + + /* repeat... */ + int msec_rate = 1000; + QTimer::singleShot( msec_rate, this, SLOT(checkAttachmentReady(void))); +} + + +void CreateGxsChannelMsg::cancelMsg() +{ + std::cerr << "CreateGxsChannelMsg::cancelMsg() :" + << "Deleting EXTRA attachments" << std::endl; + + std::cerr << std::endl; + + std::list::const_iterator it; + +#if 0 + for(it = mAttachments.begin(); it != mAttachments.end(); it++) + rsGxsChannels->channelExtraFileRemove((*it)->FileHash(), mChannelId); +#endif + + close(); + return; +} + +void CreateGxsChannelMsg::newChannelMsg() +{ + if (!rsGxsChannels) + return; + +#if 0 + GxsChannelInfo ci; + if (!rsGxsChannels->getGxsChannelInfo(mChannelId, ci)) + { + + return; + } + + + channelName->setText(QString::fromStdWString(ci.channelName)); +#endif + + subjectEdit->setFocus(); +} + +void CreateGxsChannelMsg::sendMsg() +{ + std::cerr << "CreateGxsChannelMsg::sendMsg()"; + std::cerr << std::endl; + + /* construct message bits */ + std::wstring subject = misc::removeNewLine(subjectEdit->text()).toStdWString(); + std::wstring msg = msgEdit->toPlainText().toStdWString(); + + std::list files; + + std::list::iterator fit; + + for(fit = mAttachments.begin(); fit != mAttachments.end(); fit++) + { + if (!(*fit)->isHidden()) + { + FileInfo fi; + fi.hash = (*fit)->FileHash(); + fi.fname = (*fit)->FileName(); + fi.size = (*fit)->FileSize(); + + files.push_back(fi); + + /* commence downloads - if we don't have the file */ + + if (!(*fit)->done()) + { + if ((*fit)->ready()) + { + (*fit)->download(); + } + // Skips unhashed files. + } + } + } + + sendMessage(subject, msg, files); + +} + +void CreateGxsChannelMsg::sendMessage(std::wstring subject, std::wstring msg, std::list &files) +{ + QString name = misc::removeNewLine(subjectEdit->text()); + + if(name.isEmpty()) + { /* error message */ + QMessageBox::warning(this, tr("RetroShare"), + tr("Please add a Subject"), + QMessageBox::Ok, QMessageBox::Ok); + + return; //Don't add an empty Subject!! + } + else + /* rsGxsChannels */ + if (rsGxsChannels) + { +#if 0 + GxsChannelMsgInfo msgInfo; + + msgInfo.channelId = mChannelId; + msgInfo.msgId = ""; + + msgInfo.subject = subject; + msgInfo.msg = msg; + msgInfo.files = files; + + QByteArray ba; + QBuffer buffer(&ba); + + if(!picture.isNull()){ + // send chan image + + buffer.open(QIODevice::WriteOnly); + picture.save(&buffer, "PNG"); // writes image into ba in PNG format + msgInfo.thumbnail.image_thumbnail = (unsigned char*) ba.data(); + msgInfo.thumbnail.im_thumbnail_size = ba.size(); + } + + rsGxsChannels->GxsChannelMessageSend(msgInfo); +#endif + } + + close(); + return; + +} + +void CreateGxsChannelMsg::addThumbnail() +{ + QPixmap img = misc::getOpenThumbnailedPicture(this, tr("Load thumbnail picture"), 156, 107); + + if (img.isNull()) + return; + + picture = img; + + // to show the selected + thumbnail_label->setPixmap(picture); +} diff --git a/retroshare-gui/src/gui/gxschannels/CreateGxsChannelMsg.h b/retroshare-gui/src/gui/gxschannels/CreateGxsChannelMsg.h new file mode 100644 index 000000000..4629702fc --- /dev/null +++ b/retroshare-gui/src/gui/gxschannels/CreateGxsChannelMsg.h @@ -0,0 +1,91 @@ +/**************************************************************** + * RetroShare is distributed under the following license: + * + * Copyright (C) 2013 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 _CREATE_GXSCHANNEL_MSG_H +#define _CREATE_GXSCHANNEL_MSG_H + +#include "ui_CreateGxsChannelMsg.h" +#include + +#ifdef CHANNELS_FRAME_CATCHER +#include "util/framecatcher.h" +#endif + +class SubFileItem; +class FileInfo; + +class CreateGxsChannelMsg : public QDialog, private Ui::CreateGxsChannelMsg +{ + Q_OBJECT + +public: + /** Default Constructor */ + CreateGxsChannelMsg(std::string cId); + + + /** Default Destructor */ + ~CreateGxsChannelMsg(); + + void addAttachment(const std::string &path); + void addAttachment(const std::string &hash, const std::string &fname, uint64_t size, bool local, const std::string &srcId); + + void newChannelMsg(); + + QPixmap picture; + +protected: +virtual void dragEnterEvent(QDragEnterEvent *event); +virtual void dropEvent(QDropEvent *event); + +private slots: + void addExtraFile(); + void checkAttachmentReady(); + + void cancelMsg(); + void sendMsg(); + void pasteLink() ; + void contextMenu(QPoint) ; + + void addThumbnail(); + void allowAutoMediaThumbNail(bool); + +private: + + void parseRsFileListAttachments(const std::string &attachList); + void sendMessage(std::wstring subject, std::wstring msg, std::list &files); + bool setThumbNail(const std::string& path, int frame); + + + std::string mChannelId; + + std::list mAttachments; + + bool mCheckAttachment; + bool mAutoMediaThumbNail; + +#ifdef CHANNELS_FRAME_CATCHER + framecatcher* fCatcher; +#endif + +}; + +#endif + diff --git a/retroshare-gui/src/gui/gxschannels/CreateGxsChannelMsg.ui b/retroshare-gui/src/gui/gxschannels/CreateGxsChannelMsg.ui new file mode 100644 index 000000000..cd07a88b2 --- /dev/null +++ b/retroshare-gui/src/gui/gxschannels/CreateGxsChannelMsg.ui @@ -0,0 +1,365 @@ + + + CreateGxsChannelMsg + + + + 0 + 0 + 581 + 479 + + + + true + + + New Channel Post + + + + :/images/rstray3.png:/images/rstray3.png + + + + 0 + + + 0 + + + + + + + + QFrame::StyledPanel + + + QFrame::Raised + + + + + + true + + + Qt::CustomContextMenu + + + false + + + 0 + + + + Channel Post + + + + + + + + + 75 + true + + + + Channel Post to: + + + + + + + true + + + true + + + + + + + + + + + <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> +<html><head><meta name="qrichtext" content="1" /><style type="text/css"> +p, li { white-space: pre-wrap; } +</style></head><body style=" font-family:'Ubuntu'; font-size:11pt; font-weight:400; font-style:normal;"> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'MS Shell Dlg 2'; font-size:10pt; font-weight:600;">Attachments:</span></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><img src=":/images/feedback_arrow.png" /><span style=" font-family:'MS Shell Dlg 2'; font-size:8pt;"> Use Drag and Drop / Add Files button, to Hash new files.</span></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><img src=":/images/feedback_arrow.png" /><span style=" font-family:'MS Shell Dlg 2'; font-size:8pt;"> Copy/Paste RetroShare links from your shares</span></p></body></html> + + + + + + + Add File to Attach + + + + :/images/add-share24.png:/images/add-share24.png + + + + + + + Add Channel Thumbnail + + + + :/images/add_image24.png:/images/add_image24.png + + + + + + + + + + 156 + 107 + + + + + 0 + 0 + + + + :/images/thumb-default-video.png + + + + + + + Qt::Horizontal + + + + 12 + 98 + + + + + + + + Message + + + + + + + + + 75 + true + + + + Subject : + + + + + + + + + + + + + + + + + + + + :/images/attachment.png:/images/attachment.png + + + Attachments + + + + + + + + + :/images/attachment.png + + + + + + + + 16777215 + 26 + + + + + 75 + true + + + + Attachments + + + + + + + Qt::Horizontal + + + + 334 + 26 + + + + + + + + + 0 + 0 + + + + + 34 + 34 + + + + + + + + :/images/add-share24.png:/images/add-share24.png + + + + 24 + 24 + + + + + + + + Allow channels to get frame for message thumbnail from movie media attachments or not + + + Auto Thumbnail + + + + + + + Qt::ScrollBarAlwaysOn + + + true + + + + + 0 + 0 + 98 + 24 + + + + + 0 + 0 + + + + + 3 + + + 3 + + + + + + 0 + 0 + + + + true + + + Drag and Drop Files from Search Results + + + + + + + + + + + + + + + + Qt::Horizontal + + + QDialogButtonBox::Cancel|QDialogButtonBox::Ok + + + + + + + + + + + HeaderFrame + QFrame +
gui/common/HeaderFrame.h
+ 1 +
+
+ + + + +
diff --git a/retroshare-gui/src/gui/gxschannels/GxsChannelDialog.cpp b/retroshare-gui/src/gui/gxschannels/GxsChannelDialog.cpp new file mode 100644 index 000000000..bba9959e9 --- /dev/null +++ b/retroshare-gui/src/gui/gxschannels/GxsChannelDialog.cpp @@ -0,0 +1,1092 @@ +/**************************************************************** + * 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 +#include +#include +#include + +#include +#include +#include +#include + +#include "GxsChannelDialog.h" + +//#include "../feeds/ChanMsgItem.h" +#include "../feeds/GxsChannelPostItem.h" + +#include "../common/PopularityDefs.h" +#include "../settings/rsharesettings.h" + +#include "gui/gxschannels/GxsChannelGroupDialog.h" +#include "gui/gxschannels/CreateGxsChannelMsg.h" + +//#include "../channels/ChannelDetails.h" +//#include "../channels/EditChanDetails.h" +#include "../channels/ShareKey.h" +#include "../channels/ChannelUserNotify.h" + + +#include "../notifyqt.h" +#include "../RetroShareLink.h" + +#define CHAN_DEFAULT_IMAGE ":/images/channels.png" + +#define WARNING_LIMIT 3600*24*2 + +/* Images for TreeWidget */ +#define IMAGE_CHANNELBLUE ":/images/channelsblue.png" +#define IMAGE_CHANNELGREEN ":/images/channelsgreen.png" +#define IMAGE_CHANNELRED ":/images/channelsred.png" +#define IMAGE_CHANNELYELLOW ":/images/channelsyellow.png" + +/**** + * #define CHAN_DEBUG + ***/ + +#define USE_THREAD + +/** Constructor */ +GxsChannelDialog::GxsChannelDialog(QWidget *parent) +: RsAutoUpdatePage(1000,parent), GxsServiceDialog(dynamic_cast(parent)) +{ + /* Invoke the Qt Designer generated object setup routine */ + ui.setupUi(this); + + mChannelQueue = new TokenQueue(rsGxsChannels->getTokenService(), this); + + connect(ui.newChannelButton, SIGNAL(clicked()), this, SLOT(createChannel())); + connect(ui.postButton, SIGNAL(clicked()), this, SLOT(createMsg())); + connect(NotifyQt::getInstance(), SIGNAL(channelMsgReadSatusChanged(QString,QString,int)), this, SLOT(channelMsgReadSatusChanged(QString,QString,int))); + + connect(ui.refreshButton, SIGNAL(clicked()), this, SLOT(forceUpdateDisplay())); + + + /*************** Setup Left Hand Side (List of Channels) ****************/ + + connect(ui.treeWidget, SIGNAL(treeCustomContextMenuRequested(QPoint)), this, SLOT( channelListCustomPopupMenu( QPoint ) ) ); + connect(ui.treeWidget, SIGNAL(treeCurrentItemChanged(QString)), this, SLOT(selectChannel(QString))); + + mChannelId.clear(); + + /* Set initial size the splitter */ + QList sizes; + sizes << 300 << width(); // Qt calculates the right sizes + ui.splitter->setSizes(sizes); + + /* Initialize group tree */ + ui.treeWidget->initDisplayMenu(ui.displayButton); + + ownChannels = ui.treeWidget->addCategoryItem(tr("My Channels"), QIcon(IMAGE_CHANNELBLUE), true); + subcribedChannels = ui.treeWidget->addCategoryItem(tr("Subscribed Channels"), QIcon(IMAGE_CHANNELRED), true); + popularChannels = ui.treeWidget->addCategoryItem(tr("Popular Channels"), QIcon(IMAGE_CHANNELGREEN ), false); + otherChannels = ui.treeWidget->addCategoryItem(tr("Other Channels"), QIcon(IMAGE_CHANNELYELLOW), false); + + ui.progressLabel->hide(); + ui.progressBar->hide(); + + fillThread = NULL; + + //added from ahead + //updateChannelList(); + forceUpdateDisplay(); + + ui.nameLabel->setMinimumWidth(20); + + /* load settings */ + processSettings(true); + + //updateChannelMsgs(); +} + +GxsChannelDialog::~GxsChannelDialog() +{ + if (fillThread) { + fillThread->stop(); + delete(fillThread); + fillThread = NULL; + } + + // save settings + processSettings(false); +} + + +// Callback from Widget->FeedHolder->ServiceDialog->CommentContainer->CommentDialog, +void GxsChannelDialog::openComments(uint32_t type, const RsGxsGroupId &groupId, const RsGxsMessageId &msgId) +{ + commentLoad(groupId, msgId); +} + + +UserNotify *GxsChannelDialog::getUserNotify(QObject *parent) +{ + return new ChannelUserNotify(parent); + return NULL; +} + +void GxsChannelDialog::processSettings(bool load) +{ + Settings->beginGroup(QString("GxsChannelDialog")); + + if (load) { + // load settings + + // state of splitter + ui.splitter->restoreState(Settings->value("Splitter").toByteArray()); + } else { + // save settings + + // state of splitter + Settings->setValue("Splitter", ui.splitter->saveState()); + } + + ui.treeWidget->processSettings(Settings, load); + + Settings->endGroup(); +} + +void GxsChannelDialog::channelListCustomPopupMenu( QPoint /*point*/ ) +{ + ChannelInfo ci; + if (!rsChannels->getChannelInfo(mChannelId, ci)) { + return; + } + + QMenu contextMnu(this); + + QAction *postchannelAct = new QAction(QIcon(":/images/mail_reply.png"), tr( "Post to Channel" ), &contextMnu); + connect( postchannelAct , SIGNAL( triggered() ), this, SLOT( createMsg() ) ); + + QAction *subscribechannelAct = new QAction(QIcon(":/images/edit_add24.png"), tr( "Subscribe to Channel" ), &contextMnu); + connect( subscribechannelAct , SIGNAL( triggered() ), this, SLOT( subscribeChannel() ) ); + + QAction *unsubscribechannelAct = new QAction(QIcon(":/images/cancel.png"), tr( "Unsubscribe to Channel" ), &contextMnu); + connect( unsubscribechannelAct , SIGNAL( triggered() ), this, SLOT( unsubscribeChannel() ) ); + + QAction *setallasreadchannelAct = new QAction(QIcon(":/images/message-mail-read.png"), tr( "Set all as read" ), &contextMnu); + connect( setallasreadchannelAct , SIGNAL( triggered() ), this, SLOT( setAllAsReadClicked() ) ); + + bool autoDl = false; + rsChannels->channelGetAutoDl(mChannelId, autoDl); + + QAction *autochannelAct = autoDl? (new QAction(QIcon(":/images/redled.png"), tr( "Disable Auto-Download" ), &contextMnu)) + : (new QAction(QIcon(":/images/start.png"),tr( "Enable Auto-Download" ), &contextMnu)) ; + + connect( autochannelAct , SIGNAL( triggered() ), this, SLOT( toggleAutoDownload() ) ); + + QAction *channeldetailsAct = new QAction(QIcon(":/images/info16.png"), tr( "Show Channel Details" ), &contextMnu); + connect( channeldetailsAct , SIGNAL( triggered() ), this, SLOT( showChannelDetails() ) ); + + QAction *restoreKeysAct = new QAction(QIcon(":/images/settings16.png"), tr("Restore Publish Rights for Channel" ), &contextMnu); + connect( restoreKeysAct , SIGNAL( triggered() ), this, SLOT( restoreChannelKeys() ) ); + + QAction *editChannelDetailAct = new QAction(QIcon(":/images/edit_16.png"), tr("Edit Channel Details"), &contextMnu); + connect( editChannelDetailAct, SIGNAL( triggered() ), this, SLOT( editChannelDetail() ) ); + + QAction *shareKeyAct = new QAction(QIcon(":/images/gpgp_key_generate.png"), tr("Share Channel"), &contextMnu); + connect( shareKeyAct, SIGNAL( triggered() ), this, SLOT( shareKey() ) ); + + if((ci.channelFlags & RS_DISTRIB_ADMIN) && (ci.channelFlags & RS_DISTRIB_SUBSCRIBED)) + contextMnu.addAction( editChannelDetailAct); + else + contextMnu.addAction( channeldetailsAct ); + + if((ci.channelFlags & RS_DISTRIB_PUBLISH) && (ci.channelFlags & RS_DISTRIB_SUBSCRIBED)) + { + contextMnu.addAction( postchannelAct ); + contextMnu.addAction( shareKeyAct ); + } + + if(ci.channelFlags & RS_DISTRIB_SUBSCRIBED) + { + contextMnu.addAction( unsubscribechannelAct ); + contextMnu.addAction( restoreKeysAct ); + contextMnu.addSeparator(); + contextMnu.addAction( autochannelAct ); + contextMnu.addAction( setallasreadchannelAct ); + } + else + contextMnu.addAction( subscribechannelAct ); + + contextMnu.addSeparator(); + QAction *action = contextMnu.addAction(QIcon(":/images/copyrslink.png"), tr("Copy RetroShare Link"), this, SLOT(copyChannelLink())); + action->setEnabled(!mChannelId.empty()); + +#ifdef CHAN_DEBUG + contextMnu.addSeparator(); + action = contextMnu.addAction("Generate mass data", this, SLOT(generateMassData())); + action->setEnabled (!mChannelId.empty() && (ci.channelFlags & RS_DISTRIB_PUBLISH)); +#endif + + contextMnu.exec(QCursor::pos()); +} + +void GxsChannelDialog::createChannel() +{ + GxsChannelGroupDialog cc(mChannelQueue, this); + cc.exec(); +} + +/*************************************************************************************/ +/*************************************************************************************/ +/*************************************************************************************/ + +QScrollArea *GxsChannelDialog::getScrollArea() +{ + return ui.scrollArea; +} + +void GxsChannelDialog::deleteFeedItem(QWidget * /*item*/, uint32_t /*type*/) +{ +} + +void GxsChannelDialog::openChat(std::string /*peerId*/) +{ + +} + +void GxsChannelDialog::editChannelDetail() +{ +#if 0 + EditChanDetails editUi(this, mChannelId); + editUi.exec(); +#endif +} + +void GxsChannelDialog::shareKey() +{ +#if 0 + ShareKey shareUi(this, mChannelId, CHANNEL_KEY_SHARE); + shareUi.exec(); +#endif + +} + +void GxsChannelDialog::copyChannelLink() +{ + +#if 0 + if (mChannelId.empty()) { + return; + } + + ChannelInfo ci; + if (rsChannels->getChannelInfo(mChannelId, ci)) { + RetroShareLink link; + if (link.createChannel(ci.channelId, "")) { + QList urls; + urls.push_back(link); + RSLinkClipboard::copyLinks(urls); + } + } +#endif + +} + +void GxsChannelDialog::createMsg() +{ + if (mChannelId.empty()) { + return; + } + + CreateGxsChannelMsg *msgDialog = new CreateGxsChannelMsg(mChannelId); + msgDialog->show(); +} + +void GxsChannelDialog::restoreChannelKeys() +{ + +#if 0 + if(rsChannels->channelRestoreKeys(mChannelId)) + QMessageBox::information(NULL,tr("Publish rights restored."),tr("Publish rights have been restored for this channel.")) ; + else + QMessageBox::warning(NULL,tr("Publish not restored."),tr("Publish rights can't be restored for this channel.
You're not the creator of this channel.")) ; +#endif + +} + +void GxsChannelDialog::selectChannel(const QString &id) +{ + mChannelId = id.toStdString(); + +#if 0 + bool autoDl = false; + rsChannels->channelGetAutoDl(mChannelId, autoDl); + + setAutoDownloadButton(autoDl); +#endif + + requestPosts(mChannelId); + //updateChannelMsgs(); +} + +void GxsChannelDialog::updateDisplay() +{ + if (!rsGxsChannels) { + return; + } + + if (rsGxsChannels->updated()) + { + insertChannels(); + } +} + +void GxsChannelDialog::forceUpdateDisplay() +{ + std::cerr << "GxsChannelDialog::forceUpdateDisplay()"; + std::cerr << std::endl; + + insertChannels(); +} + +static void channelInfoToGroupItemInfo(const RsGroupMetaData &channelInfo, GroupItemInfo &groupItemInfo) +{ + groupItemInfo.id = QString::fromStdString(channelInfo.mGroupId); + groupItemInfo.name = QString::fromUtf8(channelInfo.mGroupName.c_str()); + groupItemInfo.popularity = channelInfo.mPop; + groupItemInfo.lastpost = QDateTime::fromTime_t(channelInfo.mLastPost); + groupItemInfo.subscribeFlags = channelInfo.mSubscribeFlags; + + QPixmap chanImage = QPixmap(CHAN_DEFAULT_IMAGE); + groupItemInfo.icon = QIcon(chanImage); +} + +void GxsChannelDialog::insertChannelData(const std::list &channelList) +{ + std::list::const_iterator it; + + QList adminList; + QList subList; + QList popList; + QList otherList; + std::multimap popMap; + + for(it = channelList.begin(); it != channelList.end(); it++) { + /* sort it into Publish (Own), Subscribed, Popular and Other */ + uint32_t flags = it->mSubscribeFlags; + + GroupItemInfo groupItemInfo; + channelInfoToGroupItemInfo(*it, groupItemInfo); + + if (IS_GROUP_ADMIN(flags)) { + adminList.push_back(groupItemInfo); + } else if (IS_GROUP_SUBSCRIBED(flags)) { + /* subscribed forum */ + subList.push_back(groupItemInfo); + } else { + /* rate the others by popularity */ + popMap.insert(std::make_pair(it->mPop, groupItemInfo)); + } + } + + /* iterate backwards through popMap - take the top 5 or 10% of list */ + uint32_t popCount = 5; + if (popCount < popMap.size() / 10) + { + popCount = popMap.size() / 10; + } + + uint32_t i = 0; + std::multimap::reverse_iterator rit; + for (rit = popMap.rbegin(); rit != popMap.rend(); rit++) + { + if (i < popCount) + { + popList.push_back(rit->second); + i++; + } + else + { + otherList.push_back(rit->second); + } + } + + /* now we have our lists ---> update entries */ + + ui.treeWidget->fillGroupItems(ownChannels, adminList); + ui.treeWidget->fillGroupItems(subcribedChannels, subList); + ui.treeWidget->fillGroupItems(popularChannels, popList); + ui.treeWidget->fillGroupItems(otherChannels, otherList); + + updateMessageSummaryList(""); +} + + +void GxsChannelDialog::channelMsgReadSatusChanged(const QString& channelId, const QString& /*msgId*/, int /*status*/) +{ + updateMessageSummaryList(channelId.toStdString()); +} + +void GxsChannelDialog::updateMessageSummaryList(const std::string &channelId) +{ + QTreeWidgetItem *items[2] = { ownChannels, subcribedChannels }; + + for (int item = 0; item < 2; item++) { + int child; + int childCount = items[item]->childCount(); + for (child = 0; child < childCount; child++) { + QTreeWidgetItem *childItem = items[item]->child(child); + std::string childId = ui.treeWidget->itemId(childItem).toStdString(); + if (childId.empty()) { + continue; + } + + if (channelId.empty() || childId == channelId) { + /* Calculate unread messages */ + unsigned int newMessageCount = 0; + unsigned int unreadMessageCount = 0; + rsChannels->getMessageCount(childId, newMessageCount, unreadMessageCount); + + ui.treeWidget->setUnreadCount(childItem, unreadMessageCount); + + if (channelId.empty() == false) { + /* Calculate only this channel */ + break; + } + } + } + } +} + +static bool sortChannelMsgSummary(const ChannelMsgSummary &msg1, const ChannelMsgSummary &msg2) +{ + return (msg1.ts > msg2.ts); +} + +#if 0 +void GxsChannelDialog::updateChannelMsgs() +{ + if (fillThread) { +#ifdef CHAN_DEBUG + std::cerr << "GxsChannelDialog::updateChannelMsgs() stop current fill thread" << std::endl; +#endif + // stop current fill thread + GxsChannelFillThread *thread = fillThread; + fillThread = NULL; + thread->stop(); + delete(thread); + + progressLabel->hide(); + progressBar->hide(); + } + + if (!rsChannels) { + return; + } + + /* replace all the messages with new ones */ + QList::iterator mit; + for (mit = mChanMsgItems.begin(); mit != mChanMsgItems.end(); mit++) { + delete (*mit); + } + mChanMsgItems.clear(); + + ChannelInfo ci; + if (!rsChannels->getChannelInfo(mChannelId, ci)) { + postButton->setEnabled(false); + nameLabel->setText(tr("No Channel Selected")); + logoLabel->setPixmap(QPixmap(":/images/channels.png")); + logoLabel->setEnabled(false); + return; + } + + QPixmap chanImage; + if (ci.pngImageLen != 0) { + chanImage.loadFromData(ci.pngChanImage, ci.pngImageLen, "PNG"); + } else { + chanImage = QPixmap(CHAN_DEFAULT_IMAGE); + } + logoLabel->setPixmap(chanImage); + logoLabel->setEnabled(true); + + /* set Channel name */ + nameLabel->setText(QString::fromStdWString(ci.channelName)); + + if (ci.channelFlags & RS_DISTRIB_PUBLISH) { + postButton->setEnabled(true); + } else { + postButton->setEnabled(false); + } + + if (!(ci.channelFlags & RS_DISTRIB_ADMIN) && + (ci.channelFlags & RS_DISTRIB_SUBSCRIBED)) { + actionEnable_Auto_Download->setEnabled(true); + } else { + actionEnable_Auto_Download->setEnabled(false); + } + +#ifdef USE_THREAD + progressLabel->show(); + progressBar->reset(); + progressBar->show(); + + // create fill thread + fillThread = new GxsChannelFillThread(this, mChannelId); + + // connect thread + connect(fillThread, SIGNAL(finished()), this, SLOT(fillThreadFinished()), Qt::BlockingQueuedConnection); + connect(fillThread, SIGNAL(addMsg(QString,QString,int,int)), this, SLOT(fillThreadAddMsg(QString,QString,int,int)), Qt::BlockingQueuedConnection); + +#ifdef CHAN_DEBUG + std::cerr << "GxsChannelDialog::updateChannelMsgs() Start fill thread" << std::endl; +#endif + + // start thread + fillThread->start(); +#else + std::list msgs; + std::list::iterator it; + rsChannels->getChannelMsgList(mChannelId, msgs); + + msgs.sort(sortChannelMsgSummary); + + for (it = msgs.begin(); it != msgs.end(); it++) { + ChanMsgItem *cmi = new ChanMsgItem(this, 0, mChannelId, it->msgId, true); + mChanMsgItems.push_back(cmi); + verticalLayout_2->addWidget(cmi); + } +#endif +} + +void GxsChannelDialog::fillThreadFinished() +{ +#ifdef CHAN_DEBUG + std::cerr << "GxsChannelDialog::fillThreadFinished()" << std::endl; +#endif + + // thread has finished + GxsChannelFillThread *thread = dynamic_cast(sender()); + if (thread) { + if (thread == fillThread) { + // current thread has finished, hide progressbar and release thread + progressBar->hide(); + progressLabel->hide(); + fillThread = NULL; + } + +#ifdef CHAN_DEBUG + if (thread->wasStopped()) { + // thread was stopped + std::cerr << "GxsChannelDialog::fillThreadFinished() Thread was stopped" << std::endl; + } +#endif + +#ifdef CHAN_DEBUG + std::cerr << "GxsChannelDialog::fillThreadFinished() Delete thread" << std::endl; +#endif + + thread->deleteLater(); + thread = NULL; + } + +#ifdef CHAN_DEBUG + std::cerr << "GxsChannelDialog::fillThreadFinished done()" << std::endl; +#endif +} + +void GxsChannelDialog::fillThreadAddMsg(const QString &channelId, const QString &channelMsgId, int current, int count) +{ + if (sender() == fillThread) { + // show fill progress + if (count) { + progressBar->setValue(current * progressBar->maximum() / count); + } + + lockLayout(NULL, true); + + ChanMsgItem *cmi = new ChanMsgItem(this, 0, channelId.toStdString(), channelMsgId.toStdString(), true); + mChanMsgItems.push_back(cmi); + verticalLayout->addWidget(cmi); + cmi->show(); + + lockLayout(cmi, false); + } +} + +#endif + + +void GxsChannelDialog::unsubscribeChannel() +{ +#ifdef CHAN_DEBUG + std::cerr << "GxsChannelDialog::unsubscribeChannel()"; + std::cerr << std::endl; +#endif + +#if 0 + if (rsChannels) { + rsChannels->channelSubscribe(mChannelId, false, false); + } + + updateChannelMsgs(); +#endif +} + + +void GxsChannelDialog::subscribeChannel() +{ +#ifdef CHAN_DEBUG + std::cerr << "GxsChannelDialog::subscribeChannel()"; + std::cerr << std::endl; +#endif + +#if 0 + if (rsChannels) { + rsChannels->channelSubscribe(mChannelId, true, false); + } + + updateChannelMsgs(); +#endif + +} + +void GxsChannelDialog::showChannelDetails() +{ +#if 0 + if (mChannelId.empty()) { + return; + } + + if (!rsChannels) { + return; + } + + ChannelDetails channelui (this); + + channelui.showDetails(mChannelId); + channelui.exec(); +#endif + +} + +void GxsChannelDialog::setAllAsReadClicked() +{ +#if 0 + if (mChannelId.empty()) { + return; + } + + if (!rsChannels) { + return; + } + + ChannelInfo ci; + if (rsChannels->getChannelInfo(mChannelId, ci) == false) { + return; + } + + if (ci.channelFlags & RS_DISTRIB_SUBSCRIBED) { + std::list msgs; + std::list::iterator it; + + rsChannels->getChannelMsgList(mChannelId, msgs); + + for(it = msgs.begin(); it != msgs.end(); it++) { + rsChannels->setMessageStatus(mChannelId, it->msgId, CHANNEL_MSG_STATUS_READ, CHANNEL_MSG_STATUS_READ | CHANNEL_MSG_STATUS_UNREAD_BY_USER); + } + } +#endif +} + +void GxsChannelDialog::toggleAutoDownload() +{ +#if 0 + + if(mChannelId.empty()) + return; + + bool autoDl = true; + + if(rsChannels->channelGetAutoDl(mChannelId, autoDl)){ + + // if auto dl is set true, then set false + if(autoDl){ + rsChannels->channelSetAutoDl(mChannelId, false); + }else{ + rsChannels->channelSetAutoDl(mChannelId, true); + } + setAutoDownloadButton(!autoDl); + } + else{ + std::cerr << "Auto Download failed to set" + << std::endl; + } +#endif +} + +bool GxsChannelDialog::navigate(const std::string& channelId, const std::string& msgId) +{ + +#if 0 + if (channelId.empty()) { + return false; + } + + if (treeWidget->activateId(QString::fromStdString(channelId), msgId.empty()) == NULL) { + return false; + } + + /* Messages are filled in selectChannel */ + if (mChannelId != channelId) { + return false; + } + + if (msgId.empty()) { + return true; + } + + /* Search exisiting item */ + QList::iterator mit; + for (mit = mChanMsgItems.begin(); mit != mChanMsgItems.end(); mit++) { + ChanMsgItem *item = *mit; + if (item->msgId() == msgId) { + // the next two lines are necessary to calculate the layout of the widgets in the scroll area (maybe there is a better solution) + item->show(); + QCoreApplication::processEvents(); + + scrollArea->ensureWidgetVisible(item, 0, 0); + return true; + } + } +#endif + + return false; +} + +void GxsChannelDialog::setAutoDownloadButton(bool autoDl) +{ +#if 0 + if (autoDl) { + actionEnable_Auto_Download->setText(tr("Disable Auto-Download")); + }else{ + actionEnable_Auto_Download->setText(tr("Enable Auto-Download")); + } +#endif +} + + + +// ForumsFillThread +GxsChannelFillThread::GxsChannelFillThread(GxsChannelDialog *parent, const std::string &channelId) + : QThread(parent) +{ + stopped = false; + this->channelId = channelId; +} + +GxsChannelFillThread::~GxsChannelFillThread() +{ +#ifdef CHAN_DEBUG + std::cerr << "GxsChannelFillThread::~GxsChannelFillThread" << std::endl; +#endif +} + +void GxsChannelFillThread::stop() +{ + disconnect(); + stopped = true; + QApplication::processEvents(); + wait(); +} + +void GxsChannelFillThread::run() +{ +#ifdef CHAN_DEBUG + std::cerr << "GxsChannelFillThread::run()" << std::endl; +#endif + + std::list msgs; + std::list::iterator it; + rsChannels->getChannelMsgList(channelId, msgs); + + msgs.sort(sortChannelMsgSummary); + + int count = msgs.size(); + int pos = 0; + + for (it = msgs.begin(); it != msgs.end(); it++) { + if (stopped) { + break; + } + + emit addMsg(QString::fromStdString(channelId), QString::fromStdString(it->msgId), ++pos, count); + } + +#ifdef CHAN_DEBUG + std::cerr << "GxsChannelFillThread::run() stopped: " << (wasStopped() ? "yes" : "no") << std::endl; +#endif +} + + + +/********************************************************************************************** + * New Stuff here. + * + * + * + *************/ + +/*********************** **** **** **** ***********************/ +/** Request / Response of Data ********************************/ +/*********************** **** **** **** ***********************/ + +#define TOKEN_TYPE_LISTING 1 +#define TOKEN_TYPE_GROUP_DATA 2 +#define TOKEN_TYPE_POSTS 3 + +void GxsChannelDialog::insertChannels() +{ + requestGroupSummary(); +} + +void GxsChannelDialog::requestGroupSummary() +{ + std::cerr << "GxsChannelDialog::requestGroupSummary()"; + std::cerr << std::endl; + + std::list tokens; + mChannelQueue->activeRequestTokens(TOKEN_TYPE_LISTING, tokens); + if (!tokens.empty()) { + std::list::iterator tokenIt; + for (tokenIt = tokens.begin(); tokenIt != tokens.end(); ++tokenIt) { + std::cerr << "GxsChannelDialog::requestGroupSummary() Canceling Request: " << *tokenIt; + std::cerr << std::endl; + + mChannelQueue->cancelRequest(*tokenIt); + } + } + + RsTokReqOptions opts; + opts.mReqType = GXS_REQUEST_TYPE_GROUP_META; + + uint32_t token; + mChannelQueue->requestGroupInfo(token, RS_TOKREQ_ANSTYPE_SUMMARY, opts, TOKEN_TYPE_LISTING); +} + +void GxsChannelDialog::loadGroupSummary(const uint32_t &token) +{ + std::cerr << "GxsChannelDialog::loadGroupSummary()"; + std::cerr << std::endl; + + std::list groupInfo; + rsGxsChannels->getGroupSummary(token, groupInfo); + + if (groupInfo.size() > 0) + { + insertChannelData(groupInfo); + } + else + { + std::cerr << "GxsChannelDialog::loadGroupSummary() ERROR No Groups..."; + std::cerr << std::endl; + } +} + + +void GxsChannelDialog::requestGroupData(const RsGxsGroupId &grpId) +{ + std::cerr << "GxsChannelDialog::requestGroupData()"; + std::cerr << std::endl; + + std::list tokens; + mChannelQueue->activeRequestTokens(TOKEN_TYPE_GROUP_DATA, tokens); + if (!tokens.empty()) { + std::list::iterator tokenIt; + for (tokenIt = tokens.begin(); tokenIt != tokens.end(); ++tokenIt) { + std::cerr << "GxsChannelDialog::requestGroupData() Canceling Request: " << *tokenIt; + std::cerr << std::endl; + + mChannelQueue->cancelRequest(*tokenIt); + } + } + + std::list groupIds; + groupIds.push_back(grpId); + + RsTokReqOptions opts; + opts.mReqType = GXS_REQUEST_TYPE_GROUP_DATA; + + uint32_t token; + mChannelQueue->requestGroupInfo(token, RS_TOKREQ_ANSTYPE_DATA, opts, groupIds, TOKEN_TYPE_GROUP_DATA); + +} + +void GxsChannelDialog::loadGroupData(const uint32_t &token) +{ + std::cerr << "GxsChannelDialog::loadGroupData()"; + std::cerr << std::endl; + + std::vector groups; + rsGxsChannels->getGroupData(token, groups); + + if (groups.size() == 1) + { + insertChannelDetails(groups[0]); + } + else + { + std::cerr << "GxsChannelDialog::loadGroupData() ERROR Not just one Group"; + std::cerr << std::endl; + } +} + + +void GxsChannelDialog::requestPosts(const RsGxsGroupId &grpId) +{ + std::cerr << "GxsChannelDialog::requestPosts()"; + std::cerr << std::endl; + + std::list tokens; + mChannelQueue->activeRequestTokens(TOKEN_TYPE_POSTS, tokens); + if (!tokens.empty()) { + std::list::iterator tokenIt; + for (tokenIt = tokens.begin(); tokenIt != tokens.end(); ++tokenIt) { + std::cerr << "GxsChannelDialog::requestPosts() Canceling Request: " << *tokenIt; + std::cerr << std::endl; + + mChannelQueue->cancelRequest(*tokenIt); + } + } + + std::list groupIds; + groupIds.push_back(grpId); + + RsTokReqOptions opts; + opts.mReqType = GXS_REQUEST_TYPE_MSG_DATA; + + uint32_t token; + mChannelQueue->requestMsgInfo(token, RS_TOKREQ_ANSTYPE_DATA, opts, groupIds, TOKEN_TYPE_POSTS); +} + +void GxsChannelDialog::loadPosts(const uint32_t &token) +{ + std::cerr << "GxsChannelDialog::loadPosts()"; + std::cerr << std::endl; + + std::vector posts; + rsGxsChannels->getPostData(token, posts); + + insertChannelPosts(posts); +} + + +void GxsChannelDialog::loadRequest(const TokenQueue *queue, const TokenRequest &req) +{ + std::cerr << "GxsChannelDialog::loadRequest() UserType: " << req.mUserType; + std::cerr << std::endl; + + if (queue == mChannelQueue) + { + /* now switch on req */ + switch(req.mUserType) + { + case TOKEN_TYPE_LISTING: + loadGroupSummary(req.mToken); + break; + case TOKEN_TYPE_GROUP_DATA: + loadGroupData(req.mToken); + break; + case TOKEN_TYPE_POSTS: + loadPosts(req.mToken); + break; + default: + std::cerr << "GxsChannelDialog::loadRequest() ERROR: INVALID TYPE"; + std::cerr << std::endl; + break; + } + } +} + + +void GxsChannelDialog::insertChannelDetails(const RsGxsChannelGroup &group) +{ + /* replace all the messages with new ones */ + QList::iterator mit; + for (mit = mChannelPostItems.begin(); mit != mChannelPostItems.end(); mit++) { + delete (*mit); + } + + mChannelPostItems.clear(); + + /* IMAGE - TODO. */ +#if 0 + QPixmap chanImage; + if (ci.pngImageLen != 0) { + chanImage.loadFromData(ci.pngChanImage, ci.pngImageLen, "PNG"); + } else { + chanImage = QPixmap(CHAN_DEFAULT_IMAGE); + } + logoLabel->setPixmap(chanImage); + logoLabel->setEnabled(true); +#endif + + /* set Channel name */ + ui.nameLabel->setText(QString::fromUtf8(group.mMeta.mGroupName.c_str())); + +#if 0 + if (group.mMeta.channelFlags & RS_DISTRIB_PUBLISH) + { + postButton->setEnabled(true); + } + else + { + postButton->setEnabled(false); + } + + if (!(ci.channelFlags & RS_DISTRIB_ADMIN) && + (ci.channelFlags & RS_DISTRIB_SUBSCRIBED)) + { + actionEnable_Auto_Download->setEnabled(true); + } + else + { + actionEnable_Auto_Download->setEnabled(false); + } +#endif + +} + + + +void GxsChannelDialog::insertChannelPosts(const std::vector &posts) +{ + std::vector::const_iterator it; + + // Do these need sorting? probably. + // can we add that into the request? + //msgs.sort(sortChannelMsgSummary); + + uint32_t subscribeFlags = 0xffffffff; + + for (it = posts.begin(); it != posts.end(); it++) + { + GxsChannelPostItem *item = new GxsChannelPostItem(this, 0, *it, subscribeFlags, true); + mChannelPostItems.push_back(item); + ui.verticalLayout->addWidget(item); + } +} + + + + diff --git a/retroshare-gui/src/gui/gxschannels/GxsChannelDialog.h b/retroshare-gui/src/gui/gxschannels/GxsChannelDialog.h new file mode 100644 index 000000000..6edb47b28 --- /dev/null +++ b/retroshare-gui/src/gui/gxschannels/GxsChannelDialog.h @@ -0,0 +1,182 @@ +/**************************************************************** + * 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 _GXS_CHANNEL_DIALOG_H +#define _GXS_CHANNEL_DIALOG_H + +#include +#include + +#include +#include +#include + +#include "mainpage.h" +#include "RsAutoUpdatePage.h" + +#include "ui_GxsChannelDialog.h" + +#include "gui/feeds/FeedHolder.h" +#include "gui/gxs/GxsCommentContainer.h" + +#include "util/TokenQueue.h" + +//class ChanMsgItem; +class GxsChannelPostItem; +class QTreeWidgetItem; +class GxsChannelFillThread; + +class GxsChannelDialog : public RsAutoUpdatePage, public TokenResponse, public GxsServiceDialog, + public FeedHolder +{ + Q_OBJECT + +public: + /** Default Constructor */ + GxsChannelDialog(QWidget *parent = 0); + /** Default Destructor */ + ~GxsChannelDialog(); + + virtual UserNotify *getUserNotify(QObject *parent); + + /* FeedHolder */ + virtual QScrollArea *getScrollArea(); + virtual void deleteFeedItem(QWidget *item, uint32_t type); + virtual void openChat(std::string peerId); + virtual void openComments(uint32_t type, const RsGxsGroupId &groupId, const RsGxsMessageId &msgId); + + bool navigate(const std::string& channelId, const std::string& msgId); + + /* overloaded from RsAuthUpdatePage */ + virtual void updateDisplay(); + + + /* NEW GXS FNS */ + void loadRequest(const TokenQueue *queue, const TokenRequest &req); + + +private slots: + void channelListCustomPopupMenu( QPoint point ); + void selectChannel(const QString &id); + + void createChannel(); + + void subscribeChannel(); + void unsubscribeChannel(); + void setAllAsReadClicked(); + void toggleAutoDownload(); + + void createMsg(); + + void showChannelDetails(); + void restoreChannelKeys(); + void editChannelDetail(); + void shareKey(); + void copyChannelLink(); + + void channelMsgReadSatusChanged(const QString& channelId, const QString& msgId, int status); + + //void generateMassData(); + + //void fillThreadFinished(); + //void fillThreadAddMsg(const QString &channelId, const QString &channelMsgId, int current, int count); + + /* NEW GXS FNS */ + void forceUpdateDisplay(); + + + +private: + //void updateChannelList(); + //void updateChannelMsgs(); + void updateMessageSummaryList(const std::string &channelId); + + void processSettings(bool load); + + void setAutoDownloadButton(bool autoDl); + + /* NEW GXS FNS */ + void insertChannels(); + + void requestGroupSummary(); + void loadGroupSummary(const uint32_t &token); + + void requestGroupData(const RsGxsGroupId &grpId); + void loadGroupData(const uint32_t &token); + + void requestPosts(const RsGxsGroupId &grpId); + void loadPosts(const uint32_t &token); + + void insertChannelData(const std::list &channelList); + + void insertChannelDetails(const RsGxsChannelGroup &group); + void insertChannelPosts(const std::vector &posts); + + + + + std::string mChannelId; /* current Channel */ + TokenQueue *mChannelQueue; + + + /* Layout Pointers */ + QBoxLayout *mMsgLayout; + + //QList mChanMsgItems; + QList mChannelPostItems; + + std::map mChanSearchScore; //chanId, score + + QTreeWidgetItem *ownChannels; + QTreeWidgetItem *subcribedChannels; + QTreeWidgetItem *popularChannels; + QTreeWidgetItem *otherChannels; + + GxsChannelFillThread *fillThread; + + + /* UI - from Designer */ + Ui::GxsChannelDialog ui; +}; + +class GxsChannelFillThread : public QThread +{ + Q_OBJECT + +public: + GxsChannelFillThread(GxsChannelDialog *parent, const std::string &channelId); + ~GxsChannelFillThread(); + + void run(); + void stop(); + bool wasStopped() { return stopped; } + +signals: + void addMsg(const QString &channelId, const QString &channelMsgId, int current, int count); + +public: + std::string channelId; + +private: + volatile bool stopped; +}; + +#endif diff --git a/retroshare-gui/src/gui/gxschannels/GxsChannelDialog.ui b/retroshare-gui/src/gui/gxschannels/GxsChannelDialog.ui new file mode 100644 index 000000000..c5c10263e --- /dev/null +++ b/retroshare-gui/src/gui/gxschannels/GxsChannelDialog.ui @@ -0,0 +1,366 @@ + + + GxsChannelDialog + + + + 0 + 0 + 681 + 476 + + + + + + + Qt::Horizontal + + + + + 0 + 0 + + + + + 1 + + + 0 + + + + + QFrame::Box + + + QFrame::Sunken + + + + 2 + + + + + + 24 + 24 + + + + + + + :/images/channels32.png + + + true + + + + + + + + 10 + 75 + true + + + + Channels + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + refresh + + + + + + + Qt::NoFocus + + + Display + + + + :/images/looknfeel.png:/images/looknfeel.png + + + + 32 + 16 + + + + QToolButton::InstantPopup + + + true + + + + + + + true + + + Qt::NoFocus + + + Create Channel + + + + :/images/add_channel24.png:/images/add_channel24.png + + + + 32 + 16 + + + + true + + + + + + + + + + + 0 + 0 + + + + + + + + + + + + QFrame::Box + + + QFrame::Sunken + + + + 4 + + + + + + 64 + 64 + + + + + 64 + 64 + + + + + + + :/images/channels.png + + + true + + + + + + + + + + + + + + + 21 + + + + Channel Name + + + true + + + + + + + + + + true + + + + + 0 + 0 + 380 + 16 + + + + + 0 + 0 + + + + + 0 + + + 0 + + + + + + + + + + + Loading + + + + + + + 1000 + + + 24 + + + + + + + + + QFrame::Box + + + QFrame::Sunken + + + + 2 + + + + + Qt::NoFocus + + + Post to Channel + + + + :/images/mail_send.png:/images/mail_send.png + + + + 32 + 16 + + + + true + + + + + + + Qt::Horizontal + + + + 314 + 10 + + + + + + + + + + + + + + + Set all as read + + + Set all as read + + + + + Enable Auto-Download + + + Enable Auto-Download + + + + + + GroupTreeWidget + QWidget +
gui/common/GroupTreeWidget.h
+ 1 +
+
+ + + + +
diff --git a/retroshare-gui/src/gui/gxschannels/GxsChannelGroupDialog.cpp b/retroshare-gui/src/gui/gxschannels/GxsChannelGroupDialog.cpp new file mode 100644 index 000000000..fe4ccec16 --- /dev/null +++ b/retroshare-gui/src/gui/gxschannels/GxsChannelGroupDialog.cpp @@ -0,0 +1,95 @@ +/**************************************************************** + * RetroShare is distributed under the following license: + * + * Copyright (C) 2013 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 "GxsChannelGroupDialog.h" + +#include +#include + +// To start with we only have open forums - with distribution controls. + +const uint32_t ChannelCreateEnabledFlags = ( GXS_GROUP_FLAGS_ICON | + GXS_GROUP_FLAGS_DESCRIPTION | + GXS_GROUP_FLAGS_DISTRIBUTION | + // GXS_GROUP_FLAGS_PUBLISHSIGN | + GXS_GROUP_FLAGS_SHAREKEYS | + // GXS_GROUP_FLAGS_PERSONALSIGN | + GXS_GROUP_FLAGS_COMMENTS | + 0); + +const uint32_t ChannelCreateDefaultsFlags = ( GXS_GROUP_DEFAULTS_DISTRIB_PUBLIC | + //GXS_GROUP_DEFAULTS_DISTRIB_GROUP | + //GXS_GROUP_DEFAULTS_DISTRIB_LOCAL | + + GXS_GROUP_DEFAULTS_PUBLISH_OPEN | + //GXS_GROUP_DEFAULTS_PUBLISH_THREADS | + //GXS_GROUP_DEFAULTS_PUBLISH_REQUIRED | + //GXS_GROUP_DEFAULTS_PUBLISH_ENCRYPTED | + + //GXS_GROUP_DEFAULTS_PERSONAL_GPG | + GXS_GROUP_DEFAULTS_PERSONAL_REQUIRED | + //GXS_GROUP_DEFAULTS_PERSONAL_IFNOPUB | + + GXS_GROUP_DEFAULTS_COMMENTS_YES | + //GXS_GROUP_DEFAULTS_COMMENTS_NO | + 0); + +GxsChannelGroupDialog::GxsChannelGroupDialog(TokenQueue *tokenQueue, QWidget *parent) + :GxsGroupDialog(tokenQueue, ChannelCreateEnabledFlags, ChannelCreateDefaultsFlags, parent) +{ +} + +GxsChannelGroupDialog::GxsChannelGroupDialog(const RsGxsChannelGroup &group, Mode mode, QWidget *parent) + :GxsGroupDialog(group.mMeta, mode, parent) +{ +} + +void GxsChannelGroupDialog::initUi() +{ + switch (mode()) + { + case MODE_CREATE: + setUiText(UITYPE_SERVICE_HEADER, tr("Create New Channel")); + break; + case MODE_SHOW: + setUiText(UITYPE_SERVICE_HEADER, tr("Channel")); + break; + case MODE_EDIT: + setUiText(UITYPE_SERVICE_HEADER, tr("Edit Channel")); + break; + } +} + +QPixmap GxsChannelGroupDialog::serviceImage() +{ + return QPixmap(":/images/konversation64.png"); +} + +bool GxsChannelGroupDialog::service_CreateGroup(uint32_t &token, const RsGroupMetaData &meta) +{ + // Specific Function. + RsGxsChannelGroup grp; + grp.mMeta = meta; + //grp.mDescription = std::string(desc.toUtf8()); + + rsGxsChannels->createGroup(token, grp); + return true; +} diff --git a/retroshare-gui/src/gui/gxschannels/GxsChannelGroupDialog.h b/retroshare-gui/src/gui/gxschannels/GxsChannelGroupDialog.h new file mode 100644 index 000000000..f1a9d174f --- /dev/null +++ b/retroshare-gui/src/gui/gxschannels/GxsChannelGroupDialog.h @@ -0,0 +1,42 @@ +/**************************************************************** + * RetroShare is distributed under the following license: + * + * Copyright (C) 2013 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 _GXSCHANNEL_GROUP_DIALOG_H +#define _GXSCHANNEL_GROUP_DIALOG_H + +#include "gui/gxs/GxsGroupDialog.h" +#include + +class GxsChannelGroupDialog : public GxsGroupDialog +{ + Q_OBJECT + +public: + GxsChannelGroupDialog(TokenQueue *tokenQueue, QWidget *parent); + GxsChannelGroupDialog(const RsGxsChannelGroup &group, Mode mode, QWidget *parent); + +protected: + virtual void initUi(); + virtual QPixmap serviceImage(); + virtual bool service_CreateGroup(uint32_t &token, const RsGroupMetaData &meta); +}; + +#endif diff --git a/retroshare-gui/src/gui/gxsforums/GxsForumThreadWidget.cpp b/retroshare-gui/src/gui/gxsforums/GxsForumThreadWidget.cpp index d6666e14d..d1fa2341c 100644 --- a/retroshare-gui/src/gui/gxsforums/GxsForumThreadWidget.cpp +++ b/retroshare-gui/src/gui/gxsforums/GxsForumThreadWidget.cpp @@ -1808,19 +1808,6 @@ void GxsForumThreadWidget::loadMsgData_InsertPost(const uint32_t &token) void GxsForumThreadWidget::requestMsgData_ReplyMessage(const RsGxsGrpMsgIdPair &msgId) { -#if 0 - RsTokReqOptions opts; - opts.mReqType = GXS_REQUEST_TYPE_MSG_RELATED_DATA; - - std::cerr << "GxsForumsDialog::requestMsgData_ReplyMessage(" << msgId.first << "," << msgId.second << ")"; - std::cerr << std::endl; - - std::vector msgIds; - msgIds.push_back(msgId); - uint32_t token; - mThreadQueue->requestMsgRelatedInfo(token, RS_TOKREQ_ANSTYPE_DATA, opts, msgIds, TOKEN_TYPE_REPLY_MESSAGE); -#else - RsTokReqOptions opts; opts.mReqType = GXS_REQUEST_TYPE_MSG_DATA; @@ -1833,7 +1820,7 @@ void GxsForumThreadWidget::requestMsgData_ReplyMessage(const RsGxsGrpMsgIdPair & uint32_t token; mThreadQueue->requestMsgInfo(token, RS_TOKREQ_ANSTYPE_DATA, opts, msgIds, TOKEN_TYPE_REPLY_MESSAGE); -#endif + } void GxsForumThreadWidget::loadMsgData_ReplyMessage(const uint32_t &token) @@ -1842,11 +1829,7 @@ void GxsForumThreadWidget::loadMsgData_ReplyMessage(const uint32_t &token) std::cerr << std::endl; std::vector msgs; -#if 0 - if (rsGxsForums->getRelatedMessages(token, msgs)) -#else if (rsGxsForums->getMsgData(token, msgs)) -#endif { if (msgs.size() != 1) { diff --git a/retroshare-gui/src/gui/unfinished/ApplicationWindow.cpp b/retroshare-gui/src/gui/unfinished/ApplicationWindow.cpp index b6e1fc2a3..86344bfb1 100644 --- a/retroshare-gui/src/gui/unfinished/ApplicationWindow.cpp +++ b/retroshare-gui/src/gui/unfinished/ApplicationWindow.cpp @@ -32,6 +32,7 @@ #include "gui/WikiPoos/WikiDialog.h" #include "gui/Posted/PostedDialog.h" #include "gui/GxsForumsDialog.h" +#include "gui/gxschannels/ChannelDialog.h" // THESE HAVE TO BE CONVERTED TO VEG FORMAT #if USE_VEG_SERVICE @@ -57,7 +58,7 @@ #define IMAGE_GXSFORUMS ":/images/konversation.png" #define IMAGE_WIKI ":/images/wikibook_32.png" #define IMAGE_POSTED ":/images/posted_32.png" - +#define IMAGE_GXSCHANNELS ":/images/channels.png" /** Constructor */ ApplicationWindow::ApplicationWindow(QWidget* parent, Qt::WFlags flags) @@ -103,6 +104,7 @@ ApplicationWindow::ApplicationWindow(QWidget* parent, Qt::WFlags flags) PostedDialog *postedDialog = NULL; ui.stackPages->add(postedDialog = new PostedDialog(ui.stackPages), createPageAction(QIcon(IMAGE_POSTED), tr("Posted Links"), grp)); + postedDialog->setup(); WikiDialog *wikiDialog = NULL; ui.stackPages->add(wikiDialog = new WikiDialog(ui.stackPages), @@ -112,6 +114,11 @@ ApplicationWindow::ApplicationWindow(QWidget* parent, Qt::WFlags flags) ui.stackPages->add(gxsforumsDialog = new GxsForumsDialog(ui.stackPages), createPageAction(QIcon(IMAGE_GXSFORUMS), tr("GxsForums"), grp)); + ChannelDialog *gxschannelDialog = NULL; + ui.stackPages->add(gxschannelDialog = new ChannelDialog(ui.stackPages), + createPageAction(QIcon(IMAGE_GXSCHANNELS), tr("GxsChannels"), grp)); + gxschannelDialog->setup(); + // THESE HAVE TO BE CONVERTED TO VEG FORMAT #if USE_VEG_SERVICE WireDialog *wireDialog = NULL; diff --git a/retroshare-gui/src/retroshare-gui.pro b/retroshare-gui/src/retroshare-gui.pro index dc1c58320..4b25833c6 100644 --- a/retroshare-gui/src/retroshare-gui.pro +++ b/retroshare-gui/src/retroshare-gui.pro @@ -2,7 +2,7 @@ CONFIG += qt gui uic qrc resources uitools idle bitdht # Below is for GXS services. # Should be disabled for releases. -#CONFIG += gxs +#CONFIG += gxs debug gxs { CONFIG += photoshare @@ -10,6 +10,7 @@ gxs { CONFIG += identities CONFIG += circles CONFIG += gxsforums + CONFIG += gxschannels CONFIG += posted CONFIG += unfinished CONFIG += gxsgui @@ -1047,31 +1048,53 @@ gxsforums { } +gxschannels { + + HEADERS += gui/gxschannels/GxsChannelDialog.h \ + gui/gxschannels/GxsChannelGroupDialog.h \ + gui/gxschannels/CreateGxsChannelMsg.h \ + gui/gxschannels/ChannelDialog.h \ + gui/feeds/GxsChannelPostItem.h \ + + FORMS += gui/gxschannels/GxsChannelDialog.ui \ + gui/gxschannels/CreateGxsChannelMsg.ui \ + gui/feeds/GxsChannelPostItem.ui \ + + SOURCES += gui/gxschannels/GxsChannelDialog.cpp \ + gui/gxschannels/GxsChannelGroupDialog.cpp \ + gui/gxschannels/CreateGxsChannelMsg.cpp \ + gui/feeds/GxsChannelPostItem.cpp \ +} + + posted { HEADERS += gui/Posted/PostedDialog.h \ gui/Posted/PostedListDialog.h \ gui/Posted/PostedItem.h \ - gui/Posted/PostedComments.h \ gui/Posted/PostedGroupDialog.h \ gui/Posted/PostedCreatePostDialog.h \ - gui/Posted/PostedCreateCommentDialog.h \ gui/Posted/PostedUserTypes.h + + #gui/Posted/PostedCreateCommentDialog.h \ + #gui/Posted/PostedComments.h \ - FORMS += gui/Posted/PostedDialog.ui \ - gui/Posted/PostedListDialog.ui \ + FORMS += gui/Posted/PostedListDialog.ui \ gui/Posted/PostedItem.ui \ - gui/Posted/PostedComments.ui \ gui/Posted/PostedCreatePostDialog.ui \ - gui/Posted/PostedCreateCommentDialog.ui + + #gui/Posted/PostedDialog.ui \ + #gui/Posted/PostedComments.ui \ + #gui/Posted/PostedCreateCommentDialog.ui - SOURCES += gui/Posted/PostedDialog.cpp \ - gui/Posted/PostedListDialog.cpp \ + SOURCES += gui/Posted/PostedListDialog.cpp \ gui/Posted/PostedItem.cpp \ - gui/Posted/PostedComments.cpp \ gui/Posted/PostedGroupDialog.cpp \ gui/Posted/PostedCreatePostDialog.cpp \ - gui/Posted/PostedCreateCommentDialog.cpp + + #gui/Posted/PostedDialog.cpp \ + #gui/Posted/PostedComments.cpp \ + #gui/Posted/PostedCreateCommentDialog.cpp RESOURCES += gui/Posted/Posted_images.qrc } @@ -1079,30 +1102,39 @@ posted { gxsgui { HEADERS += gui/gxs/GxsGroupDialog.h \ - gui/gxs/GxsCommentTreeWidget.h \ gui/gxs/WikiGroupDialog.h \ gui/gxs/GxsIdChooser.h \ gui/gxs/GxsIdLabel.h \ gui/gxs/GxsCircleChooser.h \ gui/gxs/GxsCircleLabel.h \ gui/gxs/GxsIdTreeWidgetItem.h \ + gui/gxs/GxsCommentTreeWidget.h \ + gui/gxs/GxsCommentContainer.h \ + gui/gxs/GxsCommentDialog.h \ + gui/gxs/GxsCreateCommentDialog.h \ util/TokenQueue.h \ # gui/gxs/GxsMsgDialog.h \ FORMS += gui/gxs/GxsGroupDialog.ui \ + gui/gxs/GxsCommentContainer.ui \ + gui/gxs/GxsCommentDialog.ui \ + gui/gxs/GxsCreateCommentDialog.ui \ # gui/gxs/GxsMsgDialog.ui \ # gui/gxs/GxsCommentTreeWidget.ui \ SOURCES += gui/gxs/GxsGroupDialog.cpp \ - gui/gxs/GxsCommentTreeWidget.cpp \ gui/gxs/WikiGroupDialog.cpp \ gui/gxs/GxsIdChooser.cpp \ gui/gxs/GxsIdLabel.cpp \ gui/gxs/GxsCircleChooser.cpp \ gui/gxs/GxsCircleLabel.cpp \ gui/gxs/GxsIdTreeWidgetItem.cpp \ + gui/gxs/GxsCommentTreeWidget.cpp \ + gui/gxs/GxsCommentContainer.cpp \ + gui/gxs/GxsCommentDialog.cpp \ + gui/gxs/GxsCreateCommentDialog.cpp \ util/TokenQueue.cpp \ # gui/gxs/GxsMsgDialog.cpp \