Added threaded loading of channels (GUI).

git-svn-id: http://svn.code.sf.net/p/retroshare/code/trunk@5115 b45a01b8-16f6-495d-af2f-9b41ad6348cc
This commit is contained in:
thunder2 2012-04-21 13:00:17 +00:00
parent 2793e249b3
commit 83f49ac143
7 changed files with 293 additions and 76 deletions

View file

@ -22,6 +22,7 @@
#include <QMenu>
#include <QTimer>
#include <QStandardItemModel>
#include <QMessageBox>
#include <iostream>
#include <algorithm>
@ -91,6 +92,11 @@ ChannelFeed::ChannelFeed(QWidget *parent)
channeloptsmenu->addAction(actionEnable_Auto_Download);
channeloptions_Button->setMenu(channeloptsmenu);
progressLabel->hide();
progressBar->hide();
fillThread = NULL;
//added from ahead
updateChannelList();
@ -105,6 +111,12 @@ ChannelFeed::ChannelFeed(QWidget *parent)
ChannelFeed::~ChannelFeed()
{
if (fillThread) {
fillThread->stop();
delete(fillThread);
fillThread = NULL;
}
// save settings
processSettings(false);
}
@ -188,6 +200,12 @@ void ChannelFeed::channelListCustomPopupMenu( QPoint /*point*/ )
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());
}
@ -424,12 +442,25 @@ static bool sortChannelMsgSummary(const ChannelMsgSummary &msg1, const ChannelMs
void ChannelFeed::updateChannelMsgs()
{
if (fillThread) {
#ifdef CHAN_DEBUG
std::cerr << "ChannelFeed::updateChannelMsgs() stop current fill thread" << std::endl;
#endif
// stop current fill thread
fillThread->stop();
delete(fillThread);
fillThread = NULL;
progressLabel->hide();
progressBar->hide();
}
if (!rsChannels) {
return;
}
/* replace all the messages with new ones */
std::list<ChanMsgItem *>::iterator mit;
QList<ChanMsgItem *>::iterator mit;
for (mit = mChanMsgItems.begin(); mit != mChanMsgItems.end(); mit++) {
delete (*mit);
}
@ -463,8 +494,7 @@ void ChannelFeed::updateChannelMsgs()
iconLabel->setEnabled(true);
/* set textcolor for Channel name */
QString channelStr("<span style=\"font-size:22pt; font-weight:500;"
"color:#4F4F4F;\">%1</span>");
QString channelStr("<span style=\"font-size:22pt; font-weight:500;color:#4F4F4F;\">%1</span>");
/* set Channel name */
QString cname = QString::fromStdWString(ci.channelName);
@ -498,17 +528,74 @@ void ChannelFeed::updateChannelMsgs()
actionEnable_Auto_Download->setEnabled(false);
}
std::list<ChannelMsgSummary> msgs;
std::list<ChannelMsgSummary>::iterator it;
rsChannels->getChannelMsgList(mChannelId, msgs);
progressLabel->show();
progressBar->reset();
progressBar->show();
msgs.sort(sortChannelMsgSummary);
// create fill thread
fillThread = new ChannelFillThread(this, mChannelId);
// connect thread
connect(fillThread, SIGNAL(finished()), this, SLOT(fillThreadFinished()), Qt::BlockingQueuedConnection);
connect(fillThread, SIGNAL(progress(int,int)), this, SLOT(fillThreadProgress(int,int)));
connect(fillThread, SIGNAL(addMsg(QString,QString)), this, SLOT(fillThreadAddMsg(QString,QString)), Qt::BlockingQueuedConnection);
for(it = msgs.begin(); it != msgs.end(); it++) {
ChanMsgItem *cmi = new ChanMsgItem(this, 0, mChannelId, it->msgId, true);
#ifdef DEBUG_FORUMS
std::cerr << "ChannelFeed::updateChannelMsgs() Start fill thread" << std::endl;
#endif
// start thread
fillThread->start();
}
void ChannelFeed::fillThreadFinished()
{
#ifdef DEBUG_FORUMS
std::cerr << "ChannelFeed::fillThreadFinished" << std::endl;
#endif
// thread has finished
ChannelFillThread *thread = dynamic_cast<ChannelFillThread*>(sender());
if (thread) {
if (thread == fillThread) {
// current thread has finished, hide progressbar and release thread
progressBar->hide();
progressLabel->hide();
fillThread = NULL;
}
if (thread->wasStopped()) {
// thread was stopped
#ifdef DEBUG_FORUMS
std::cerr << "ChannelFeed::fillThreadFinished Thread was stopped" << std::endl;
#endif
}
#ifdef DEBUG_FORUMS
std::cerr << "ChannelFeed::fillThreadFinished Delete thread" << std::endl;
#endif
thread->deleteLater();
thread = NULL;
}
#ifdef DEBUG_FORUMS
std::cerr << "ChannelFeed::fillThreadFinished done" << std::endl;
#endif
}
void ChannelFeed::fillThreadProgress(int current, int count)
{
// show fill progress
if (count) {
progressBar->setValue(current * progressBar->maximum() / count);
}
}
void ChannelFeed::fillThreadAddMsg(const QString &channelId, const QString &channelMsgId)
{
if (sender() == fillThread) {
ChanMsgItem *cmi = new ChanMsgItem(this, 0, channelId.toStdString(), channelMsgId.toStdString(), true);
mChanMsgItems.push_back(cmi);
verticalLayout_2->addWidget(cmi);
}
@ -629,7 +716,7 @@ bool ChannelFeed::navigate(const std::string& channelId, const std::string& msgI
}
/* Search exisiting item */
std::list<ChanMsgItem*>::iterator mit;
QList<ChanMsgItem*>::iterator mit;
for (mit = mChanMsgItems.begin(); mit != mChanMsgItems.end(); mit++) {
ChanMsgItem *item = *mit;
if (item->msgId() == msgId) {
@ -653,3 +740,79 @@ void ChannelFeed::setAutoDownloadButton(bool autoDl)
actionEnable_Auto_Download->setText(tr("Enable Auto-Download"));
}
}
void ChannelFeed::generateMassData()
{
#ifdef CHAN_DEBUG
if (mChannelId.empty ()) {
return;
}
if (QMessageBox::question(this, "Generate mass data", "Do you really want to generate mass data ?", QMessageBox::Yes|QMessageBox::No, QMessageBox::No) == QMessageBox::No) {
return;
}
for (int thread = 1; thread < 1000; thread++) {
ChannelMsgInfo msgInfo;
msgInfo.channelId = mChannelId;
msgInfo.subject = QString("Test %1").arg(thread, 3, 10, QChar('0')).toStdWString();
msgInfo.msg = QString("That is only a test").toStdWString();
if (rsChannels->ChannelMessageSend(msgInfo) == false) {
return;
}
}
#endif
}
// ForumsFillThread
ChannelFillThread::ChannelFillThread(ChannelFeed *parent, const std::string &channelId)
: QThread(parent)
{
stopped = false;
this->channelId = channelId;
}
ChannelFillThread::~ChannelFillThread()
{
#ifdef CHAN_DEBUG
std::cerr << "ChannelFillThread::~ChannelFillThread" << std::endl;
#endif
}
void ChannelFillThread::stop()
{
disconnect();
stopped = true;
QApplication::processEvents();
wait();
}
void ChannelFillThread::run()
{
#ifdef CHAN_DEBUG
std::cerr << "ChannelFillThread::run()" << std::endl;
#endif
std::list<ChannelMsgSummary> msgs;
std::list<ChannelMsgSummary>::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));
emit progress(++pos, count);
}
#ifdef CHAN_DEBUG
std::cerr << "ChannelFillThread::run() stopped: " << (wasStopped() ? "yes" : "no") << std::endl;
#endif
}

