removed unused files to fix compilation

This commit is contained in:
csoler 2020-09-12 22:34:58 +02:00
parent 138cff6547
commit 27e298b9f6
6 changed files with 0 additions and 1976 deletions

View File

@ -1,251 +0,0 @@
/*******************************************************************************
* retroshare-gui/src/gui/gxschannels/GxsChannelFilesWidget.cpp *
* *
* Copyright 2014 by Retroshare Team <retroshare.project@gmail.com> *
* *
* This program is free software: you can redistribute it and/or modify *
* it under the terms of the GNU Affero General Public License as *
* published by the Free Software Foundation, either version 3 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 Affero General Public License for more details. *
* *
* You should have received a copy of the GNU Affero General Public License *
* along with this program. If not, see <https://www.gnu.org/licenses/>. *
* *
*******************************************************************************/
#include <QDateTime>
#include "GxsChannelFilesWidget.h"
#include "ui_GxsChannelFilesWidget.h"
#include "GxsChannelFilesStatusWidget.h"
#include "GxsChannelPostsWidget.h"
#include "gui/feeds/GxsChannelPostItem.h"
#include "gui/common/RSTreeWidgetItem.h"
#include "util/misc.h"
#include "util/DateTime.h"
#include "gui/gxs/GxsFeedItem.h"
#include "retroshare/rsgxschannels.h"
#define COLUMN_FILENAME 0
#define COLUMN_SIZE 1
#define COLUMN_STATUS 2
#define COLUMN_TITLE 3
#define COLUMN_PUBLISHED 4
#define COLUMN_COUNT 5
#define COLUMN_DATA 0
#define ROLE_SORT Qt::UserRole
#define ROLE_GROUP_ID Qt::UserRole + 1
#define ROLE_MESSAGE_ID Qt::UserRole + 2
#define ROLE_FILE_HASH Qt::UserRole + 3
#define ROLE_MSG Qt::UserRole + 4
Q_DECLARE_METATYPE(Sha1CheckSum)
GxsChannelFilesWidget::GxsChannelFilesWidget(QWidget *parent) :
QWidget(parent), ui(new Ui::GxsChannelFilesWidget)
{
ui->setupUi(this);
mFeedItem = NULL;
/* Connect signals */
connect(ui->treeWidget, SIGNAL(currentItemChanged(QTreeWidgetItem*,QTreeWidgetItem*)), this, SLOT(currentItemChanged(QTreeWidgetItem*,QTreeWidgetItem*)));
/* Sort */
mCompareRole = new RSTreeWidgetItemCompareRole;
mCompareRole->setRole(COLUMN_SIZE, ROLE_SORT);
mCompareRole->setRole(COLUMN_PUBLISHED, ROLE_SORT);
/* Filter */
mFilterType = 0;
/* Initialize file tree */
ui->treeWidget->setColumnCount(COLUMN_COUNT);
QTreeWidgetItem *headerItem = ui->treeWidget->headerItem();
headerItem->setText(COLUMN_FILENAME, tr("Filename"));
headerItem->setText(COLUMN_SIZE, tr("Size"));
headerItem->setText(COLUMN_TITLE, tr("Title"));
headerItem->setText(COLUMN_PUBLISHED, tr("Published"));
headerItem->setText(COLUMN_STATUS, tr("Status"));
ui->treeWidget->setColumnWidth(COLUMN_FILENAME, 400);
ui->treeWidget->setColumnWidth(COLUMN_SIZE, 80);
ui->treeWidget->setColumnWidth(COLUMN_PUBLISHED, 150);
}
GxsChannelFilesWidget::~GxsChannelFilesWidget()
{
delete(mCompareRole);
delete ui;
}
void GxsChannelFilesWidget::addFiles(const RsGxsChannelPost& post, bool related)
{
if (related) {
removeItems(post.mMeta.mGroupId, post.mMeta.mMsgId);
}
std::list<RsGxsFile>::const_iterator fileIt;
for (fileIt = post.mFiles.begin(); fileIt != post.mFiles.end(); ++fileIt) {
const RsGxsFile &file = *fileIt;
QTreeWidgetItem *treeItem = new RSTreeWidgetItem(mCompareRole);
treeItem->setText(COLUMN_FILENAME, QString::fromUtf8(file.mName.c_str()));
treeItem->setText(COLUMN_SIZE, misc::friendlyUnit(file.mSize));
treeItem->setData(COLUMN_SIZE, ROLE_SORT, (qulonglong)file.mSize);
treeItem->setText(COLUMN_TITLE, QString::fromUtf8(post.mMeta.mMsgName.c_str()));
treeItem->setText(COLUMN_PUBLISHED, DateTime::formatDateTime(post.mMeta.mPublishTs));
treeItem->setData(COLUMN_PUBLISHED, ROLE_SORT, QDateTime::fromTime_t(post.mMeta.mPublishTs));
treeItem->setData(COLUMN_DATA, ROLE_GROUP_ID, qVariantFromValue(post.mMeta.mGroupId));
treeItem->setData(COLUMN_DATA, ROLE_MESSAGE_ID, qVariantFromValue(post.mMeta.mMsgId));
treeItem->setData(COLUMN_DATA, ROLE_FILE_HASH, qVariantFromValue(file.mHash));
treeItem->setData(COLUMN_DATA, ROLE_MSG, QString::fromUtf8(post.mMsg.c_str()));
treeItem->setTextAlignment(COLUMN_SIZE, Qt::AlignRight) ;
ui->treeWidget->addTopLevelItem(treeItem);
QWidget *statusWidget = new GxsChannelFilesStatusWidget(file);
ui->treeWidget->setItemWidget(treeItem, COLUMN_STATUS, statusWidget);
filterItem(treeItem);
}
}
void GxsChannelFilesWidget::clear()
{
ui->treeWidget->clear();
closeFeedItem();
}
void GxsChannelFilesWidget::setFilter(const QString &text, int type)
{
if (mFilterText == text && mFilterType == type) {
return;
}
mFilterText = text;
mFilterType = type;
filterItems();
}
void GxsChannelFilesWidget::setFilterText(const QString &text)
{
setFilter(text, mFilterType);
}
void GxsChannelFilesWidget::setFilterType(int type)
{
setFilter(mFilterText, type);
}
void GxsChannelFilesWidget::filterItems()
{
QTreeWidgetItemIterator it(ui->treeWidget);
QTreeWidgetItem *treeItem;
while ((treeItem = *it) != NULL) {
++it;
filterItem(treeItem);
}
}
void GxsChannelFilesWidget::filterItem(QTreeWidgetItem *treeItem)
{
bool visible = mFilterText.isEmpty();
switch (mFilterType) {
case GxsChannelPostsWidget::FILTER_TITLE:
visible = treeItem->text(COLUMN_TITLE).contains(mFilterText, Qt::CaseInsensitive);
break;
case GxsChannelPostsWidget::FILTER_MSG:
visible = treeItem->data(COLUMN_DATA, ROLE_MSG).toString().contains(mFilterText, Qt::CaseInsensitive);
break;
case GxsChannelPostsWidget::FILTER_FILE_NAME:
visible = treeItem->text(COLUMN_FILENAME).contains(mFilterText, Qt::CaseInsensitive);
break;
}
treeItem->setHidden(!visible);
}
//QTreeWidgetItem *GxsChannelFilesWidget::findFile(const RsGxsGroupId &groupId, const RsGxsMessageId &messageId, const RsFileHash &fileHash)
//{
// QTreeWidgetItemIterator it(ui->treeWidget);
// QTreeWidgetItem *treeItem;
// while ((treeItem = *it) != NULL) {
// ++it;
// if (fileHash != treeItem->data(COLUMN_DATA, ROLE_FILE_HASH).value<RsFileHash>()) {
// continue;
// }
// if (messageId != treeItem->data(COLUMN_DATA, ROLE_MESSAGE_ID).value<RsGxsMessageId>()) {
// continue;
// }
// if (groupId != treeItem->data(COLUMN_DATA, ROLE_GROUP_ID).value<RsGxsGroupId>()) {
// continue;
// }
// return treeItem;
// }
// return NULL;
//}
void GxsChannelFilesWidget::removeItems(const RsGxsGroupId &groupId, const RsGxsMessageId &messageId)
{
QTreeWidgetItemIterator it(ui->treeWidget);
QTreeWidgetItem *treeItem;
while ((treeItem = *it) != NULL) {
++it;
if (messageId != treeItem->data(COLUMN_DATA, ROLE_MESSAGE_ID).value<RsGxsMessageId>()) {
continue;
}
if (groupId != treeItem->data(COLUMN_DATA, ROLE_GROUP_ID).value<RsGxsGroupId>()) {
continue;
}
delete(treeItem);
}
}
void GxsChannelFilesWidget::closeFeedItem()
{
if (mFeedItem) {
delete(mFeedItem);
mFeedItem = NULL;
}
ui->feedItemFrame->hide();
}
void GxsChannelFilesWidget::currentItemChanged(QTreeWidgetItem *current, QTreeWidgetItem */*previous*/)
{
if (!current) {
closeFeedItem();
return;
}
RsGxsGroupId groupId = current->data(COLUMN_DATA, ROLE_GROUP_ID).value<RsGxsGroupId>();
RsGxsMessageId messageId = current->data(COLUMN_DATA, ROLE_MESSAGE_ID).value<RsGxsMessageId>();
if (mFeedItem) {
if (mFeedItem->groupId() == groupId && mFeedItem->messageId() == messageId) {
return;
}
closeFeedItem();
}
mFeedItem = new GxsChannelPostItem(NULL, 0, groupId, messageId, true, true);
ui->feedItemFrame->show();
ui->feedItemFrame->layout()->addWidget(mFeedItem);
}

