mirror of
https://github.com/RetroShare/RetroShare.git
synced 2024-10-01 02:35:48 -04:00
261 lines
6.4 KiB
C++
261 lines
6.4 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/rsgxsforums.h>
|
||
|
|
||
|
#include <iostream>
|
||
|
|
||
|
#define DEBUG_FORUMS
|
||
|
|
||
|
GxsForumsFillThread::GxsForumsFillThread(GxsForumThreadWidget *parent)
|
||
|
: QThread(parent), mParent(parent)
|
||
|
{
|
||
|
mStopped = false;
|
||
|
mCompareRole = NULL;
|
||
|
|
||
|
mExpandNewMessages = true;
|
||
|
mFillComplete = false;
|
||
|
|
||
|
mFilterColumn = 0;
|
||
|
mSubscribeFlags = 0;
|
||
|
|
||
|
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::run()
|
||
|
{
|
||
|
RsTokenService *service = rsGxsForums->getTokenService();
|
||
|
|
||
|
emit status(tr("Waiting"));
|
||
|
|
||
|
/* get all messages of the forum */
|
||
|
RsTokReqOptions opts;
|
||
|
opts.mReqType = GXS_REQUEST_TYPE_MSG_DATA;
|
||
|
opts.mOptions = RS_TOKREQOPT_MSG_LATEST;
|
||
|
|
||
|
std::list<std::string> 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;
|
||
|
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;
|
||
|
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 (!msg.mMeta.mParentId.empty()) {
|
||
|
++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);
|
||
|
threadList.push_back(QPair<std::string, QTreeWidgetItem*>(msg.mMeta.mMsgId, item));
|
||
|
|
||
|
mItems.append(item);
|
||
|
emit progress(++pos, count);
|
||
|
|
||
|
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 != 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);
|
||
|
if (mFlatView) {
|
||
|
mItems.append(item);
|
||
|
} else {
|
||
|
threadPair.second->addChild(item);
|
||
|
}
|
||
|
|
||
|
|
||
|
/* add item to process list */
|
||
|
threadList.push_back(QPair<std::string, QTreeWidgetItem*>(msg.mMeta.mMsgId, item));
|
||
|
|
||
|
emit progress(++pos, count);
|
||
|
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, item));
|
||
|
|
||
|
mItems.append(item);
|
||
|
break;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
#ifdef DEBUG_FORUMS
|
||
|
std::cerr << "GxsForumsFillThread::run() stopped: " << (wasStopped() ? "yes" : "no") << std::endl;
|
||
|
#endif
|
||
|
}
|