View file

@ -24,6 +24,7 @@
#include <retroshare/rschannels.h>
#include <QStandardItemModel>
#include <QThread>
#include <map>
#include "mainpage.h"
@ -35,6 +36,7 @@
class ChanMsgItem;
class QTreeWidgetItem;
class ChannelFillThread;
class ChannelFeed : public RsAutoUpdatePage, public FeedHolder, private Ui::ChannelFeed
{
@ -75,6 +77,12 @@ private slots:
void channelMsgReadSatusChanged(const QString& channelId, const QString& msgId, int status);
void generateMassData();
void fillThreadFinished();
void fillThreadProgress(int current, int count);
void fillThreadAddMsg(const QString &channelId, const QString &channelMsgId);
private:
void updateChannelList();
void updateChannelMsgs();
@ -89,14 +97,38 @@ private:
/* Layout Pointers */
QBoxLayout *mMsgLayout;
std::list<ChanMsgItem *> mChanMsgItems;
QList<ChanMsgItem *> mChanMsgItems;
std::map<std::string, uint32_t> mChanSearchScore; //chanId, score
QTreeWidgetItem *ownChannels;
QTreeWidgetItem *subcribedChannels;
QTreeWidgetItem *popularChannels;
QTreeWidgetItem *otherChannels;
ChannelFillThread *fillThread;
};
class ChannelFillThread : public QThread
{
Q_OBJECT
public:
ChannelFillThread(ChannelFeed *parent, const std::string &channelId);
~ChannelFillThread();
void run();
void stop();
bool wasStopped() { return stopped; }
signals:
void progress(int current, int count);
void addMsg(const QString &channelId, const QString &channelMsgId);
public:
std::string channelId;
private:
volatile bool stopped;
};
#endif

View file