View File

@ -1,76 +0,0 @@
/*******************************************************************************
* retroshare-gui/src/gui/gxschannels/GxsChannelFilesWidget.h *
* *
* Copyright 2014 by Retroshare Team <retroshare.project@gmail.com> *
* *
* This program is free software: you can redistribute it and/or modify *
* it under the terms of the GNU Affero General Public License as *
* published by the Free Software Foundation, either version 3 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 Affero General Public License for more details. *
* *
* You should have received a copy of the GNU Affero General Public License *
* along with this program. If not, see <https://www.gnu.org/licenses/>. *
* *
*******************************************************************************/
#ifndef GXSCHANNELFILESWIDGET_H
#define GXSCHANNELFILESWIDGET_H
#include <QWidget>
#include "retroshare/rsgxsifacetypes.h"
struct RsGxsChannelPost;
class RSTreeWidgetItemCompareRole;
class QTreeWidgetItem;
class GxsFeedItem;
namespace Ui {
class GxsChannelFilesWidget;
}
class GxsChannelFilesWidget : public QWidget
{
Q_OBJECT
public:
explicit GxsChannelFilesWidget(QWidget *parent = 0);
~GxsChannelFilesWidget();
void addFiles(const RsGxsChannelPost &post, bool related);
void clear();
public slots:
void setFilter(const QString &text, int type);
void setFilterText(const QString &text);
void setFilterType(int type);
private:
// QTreeWidgetItem *findFile(const RsGxsGroupId &groupId, const RsGxsMessageId &messageId, const RsFileHash &fileHash);
void removeItems(const RsGxsGroupId &groupId, const RsGxsMessageId &messageId);
void closeFeedItem();
void filterItems();
void filterItem(QTreeWidgetItem *treeItem);
private slots:
void currentItemChanged(QTreeWidgetItem *current, QTreeWidgetItem *previous);
private:
/* Sort */
RSTreeWidgetItemCompareRole *mCompareRole;
/* Filter */
QString mFilterText;
int mFilterType;
GxsFeedItem *mFeedItem;
Ui::GxsChannelFilesWidget *ui;
};
#endif // GXSCHANNELFILESWIDGET_H

View File

