mirror of
https://github.com/RetroShare/RetroShare.git
synced 2024-10-01 02:35:48 -04:00
d164428bf9
git-svn-id: http://svn.code.sf.net/p/retroshare/code/trunk@7720 b45a01b8-16f6-495d-af2f-9b41ad6348cc
293 lines
7.5 KiB
C++
293 lines
7.5 KiB
C++
/****************************************************************
|
|
* RetroShare is distributed under the following license:
|
|
*
|
|
* Copyright (C) 2012, RetroShare Team
|
|
*
|
|
* 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 <QApplication>
|
|
#include <QTreeWidgetItem>
|
|
|
|
#include "GxsForumsFillThread.h"
|
|
#include "GxsForumThreadWidget.h"
|
|
|
|
#include "retroshare/rsgxsflags.h"
|
|
#include <retroshare/rsgxsforums.h>
|
|
|
|
#include <iostream>
|
|
#include <algorithm>
|
|
|
|
//#define DEBUG_FORUMS
|
|
|
|
#define PROGRESSBAR_MAX 100
|
|
|
|
GxsForumsFillThread::GxsForumsFillThread(GxsForumThreadWidget *parent)
|
|
: QThread(parent), mParent(parent)
|
|
{
|
|
mStopped = false;
|
|
mCompareRole = NULL;
|
|
|
|
mExpandNewMessages = true;
|
|
mFillComplete = false;
|
|
|
|
mFilterColumn = 0;
|
|
mFilterString = QString();
|
|
|
|
mViewType = 0;
|
|
mFlatView = false;
|
|
mUseChildTS = false;
|
|
}
|
|
|
|
GxsForumsFillThread::~GxsForumsFillThread()
|
|
{
|
|
#ifdef DEBUG_FORUMS
|
|
std::cerr << "GxsForumsFillThread::~GxsForumsFillThread" << std::endl;
|
|
#endif
|
|
|
|
// remove all items (when items are available, the thread was terminated)
|
|
QList<QTreeWidgetItem *>::iterator item;
|
|
for (item = mItems.begin (); item != mItems.end (); ++item) {
|
|
if (*item) {
|
|
delete (*item);
|
|
}
|
|
}
|
|
mItems.clear();
|
|
|
|
mItemToExpand.clear();
|
|
}
|
|
|
|
void GxsForumsFillThread::stop()
|
|
{
|
|
disconnect();
|
|
mStopped = true;
|
|
QApplication::processEvents();
|
|
wait();
|
|
}
|
|
|
|
void GxsForumsFillThread::calculateExpand(const RsGxsForumMsg &msg, QTreeWidgetItem *item)
|
|
{
|
|
if (mFillComplete && mExpandNewMessages && IS_MSG_UNREAD(msg.mMeta.mMsgStatus)) {
|
|
QTreeWidgetItem *parentItem = item;
|
|
while ((parentItem = parentItem->parent()) != NULL) {
|
|
if (std::find(mItemToExpand.begin(), mItemToExpand.end(), parentItem) == mItemToExpand.end()) {
|
|
mItemToExpand.push_back(parentItem);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
void GxsForumsFillThread::run()
|
|
{
|
|
RsTokenService *service = rsGxsForums->getTokenService();
|
|
|
|
emit status(tr("Waiting"));
|
|
|
|
/* get all messages of the forum */
|
|
RsTokReqOptions opts;
|
|
opts.mReqType = GXS_REQUEST_TYPE_MSG_DATA;
|
|
|
|
std::list<RsGxsGroupId> grpIds;
|
|
grpIds.push_back(mForumId);
|
|
|
|
#ifdef DEBUG_FORUMS
|
|
std::cerr << "GxsForumsFillThread::run() forum id " << mForumId << std::endl;
|
|
#endif
|
|
|
|
uint32_t token;
|
|
service->requestMsgInfo(token, RS_TOKREQ_ANSTYPE_DATA, opts, grpIds);
|
|
|
|
/* wait for the answer */
|
|
uint32_t requestStatus = RsTokenService::GXS_REQUEST_V2_STATUS_PENDING;
|
|
while (!wasStopped()) {
|
|
requestStatus = service->requestStatus(token);
|
|
if (requestStatus == RsTokenService::GXS_REQUEST_V2_STATUS_FAILED ||
|
|
requestStatus == RsTokenService::GXS_REQUEST_V2_STATUS_COMPLETE) {
|
|
break;
|
|
}
|
|
msleep(100);
|
|
}
|
|
|
|
if (wasStopped()) {
|
|
#ifdef DEBUG_FORUMS
|
|
std::cerr << "GxsForumsFillThread::run() thread stopped, cancel request" << std::endl;
|
|
#endif
|
|
|
|
/* cancel request */
|
|
service->cancelRequest(token);
|
|
return;
|
|
}
|
|
|
|
if (requestStatus == RsTokenService::GXS_REQUEST_V2_STATUS_FAILED) {
|
|
//#TODO
|
|
return;
|
|
}
|
|
|
|
//#TODO
|
|
// if (failed) {
|
|
// mService->cancelRequest(token);
|
|
// return;
|
|
// }
|
|
|
|
emit status(tr("Retrieving"));
|
|
|
|
/* get messages */
|
|
std::vector<RsGxsForumMsg> msgs;
|
|
if (!rsGxsForums->getMsgData(token, msgs)) {
|
|
return;
|
|
}
|
|
|
|
emit status(tr("Loading"));
|
|
|
|
int count = msgs.size();
|
|
int pos = 0;
|
|
int steps = count / PROGRESSBAR_MAX;
|
|
int step = 0;
|
|
QList<QPair<std::string, QTreeWidgetItem*> > threadList;
|
|
QPair<std::string, QTreeWidgetItem*> threadPair;
|
|
|
|
/* add all threads */
|
|
std::vector<RsGxsForumMsg>::iterator msgIt;
|
|
for (msgIt = msgs.begin(); msgIt != msgs.end(); ) {
|
|
if (wasStopped()) {
|
|
break;
|
|
}
|
|
|
|
const RsGxsForumMsg &msg = *msgIt;
|
|
|
|
if (!mFlatView && !msg.mMeta.mParentId.isNull()) {
|
|
++msgIt;
|
|
continue;
|
|
}
|
|
|
|
#ifdef DEBUG_FORUMS
|
|
std::cerr << "GxsForumsFillThread::run() Adding TopLevel Thread: mId: " << msg.mMeta.mMsgId << std::endl;
|
|
#endif
|
|
|
|
QTreeWidgetItem *item = mParent->convertMsgToThreadWidget(msg, mUseChildTS, mFilterColumn, mFilterString);
|
|
if (!mFlatView) {
|
|
threadList.push_back(QPair<std::string, QTreeWidgetItem*>(msg.mMeta.mMsgId.toStdString(), item));
|
|
}
|
|
calculateExpand(msg, item);
|
|
|
|
mItems.append(item);
|
|
|
|
if (++step >= steps) {
|
|
step = 0;
|
|
emit progress(++pos, PROGRESSBAR_MAX);
|
|
}
|
|
|
|
msgIt = msgs.erase(msgIt);
|
|
}
|
|
|
|
/* process messages */
|
|
while (msgs.size()) {
|
|
while (threadList.size() > 0) {
|
|
if (wasStopped()) {
|
|
break;
|
|
}
|
|
|
|
threadPair = threadList.front();
|
|
threadList.pop_front();
|
|
|
|
#ifdef DEBUG_FORUMS
|
|
std::cerr << "GxsForumsFillThread::run() Getting Children of : " << threadPair.first << std::endl;
|
|
#endif
|
|
/* iterate through child */
|
|
for (msgIt = msgs.begin(); msgIt != msgs.end(); ) {
|
|
const RsGxsForumMsg &msg = *msgIt;
|
|
|
|
if (msg.mMeta.mParentId.toStdString() != threadPair.first) {
|
|
++msgIt;
|
|
continue;
|
|
}
|
|
|
|
#ifdef DEBUG_FORUMS
|
|
std::cerr << "GxsForumsFillThread::run() adding " << msg.mMeta.mMsgId << std::endl;
|
|
#endif
|
|
|
|
QTreeWidgetItem *item = mParent->convertMsgToThreadWidget(msg, mUseChildTS, mFilterColumn, mFilterString);
|
|
threadPair.second->addChild(item);
|
|
|
|
if ( !item->isHidden() && threadPair.second->isHidden() ){
|
|
threadPair.second->setHidden(false);
|
|
for (QTreeWidgetItem *cursIt = threadPair.second->parent(); cursIt; cursIt = cursIt->parent()){
|
|
cursIt->setHidden(false);
|
|
}
|
|
}
|
|
|
|
calculateExpand(msg, item);
|
|
|
|
/* add item to process list */
|
|
threadList.push_back(QPair<std::string, QTreeWidgetItem*>(msg.mMeta.mMsgId.toStdString(), item));
|
|
|
|
if (++step >= steps) {
|
|
step = 0;
|
|
emit progress(++pos, PROGRESSBAR_MAX);
|
|
}
|
|
|
|
msgIt = msgs.erase(msgIt);
|
|
}
|
|
}
|
|
|
|
if (wasStopped()) {
|
|
break;
|
|
}
|
|
|
|
/* process missing messages */
|
|
|
|
/* search for a message with missing parent */
|
|
for (msgIt = msgs.begin(); msgIt != msgs.end(); ++msgIt) {
|
|
const RsGxsForumMsg &msg = *msgIt;
|
|
|
|
/* search for parent */
|
|
std::vector<RsGxsForumMsg>::iterator msgIt1;
|
|
for (msgIt1 = msgs.begin(); msgIt1 != msgs.end(); ++msgIt1) {
|
|
if (wasStopped()) {
|
|
break;
|
|
}
|
|
|
|
const RsGxsForumMsg &msg1 = *msgIt1;
|
|
|
|
if (msg.mMeta.mParentId == msg1.mMeta.mMsgId) {
|
|
/* found parent */
|
|
break;
|
|
}
|
|
}
|
|
|
|
if (wasStopped()) {
|
|
break;
|
|
}
|
|
|
|
if (msgIt1 != msgs.end()) {
|
|
/* parant found */
|
|
continue;
|
|
}
|
|
|
|
/* add dummy item */
|
|
QTreeWidgetItem *item = mParent->generateMissingItem(msg.mMeta.mParentId);
|
|
threadList.push_back(QPair<std::string, QTreeWidgetItem*>(msg.mMeta.mParentId.toStdString(), item));
|
|
|
|
mItems.append(item);
|
|
break;
|
|
}
|
|
}
|
|
|
|
#ifdef DEBUG_FORUMS
|
|
std::cerr << "GxsForumsFillThread::run() stopped: " << (wasStopped() ? "yes" : "no") << std::endl;
|
|
#endif
|
|
}
|