RetroShare/retroshare-gui/src/gui/gxschannels/GxsChannelDialog.cpp
drbob 5ba4c8f7ff Major improvements to Comments GUI for channels and posted.
- Split GxsIdWidgetTreeItem into two types.
 - Added Voter Id into Comment Dialog.
 - Expanded Comment display to show Votes and Score.
 - Expanded Comment Context Menu to include Voting and Reputation Options.
 - Fixed up CreateComment Dialog to include AuthorId, and enabled.
 - Completed Basic Comment Voting.
 - Made Comment Windows Closable.
 - Cleanup up Channel Posts before loading new ones.
 - Fixed up Channel Post Attachments, and Thumbnails.
 - Added View Comments button to Channel Posts
 - Misc other Bugs.



git-svn-id: http://svn.code.sf.net/p/retroshare/code/trunk@6219 b45a01b8-16f6-495d-af2f-9b41ad6348cc
2013-03-13 00:33:14 +00:00

1100 lines
29 KiB
C++

/****************************************************************
* 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 <QMenu>
#include <QTimer>
#include <QStandardItemModel>
#include <QMessageBox>
#include <iostream>
#include <algorithm>
#include <set>
#include <map>
#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<GxsCommentContainer *>(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<int> 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<RetroShareLink> 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.<br/>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<RsGroupMetaData> &channelList)
{
std::list<RsGroupMetaData>::const_iterator it;
QList<GroupItemInfo> adminList;
QList<GroupItemInfo> subList;
QList<GroupItemInfo> popList;
QList<GroupItemInfo> otherList;
std::multimap<uint32_t, GroupItemInfo> 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<uint32_t, GroupItemInfo>::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<ChanMsgItem *>::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<ChannelMsgSummary> msgs;
std::list<ChannelMsgSummary>::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<GxsChannelFillThread*>(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<ChannelMsgSummary> msgs;
std::list<ChannelMsgSummary>::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<ChanMsgItem*>::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<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), ++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<uint32_t> tokens;
mChannelQueue->activeRequestTokens(TOKEN_TYPE_LISTING, tokens);
if (!tokens.empty()) {
std::list<uint32_t>::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<RsGroupMetaData> 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<uint32_t> tokens;
mChannelQueue->activeRequestTokens(TOKEN_TYPE_GROUP_DATA, tokens);
if (!tokens.empty()) {
std::list<uint32_t>::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<RsGxsGroupId> 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<RsGxsChannelGroup> 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<uint32_t> tokens;
mChannelQueue->activeRequestTokens(TOKEN_TYPE_POSTS, tokens);
if (!tokens.empty()) {
std::list<uint32_t>::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<RsGxsGroupId> 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<RsGxsChannelPost> 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<GxsChannelPostItem *>::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<RsGxsChannelPost> &posts)
{
std::vector<RsGxsChannelPost>::const_iterator it;
// Do these need sorting? probably.
// can we add that into the request?
//msgs.sort(sortChannelMsgSummary);
/* replace all the messages with new ones */
QList<GxsChannelPostItem *>::iterator mit;
for (mit = mChannelPostItems.begin(); mit != mChannelPostItems.end(); mit++) {
delete (*mit);
}
mChannelPostItems.clear();
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);
}
}