@ -1,934 +0,0 @@
/*******************************************************************************
* retroshare-gui/src/gui/gxschannels/GxsChannelPostsWidget.cpp *
* *
* Copyright 2013 by Robert Fernie <retroshare.project@gmail.com> *
* *
* This program is free software: you can redistribute it and/or modify *
* it under the terms of the GNU Affero General Public License as *
* published by the Free Software Foundation, either version 3 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 Affero General Public License for more details. *
* *
* You should have received a copy of the GNU Affero General Public License *
* along with this program. If not, see <https://www.gnu.org/licenses/>. *
* *
*******************************************************************************/
#include <QDateTime>
#include <QSignalMapper>
#include "retroshare/rsgxscircles.h"
#include "GxsChannelPostsWidget.h"
#include "ui_GxsChannelPostsWidget.h"
#include "gui/feeds/GxsChannelPostItem.h"
#include "gui/gxs/GxsIdDetails.h"
#include "gui/gxschannels/CreateGxsChannelMsg.h"
#include "gui/common/UIStateHelper.h"
#include "gui/settings/rsharesettings.h"
#include "gui/feeds/SubFileItem.h"
#include "gui/notifyqt.h"
#include "gui/RetroShareLink.h"
#include "util/HandleRichText.h"
#include "util/DateTime.h"
#include "util/qtthreadsutils.h"
#include <algorithm>
#define CHAN_DEFAULT_IMAGE ":/icons/png/channels.png"
#define ROLE_PUBLISH FEED_TREEWIDGET_SORTROLE
/****
* #define DEBUG_CHANNEL
***/
/* View mode */
#define VIEW_MODE_FEEDS 1
#define VIEW_MODE_FILES 2
/** Constructor */
GxsChannelPostsWidget::GxsChannelPostsWidget(const RsGxsGroupId &channelId, QWidget *parent) :
GxsMessageFramePostWidget(rsGxsChannels, parent),
ui(new Ui::GxsChannelPostsWidget)
{
/* Invoke the Qt Designer generated object setup routine */
ui->setupUi(this);
/* Setup UI helper */
mStateHelper->addWidget(mTokenTypeAllPosts, ui->progressBar, UISTATE_LOADING_VISIBLE);
mStateHelper->addWidget(mTokenTypeAllPosts, ui->loadingLabel, UISTATE_LOADING_VISIBLE);
mStateHelper->addWidget(mTokenTypeAllPosts, ui->filterLineEdit);
mStateHelper->addWidget(mTokenTypePosts, ui->loadingLabel, UISTATE_LOADING_VISIBLE);
mStateHelper->addLoadPlaceholder(mTokenTypeGroupData, ui->nameLabel);
mStateHelper->addWidget(mTokenTypeGroupData, ui->postButton);
mStateHelper->addWidget(mTokenTypeGroupData, ui->logoLabel);
mStateHelper->addWidget(mTokenTypeGroupData, ui->subscribeToolButton);
/* Connect signals */
connect(ui->postButton, SIGNAL(clicked()), this, SLOT(createMsg()));
connect(ui->subscribeToolButton, SIGNAL(subscribe(bool)), this, SLOT(subscribeGroup(bool)));
connect(NotifyQt::getInstance(), SIGNAL(settingsChanged()), this, SLOT(settingsChanged()));
ui->postButton->setText(tr("Add new post"));
/* add filter actions */
ui->filterLineEdit->addFilter(QIcon(), tr("Title"), FILTER_TITLE, tr("Search Title"));
ui->filterLineEdit->addFilter(QIcon(), tr("Message"), FILTER_MSG, tr("Search Message"));
ui->filterLineEdit->addFilter(QIcon(), tr("Filename"), FILTER_FILE_NAME, tr("Search Filename"));
connect(ui->filterLineEdit, SIGNAL(textChanged(QString)), ui->feedWidget, SLOT(setFilterText(QString)));
connect(ui->filterLineEdit, SIGNAL(textChanged(QString)), ui->fileWidget, SLOT(setFilterText(QString)));
connect(ui->filterLineEdit, SIGNAL(filterChanged(int)), this, SLOT(filterChanged(int)));
/* Initialize view button */
//setViewMode(VIEW_MODE_FEEDS); see processSettings
ui->infoWidget->hide();
QSignalMapper *signalMapper = new QSignalMapper(this);
connect(ui->feedToolButton, SIGNAL(clicked()), signalMapper, SLOT(map()));
connect(ui->fileToolButton, SIGNAL(clicked()), signalMapper, SLOT(map()));
signalMapper->setMapping(ui->feedToolButton, VIEW_MODE_FEEDS);
signalMapper->setMapping(ui->fileToolButton, VIEW_MODE_FILES);
connect(signalMapper, SIGNAL(mapped(int)), this, SLOT(setViewMode(int)));
/*************** Setup Left Hand Side (List of Channels) ****************/
ui->loadingLabel->hide();
ui->progressBar->hide();
ui->nameLabel->setMinimumWidth(20);
/* Initialize feed widget */
ui->feedWidget->setSortRole(ROLE_PUBLISH, Qt::DescendingOrder);
ui->feedWidget->setFilterCallback(filterItem);
/* load settings */
processSettings(true);
/* Initialize subscribe button */
QIcon icon;
icon.addPixmap(QPixmap(":/images/redled.png"), QIcon::Normal, QIcon::On);
icon.addPixmap(QPixmap(":/images/start.png"), QIcon::Normal, QIcon::Off);
mAutoDownloadAction = new QAction(icon, "", this);
mAutoDownloadAction->setCheckable(true);
connect(mAutoDownloadAction, SIGNAL(triggered()), this, SLOT(toggleAutoDownload()));
ui->subscribeToolButton->addSubscribedAction(mAutoDownloadAction);
/* Initialize GUI */
setAutoDownload(false);
settingsChanged();
setGroupId(channelId);
mEventHandlerId = 0;
// Needs to be asynced because this function is called by another thread!
rsEvents->registerEventsHandler(
[this](std::shared_ptr<const RsEvent> event)
{ RsQThreadUtils::postToObject([=](){ handleEvent_main_thread(event); }, this ); },
mEventHandlerId, RsEventType::GXS_CHANNELS );
}
void GxsChannelPostsWidget::handleEvent_main_thread(std::shared_ptr<const RsEvent> event)
{
const RsGxsChannelEvent *e = dynamic_cast<const RsGxsChannelEvent*>(event.get());
if(!e)
return;
switch(e->mChannelEventCode)
{
case RsChannelEventCode::NEW_CHANNEL: // [[fallthrough]];
case RsChannelEventCode::UPDATED_CHANNEL: // [[fallthrough]];
case RsChannelEventCode::NEW_MESSAGE: // [[fallthrough]];
case RsChannelEventCode::UPDATED_MESSAGE:
if(e->mChannelGroupId == groupId())
updateDisplay(true);
break;
case RsChannelEventCode::READ_STATUS_CHANGED:
if (FeedItem *feedItem = ui->feedWidget->findFeedItem(GxsChannelPostItem::computeIdentifier(e->mChannelMsgId)))
if (GxsChannelPostItem *channelPostItem = dynamic_cast<GxsChannelPostItem*>(feedItem))
channelPostItem->setReadStatus(false,!channelPostItem->isUnread());
//channelPostItem->setReadStatus(false,e->Don't get read status. Will be more easier and accurate);
break;
default:
break;
}
}
GxsChannelPostsWidget::~GxsChannelPostsWidget()
{
rsEvents->unregisterEventsHandler(mEventHandlerId);
// save settings
processSettings(false);
delete(mAutoDownloadAction);
delete ui;
}
void GxsChannelPostsWidget::processSettings(bool load)
{
Settings->beginGroup(QString("ChannelPostsWidget"));
if (load) {
// load settings
/* Filter */
ui->filterLineEdit->setCurrentFilter(Settings->value("filter", FILTER_TITLE).toInt());
/* View mode */
setViewMode(Settings->value("viewMode", VIEW_MODE_FEEDS).toInt());
} else {
// save settings
/* Filter */
Settings->setValue("filter", ui->filterLineEdit->currentFilter());
/* View mode */
Settings->setValue("viewMode", viewMode());
}
Settings->endGroup();
}
void GxsChannelPostsWidget::settingsChanged()
{
mUseThread = Settings->getChannelLoadThread();
mStateHelper->setWidgetVisible(ui->progressBar, mUseThread);
}
void GxsChannelPostsWidget::groupNameChanged(const QString &name)
{
if (groupId().isNull()) {
ui->nameLabel->setText(tr("No Channel Selected"));
ui->logoLabel->setPixmap(QPixmap(":/icons/png/channels.png"));
} else {
ui->nameLabel->setText(name);
}
}
QIcon GxsChannelPostsWidget::groupIcon()
{
if (mStateHelper->isLoading(mTokenTypeGroupData) || mStateHelper->isLoading(mTokenTypeAllPosts)) {
return FilesDefs::getIconFromQtResourcePath(":/images/kalarm.png");
}
// if (mNewCount) {
// return FilesDefs::getIconFromQtResourcePath(":/images/message-state-new.png");
// }
return QIcon();
}
/*************************************************************************************/
/*************************************************************************************/
/*************************************************************************************/
QScrollArea *GxsChannelPostsWidget::getScrollArea()
{
return NULL;
}
void GxsChannelPostsWidget::deleteFeedItem(FeedItem *feedItem, uint32_t /*type*/)
{
if (!feedItem)
return;
ui->feedWidget->removeFeedItem(feedItem);
}
void GxsChannelPostsWidget::openChat(const RsPeerId & /*peerId*/)
{
}
// Callback from Widget->FeedHolder->ServiceDialog->CommentContainer->CommentDialog,
void GxsChannelPostsWidget::openComments(uint32_t /*type*/, const RsGxsGroupId &groupId, const QVector<RsGxsMessageId>& msg_versions,const RsGxsMessageId &msgId, const QString &title)
{
emit loadComment(groupId, msg_versions,msgId, title);
}
void GxsChannelPostsWidget::createMsg()
{
if (groupId().isNull()) {
return;
}
if (!IS_GROUP_SUBSCRIBED(subscribeFlags())) {
return;
}
CreateGxsChannelMsg *msgDialog = new CreateGxsChannelMsg(groupId());
msgDialog->show();
/* window will destroy itself! */
}
void GxsChannelPostsWidget::insertChannelDetails(const RsGxsChannelGroup &group)
{
/* IMAGE */
QPixmap chanImage;
if (group.mImage.mData != NULL) {
GxsIdDetails::loadPixmapFromData(group.mImage.mData, group.mImage.mSize, chanImage,GxsIdDetails::ORIGINAL);
} else {
chanImage = QPixmap(CHAN_DEFAULT_IMAGE);
}
ui->logoLabel->setPixmap(chanImage);
if (group.mMeta.mSubscribeFlags & GXS_SERV::GROUP_SUBSCRIBE_PUBLISH)
{
mStateHelper->setWidgetEnabled(ui->postButton, true);
}
else
{
mStateHelper->setWidgetEnabled(ui->postButton, false);
}
ui->subscribeToolButton->setSubscribed(IS_GROUP_SUBSCRIBED(group.mMeta.mSubscribeFlags));
mStateHelper->setWidgetEnabled(ui->subscribeToolButton, true);
bool autoDownload ;
rsGxsChannels->getChannelAutoDownload(group.mMeta.mGroupId,autoDownload);
setAutoDownload(autoDownload);
RetroShareLink link;
if (IS_GROUP_SUBSCRIBED(group.mMeta.mSubscribeFlags)) {
ui->feedToolButton->setEnabled(true);
ui->fileToolButton->setEnabled(true);
ui->infoWidget->hide();
setViewMode(viewMode());
ui->subscribeToolButton->setText(tr("Subscribed") + " " + QString::number(group.mMeta.mPop) );
ui->infoPosts->clear();
ui->infoDescription->clear();
} else {
ui->infoPosts->setText(QString::number(group.mMeta.mVisibleMsgCount));
if(group.mMeta.mLastPost==0)
ui->infoLastPost->setText(tr("Never"));
else
ui->infoLastPost->setText(DateTime::formatLongDateTime(group.mMeta.mLastPost));
QString formatDescription = QString::fromUtf8(group.mDescription.c_str());
unsigned int formatFlag = RSHTML_FORMATTEXT_EMBED_LINKS;
// embed smileys ?
if (Settings->valueFromGroup(QString("ChannelPostsWidget"), QString::fromUtf8("Emoteicons_ChannelDecription"), true).toBool()) {
formatFlag |= RSHTML_FORMATTEXT_EMBED_SMILEYS;
}
formatDescription = RsHtml().formatText(NULL, formatDescription, formatFlag);
ui->infoDescription->setText(formatDescription);
ui->infoAdministrator->setId(group.mMeta.mAuthorId) ;
link = RetroShareLink::createMessage(group.mMeta.mAuthorId, "");
ui->infoAdministrator->setText(link.toHtml());
ui->infoCreated->setText(DateTime::formatLongDateTime(group.mMeta.mPublishTs));
QString distrib_string ( "[unknown]" );
switch(group.mMeta.mCircleType)
{
case GXS_CIRCLE_TYPE_PUBLIC: distrib_string = tr("Public") ;
break ;
case GXS_CIRCLE_TYPE_EXTERNAL:
{
RsGxsCircleDetails det ;
// !! What we need here is some sort of CircleLabel, which loads the circle and updates the label when done.
if(rsGxsCircles->getCircleDetails(group.mMeta.mCircleId,det))
distrib_string = tr("Restricted to members of circle \"")+QString::fromUtf8(det.mCircleName.c_str()) +"\"";
else
distrib_string = tr("Restricted to members of circle ")+QString::fromStdString(group.mMeta.mCircleId.toStdString()) ;
}
break ;
case GXS_CIRCLE_TYPE_YOUR_EYES_ONLY: distrib_string = tr("Your eyes only");
break ;
case GXS_CIRCLE_TYPE_LOCAL: distrib_string = tr("You and your friend nodes");
break ;
default:
std::cerr << "(EE) badly initialised group distribution ID = " << group.mMeta.mCircleType << std::endl;
}
ui->infoDistribution->setText(distrib_string);
ui->infoWidget->show();
ui->feedWidget->hide();
ui->fileWidget->hide();
ui->feedToolButton->setEnabled(false);
ui->fileToolButton->setEnabled(false);
ui->subscribeToolButton->setText(tr("Subscribe ") + " " + QString::number(group.mMeta.mPop) );
}
}
int GxsChannelPostsWidget::viewMode()
{
if (ui->feedToolButton->isChecked()) {
return VIEW_MODE_FEEDS;
} else if (ui->fileToolButton->isChecked()) {
return VIEW_MODE_FILES;
}
/* Default */
return VIEW_MODE_FEEDS;
}
void GxsChannelPostsWidget::setViewMode(int viewMode)
{
switch (viewMode) {
case VIEW_MODE_FEEDS:
ui->feedWidget->show();
ui->fileWidget->hide();
ui->feedToolButton->setChecked(true);
ui->fileToolButton->setChecked(false);
break;
case VIEW_MODE_FILES:
ui->feedWidget->hide();
ui->fileWidget->show();
ui->feedToolButton->setChecked(false);
ui->fileToolButton->setChecked(true);
break;
default:
setViewMode(VIEW_MODE_FEEDS);
return;
}
}
void GxsChannelPostsWidget::filterChanged(int filter)
{
ui->feedWidget->setFilterType(filter);
ui->fileWidget->setFilterType(filter);
}
/*static*/ bool GxsChannelPostsWidget::filterItem(FeedItem *feedItem, const QString &text, int filter)
{
GxsChannelPostItem *item = dynamic_cast<GxsChannelPostItem*>(feedItem);
if (!item) {
return true;
}
bool bVisible = text.isEmpty();
if (!bVisible)
{
switch(filter)
{
case FILTER_TITLE:
bVisible = item->getTitleLabel().contains(text,Qt::CaseInsensitive);
break;
case FILTER_MSG:
bVisible = item->getMsgLabel().contains(text,Qt::CaseInsensitive);
break;
case FILTER_FILE_NAME:
{
std::list<SubFileItem *> fileItems = item->getFileItems();
std::list<SubFileItem *>::iterator lit;
for(lit = fileItems.begin(); lit != fileItems.end(); ++lit)
{
SubFileItem *fi = *lit;
QString fileName = QString::fromUtf8(fi->FileName().c_str());
bVisible = (bVisible || fileName.contains(text,Qt::CaseInsensitive));
}
break;
}
default:
bVisible = true;
break;
}
}
return bVisible;
}
#ifdef TODO
void GxsChannelPostsWidget::createPostItemFromMetaData(const RsGxsMsgMetaData& meta,bool related)
{
GxsChannelPostItem *item = NULL;
RsGxsChannelPost post;
if(!meta.mOrigMsgId.isNull())
{
FeedItem *feedItem = ui->feedWidget->findFeedItem(GxsChannelPostItem::computeIdentifier(meta.mOrigMsgId)) ;
item = dynamic_cast<GxsChannelPostItem*>(feedItem);
if(item)
{
post = feedItem->post();
ui->feedWidget->removeFeedItem(item) ;
post.mOlderVersions.insert(post.mMeta.mMsgId);
GxsChannelPostItem *item = new GxsChannelPostItem(this, 0, post, true, false,post.mOlderVersions);
ui->feedWidget->addFeedItem(item, ROLE_PUBLISH, QDateTime::fromTime_t(post.mMeta.mPublishTs));
return ;
}
}
if (related)
{
FeedItem *feedItem = ui->feedWidget->findFeedItem(GxsChannelPostItem::computeIdentifier(meta.mMsgId)) ;
item = dynamic_cast<GxsChannelPostItem*>(feedItem);
}
if (item)
{
item->setPost(post);
ui->feedWidget->setSort(item, ROLE_PUBLISH, QDateTime::fromTime_t(meta.mPublishTs));
}
else
{
GxsChannelPostItem *item = new GxsChannelPostItem(this, 0, meta.mGroupId,meta.mMsgId, true, true);
ui->feedWidget->addFeedItem(item, ROLE_PUBLISH, QDateTime::fromTime_t(post.mMeta.mPublishTs));
}
#ifdef TODO
ui->fileWidget->addFiles(post, related);
#endif
}
#endif
void GxsChannelPostsWidget::createPostItem(const RsGxsChannelPost& post, bool related)
{
GxsChannelPostItem *item = NULL;
const RsMsgMetaData& meta(post.mMeta);
if(!meta.mOrigMsgId.isNull())
{
FeedItem *feedItem = ui->feedWidget->findFeedItem(GxsChannelPostItem::computeIdentifier(meta.mOrigMsgId)) ;
item = dynamic_cast<GxsChannelPostItem*>(feedItem);
if(item)
{
std::set<RsGxsMessageId> older_versions(item->olderVersions()); // we make a copy because the item will be deleted
ui->feedWidget->removeFeedItem(item) ;
older_versions.insert(meta.mMsgId);
GxsChannelPostItem *item = new GxsChannelPostItem(this, 0, mGroup.mMeta,meta.mMsgId, true, false,older_versions);
ui->feedWidget->addFeedItem(item, ROLE_PUBLISH, QDateTime::fromTime_t(meta.mPublishTs));
return ;
}
}
if (related)
{
FeedItem *feedItem = ui->feedWidget->findFeedItem(GxsChannelPostItem::computeIdentifier(meta.mMsgId)) ;
item = dynamic_cast<GxsChannelPostItem*>(feedItem);
}
if (item)
{
item->setPost(post);
ui->feedWidget->setSort(item, ROLE_PUBLISH, QDateTime::fromTime_t(meta.mPublishTs));
}
else
{
GxsChannelPostItem *item = new GxsChannelPostItem(this, 0, mGroup.mMeta,meta.mMsgId, true, true);
ui->feedWidget->addFeedItem(item, ROLE_PUBLISH, QDateTime::fromTime_t(meta.mPublishTs));
}
ui->fileWidget->addFiles(post, related);
}
void GxsChannelPostsWidget::fillThreadCreatePost(const QVariant &post, bool related, int current, int count)
{
/* show fill progress */
if (count) {
ui->progressBar->setValue(current * ui->progressBar->maximum() / count);
}
if (!post.canConvert<RsGxsChannelPost>()) {
return;
}
createPostItem(post.value<RsGxsChannelPost>(), related);
}
void GxsChannelPostsWidget::insertChannelPosts(std::vector<RsGxsChannelPost>& posts, GxsMessageFramePostThread *thread, bool related)
{
if (related && thread) {
std::cerr << "GxsChannelPostsWidget::insertChannelPosts fill only related posts as thread is not possible" << std::endl;
return;
}
int count = posts.size();
int pos = 0;
if (!thread) {
ui->feedWidget->setSortingEnabled(false);
}
// collect new versions of posts if any
#ifdef DEBUG_CHANNEL
std::cerr << "Inserting channel posts" << std::endl;
#endif
std::vector<uint32_t> new_versions ;
for (uint32_t i=0;i<posts.size();++i)
{
if(posts[i].mMeta.mOrigMsgId == posts[i].mMeta.mMsgId)
posts[i].mMeta.mOrigMsgId.clear();
#ifdef DEBUG_CHANNEL
std::cerr << " " << i << ": msg_id=" << posts[i].mMeta.mMsgId << ": orig msg id = " << posts[i].mMeta.mOrigMsgId << std::endl;
#endif
if(!posts[i].mMeta.mOrigMsgId.isNull())
new_versions.push_back(i) ;
}
#ifdef DEBUG_CHANNEL
std::cerr << "New versions: " << new_versions.size() << std::endl;
#endif
if(!new_versions.empty())
{
#ifdef DEBUG_CHANNEL
std::cerr << " New versions present. Replacing them..." << std::endl;
std::cerr << " Creating search map." << std::endl;
#endif
// make a quick search map
std::map<RsGxsMessageId,uint32_t> search_map ;
for (uint32_t i=0;i<posts.size();++i)
search_map[posts[i].mMeta.mMsgId] = i ;
for(uint32_t i=0;i<new_versions.size();++i)
{
#ifdef DEBUG_CHANNEL
std::cerr << " Taking care of new version at index " << new_versions[i] << std::endl;
#endif
uint32_t current_index = new_versions[i] ;
uint32_t source_index = new_versions[i] ;
#ifdef DEBUG_CHANNEL
RsGxsMessageId source_msg_id = posts[source_index].mMeta.mMsgId ;
#endif
// What we do is everytime we find a replacement post, we climb up the replacement graph until we find the original post
// (or the most recent version of it). When we reach this post, we replace it with the data of the source post.
// In the mean time, all other posts have their MsgId cleared, so that the posts are removed from the list.
//std::vector<uint32_t> versions ;
std::map<RsGxsMessageId,uint32_t>::const_iterator vit ;
while(search_map.end() != (vit=search_map.find(posts[current_index].mMeta.mOrigMsgId)))
{
#ifdef DEBUG_CHANNEL
std::cerr << " post at index " << current_index << " replaces a post at position " << vit->second ;
#endif
// Now replace the post only if the new versionis more recent. It may happen indeed that the same post has been corrected multiple
// times. In this case, we only need to replace the post with the newest version
//uint32_t prev_index = current_index ;
current_index = vit->second ;
if(posts[current_index].mMeta.mMsgId.isNull()) // This handles the branching situation where this post has been already erased. No need to go down further.
{
#ifdef DEBUG_CHANNEL
std::cerr << " already erased. Stopping." << std::endl;
#endif
break ;
}
if(posts[current_index].mMeta.mPublishTs < posts[source_index].mMeta.mPublishTs)
{
#ifdef DEBUG_CHANNEL
std::cerr << " and is more recent => following" << std::endl;
#endif
for(std::set<RsGxsMessageId>::const_iterator itt(posts[current_index].mOlderVersions.begin());itt!=posts[current_index].mOlderVersions.end();++itt)
posts[source_index].mOlderVersions.insert(*itt);
posts[source_index].mOlderVersions.insert(posts[current_index].mMeta.mMsgId);
posts[current_index].mMeta.mMsgId.clear(); // clear the msg Id so the post will be ignored
}
#ifdef DEBUG_CHANNEL
else
std::cerr << " but is older -> Stopping" << std::endl;
#endif
}
}
}
#ifdef DEBUG_CHANNEL
std::cerr << "Now adding posts..." << std::endl;
#endif
for (std::vector<RsGxsChannelPost>::const_reverse_iterator it = posts.rbegin(); it != posts.rend(); ++it)
{
#ifdef DEBUG_CHANNEL
std::cerr << " adding post: " << (*it).mMeta.mMsgId ;
#endif
if(!(*it).mMeta.mMsgId.isNull())
{
#ifdef DEBUG_CHANNEL
std::cerr << " added" << std::endl;
#endif
if (thread && thread->stopped())
break;
if (thread)
thread->emitAddPost(QVariant::fromValue(*it), related, ++pos, count);
else
createPostItem(*it, related);
}
#ifdef DEBUG_CHANNEL
else
std::cerr << " skipped" << std::endl;
#endif
}
if (!thread) {
ui->feedWidget->setSortingEnabled(true);
}
}
void GxsChannelPostsWidget::clearPosts()
{
ui->feedWidget->clear();
ui->fileWidget->clear();
}
void GxsChannelPostsWidget::blank()
{
mStateHelper->setWidgetEnabled(ui->postButton, false);
mStateHelper->setWidgetEnabled(ui->subscribeToolButton, false);
clearPosts();
groupNameChanged(QString());
ui->infoWidget->hide();
ui->feedWidget->show();
ui->fileWidget->hide();
}
bool GxsChannelPostsWidget::navigatePostItem(const RsGxsMessageId &msgId)
{
FeedItem *feedItem = ui->feedWidget->findFeedItem(GxsChannelPostItem::computeIdentifier(msgId));
if (!feedItem) {
return false;
}
return ui->feedWidget->scrollTo(feedItem, true);
}
void GxsChannelPostsWidget::subscribeGroup(bool subscribe)
{
RsGxsGroupId grpId(groupId());
if (grpId.isNull()) return;
RsThread::async([=]()
{
rsGxsChannels->subscribeToChannel(grpId, subscribe);
} );
}
void GxsChannelPostsWidget::setAutoDownload(bool autoDl)
{
mAutoDownloadAction->setChecked(autoDl);
mAutoDownloadAction->setText(autoDl ? tr("Disable Auto-Download") : tr("Enable Auto-Download"));
}
void GxsChannelPostsWidget::toggleAutoDownload()
{
RsGxsGroupId grpId = groupId();
if (grpId.isNull()) {
return;
}
bool autoDownload;
if(!rsGxsChannels->getChannelAutoDownload(grpId, autoDownload))
{
std::cerr << __PRETTY_FUNCTION__ << " failed to get autodownload value "
<< "for channel: " << grpId.toStdString() << std::endl;
return;
}
RsThread::async([this, grpId, autoDownload]()
{
if(!rsGxsChannels->setChannelAutoDownload(grpId, !autoDownload))
{
std::cerr << __PRETTY_FUNCTION__ << " failed to set autodownload "
<< "for channel: " << grpId.toStdString() << std::endl;
return;
}
// RsQThreadUtils::postToObject( [=]()
// {
// /* Here it goes any code you want to be executed on the Qt Gui
// * thread, for example to update the data model with new information
// * after a blocking call to RetroShare API complete, note that
// * Qt::QueuedConnection is important!
// */
//
// std::cerr << __PRETTY_FUNCTION__ << " Has been executed on GUI "
// << "thread but was scheduled by async thread" << std::endl;
// }, this );
});
}
bool GxsChannelPostsWidget::insertGroupData(const RsGxsGenericGroupData *data)
{
const RsGxsChannelGroup *d = dynamic_cast<const RsGxsChannelGroup*>(data);
if(!d)
{
RsErr() << __PRETTY_FUNCTION__ << " Cannot dynamic cast input data (" << (void*)data << " to RsGxsGenericGroupData. Something bad happenned." << std::endl;
return false;
}
insertChannelDetails(*d);
return true;
}
void GxsChannelPostsWidget::getMsgData(const std::set<RsGxsMessageId>& msgIds,std::vector<RsGxsGenericMsgData*>& psts)
{
std::vector<RsGxsChannelPost> posts;
std::vector<RsGxsComment> comments;
std::vector<RsGxsVote> votes;
rsGxsChannels->getChannelContent( groupId(),msgIds,posts,comments,votes );
psts.clear();
for(auto& post: posts)
psts.push_back(new RsGxsChannelPost(post));
}
void GxsChannelPostsWidget::getAllMsgData(std::vector<RsGxsGenericMsgData*>& psts)
{
std::vector<RsGxsChannelPost> posts;
std::vector<RsGxsComment> comments;
std::vector<RsGxsVote> votes;
rsGxsChannels->getChannelAllContent( groupId(),posts,comments,votes );
psts.clear();
for(auto& post: posts)
psts.push_back(new RsGxsChannelPost(post));
}
bool GxsChannelPostsWidget::getGroupData(RsGxsGenericGroupData *& data)
{
if(groupId().isNull())
{
RsErr() << __PRETTY_FUNCTION__ << " Trying to get data about null group!!" << std::endl;
return false;
}
std::vector<RsGxsChannelGroup> groups;
if(rsGxsChannels->getChannelsInfo(std::list<RsGxsGroupId>({groupId()}),groups) && groups.size()==1)
{
data = new RsGxsChannelGroup(groups[0]);
mGroup = groups[0]; // make a local copy to pass on to items
return true;
}
else
{
RsGxsChannelGroup distant_group;
if(rsGxsChannels->getDistantSearchResultGroupData(groupId(),distant_group))
{
insertChannelDetails(distant_group);
data = new RsGxsChannelGroup(distant_group);
mGroup = distant_group; // make a local copy to pass on to items
return true ;
}
}
return false;
}
void GxsChannelPostsWidget::insertAllPosts(const std::vector<RsGxsGenericMsgData*>& posts, GxsMessageFramePostThread *thread)
{
std::vector<RsGxsChannelPost> cposts;
for(auto post: posts) // This is not so nice but we have somehow to convert to RsGxsChannelPost at some time, and the cposts list is being modified in the insert method.
cposts.push_back(*static_cast<RsGxsChannelPost*>(post));
insertChannelPosts(cposts, thread, false);
}
void GxsChannelPostsWidget::insertPosts(const std::vector<RsGxsGenericMsgData*>& posts)
{
std::vector<RsGxsChannelPost> cposts;
for(auto post: posts) // This is not so nice but we have somehow to convert to RsGxsChannelPost at some timer, and the cposts list is being modified in the insert method.
cposts.push_back(*static_cast<RsGxsChannelPost*>(post));
insertChannelPosts(cposts, NULL, true);
}
class GxsChannelPostsReadData
{
public:
GxsChannelPostsReadData(bool read)
{
mRead = read;
mLastToken = 0;
}
public:
bool mRead;
uint32_t mLastToken;
};
static void setAllMessagesReadCallback(FeedItem *feedItem, void *data)
{
GxsChannelPostItem *channelPostItem = dynamic_cast<GxsChannelPostItem*>(feedItem);
if (!channelPostItem) {
return;
}
GxsChannelPostsReadData *readData = (GxsChannelPostsReadData*) data;
bool isRead = !channelPostItem->isUnread() ;
if(channelPostItem->isLoaded() && (isRead == readData->mRead))
return ;
RsGxsGrpMsgIdPair msgPair = std::make_pair(channelPostItem->groupId(), channelPostItem->messageId());
rsGxsChannels->setMessageReadStatus(readData->mLastToken, msgPair, readData->mRead);
}
void GxsChannelPostsWidget::setAllMessagesReadDo(bool read, uint32_t &token)
{
if (groupId().isNull() || !IS_GROUP_SUBSCRIBED(subscribeFlags())) {
return;
}
GxsChannelPostsReadData data(read);
ui->feedWidget->withAll(setAllMessagesReadCallback, &data);
token = data.mLastToken;
}

