Added basic widget RSFeedWidget for showing feed items in a QTreeWidget as replacement for the QScrollArea.

- Use sort of QTreeWidget
- Filter items
- Open/collapse selected item with +/-
- Remove selecteds item with dselete key

git-svn-id: http://svn.code.sf.net/p/retroshare/code/trunk@7478 b45a01b8-16f6-495d-af2f-9b41ad6348cc
This commit is contained in:
thunder2 2014-08-01 14:49:58 +00:00
parent e588b25b67
commit d13aa90b2b
20 changed files with 841 additions and 183 deletions

View file

@ -19,6 +19,8 @@
* Boston, MA 02110-1301, USA.
****************************************************************/
#include <QDateTime>
#include "GxsChannelPostsWidget.h"
#include "ui_GxsChannelPostsWidget.h"
#include "gui/feeds/GxsChannelPostItem.h"
@ -31,6 +33,8 @@
#define CHAN_DEFAULT_IMAGE ":/images/channels.png"
#define ROLE_PUBLISH FEED_TREEWIDGET_SORTROLE
/****
* #define DEBUG_CHANNEL
***/
@ -49,6 +53,8 @@ GxsChannelPostsWidget::GxsChannelPostsWidget(const RsGxsGroupId &channelId, QWid
/* Invoke the Qt Designer generated object setup routine */
ui->setupUi(this);
mInProcessSettings = false;
/* Setup UI helper */
// No progress yet
@ -69,8 +75,7 @@ GxsChannelPostsWidget::GxsChannelPostsWidget(const RsGxsGroupId &channelId, QWid
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"));
ui->filterLineEdit->setCurrentFilter( Settings->valueFromGroup("ChannelFeed", "filter", FILTER_TITLE).toInt());
connect(ui->filterLineEdit, SIGNAL(textChanged(QString)), this, SLOT(filterItems(QString)));
connect(ui->filterLineEdit, SIGNAL(textChanged(QString)), ui->feedWidget, SLOT(setFilterText(QString)));
connect(ui->filterLineEdit, SIGNAL(filterChanged(int)), this, SLOT(filterChanged(int)));
/*************** Setup Left Hand Side (List of Channels) ****************/
@ -81,7 +86,9 @@ GxsChannelPostsWidget::GxsChannelPostsWidget(const RsGxsGroupId &channelId, QWid
ui->nameLabel->setMinimumWidth(20);
mInProcessSettings = false;
/* Initialize feed widget */
ui->feedWidget->setSortRole(ROLE_PUBLISH, Qt::DescendingOrder);
ui->feedWidget->setFilterCallback(filterItem);
/* load settings */
processSettings(true);
@ -111,18 +118,19 @@ GxsChannelPostsWidget::~GxsChannelPostsWidget()
delete ui;
}
void GxsChannelPostsWidget::processSettings(bool /*load*/)
void GxsChannelPostsWidget::processSettings(bool load)
{
mInProcessSettings = true;
// Settings->beginGroup(QString("ChannelPostsWidget"));
//
// if (load) {
// // load settings
// } else {
// // save settings
// }
//
// Settings->endGroup();
Settings->beginGroup(QString("ChannelPostsWidget"));
if (load) {
// load settings
ui->filterLineEdit->setCurrentFilter(Settings->value("filter", FILTER_TITLE).toInt());
} else {
// save settings
}
Settings->endGroup();
mInProcessSettings = false;
}
@ -155,7 +163,7 @@ QIcon GxsChannelPostsWidget::groupIcon()
QScrollArea *GxsChannelPostsWidget::getScrollArea()
{
return ui->scrollArea;
return NULL;
}
void GxsChannelPostsWidget::deleteFeedItem(QWidget * /*item*/, uint32_t /*type*/)
@ -216,116 +224,85 @@ void GxsChannelPostsWidget::insertChannelDetails(const RsGxsChannelGroup &group)
void GxsChannelPostsWidget::filterChanged(int filter)
{
ui->feedWidget->setFilterType(filter);
if (mInProcessSettings) {
return;
}
filterItems(ui->filterLineEdit->text());
// save index
Settings->setValueToGroup("ChannelFeed", "filter", filter);
Settings->setValueToGroup("ChannelPostsWidget", "filter", filter);
}
void GxsChannelPostsWidget::filterItems(const QString& text)
/*static*/ bool GxsChannelPostsWidget::filterItem(FeedItem *feedItem, const QString &text, int filter)
{
int filter = ui->filterLineEdit->currentFilter();
/* Search exisiting item */
QList<GxsFeedItem*>::iterator lit;
for (lit = mPostItems.begin(); lit != mPostItems.end(); lit++)
{
GxsChannelPostItem *item = dynamic_cast<GxsChannelPostItem*>(*lit);
if (!item) {
continue;
}
filterItem(item,text,filter);
GxsChannelPostItem *item = dynamic_cast<GxsChannelPostItem*>(feedItem);
if (!item) {
return true;
}
}
bool GxsChannelPostsWidget::filterItem(GxsChannelPostItem *pItem, const QString &text, const int filter)
{
bool bVisible = text.isEmpty();
switch(filter)
{
case FILTER_TITLE:
bVisible=pItem->getTitleLabel().contains(text,Qt::CaseInsensitive);
bVisible = item->getTitleLabel().contains(text,Qt::CaseInsensitive);
break;
case FILTER_MSG:
bVisible=pItem->getMsgLabel().contains(text,Qt::CaseInsensitive);
bVisible = item->getMsgLabel().contains(text,Qt::CaseInsensitive);
break;
case FILTER_FILE_NAME:
{
std::list<SubFileItem *> fileItems=pItem->getFileItems();
std::list<SubFileItem *> fileItems = item->getFileItems();
std::list<SubFileItem *>::iterator lit;
for(lit = fileItems.begin(); lit != fileItems.end(); 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));
QString fileName = QString::fromUtf8(fi->FileName().c_str());
bVisible = (bVisible || fileName.contains(text,Qt::CaseInsensitive));
}
}
break;
}
default:
bVisible=true;
bVisible = true;
break;
}
pItem->setVisible(bVisible);
return (bVisible);
}
static bool sortChannelMsgSummaryAsc(const RsGxsChannelPost &msg1, const RsGxsChannelPost &msg2)
{
return (msg1.mMeta.mPublishTs > msg2.mMeta.mPublishTs);
}
static bool sortChannelMsgSummaryDesc(const RsGxsChannelPost &msg1, const RsGxsChannelPost &msg2)
{
return (msg1.mMeta.mPublishTs < msg2.mMeta.mPublishTs);
return bVisible;
}
void GxsChannelPostsWidget::insertChannelPosts(std::vector<RsGxsChannelPost> &posts, bool related)
{
std::vector<RsGxsChannelPost>::const_iterator it;
// Do these need sorting? probably.
// can we add that into the request?
if (related) {
/* Sort descending to add posts at top */
std::sort(posts.begin(), posts.end(), sortChannelMsgSummaryDesc);
} else {
std::sort(posts.begin(), posts.end(), sortChannelMsgSummaryAsc);
}
uint32_t subscribeFlags = 0xffffffff;
ui->feedWidget->setSortingEnabled(false);
for (it = posts.begin(); it != posts.end(); it++)
{
const RsGxsChannelPost &msg = *it;
GxsChannelPostItem *item = NULL;
if (related) {
foreach (GxsFeedItem *loopItem, mPostItems) {
if (loopItem->messageId() == it->mMeta.mMsgId) {
item = dynamic_cast<GxsChannelPostItem*>(loopItem);
break;
}
}
FeedItem *feedItem = ui->feedWidget->findGxsFeedItem(msg.mMeta.mGroupId, msg.mMeta.mMsgId);
item = dynamic_cast<GxsChannelPostItem*>(feedItem);
}
if (item) {
item->setContent(*it);
//TODO: Sort timestamp
} else {
item = new GxsChannelPostItem(this, 0, *it, subscribeFlags, true, false);
if (!ui->filterLineEdit->text().isEmpty())
filterItem(item, ui->filterLineEdit->text(), ui->filterLineEdit->currentFilter());
mPostItems.push_back(item);
if (related) {
ui->verticalLayout->insertWidget(0, item);
} else {
ui->verticalLayout->addWidget(item);
}
ui->feedWidget->addFeedItem(item, ROLE_PUBLISH, QDateTime::fromTime_t(msg.mMeta.mPublishTs));
}
}
ui->feedWidget->setSortingEnabled(true);
}
void GxsChannelPostsWidget::clearPosts()
{
ui->feedWidget->clear();
}
void GxsChannelPostsWidget::subscribeGroup(bool subscribe)
@ -391,10 +368,24 @@ void GxsChannelPostsWidget::insertRelatedPosts(const uint32_t &token)
insertChannelPosts(posts, true);
}
void GxsChannelPostsWidget::setMessageRead(GxsFeedItem *item, bool read)
static void setAllMessagesReadCallback(FeedItem *feedItem, const QVariant &data)
{
RsGxsGrpMsgIdPair msgPair = std::make_pair(item->groupId(), item->messageId());
GxsChannelPostItem *channelPostItem = dynamic_cast<GxsChannelPostItem*>(feedItem);
if (!channelPostItem) {
return;
}
RsGxsGrpMsgIdPair msgPair = std::make_pair(channelPostItem->groupId(), channelPostItem->messageId());
uint32_t token;
rsGxsChannels->setMessageReadStatus(token, msgPair, read);
rsGxsChannels->setMessageReadStatus(token, msgPair, data.toBool());
}
void GxsChannelPostsWidget::setAllMessagesRead(bool read)
{
if (groupId().isNull() || !IS_GROUP_SUBSCRIBED(subscribeFlags())) {
return;
}
ui->feedWidget->withAll(setAllMessagesReadCallback, read);
}