@ -508,7 +508,7 @@ border-image: url(:/images/btn_26_pressed.png) 4;
</layout>
</widget>
</item>
<item row="1" column="0">
<item row="2" column="0">
<widget class="QScrollArea" name="scrollArea">
<property name="widgetResizable">
<bool>true</bool>
@ -521,8 +521,8 @@ border-image: url(:/images/btn_26_pressed.png) 4;
<rect>
<x>0</x>
<y>0</y>
<width>392</width>
<height>333</height>
<width>400</width>
<height>304</height>
</rect>
</property>
<property name="styleSheet">
@ -558,6 +558,27 @@ border-image: url(:/images/btn_26_pressed.png) 4;
</widget>
</widget>
</item>
<item row="1" column="0">
<layout class="QHBoxLayout" name="progressLayout">
<item>
<widget class="QLabel" name="progressLabel">
<property name="text">
<string>Loading</string>
</property>
</widget>
</item>
<item>
<widget class="QProgressBar" name="progressBar">
<property name="maximum">
<number>1000</number>
</property>
<property name="value">
<number>24</number>
</property>
</widget>
</item>
</layout>
</item>
</layout>
</widget>
</widget>

View file

@ -208,12 +208,10 @@ ForumsDialog::ForumsDialog(QWidget *parent)
ttheader->setResizeMode (COLUMN_THREAD_READ, QHeaderView::Fixed);
ttheader->hideSection (COLUMN_THREAD_CONTENT);
ui.progressBar->setTextVisible(true);
ui.progressBar->hide();
ui.progLayOutTxt->hide();
ui.progressBarLayOut->setEnabled(false);
fillThread = NULL;
insertThreads();
@ -495,15 +493,15 @@ void ForumsDialog::updateDisplay()
}
}
static void CleanupItems (QList<QTreeWidgetItem *> &Items)
static void CleanupItems (QList<QTreeWidgetItem *> &items)
{
QList<QTreeWidgetItem *>::iterator Item;
for (Item = Items.begin (); Item != Items.end (); Item++) {
if (*Item) {
delete (*Item);
QList<QTreeWidgetItem *>::iterator item;
for (item = items.begin (); item != items.end (); item++) {
if (*item) {
delete (*item);
}
}
Items.clear();
items.clear();
}
void ForumsDialog::forumInfoToGroupItemInfo(const ForumInfo &forumInfo, GroupItemInfo &groupItemInfo)
@ -844,7 +842,6 @@ void ForumsDialog::fillThreadProgress(int current, int count)
if (count) {
ui.progressBar->setValue(current * ui.progressBar->maximum() / count);
}
}
void ForumsDialog::insertThreads()
@ -858,15 +855,13 @@ void ForumsDialog::insertThreads()
#ifdef DEBUG_FORUMS
std::cerr << "ForumsDialog::insertThreads() stop current fill thread" << std::endl;
#endif
// stop and disconnect current fill thread
ForumsFillThread *thread = fillThread;
// stop current fill thread
fillThread->stop();
delete(fillThread);
fillThread = NULL;
// disconnect only the signal "progress", the signal "finished" is needed to delete the thread
thread->disconnect(this, SIGNAL(progress(int,int)));
thread->stop();
ui.progressBar->hide();
ui.progLayOutTxt->hide();
}
subscribeFlags = 0;
@ -905,6 +900,7 @@ void ForumsDialog::insertThreads()
ui.progressBarLayOut->setEnabled(true);
ui.progLayOutTxt->show();
ui.progressBar->reset();
ui.progressBar->show();
// create fill thread
@ -1761,7 +1757,10 @@ ForumsFillThread::~ForumsFillThread()
void ForumsFillThread::stop()
{
disconnect();
stopped = true;
QApplication::processEvents();
wait();
}
void ForumsFillThread::run()

View file

@ -1192,9 +1192,6 @@ border: 1px solid #CCCCCC;}</string>
<property name="value">
<number>0</number>
</property>
<property name="textVisible">
<bool>false</bool>
</property>
</widget>
</item>
</layout>
@ -1230,6 +1227,12 @@ border: 1px solid #CCCCCC;}</string>
</action>
</widget>
<customwidgets>
<customwidget>
<class>GroupTreeWidget</class>
<extends>QWidget</extends>
<header>gui/common/GroupTreeWidget.h</header>
<container>1</container>
</customwidget>
<customwidget>
<class>LineEditClear</class>
<extends>QLineEdit</extends>
@ -1240,12 +1243,6 @@ border: 1px solid #CCCCCC;}</string>
<extends>QTextBrowser</extends>
<header>gui/common/LinkTextBrowser.h</header>
</customwidget>
<customwidget>
<class>GroupTreeWidget</class>
<extends>QWidget</extends>
<header>gui/common/GroupTreeWidget.h</header>
<container>1</container>
</customwidget>
</customwidgets>
<resources>
<include location="images.qrc"/>