View File

@ -1,117 +0,0 @@
/*******************************************************************************
* retroshare-gui/src/gui/gxschannels/GxsChannelPostsWidget.h *
* *
* Copyright 2013 by Robert Fernie <retroshare.project@gmail.com> *
* *
* This program is free software: you can redistribute it and/or modify *
* it under the terms of the GNU Affero General Public License as *
* published by the Free Software Foundation, either version 3 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 Affero General Public License for more details. *
* *
* You should have received a copy of the GNU Affero General Public License *
* along with this program. If not, see <https://www.gnu.org/licenses/>. *
* *
*******************************************************************************/
#ifndef _GXS_CHANNELPOSTSWIDGET_H
#define _GXS_CHANNELPOSTSWIDGET_H
#include <map>
#include "gui/gxs/GxsMessageFramePostWidget.h"
#include "gui/feeds/FeedHolder.h"
namespace Ui {
class GxsChannelPostsWidget;
}
class GxsChannelPostItem;
class QTreeWidgetItem;
class FeedItem;
class GxsChannelPostsWidget : public GxsMessageFramePostWidget, public FeedHolder
{
Q_OBJECT
public:
/* Filters */
enum Filter {
FILTER_TITLE = 1,
FILTER_MSG = 2,
FILTER_FILE_NAME = 3
};
public:
/** Default Constructor */
GxsChannelPostsWidget(const RsGxsGroupId &channelId, QWidget *parent = 0);
/** Default Destructor */
~GxsChannelPostsWidget();
/* GxsMessageFrameWidget */
virtual QIcon groupIcon();
/* FeedHolder */
virtual QScrollArea *getScrollArea();
virtual void deleteFeedItem(FeedItem *feedItem, uint32_t type);
virtual void openChat(const RsPeerId& peerId);
virtual void openComments(uint32_t type, const RsGxsGroupId &groupId, const QVector<RsGxsMessageId> &msg_versions, const RsGxsMessageId &msgId, const QString &title);
protected:
/* GxsMessageFramePostWidget */
virtual void groupNameChanged(const QString &name);
virtual bool insertGroupData(const RsGxsGenericGroupData *data) override;
virtual void clearPosts();
virtual bool useThread() { return mUseThread; }
virtual void fillThreadCreatePost(const QVariant &post, bool related, int current, int count);
virtual bool navigatePostItem(const RsGxsMessageId& msgId);
virtual void blank() ;
virtual bool getGroupData(RsGxsGenericGroupData *& data) override;
virtual void getMsgData(const std::set<RsGxsMessageId>& msgIds,std::vector<RsGxsGenericMsgData*>& posts) override;
virtual void getAllMsgData(std::vector<RsGxsGenericMsgData*>& posts) override;
virtual void insertPosts(const std::vector<RsGxsGenericMsgData*>& posts) override;
virtual void insertAllPosts(const std::vector<RsGxsGenericMsgData*>& posts, GxsMessageFramePostThread *thread) override;
/* GxsMessageFrameWidget */
virtual void setAllMessagesReadDo(bool read, uint32_t &token);
private slots:
void createMsg();
void toggleAutoDownload();
void subscribeGroup(bool subscribe);
void filterChanged(int filter);
void setViewMode(int viewMode);
void settingsChanged();
private:
void processSettings(bool load);
void setAutoDownload(bool autoDl);
static bool filterItem(FeedItem *feedItem, const QString &text, int filter);
int viewMode();
void insertChannelDetails(const RsGxsChannelGroup &group);
void insertChannelPosts(std::vector<RsGxsChannelPost>& posts, GxsMessageFramePostThread *thread, bool related);
void createPostItem(const RsGxsChannelPost &post, bool related);
void handleEvent_main_thread(std::shared_ptr<const RsEvent> event);
private:
QAction *mAutoDownloadAction;
RsGxsChannelGroup mGroup;
bool mUseThread;
RsEventsHandlerId_t mEventHandlerId ;
/* UI - from Designer */
Ui::GxsChannelPostsWidget *ui;
};
#endif