View file

@ -32,9 +32,9 @@ namespace Ui {
class GxsChannelPostsWidget;
}
//class ChanMsgItem;
class GxsChannelPostItem;
class QTreeWidgetItem;
class FeedItem;
class GxsChannelPostsWidget : public GxsMessageFramePostWidget, public FeedHolder
{
@ -48,6 +48,7 @@ public:
/* GxsMessageFrameWidget */
virtual QIcon groupIcon();
virtual void setAllMessagesRead(bool read);
/* FeedHolder */
virtual QScrollArea *getScrollArea();
@ -61,14 +62,13 @@ protected:
virtual bool insertGroupData(const uint32_t &token, RsGroupMetaData &metaData);
virtual void insertPosts(const uint32_t &token);
virtual void insertRelatedPosts(const uint32_t &token);
virtual void setMessageRead(GxsFeedItem *item, bool read);
virtual void clearPosts();
private slots:
void createMsg();
void toggleAutoDownload();
void subscribeGroup(bool subscribe);
void filterChanged(int filter);
void filterItems(const QString& text);
//void fillThreadFinished();
//void fillThreadAddMsg(const QString &channelId, const QString &channelMsgId, int current, int count);
@ -77,7 +77,7 @@ private:
void processSettings(bool load);
void setAutoDownload(bool autoDl);
bool filterItem(GxsChannelPostItem *pItem, const QString &text, const int filter);
static bool filterItem(FeedItem *feedItem, const QString &text, int filter);
void insertChannelDetails(const RsGxsChannelGroup &group);
void insertChannelPosts(std::vector<RsGxsChannelPost> &posts, bool related);

View file

@ -14,7 +14,16 @@
<property name="spacing">
<number>4</number>
</property>
<property name="margin">
<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>
@ -26,7 +35,16 @@
<enum>QFrame::Sunken</enum>
</property>
<layout class="QHBoxLayout" name="horizontalLayout_3">
<property name="margin">
<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>
@ -212,40 +230,19 @@
</layout>
</item>
<item>
<widget class="QScrollArea" name="scrollArea">
<property name="widgetResizable">
<bool>true</bool>
<widget class="RSFeedWidget" name="feedWidget" native="true">
<property name="sizePolicy">
<sizepolicy hsizetype="Expanding" vsizetype="Expanding">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<widget class="QWidget" name="scrollAreaWidgetContents">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>679</width>
<height>16</height>
</rect>
</property>
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<layout class="QVBoxLayout" name="verticalLayout">
<property name="spacing">
<number>0</number>
</property>
<property name="margin">
<number>0</number>
</property>
</layout>
</widget>
</widget>
</item>
</layout>
<zorder>toolBarFrame</zorder>
<zorder>scrollArea</zorder>
<zorder>headFrame</zorder>
<zorder>feedWidget</zorder>
</widget>
<customwidgets>
<customwidget>
@ -258,6 +255,12 @@
<extends>QToolButton</extends>
<header>gui/common/SubscribeToolButton.h</header>
</customwidget>
<customwidget>
<class>RSFeedWidget</class>
<extends>QWidget</extends>
<header>gui/common/RSFeedWidget.h</header>
<container>1</container>
</customwidget>
</customwidgets>
<resources>
<include location="../images.qrc"/>