From 48683a19d59d3971890ddc3adb017df167c045e2 Mon Sep 17 00:00:00 2001 From: drbob Date: Wed, 1 Aug 2012 01:47:53 +0000 Subject: [PATCH] * Added first pass at Generic Comment Tree. - Specific to Posted at the moment. * Modified Posted to load Comments when Post "comment" button is pressed. git-svn-id: http://svn.code.sf.net/p/retroshare/code/branches/v0.5-gxs-b1@5366 b45a01b8-16f6-495d-af2f-9b41ad6348cc --- retroshare-gui/src/RetroShare.pro | 6 +- .../src/gui/Posted/PostedComments.cpp | 11 + .../src/gui/Posted/PostedComments.h | 5 + .../src/gui/Posted/PostedComments.ui | 164 +++----- .../src/gui/Posted/PostedDialog.cpp | 1 + retroshare-gui/src/gui/Posted/PostedItem.cpp | 13 + retroshare-gui/src/gui/Posted/PostedItem.h | 9 + retroshare-gui/src/gui/Posted/PostedItem.ui | 2 +- .../src/gui/Posted/PostedListDialog.cpp | 11 + .../src/gui/Posted/PostedListDialog.h | 3 + .../src/gui/Posted/PostedListDialog.ui | 3 + .../src/gui/gxs/GxsCommentTreeWidget.cpp | 372 ++++++++++++++++++ .../src/gui/gxs/GxsCommentTreeWidget.h | 88 +++++ 13 files changed, 576 insertions(+), 112 deletions(-) create mode 100644 retroshare-gui/src/gui/gxs/GxsCommentTreeWidget.cpp create mode 100644 retroshare-gui/src/gui/gxs/GxsCommentTreeWidget.h diff --git a/retroshare-gui/src/RetroShare.pro b/retroshare-gui/src/RetroShare.pro index ac3200f91..4e3c47782 100644 --- a/retroshare-gui/src/RetroShare.pro +++ b/retroshare-gui/src/RetroShare.pro @@ -973,19 +973,19 @@ gxsgui { gui/gxs/ForumV2GroupDialog.h \ gui/gxs/WikiGroupDialog.h \ gui/gxs/PostedGroupDialog.h \ + gui/gxs/GxsCommentTreeWidget.h \ # gui/gxs/GxsMsgDialog.h \ -# gui/gxs/GxsCommentWidget.h \ FORMS += gui/gxs/GxsGroupDialog.ui \ # gui/gxs/GxsMsgDialog.ui \ -# gui/gxs/GxsCommentWidget.ui \ +# gui/gxs/GxsCommentTreeWidget.ui \ SOURCES += gui/gxs/GxsGroupDialog.cpp \ gui/gxs/ForumV2GroupDialog.cpp \ gui/gxs/WikiGroupDialog.cpp \ gui/gxs/PostedGroupDialog.cpp \ + gui/gxs/GxsCommentTreeWidget.cpp \ # gui/gxs/GxsMsgDialog.cpp \ -# gui/gxs/GxsCommentWidget.cpp \ } diff --git a/retroshare-gui/src/gui/Posted/PostedComments.cpp b/retroshare-gui/src/gui/Posted/PostedComments.cpp index 4e1f73bab..00328335a 100644 --- a/retroshare-gui/src/gui/Posted/PostedComments.cpp +++ b/retroshare-gui/src/gui/Posted/PostedComments.cpp @@ -83,8 +83,19 @@ PostedComments::PostedComments(QWidget *parent) /* setup TokenQueue */ //mPhotoQueue = new TokenQueue(rsPhoto, this); + ui.treeWidget->setup(rsPosted); + } +void PostedComments::loadComments( std::string threadId ) +{ + std::cerr << "PostedComments::loadComments(" << threadId << ")"; + std::cerr << std::endl; + + ui.treeWidget->requestComments(threadId); +} + + #if 0 void PhotoDialog::notifySelection(PhotoItem *item, int ptype) diff --git a/retroshare-gui/src/gui/Posted/PostedComments.h b/retroshare-gui/src/gui/Posted/PostedComments.h index 78d52354d..9da5a8447 100644 --- a/retroshare-gui/src/gui/Posted/PostedComments.h +++ b/retroshare-gui/src/gui/Posted/PostedComments.h @@ -43,6 +43,9 @@ class PostedComments: public QWidget, public TokenResponse public: PostedComments(QWidget *parent = 0); +public slots: + void loadComments( std::string ); + private: void loadRequest(const TokenQueue *queue, const TokenRequest &req) { return; } @@ -53,6 +56,8 @@ virtual void notifySelection(PhotoItem *item, int ptype); void notifyAlbumSelection(PhotoItem *item); void notifyPhotoSelection(PhotoItem *item); + + private slots: void checkUpdate(); diff --git a/retroshare-gui/src/gui/Posted/PostedComments.ui b/retroshare-gui/src/gui/Posted/PostedComments.ui index 0b974c14f..e2ea38c34 100644 --- a/retroshare-gui/src/gui/Posted/PostedComments.ui +++ b/retroshare-gui/src/gui/Posted/PostedComments.ui @@ -13,8 +13,8 @@ Form - - + + @@ -51,119 +51,67 @@ - - - - Today - - - - - Yesterday - - - - - This Week - - - - - This Month - - - - - This Year - - + + + Refresh + - - - - - - - - Refresh - - - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - Showing 1-100 - - - - - - - Prev - - - - - - - Next - - - - - - - - - true - - - - - 0 - 0 - 382 - 302 - - - - - - - - - - 0 - 0 - - - - - 1 - - - - - + + + + + Stuff + + + + + New Column + + + + + Yes More + + + + + more, more, more + + + + + More Stuff + + + + + Less Stuff + + + + + More + + + + + asdf + + + + + + GxsCommentTreeWidget + QTreeWidget +
gui/gxs/GxsCommentTreeWidget.h
+
+
diff --git a/retroshare-gui/src/gui/Posted/PostedDialog.cpp b/retroshare-gui/src/gui/Posted/PostedDialog.cpp index 934fd02dd..38d92a186 100644 --- a/retroshare-gui/src/gui/Posted/PostedDialog.cpp +++ b/retroshare-gui/src/gui/Posted/PostedDialog.cpp @@ -70,6 +70,7 @@ PostedDialog::PostedDialog(QWidget *parent) QString comments("Comments"); ui.tabWidget->addTab(mPostedComments, comments); + connect(mPostedList, SIGNAL(loadComments( std::string ) ), mPostedComments, SLOT(loadComments( std::string ) ) ); } diff --git a/retroshare-gui/src/gui/Posted/PostedItem.cpp b/retroshare-gui/src/gui/Posted/PostedItem.cpp index e1b57e754..92c7717dc 100644 --- a/retroshare-gui/src/gui/Posted/PostedItem.cpp +++ b/retroshare-gui/src/gui/Posted/PostedItem.cpp @@ -72,10 +72,23 @@ PostedItem::PostedItem(PostedHolder *parent, const RsPostedPost &post) ts.setTime_t(post.mMeta.mPublishTs); dateLabel->setText(ts.toString(QString("yyyy/MM/dd hh:mm:ss"))); + mThreadId = post.mMeta.mThreadId; + mParent = parent; + + connect( commentButton, SIGNAL( clicked() ), this, SLOT( loadComments() ) ); + return; } +void PostedItem::loadComments() +{ + std::cerr << "PostedItem::loadComments() Requesting for " << mThreadId; + std::cerr << std::endl; + mParent->requestComments(mThreadId); +} + + #if 0 PhotoItem::PhotoItem(PhotoHolder *parent, const RsPhotoAlbum &album) diff --git a/retroshare-gui/src/gui/Posted/PostedItem.h b/retroshare-gui/src/gui/Posted/PostedItem.h index c0d830811..b13925802 100644 --- a/retroshare-gui/src/gui/Posted/PostedItem.h +++ b/retroshare-gui/src/gui/Posted/PostedItem.h @@ -36,6 +36,8 @@ class PostedHolder public: virtual void deletePostedItem(PostedItem *, uint32_t ptype) = 0; virtual void notifySelection(PostedItem *item, int ptype) = 0; + +virtual void requestComments(std::string threadId) = 0; }; class PostedItem : public QWidget, private Ui::PostedItem @@ -55,9 +57,16 @@ public: protected: //void mousePressEvent(QMouseEvent *event); +private slots: + void loadComments(); + private: uint32_t mType; bool mSelected; + + std::string mThreadId; + PostedHolder *mParent; + }; diff --git a/retroshare-gui/src/gui/Posted/PostedItem.ui b/retroshare-gui/src/gui/Posted/PostedItem.ui index ad1501e08..bacacace5 100644 --- a/retroshare-gui/src/gui/Posted/PostedItem.ui +++ b/retroshare-gui/src/gui/Posted/PostedItem.ui @@ -265,7 +265,7 @@ border-radius: 10px}
- + View Comments diff --git a/retroshare-gui/src/gui/Posted/PostedListDialog.cpp b/retroshare-gui/src/gui/Posted/PostedListDialog.cpp index 745035c7e..0c926be1e 100644 --- a/retroshare-gui/src/gui/Posted/PostedListDialog.cpp +++ b/retroshare-gui/src/gui/Posted/PostedListDialog.cpp @@ -185,6 +185,17 @@ void PostedListDialog::updateDisplay() } +void PostedListDialog::requestComments(std::string threadId) +{ + /* call a signal */ + std::cerr << "PostedListDialog::requestComments(" << threadId << ")"; + std::cerr << std::endl; + + loadComments(threadId); + +} + + void PostedListDialog::changedTopic(const QString &id) { mCurrTopicId = id.toStdString(); diff --git a/retroshare-gui/src/gui/Posted/PostedListDialog.h b/retroshare-gui/src/gui/Posted/PostedListDialog.h index 0cd6c4670..14dd7c2ca 100644 --- a/retroshare-gui/src/gui/Posted/PostedListDialog.h +++ b/retroshare-gui/src/gui/Posted/PostedListDialog.h @@ -47,7 +47,10 @@ public: virtual void deletePostedItem(PostedItem *, uint32_t ptype) { return; } virtual void notifySelection(PostedItem *item, int ptype) { return; } +virtual void requestComments(std::string threadId); +signals: + void loadComments( std::string ); private slots: diff --git a/retroshare-gui/src/gui/Posted/PostedListDialog.ui b/retroshare-gui/src/gui/Posted/PostedListDialog.ui index 36a536087..a685a6d99 100644 --- a/retroshare-gui/src/gui/Posted/PostedListDialog.ui +++ b/retroshare-gui/src/gui/Posted/PostedListDialog.ui @@ -18,6 +18,9 @@ + + false + -1 diff --git a/retroshare-gui/src/gui/gxs/GxsCommentTreeWidget.cpp b/retroshare-gui/src/gui/gxs/GxsCommentTreeWidget.cpp new file mode 100644 index 000000000..e1ea83ec4 --- /dev/null +++ b/retroshare-gui/src/gui/gxs/GxsCommentTreeWidget.cpp @@ -0,0 +1,372 @@ +/**************************************************************** +* 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 "gui/gxs/GxsCommentTreeWidget.h" + +#include + +#define PCITEM_COLUMN_DATE 0 +#define PCITEM_COLUMN_COMMENT 1 +#define PCITEM_COLUMN_AUTHOR 2 +#define PCITEM_COLUMN_SERVSTRING 3 +#define PCITEM_COLUMN_MSGID 4 +#define PCITEM_COLUMN_PARENTID 5 + +#define GXSCOMMENTS_LOADTHREAD 1 + +// Temporarily make this specific. +#include "retroshare/rsposted.h" + + +GxsCommentTreeWidget::GxsCommentTreeWidget(QWidget *parent) + :QTreeWidget(parent), mRsService(NULL), mTokenQueue(NULL) +{ + + return; +} + +void GxsCommentTreeWidget::setup(RsTokenService *service) +{ + mRsService = service; + mTokenQueue = new TokenQueue(service, this); + + return; +} + + +/* Load Comments */ +void GxsCommentTreeWidget::requestComments(std::string threadId) +{ + /* request comments */ + + service_requestComments(threadId); +} + +void GxsCommentTreeWidget::service_requestComments(std::string threadId) +{ + /* request comments */ + //std::cerr << "GxsCommentTreeWidget::service_requestComments() ERROR must be overloaded!"; + //std::cerr << std::endl; + + std::cerr << "GxsCommentTreeWidget::service_requestComments(" << threadId << ")"; + std::cerr << std::endl; + + RsTokReqOptions opts; + + opts.mOptions = RS_TOKREQOPT_MSG_THREAD | RS_TOKREQOPT_MSG_LATEST; + opts.mFlagsFilter = RSPOSTED_MSGTYPE_COMMENT; + opts.mFlagsMask = RSPOSTED_MSGTYPE_COMMENT; + + std::list msgIds; + msgIds.push_back(threadId); + + mThreadId = threadId; + + uint32_t token; + mTokenQueue->requestMsgRelatedInfo(token, RS_TOKREQ_ANSTYPE_DATA, opts, msgIds, GXSCOMMENTS_LOADTHREAD); +} + + +/* Generic Handling */ +void GxsCommentTreeWidget::clearItems() +{ + mPendingInsertMap.clear(); + mLoadingMap.clear(); +} + + +void GxsCommentTreeWidget::completeItems() +{ + /* handle pending items */ + std::string parentId; + QTreeWidgetItem *parent = NULL; + QList topLevelItems; + + std::map::iterator lit; + std::multimap::iterator pit; + + std::cerr << "GxsCommentTreeWidget::completeItems() " << mPendingInsertMap.size(); + std::cerr << " PendingItems"; + std::cerr << std::endl; + + for(pit = mPendingInsertMap.begin(); pit != mPendingInsertMap.end(); pit++) + { + std::cerr << "GxsCommentTreeWidget::completeItems() item->parent: " << pit->first; + std::cerr << std::endl; + + if (pit->first != parentId) + { + /* find parent */ + parentId = pit->first; + lit = mLoadingMap.find(pit->first); + if (lit != mLoadingMap.end()) + { + parent = lit->second; + } + else + { + parent = NULL; + } + } + + if (parent) + { + std::cerr << "GxsCommentTreeWidget::completeItems() Added to Parent"; + std::cerr << std::endl; + + parent->addChild(pit->second); + } + else if (parentId == mThreadId) + { + std::cerr << "GxsCommentTreeWidget::completeItems() Added to topLevelItems"; + std::cerr << std::endl; + + topLevelItems.append(pit->second); + } + else + { + + /* missing parent -> insert At Top Level */ + QTreeWidgetItem *missingItem = service_createMissingItem(pit->first); + + std::cerr << "GxsCommentTreeWidget::completeItems() Added MissingItem"; + std::cerr << std::endl; + + parent = missingItem; + parent->addChild(pit->second); + topLevelItems.append(parent); + } + } + + /* now push final tree into Tree */ + clear(); + insertTopLevelItems(0, topLevelItems); + + /* cleanup temp stuff */ + mLoadingMap.clear(); + mPendingInsertMap.clear(); +} + + +void GxsCommentTreeWidget::addItem(std::string itemId, std::string parentId, QTreeWidgetItem *item) +{ + std::cerr << "GxsCommentTreeWidget::addItem() Id: " << itemId; + std::cerr << " ParentId: " << parentId; + std::cerr << std::endl; + + /* store in map -> for children */ + mLoadingMap[itemId] = item; + + std::map::iterator it; + it = mLoadingMap.find(parentId); + if (it != mLoadingMap.end()) + { + std::cerr << "GxsCommentTreeWidget::addItem() Added to Parent"; + std::cerr << std::endl; + + it->second->addChild(item); + } + else + { + std::cerr << "GxsCommentTreeWidget::addItem() Added to Pending List"; + std::cerr << std::endl; + + mPendingInsertMap.insert(std::make_pair(parentId, item)); + } +} + +void GxsCommentTreeWidget::loadThread(const uint32_t &token) +{ + clearItems(); + + service_loadThread(token); + + completeItems(); +} + + +void GxsCommentTreeWidget::service_loadThread(const uint32_t &token) +{ + std::cerr << "GxsCommentTreeWidget::service_loadThread() ERROR must be overloaded!"; + std::cerr << std::endl; + + RsPostedComment comment; + while(rsPosted->getComment(token, comment)) + { + /* convert to a QTreeWidgetItem */ + std::cerr << "GxsCommentTreeWidget::service_loadThread() Got Comment: " << comment; + std::cerr << std::endl; + + QTreeWidgetItem *item = new QTreeWidgetItem(); + QString text; + + { + QDateTime qtime; + qtime.setTime_t(comment.mMeta.mPublishTs); + + text = qtime.toString("yyyy-MM-dd hh:mm:ss"); + item->setText(PCITEM_COLUMN_DATE, text); + } + + text = QString::fromUtf8(comment.mComment.c_str()); + item->setText(PCITEM_COLUMN_COMMENT, text); + + text = QString::fromUtf8(comment.mMeta.mAuthorId.c_str()); + if (text.isEmpty()) + { + item->setText(PCITEM_COLUMN_AUTHOR, tr("Anonymous")); + } + else + { + item->setText(PCITEM_COLUMN_AUTHOR, text); + } + + + text = QString::fromUtf8(comment.mMeta.mMsgId.c_str()); + item->setText(PCITEM_COLUMN_MSGID, text); + + text = QString::fromUtf8(comment.mMeta.mParentId.c_str()); + item->setText(PCITEM_COLUMN_PARENTID, text); + + text = QString::fromUtf8(comment.mMeta.mServiceString.c_str()); + item->setText(PCITEM_COLUMN_SERVSTRING, text); + + addItem(comment.mMeta.mMsgId, comment.mMeta.mParentId, item); + } + + return; +} + +QTreeWidgetItem *GxsCommentTreeWidget::service_createMissingItem(std::string parent) +{ + //std::cerr << "GxsCommentTreeWidget::service_createMissingItem() ERROR must be overloaded!"; + //std::cerr << std::endl; + + std::cerr << "GxsCommentTreeWidget::service_createMissingItem()"; + std::cerr << std::endl; + + QTreeWidgetItem *item = new QTreeWidgetItem(); + QString text("Unknown"); + + item->setText(PCITEM_COLUMN_DATE, text); + + item->setText(PCITEM_COLUMN_COMMENT, text); + + item->setText(PCITEM_COLUMN_AUTHOR, text); + + item->setText(PCITEM_COLUMN_MSGID, text); + + item->setText(PCITEM_COLUMN_SERVSTRING, text); + + text = QString::fromUtf8(parent.c_str()); + item->setText(PCITEM_COLUMN_PARENTID, text); + + return item; +} + + +void GxsCommentTreeWidget::loadRequest(const TokenQueue *queue, const TokenRequest &req) +{ + std::cerr << "GxsCommentTreeWidget::loadRequest() UserType: " << req.mUserType; + std::cerr << std::endl; + + if (queue != mTokenQueue) + { + std::cerr << "GxsCommentTreeWidget::loadRequest() Queue ERROR"; + std::cerr << std::endl; + return; + } + + /* now switch on req */ + switch(req.mUserType) + { + + case GXSCOMMENTS_LOADTHREAD: + loadThread(req.mToken); + break; + default: + std::cerr << "GxsCommentTreeWidget::loadRequest() UNKNOWN UserType "; + std::cerr << std::endl; + break; + } +} + + + +#if 0 + + +QMimeData * GxsCommentTreeWidget::mimeData ( const QList items ) const +{ + /* extract from each QTreeWidgetItem... all the member text */ + QList::const_iterator it; + QString text; + for(it = items.begin(); it != items.end(); it++) + { + QString line = QString("%1/%2/%3/").arg((*it)->text(SR_NAME_COL), (*it)->text(SR_HASH_COL), (*it)->text(SR_SIZE_COL)); + + bool isLocal = (*it)->data(SR_DATA_COL, SR_ROLE_LOCAL).toBool(); + if (isLocal) + { + line += "Local"; + } + else + { + line += "Remote"; + } + line += "/\n"; + + text += line; + } + + std::cerr << "Created MimeData:"; + std::cerr << std::endl; + + std::string str = text.toUtf8().constData(); + std::cerr << str; + std::cerr << std::endl; + + QMimeData *data = new QMimeData(); + data->setData("application/x-rsfilelist", QByteArray(str.c_str())); + + return data; +} + + + +QStringList GxsCommentTreeWidget::mimeTypes () const +{ + QStringList list; + list.push_back("application/x-rsfilelist"); + + return list; +} + + +Qt::DropActions GxsCommentTreeWidget::supportedDropActions () const +{ + return Qt::CopyAction; +} + +#endif diff --git a/retroshare-gui/src/gui/gxs/GxsCommentTreeWidget.h b/retroshare-gui/src/gui/gxs/GxsCommentTreeWidget.h new file mode 100644 index 000000000..41850b9ba --- /dev/null +++ b/retroshare-gui/src/gui/gxs/GxsCommentTreeWidget.h @@ -0,0 +1,88 @@ +/**************************************************************** +* 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_COMMENT_TREE_WIDGET_H +#define _GXS_COMMENT_TREE_WIDGET_H + +#include + +#include "util/TokenQueue.h" + +/* indicies for search results item columns SR_ = Search Result */ +#define SR_NAME_COL 0 +#define SR_SIZE_COL 1 +#define SR_ID_COL 2 +#define SR_TYPE_COL 3 +#define SR_AGE_COL 4 +#define SR_HASH_COL 5 +#define SR_SEARCH_ID_COL 6 +#define SR_UID_COL 7 +#define SR_DATA_COL SR_NAME_COL + +#define SR_ROLE_LOCAL Qt::UserRole + +class GxsCommentTreeWidget : public QTreeWidget, public TokenResponse +{ + Q_OBJECT + +public: + GxsCommentTreeWidget(QWidget *parent = 0); + void setup(RsTokenService *service); + + void requestComments(std::string threadId); + + void loadRequest(const TokenQueue *queue, const TokenRequest &req); + +protected: + + /* to be overloaded */ + virtual void service_requestComments(std::string threadId); + virtual void service_loadThread(const uint32_t &token); + virtual QTreeWidgetItem *service_createMissingItem(std::string parent); + + void clearItems(); + void completeItems(); + + void loadThread(const uint32_t &token); + + void addItem(std::string itemId, std::string parentId, QTreeWidgetItem *item); + + + + /* Data */ + std::string mThreadId; + + std::map mLoadingMap; + std::multimap mPendingInsertMap; + + TokenQueue *mTokenQueue; + RsTokenService *mRsService; + + protected: +//virtual QMimeData * mimeData ( const QList items ) const; +//virtual QStringList mimeTypes () const; +//virtual Qt::DropActions supportedDropActions () const; + +}; + + +#endif +