View File

@ -1,593 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>GxsChannelPostsWidget</class>
<widget class="QWidget" name="GxsChannelPostsWidget">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>977</width>
<height>628</height>
</rect>
</property>
<layout class="QVBoxLayout" name="verticalLayout_2">
<property name="spacing">
<number>4</number>
</property>
<property name="leftMargin">
<number>0</number>
</property>
<property name="topMargin">
<number>0</number>
</property>
<property name="rightMargin">
<number>0</number>
</property>
<property name="bottomMargin">
<number>0</number>
</property>
<item>
<widget class="QFrame" name="headFrame">
<property name="frameShape">
<enum>QFrame::Box</enum>
</property>
<property name="frameShadow">
<enum>QFrame::Sunken</enum>
</property>
<layout class="QHBoxLayout" name="horizontalLayout_3">
<property name="leftMargin">
<number>4</number>
</property>
<property name="topMargin">
<number>4</number>
</property>
<property name="rightMargin">
<number>4</number>
</property>
<property name="bottomMargin">
<number>4</number>
</property>
<item>
<widget class="QLabel" name="logoLabel">
<property name="minimumSize">
<size>
<width>64</width>
<height>64</height>
</size>
</property>
<property name="maximumSize">
<size>
<width>64</width>
<height>64</height>
</size>
</property>
<property name="text">
<string/>
</property>
<property name="pixmap">
<pixmap resource="../images.qrc">:/images/channels.png</pixmap>
</property>
<property name="scaledContents">
<bool>true</bool>
</property>
</widget>
</item>
<item>
<widget class="StyledElidedLabel" name="nameLabel">
<property name="palette">
<palette>
<active/>
<inactive/>
<disabled/>
</palette>
</property>
<property name="text">
<string notr="true">Channel Name</string>
</property>
</widget>
</item>
</layout>
</widget>
</item>
<item>
<widget class="QFrame" name="toolBarFrame">
<property name="frameShape">
<enum>QFrame::Box</enum>
</property>
<property name="frameShadow">
<enum>QFrame::Sunken</enum>
</property>
<layout class="QHBoxLayout" name="horizontalLayout_2">
<property name="leftMargin">
<number>4</number>
</property>
<property name="topMargin">
<number>2</number>
</property>
<property name="rightMargin">
<number>6</number>
</property>
<property name="bottomMargin">
<number>2</number>
</property>
<item>
<widget class="SubscribeToolButton" name="subscribeToolButton">
<property name="sizePolicy">
<sizepolicy hsizetype="Fixed" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="text">
<string notr="true">Subscribe</string>
</property>
<property name="iconSize">
<size>
<width>16</width>
<height>16</height>
</size>
</property>
<property name="popupMode">
<enum>QToolButton::MenuButtonPopup</enum>
</property>
<property name="toolButtonStyle">
<enum>Qt::ToolButtonTextBesideIcon</enum>
</property>
<property name="autoRaise">
<bool>true</bool>
</property>
</widget>
</item>
<item>
<widget class="QToolButton" name="postButton">
<property name="focusPolicy">
<enum>Qt::NoFocus</enum>
</property>
<property name="toolTip">
<string>Post to Channel</string>
</property>
<property name="text">
<string>Add new post</string>
</property>
<property name="icon">
<iconset resource="../icons.qrc">
<normaloff>:/icons/png/add.png</normaloff>:/icons/png/add.png</iconset>
</property>
<property name="iconSize">
<size>
<width>32</width>
<height>16</height>
</size>
</property>
<property name="toolButtonStyle">
<enum>Qt::ToolButtonTextBesideIcon</enum>
</property>
<property name="autoRaise">
<bool>true</bool>
</property>
</widget>
</item>
<item>
<spacer name="horizontalSpacer">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeType">
<enum>QSizePolicy::MinimumExpanding</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>0</width>
<height>0</height>
</size>
</property>
</spacer>
</item>
<item>
<widget class="QLabel" name="loadingLabel">
<property name="text">
<string>Loading</string>
</property>
</widget>
</item>
<item>
<widget class="QProgressBar" name="progressBar">
<property name="sizePolicy">
<sizepolicy hsizetype="Minimum" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="maximumSize">
<size>
<width>16777215</width>
<height>10</height>
</size>
</property>
<property name="maximum">
<number>1000</number>
</property>
<property name="value">
<number>0</number>
</property>
</widget>
</item>
<item>
<layout class="QHBoxLayout" name="viewModeLayout">
<property name="spacing">
<number>0</number>
</property>
<item>
<widget class="QToolButton" name="feedToolButton">
<property name="toolTip">
<string>Show feeds</string>
</property>
<property name="icon">
<iconset resource="../images.qrc">
<normaloff>:/images/view-feeds.png</normaloff>:/images/view-feeds.png</iconset>
</property>
<property name="checkable">
<bool>true</bool>
</property>
<property name="autoRaise">
<bool>true</bool>
</property>
</widget>
</item>
<item>
<widget class="QToolButton" name="fileToolButton">
<property name="toolTip">
<string>Show files</string>
</property>
<property name="icon">
<iconset resource="../images.qrc">
<normaloff>:/images/view-files.png</normaloff>:/images/view-files.png</iconset>
</property>
<property name="checkable">
<bool>true</bool>
</property>
<property name="autoRaise">
<bool>true</bool>
</property>
</widget>
</item>
</layout>
</item>
<item>
<widget class="LineEditClear" name="filterLineEdit">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="minimumSize">
<size>
<width>200</width>
<height>0</height>
</size>
</property>
<property name="maximumSize">
<size>
<width>200</width>
<height>16777215</height>
</size>
</property>
<property name="toolTip">
<string>Search channels</string>
</property>
<property name="frame">
<bool>true</bool>
</property>
</widget>
</item>
</layout>
</widget>
</item>
<item>
<widget class="QWidget" name="infoWidget" native="true">
<property name="styleSheet">
<string notr="true"/>
</property>
<layout class="QVBoxLayout" name="verticalLayout">
<property name="leftMargin">
<number>3</number>
</property>
<property name="topMargin">
<number>0</number>
</property>
<property name="rightMargin">
<number>3</number>
</property>
<property name="bottomMargin">
<number>3</number>
</property>
<item>
<widget class="QFrame" name="infoFrame">
<property name="autoFillBackground">
<bool>false</bool>
</property>
<property name="frameShape">
<enum>QFrame::NoFrame</enum>
</property>
<property name="frameShadow">
<enum>QFrame::Plain</enum>
</property>
<layout class="QGridLayout" name="gridLayout_2">
<property name="leftMargin">
<number>6</number>
</property>
<property name="topMargin">
<number>6</number>
</property>
<property name="rightMargin">
<number>6</number>
</property>
<property name="bottomMargin">
<number>6</number>
</property>
<item row="0" column="0">
<widget class="QGroupBox" name="groupBox">
<property name="title">
<string>Channel details</string>
</property>
<layout class="QGridLayout" name="gridLayout">
<property name="leftMargin">
<number>9</number>
</property>
<property name="topMargin">
<number>9</number>
</property>
<property name="rightMargin">
<number>9</number>
</property>
<property name="bottomMargin">
<number>9</number>
</property>
<item row="1" column="0">
<widget class="QLabel" name="infoLastPostLabel">
<property name="sizePolicy">
<sizepolicy hsizetype="Maximum" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="font">
<font>
<weight>75</weight>
<bold>true</bold>
</font>
</property>
<property name="text">
<string>Last Post:</string>
</property>
</widget>
</item>
<item row="6" column="0" colspan="3">
<widget class="QTextBrowser" name="infoDescription">
<property name="html">
<string notr="true">&lt;!DOCTYPE HTML PUBLIC &quot;-//W3C//DTD HTML 4.0//EN&quot; &quot;http://www.w3.org/TR/REC-html40/strict.dtd&quot;&gt;
&lt;html&gt;&lt;head&gt;&lt;meta name=&quot;qrichtext&quot; content=&quot;1&quot; /&gt;&lt;style type=&quot;text/css&quot;&gt;
p, li { white-space: pre-wrap; }
&lt;/style&gt;&lt;/head&gt;&lt;body style=&quot; font-family:'Sans'; font-size:9pt; font-weight:400; font-style:normal;&quot;&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;&lt;span style=&quot; font-family:'MS Shell Dlg 2'; font-size:8pt;&quot;&gt;Description&lt;/span&gt;&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
</property>
<property name="textInteractionFlags">
<set>Qt::LinksAccessibleByMouse|Qt::TextSelectableByMouse</set>
</property>
<property name="openExternalLinks">
<bool>true</bool>
</property>
<property name="openLinks">
<bool>true</bool>
</property>
</widget>
</item>
<item row="5" column="0">
<widget class="QLabel" name="infoDescriptionLabel">
<property name="font">
<font>
<weight>75</weight>
<bold>true</bold>
</font>
</property>
<property name="text">
<string>Description:</string>
</property>
</widget>
</item>
<item row="4" column="0">
<widget class="QLabel" name="label_2">
<property name="font">
<font>
<weight>75</weight>
<bold>true</bold>
</font>
</property>
<property name="text">
<string>Created:</string>
</property>
</widget>
</item>
<item row="2" column="0">
<widget class="QLabel" name="label">
<property name="font">
<font>
<weight>75</weight>
<bold>true</bold>
</font>
</property>
<property name="text">
<string>Administrator:</string>
</property>
</widget>
</item>
<item row="0" column="0">
<widget class="QLabel" name="infoPostsLabel">
<property name="sizePolicy">
<sizepolicy hsizetype="Maximum" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="font">
<font>
<weight>75</weight>
<bold>true</bold>
</font>
</property>
<property name="text">
<string>Posts:</string>
</property>
</widget>
</item>
<item row="3" column="0">
<widget class="QLabel" name="label_3">
<property name="font">
<font>
<weight>75</weight>
<bold>true</bold>
</font>
</property>
<property name="text">
<string>Distribution:</string>
</property>
</widget>
</item>
<item row="4" column="1" colspan="2">
<widget class="QLabel" name="infoCreated">
<property name="text">
<string>unknown</string>
</property>
</widget>
</item>
<item row="3" column="1" colspan="2">
<widget class="QLabel" name="infoDistribution">
<property name="text">
<string>unknown</string>
</property>
</widget>
</item>
<item row="2" column="1" colspan="2">
<widget class="GxsIdLabel" name="infoAdministrator">
<property name="text">
<string>unknown</string>
</property>
<property name="openExternalLinks">
<bool>true</bool>
</property>
</widget>
</item>
<item row="1" column="1" colspan="2">
<widget class="QLabel" name="infoLastPost">
<property name="text">
<string notr="true">unknown</string>
</property>
</widget>
</item>
<item row="0" column="1" colspan="2">
<widget class="QLabel" name="infoPosts">
<property name="text">
<string notr="true">0</string>
</property>
</widget>
</item>
</layout>
</widget>
</item>
</layout>
</widget>
</item>
<item>
<spacer name="verticalSpacer">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>0</width>
<height>0</height>
</size>
</property>
</spacer>
</item>
</layout>
</widget>
</item>
<item>
<widget class="GxsChannelFilesWidget" name="fileWidget" native="true">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Expanding">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
</widget>
</item>
<item>
<widget class="RSFeedWidget" name="feedWidget" native="true">
<property name="sizePolicy">
<sizepolicy hsizetype="Expanding" vsizetype="Expanding">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
</widget>
</item>
</layout>
<action name="actionFeeds">
<property name="text">
<string>Feeds</string>
</property>
</action>
<action name="actionFiles">
<property name="text">
<string>Files</string>
</property>
</action>
<zorder>toolBarFrame</zorder>
<zorder>headFrame</zorder>
<zorder>feedWidget</zorder>
<zorder>fileWidget</zorder>
<zorder>infoWidget</zorder>
</widget>
<customwidgets>
<customwidget>
<class>GxsIdLabel</class>
<extends>QLabel</extends>
<header>gui/gxs/GxsIdLabel.h</header>
</customwidget>
<customwidget>
<class>SubscribeToolButton</class>
<extends>QToolButton</extends>
<header>gui/common/SubscribeToolButton.h</header>
</customwidget>
<customwidget>
<class>StyledElidedLabel</class>
<extends>QLabel</extends>
<header>gui/common/StyledElidedLabel.h</header>
</customwidget>
<customwidget>
<class>LineEditClear</class>
<extends>QLineEdit</extends>
<header location="global">gui/common/LineEditClear.h</header>
</customwidget>
<customwidget>
<class>GxsChannelFilesWidget</class>
<extends>QWidget</extends>
<header>gui/gxschannels/GxsChannelFilesWidget.h</header>
<container>1</container>
</customwidget>
<customwidget>
<class>RSFeedWidget</class>
<extends>QWidget</extends>
<header>gui/common/RSFeedWidget.h</header>
<container>1</container>
</customwidget>
</customwidgets>
<resources>
<include location="../icons.qrc"/>
<include location="../images.qrc"/>
</resources>
<connections/>
</ui>

View File

@ -1356,11 +1356,9 @@ gxschannels {
HEADERS += gui/gxschannels/GxsChannelDialog.h \
gui/gxschannels/GxsChannelGroupDialog.h \
gui/gxschannels/CreateGxsChannelMsg.h \
gui/gxschannels/GxsChannelPostsWidget.h \
gui/gxschannels/GxsChannelPostsWidgetWithModel.h \
gui/gxschannels/GxsChannelPostsModel.h \
gui/gxschannels/GxsChannelPostFilesModel.h \
gui/gxschannels/GxsChannelFilesWidget.h \
gui/gxschannels/GxsChannelPostThumbnail.h \
gui/gxschannels/GxsChannelFilesStatusWidget.h \
gui/feeds/GxsChannelGroupItem.h \
@ -1369,7 +1367,6 @@ gxschannels {
FORMS += \
gui/gxschannels/GxsChannelPostsWidgetWithModel.ui \
gui/gxschannels/GxsChannelPostsWidget.ui \
gui/gxschannels/GxsChannelFilesWidget.ui \
gui/gxschannels/GxsChannelFilesStatusWidget.ui \
gui/gxschannels/CreateGxsChannelMsg.ui \
@ -1377,11 +1374,9 @@ gxschannels {
gui/feeds/GxsChannelPostItem.ui
SOURCES += gui/gxschannels/GxsChannelDialog.cpp \
gui/gxschannels/GxsChannelPostsWidget.cpp \
gui/gxschannels/GxsChannelPostsWidgetWithModel.cpp \
gui/gxschannels/GxsChannelPostsModel.cpp \
gui/gxschannels/GxsChannelPostFilesModel.cpp \
gui/gxschannels/GxsChannelFilesWidget.cpp \
gui/gxschannels/GxsChannelPostThumbnail.cpp \
gui/gxschannels/GxsChannelFilesStatusWidget.cpp \
gui/gxschannels/GxsChannelGroupDialog.cpp \