mirror of
https://github.com/RetroShare/RetroShare.git
synced 2024-10-01 02:35:48 -04:00
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:
parent
e588b25b67
commit
d13aa90b2b
@ -32,14 +32,14 @@
|
||||
|
||||
/** Constructor */
|
||||
|
||||
PostedItem::PostedItem(FeedHolder *parent, uint32_t feedId, const RsGxsGroupId &groupId, const RsGxsMessageId &messageId, bool isHome) :
|
||||
GxsFeedItem(parent, feedId, groupId, messageId, isHome, rsPosted, true, false)
|
||||
PostedItem::PostedItem(FeedHolder *feedHolder, uint32_t feedId, const RsGxsGroupId &groupId, const RsGxsMessageId &messageId, bool isHome) :
|
||||
GxsFeedItem(feedHolder, feedId, groupId, messageId, isHome, rsPosted, true, false)
|
||||
{
|
||||
setup();
|
||||
}
|
||||
|
||||
PostedItem::PostedItem(FeedHolder *parent, uint32_t feedId, const RsPostedPost &post, bool isHome) :
|
||||
GxsFeedItem(parent, feedId, post.mMeta.mGroupId, post.mMeta.mMsgId, isHome, rsPosted, false, false),
|
||||
PostedItem::PostedItem(FeedHolder *feedHolder, uint32_t feedId, const RsPostedPost &post, bool isHome) :
|
||||
GxsFeedItem(feedHolder, feedId, post.mMeta.mGroupId, post.mMeta.mMsgId, isHome, rsPosted, false, false),
|
||||
mPost(post)
|
||||
{
|
||||
setup();
|
||||
@ -115,7 +115,7 @@ void PostedItem::setContent(const RsPostedPost &post)
|
||||
// FIX THIS UP LATER.
|
||||
notes->setText(QString::fromUtf8(post.mNotes.c_str()));
|
||||
// differences between Feed or Top of Comment.
|
||||
if (mParent)
|
||||
if (mFeedHolder)
|
||||
{
|
||||
// feed.
|
||||
frame_notes->hide();
|
||||
@ -218,9 +218,10 @@ void PostedItem::loadComments()
|
||||
{
|
||||
std::cerr << "PostedItem::loadComments()";
|
||||
std::cerr << std::endl;
|
||||
if (mParent)
|
||||
|
||||
if (mFeedHolder)
|
||||
{
|
||||
QString title = QString::fromUtf8(mPost.mMeta.mMsgName.c_str());
|
||||
mParent->openComments(0, mPost.mMeta.mGroupId, mPost.mMeta.mMsgId, title);
|
||||
mFeedHolder->openComments(0, mPost.mMeta.mGroupId, mPost.mMeta.mMsgId, title);
|
||||
}
|
||||
}
|
||||
|
@ -46,6 +46,9 @@ public:
|
||||
void setContent(const RsPostedPost& post);
|
||||
virtual void setContent(const QVariant &content);
|
||||
|
||||
/* FeedItem */
|
||||
virtual void expand(bool /*open*/) {}
|
||||
|
||||
private slots:
|
||||
void loadComments();
|
||||
void makeUpVote();
|
||||
|
@ -423,12 +423,8 @@ void PostedListWidget::applyRanking()
|
||||
QLayout *alayout = ui->scrollAreaWidgetContents->layout();
|
||||
int counter = 0;
|
||||
time_t min_ts = 0;
|
||||
foreach (GxsFeedItem *feedItem, mPostItems)
|
||||
foreach (PostedItem *item, mPostItems)
|
||||
{
|
||||
PostedItem *item = dynamic_cast<PostedItem*>(feedItem);
|
||||
if (!item) {
|
||||
continue;
|
||||
}
|
||||
std::cerr << "PostedListWidget::applyRanking() Item: " << item;
|
||||
std::cerr << std::endl;
|
||||
|
||||
@ -472,8 +468,11 @@ void PostedListWidget::applyRanking()
|
||||
|
||||
void PostedListWidget::clearPosts()
|
||||
{
|
||||
GxsMessageFramePostWidget::clearPosts();
|
||||
|
||||
/* clear all messages */
|
||||
foreach (PostedItem *item, mPostItems) {
|
||||
delete(item);
|
||||
}
|
||||
mPostItems.clear();
|
||||
mPosts.clear();
|
||||
}
|
||||
|
||||
@ -585,12 +584,18 @@ void PostedListWidget::insertRelatedPosts(const uint32_t &token)
|
||||
applyRanking();
|
||||
}
|
||||
|
||||
void PostedListWidget::setMessageRead(GxsFeedItem *item, bool read)
|
||||
void PostedListWidget::setAllMessagesRead(bool read)
|
||||
{
|
||||
RsGxsGrpMsgIdPair msgPair = std::make_pair(item->groupId(), item->messageId());
|
||||
if (groupId().isNull() || !IS_GROUP_SUBSCRIBED(subscribeFlags())) {
|
||||
return;
|
||||
}
|
||||
|
||||
uint32_t token;
|
||||
rsPosted->setMessageReadStatus(token, msgPair, read);
|
||||
foreach (PostedItem *item, mPostItems) {
|
||||
RsGxsGrpMsgIdPair msgPair = std::make_pair(item->groupId(), item->messageId());
|
||||
|
||||
uint32_t token;
|
||||
rsPosted->setMessageReadStatus(token, msgPair, read);
|
||||
}
|
||||
}
|
||||
|
||||
/*********************** **** **** **** ***********************/
|
||||
|
@ -47,6 +47,7 @@ public:
|
||||
|
||||
/* GxsMessageFrameWidget */
|
||||
virtual QIcon groupIcon();
|
||||
virtual void setAllMessagesRead(bool read);
|
||||
|
||||
/* FeedHolder */
|
||||
virtual QScrollArea *getScrollArea();
|
||||
@ -62,7 +63,6 @@ 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:
|
||||
@ -112,6 +112,7 @@ private:
|
||||
uint32_t mTokenTypeVote;
|
||||
|
||||
QMap<RsGxsMessageId, PostedItem*> mPosts;
|
||||
QList<PostedItem*> mPostItems;
|
||||
|
||||
/* UI - from Designer */
|
||||
Ui::PostedListWidget *ui;
|
||||
|
@ -182,7 +182,7 @@ void LineEditClear::setCurrentFilter(int id)
|
||||
if (action->data().toInt() == id) {
|
||||
action->setChecked(true);
|
||||
activateAction(action);
|
||||
// emit filterChanged(id);
|
||||
emit filterChanged(id);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
406
retroshare-gui/src/gui/common/RSFeedWidget.cpp
Normal file
406
retroshare-gui/src/gui/common/RSFeedWidget.cpp
Normal file
@ -0,0 +1,406 @@
|
||||
/****************************************************************
|
||||
* This file is distributed under the following license:
|
||||
*
|
||||
* Copyright (c) 2014, RetroShare Team
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor,
|
||||
* Boston, MA 02110-1301, USA.
|
||||
****************************************************************/
|
||||
|
||||
#include <QKeyEvent>
|
||||
|
||||
#include "RSFeedWidget.h"
|
||||
#include "ui_RSFeedWidget.h"
|
||||
#include "RSTreeWidgetItem.h"
|
||||
#include "gui/feeds/FeedItem.h"
|
||||
#include "gui/gxs/GxsFeedItem.h"
|
||||
|
||||
#define COLUMN_FEED 0
|
||||
|
||||
RSFeedWidget::RSFeedWidget(QWidget *parent)
|
||||
: QWidget(parent), ui(new Ui::RSFeedWidget)
|
||||
{
|
||||
/* Invoke the Qt Designer generated object setup routine */
|
||||
ui->setupUi(this);
|
||||
|
||||
/* Sort */
|
||||
mFeedCompareRole = new RSTreeWidgetItemCompareRole;
|
||||
|
||||
/* Filter */
|
||||
mFilterCallback = NULL;
|
||||
mFilterType = 0;
|
||||
|
||||
/* Remove */
|
||||
mEnableRemove = false;
|
||||
|
||||
ui->treeWidget->installEventFilter(this);
|
||||
}
|
||||
|
||||
RSFeedWidget::~RSFeedWidget()
|
||||
{
|
||||
delete(mFeedCompareRole);
|
||||
delete(ui);
|
||||
}
|
||||
|
||||
bool RSFeedWidget::eventFilter(QObject *object, QEvent *event)
|
||||
{
|
||||
if (object == ui->treeWidget) {
|
||||
if (event->type() == QEvent::KeyPress) {
|
||||
QKeyEvent *keyEvent = static_cast<QKeyEvent*>(event);
|
||||
if (keyEvent) {
|
||||
if (keyEvent->key() == Qt::Key_Plus || keyEvent->key() == Qt::Key_Minus) {
|
||||
bool open = (keyEvent->key() == Qt::Key_Plus);
|
||||
|
||||
QList<FeedItem*> feedItems;
|
||||
selectedFeedItems(feedItems);
|
||||
|
||||
foreach (FeedItem *feedItem, feedItems) {
|
||||
feedItem->expand(open);
|
||||
}
|
||||
|
||||
return true; // eat event
|
||||
}
|
||||
|
||||
if (mEnableRemove && keyEvent->key() == Qt::Key_Delete) {
|
||||
QList<QTreeWidgetItem*> selectedItems = ui->treeWidget->selectedItems();
|
||||
|
||||
foreach (QTreeWidgetItem *treeItem, selectedItems) {
|
||||
FeedItem *feedItem = feedItemFromTreeItem(treeItem);
|
||||
if (feedItem) {
|
||||
disconnectSignals(feedItem);
|
||||
delete(feedItem);
|
||||
}
|
||||
delete(treeItem);
|
||||
}
|
||||
|
||||
return true; // eat event
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Pass the event on to the parent class */
|
||||
return QWidget::eventFilter(object, event);
|
||||
}
|
||||
|
||||
void RSFeedWidget::connectSignals(FeedItem *feedItem)
|
||||
{
|
||||
connect(feedItem, SIGNAL(feedItemDestroyed(FeedItem*)), this, SLOT(feedItemDestroyed(FeedItem*)));
|
||||
connect(feedItem, SIGNAL(sizeChanged(FeedItem*)), this, SLOT(feedItemSizeChanged(FeedItem*)));
|
||||
}
|
||||
|
||||
void RSFeedWidget::disconnectSignals(FeedItem *feedItem)
|
||||
{
|
||||
disconnect(feedItem, SIGNAL(feedItemDestroyed(FeedItem*)), this, SLOT(feedItemDestroyed(FeedItem*)));
|
||||
disconnect(feedItem, SIGNAL(sizeChanged(FeedItem*)), this, SLOT(feedItemSizeChanged(FeedItem*)));
|
||||
}
|
||||
|
||||
FeedItem *RSFeedWidget::feedItemFromTreeItem(QTreeWidgetItem *treeItem)
|
||||
{
|
||||
return dynamic_cast<FeedItem*>(ui->treeWidget->itemWidget(treeItem, COLUMN_FEED));
|
||||
}
|
||||
|
||||
void RSFeedWidget::addFeedItem(FeedItem *feedItem, Qt::ItemDataRole sortRole, const QVariant &value)
|
||||
{
|
||||
if (!feedItem) {
|
||||
return;
|
||||
}
|
||||
|
||||
QTreeWidgetItem *treeItem = new RSTreeWidgetItem(mFeedCompareRole);
|
||||
|
||||
treeItem->setData(COLUMN_FEED, sortRole, value);
|
||||
|
||||
ui->treeWidget->addTopLevelItem(treeItem);
|
||||
ui->treeWidget->setItemWidget(treeItem, 0, feedItem);
|
||||
|
||||
connectSignals(feedItem);
|
||||
|
||||
filterItem(treeItem, feedItem);
|
||||
}
|
||||
|
||||
void RSFeedWidget::addFeedItem(FeedItem *feedItem, const QMap<Qt::ItemDataRole, QVariant> &sort)
|
||||
{
|
||||
if (!feedItem) {
|
||||
return;
|
||||
}
|
||||
|
||||
QTreeWidgetItem *treeItem = new RSTreeWidgetItem(mFeedCompareRole);
|
||||
|
||||
QMap<Qt::ItemDataRole, QVariant>::const_iterator it;
|
||||
for (it = sort.begin(); it != sort.end(); ++it) {
|
||||
treeItem->setData(COLUMN_FEED, it.key(), it.value());
|
||||
}
|
||||
|
||||
ui->treeWidget->addTopLevelItem(treeItem);
|
||||
ui->treeWidget->setItemWidget(treeItem, 0, feedItem);
|
||||
|
||||
connectSignals(feedItem);
|
||||
|
||||
filterItem(treeItem, feedItem);
|
||||
}
|
||||
|
||||
void RSFeedWidget::setSort(FeedItem *feedItem, Qt::ItemDataRole sortRole, const QVariant &value)
|
||||
{
|
||||
if (!feedItem) {
|
||||
return;
|
||||
}
|
||||
|
||||
QTreeWidgetItem *treeItem = findTreeWidgetItem(feedItem);
|
||||
if (!treeItem) {
|
||||
return;
|
||||
}
|
||||
|
||||
treeItem->setData(COLUMN_FEED, sortRole, value);
|
||||
}
|
||||
|
||||
void RSFeedWidget::setSort(FeedItem *feedItem, const QMap<Qt::ItemDataRole, QVariant> &sort)
|
||||
{
|
||||
if (!feedItem) {
|
||||
return;
|
||||
}
|
||||
|
||||
QTreeWidgetItem *treeItem = findTreeWidgetItem(feedItem);
|
||||
if (!treeItem) {
|
||||
return;
|
||||
}
|
||||
|
||||
QMap<Qt::ItemDataRole, QVariant>::const_iterator it;
|
||||
for (it = sort.begin(); it != sort.end(); ++it) {
|
||||
treeItem->setData(COLUMN_FEED, it.key(), it.value());
|
||||
}
|
||||
}
|
||||
|
||||
void RSFeedWidget::clear()
|
||||
{
|
||||
ui->treeWidget->clear();
|
||||
}
|
||||
|
||||
void RSFeedWidget::setSortRole(Qt::ItemDataRole role, Qt::SortOrder order)
|
||||
{
|
||||
setSortingEnabled(true);
|
||||
mFeedCompareRole->setRole(COLUMN_FEED, role);
|
||||
ui->treeWidget->sortItems(COLUMN_FEED, order);
|
||||
}
|
||||
|
||||
void RSFeedWidget::setSortingEnabled(bool enable)
|
||||
{
|
||||
ui->treeWidget->setSortingEnabled(enable);
|
||||
}
|
||||
|
||||
void RSFeedWidget::setFilterCallback(RSFeedWidgetFilterCallbackFunction callback)
|
||||
{
|
||||
mFilterCallback = callback;
|
||||
filterItems();
|
||||
}
|
||||
|
||||
void RSFeedWidget::setFilter(const QString &text, int type)
|
||||
{
|
||||
if (mFilterText == text && mFilterType == type) {
|
||||
return;
|
||||
}
|
||||
|
||||
mFilterText = text;
|
||||
mFilterType = type;
|
||||
|
||||
filterItems();
|
||||
}
|
||||
|
||||
void RSFeedWidget::setFilterText(const QString &text)
|
||||
{
|
||||
setFilter(text, mFilterType);
|
||||
}
|
||||
|
||||
void RSFeedWidget::setFilterType(int type)
|
||||
{
|
||||
setFilter(mFilterText, type);
|
||||
}
|
||||
|
||||
void RSFeedWidget::filterItems()
|
||||
{
|
||||
if (!mFilterCallback) {
|
||||
return;
|
||||
}
|
||||
|
||||
QTreeWidgetItemIterator it(ui->treeWidget);
|
||||
QTreeWidgetItem *item;
|
||||
while ((item = *it) != NULL) {
|
||||
++it;
|
||||
FeedItem *feedItem = feedItemFromTreeItem(item);
|
||||
if (!feedItem) {
|
||||
continue;
|
||||
}
|
||||
|
||||
filterItem(item, feedItem);
|
||||
}
|
||||
}
|
||||
|
||||
void RSFeedWidget::filterItem(QTreeWidgetItem *treeItem, FeedItem *feedItem)
|
||||
{
|
||||
if (!mFilterCallback) {
|
||||
return;
|
||||
}
|
||||
|
||||
treeItem->setHidden(!mFilterCallback(feedItem, mFilterText, mFilterType));
|
||||
}
|
||||
|
||||
void RSFeedWidget::enableRemove(bool enable)
|
||||
{
|
||||
mEnableRemove = enable;
|
||||
}
|
||||
|
||||
void RSFeedWidget::setSelectionMode(QAbstractItemView::SelectionMode mode)
|
||||
{
|
||||
ui->treeWidget->setSelectionMode(mode);
|
||||
}
|
||||
|
||||
void RSFeedWidget::removeFeedItem(FeedItem *feedItem)
|
||||
{
|
||||
if (!feedItem) {
|
||||
return;
|
||||
}
|
||||
|
||||
disconnectSignals(feedItem);
|
||||
|
||||
QTreeWidgetItem *treeItem = findTreeWidgetItem(feedItem);
|
||||
if (treeItem) {
|
||||
delete(treeItem);
|
||||
}
|
||||
}
|
||||
|
||||
void RSFeedWidget::feedItemSizeChanged(FeedItem */*feedItem*/)
|
||||
{
|
||||
if (updatesEnabled()) {
|
||||
setUpdatesEnabled(false);
|
||||
QApplication::processEvents();
|
||||
setUpdatesEnabled(true);
|
||||
} else {
|
||||
QApplication::processEvents();
|
||||
}
|
||||
|
||||
ui->treeWidget->doItemsLayout();
|
||||
}
|
||||
|
||||
void RSFeedWidget::feedItemDestroyed(FeedItem *feedItem)
|
||||
{
|
||||
/* No need to disconnect when object will be destroyed */
|
||||
|
||||
QTreeWidgetItem *treeItem = findTreeWidgetItem(feedItem);
|
||||
if (treeItem) {
|
||||
delete(treeItem);
|
||||
}
|
||||
}
|
||||
|
||||
QTreeWidgetItem *RSFeedWidget::findTreeWidgetItem(FeedItem *feedItem)
|
||||
{
|
||||
QTreeWidgetItemIterator it(ui->treeWidget);
|
||||
QTreeWidgetItem *treeItem;
|
||||
while ((treeItem = *it) != NULL) {
|
||||
++it;
|
||||
if (feedItemFromTreeItem(treeItem) == feedItem) {
|
||||
return treeItem;
|
||||
}
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
class RSFeedWidgetCallback
|
||||
{
|
||||
public:
|
||||
RSFeedWidgetCallback() {}
|
||||
|
||||
virtual void callback(FeedItem *feedItem, const QVariant &data) = 0;
|
||||
};
|
||||
|
||||
void RSFeedWidget::withAll(RSFeedWidgetCallbackFunction callback, const QVariant &data)
|
||||
{
|
||||
if (!callback) {
|
||||
return;
|
||||
}
|
||||
|
||||
QTreeWidgetItemIterator it(ui->treeWidget);
|
||||
QTreeWidgetItem *treeItem;
|
||||
while ((treeItem = *it) != NULL) {
|
||||
++it;
|
||||
|
||||
FeedItem *feedItem = feedItemFromTreeItem(treeItem);
|
||||
if (!feedItem) {
|
||||
continue;
|
||||
}
|
||||
|
||||
callback(feedItem, data);
|
||||
}
|
||||
}
|
||||
|
||||
FeedItem *RSFeedWidget::findFeedItem(RSFeedWidgetFindCallbackFunction callback, const QVariant &data1, const QVariant &data2)
|
||||
{
|
||||
if (!callback) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
QTreeWidgetItemIterator it(ui->treeWidget);
|
||||
QTreeWidgetItem *treeItem;
|
||||
while ((treeItem = *it) != NULL) {
|
||||
++it;
|
||||
|
||||
FeedItem *feedItem = feedItemFromTreeItem(treeItem);
|
||||
if (!feedItem) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (callback(feedItem, data1, data2)) {
|
||||
return feedItem;
|
||||
}
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void RSFeedWidget::selectedFeedItems(QList<FeedItem*> &feedItems)
|
||||
{
|
||||
foreach (QTreeWidgetItem *treeItem, ui->treeWidget->selectedItems()) {
|
||||
FeedItem *feedItem = feedItemFromTreeItem(treeItem);
|
||||
if (!feedItem) {
|
||||
continue;
|
||||
}
|
||||
|
||||
feedItems.push_back(feedItem);
|
||||
}
|
||||
}
|
||||
|
||||
static bool findGxsFeedItemCallback(FeedItem *feedItem, const QVariant &data1, const QVariant &data2)
|
||||
{
|
||||
if (!data1.canConvert<RsGxsGroupId>() || !data2.canConvert<RsGxsMessageId>()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
GxsFeedItem *item = dynamic_cast<GxsFeedItem*>(feedItem);
|
||||
if (!item) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (item->groupId() != data1.value<RsGxsGroupId>() ||
|
||||
item->messageId() != data2.value<RsGxsMessageId>()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
GxsFeedItem *RSFeedWidget::findGxsFeedItem(const RsGxsGroupId &groupId, const RsGxsMessageId &messageId)
|
||||
{
|
||||
FeedItem *feedItem = findFeedItem(findGxsFeedItemCallback, qVariantFromValue(groupId), qVariantFromValue(messageId));
|
||||
return dynamic_cast<GxsFeedItem*>(feedItem);
|
||||
}
|
113
retroshare-gui/src/gui/common/RSFeedWidget.h
Normal file
113
retroshare-gui/src/gui/common/RSFeedWidget.h
Normal file
@ -0,0 +1,113 @@
|
||||
/****************************************************************
|
||||
* This file is distributed under the following license:
|
||||
*
|
||||
* Copyright (c) 2014, RetroShare Team
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor,
|
||||
* Boston, MA 02110-1301, USA.
|
||||
****************************************************************/
|
||||
|
||||
#ifndef _RSFEEDTREEWIDGET_H
|
||||
#define _RSFEEDTREEWIDGET_H
|
||||
|
||||
#include <QAbstractItemView>
|
||||
#include <QWidget>
|
||||
#include <QMap>
|
||||
|
||||
#include "retroshare/rsgxsifacetypes.h"
|
||||
|
||||
#define FEED_TREEWIDGET_SORTROLE Qt::UserRole
|
||||
|
||||
class FeedItem;
|
||||
class QTreeWidgetItem;
|
||||
class RSTreeWidgetItemCompareRole;
|
||||
class GxsFeedItem;
|
||||
|
||||
namespace Ui {
|
||||
class RSFeedWidget;
|
||||
}
|
||||
|
||||
typedef void (*RSFeedWidgetCallbackFunction)(FeedItem *feedItem, const QVariant &data);
|
||||
typedef bool (*RSFeedWidgetFindCallbackFunction)(FeedItem *feedItem, const QVariant &data1, const QVariant &data2);
|
||||
typedef bool (*RSFeedWidgetFilterCallbackFunction)(FeedItem *feedItem, const QString &text, int filter);
|
||||
|
||||
class RSFeedWidget : public QWidget
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
RSFeedWidget(QWidget *parent = 0);
|
||||
virtual ~RSFeedWidget();
|
||||
|
||||
void addFeedItem(FeedItem *feedItem, Qt::ItemDataRole sortRole, const QVariant &value);
|
||||
void addFeedItem(FeedItem *feedItem, const QMap<Qt::ItemDataRole, QVariant> &sort);
|
||||
|
||||
void setSort(FeedItem *feedItem, Qt::ItemDataRole sortRole, const QVariant &value);
|
||||
void setSort(FeedItem *feedItem, const QMap<Qt::ItemDataRole, QVariant> &sort);
|
||||
|
||||
void removeFeedItem(FeedItem *feedItem);
|
||||
void clear();
|
||||
|
||||
void setSortRole(Qt::ItemDataRole role, Qt::SortOrder order);
|
||||
void setSortingEnabled(bool enable);
|
||||
void setFilterCallback(RSFeedWidgetFilterCallbackFunction callback);
|
||||
|
||||
void enableRemove(bool enable);
|
||||
void setSelectionMode(QAbstractItemView::SelectionMode mode);
|
||||
|
||||
void withAll(RSFeedWidgetCallbackFunction callback, const QVariant &data);
|
||||
FeedItem *findFeedItem(RSFeedWidgetFindCallbackFunction callback, const QVariant &data1, const QVariant &data2);
|
||||
|
||||
void selectedFeedItems(QList<FeedItem*> &feedItems);
|
||||
|
||||
/* Convenience functions */
|
||||
GxsFeedItem *findGxsFeedItem(const RsGxsGroupId &groupId, const RsGxsMessageId &messageId);
|
||||
|
||||
public slots:
|
||||
void setFilter(const QString &text, int type);
|
||||
void setFilterText(const QString &text);
|
||||
void setFilterType(int type);
|
||||
|
||||
protected:
|
||||
bool eventFilter(QObject *object, QEvent *event);
|
||||
|
||||
private slots:
|
||||
void feedItemDestroyed(FeedItem *feedItem);
|
||||
void feedItemSizeChanged(FeedItem *feedItem);
|
||||
|
||||
private:
|
||||
void connectSignals(FeedItem *feedItem);
|
||||
void disconnectSignals(FeedItem *feedItem);
|
||||
FeedItem *feedItemFromTreeItem(QTreeWidgetItem *treeItem);
|
||||
QTreeWidgetItem *findTreeWidgetItem(FeedItem *feedItem);
|
||||
void filterItems();
|
||||
void filterItem(QTreeWidgetItem *treeItem, FeedItem *feedItem);
|
||||
|
||||
private:
|
||||
/* Sort */
|
||||
RSTreeWidgetItemCompareRole *mFeedCompareRole;
|
||||
|
||||
/* Filter */
|
||||
RSFeedWidgetFilterCallbackFunction mFilterCallback;
|
||||
QString mFilterText;
|
||||
int mFilterType;
|
||||
|
||||
/* Remove */
|
||||
bool mEnableRemove;
|
||||
|
||||
Ui::RSFeedWidget *ui;
|
||||
};
|
||||
|
||||
#endif
|
60
retroshare-gui/src/gui/common/RSFeedWidget.ui
Normal file
60
retroshare-gui/src/gui/common/RSFeedWidget.ui
Normal file
@ -0,0 +1,60 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<ui version="4.0">
|
||||
<class>RSFeedWidget</class>
|
||||
<widget class="QWidget" name="RSFeedWidget">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>337</width>
|
||||
<height>229</height>
|
||||
</rect>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="verticalLayout">
|
||||
<property name="spacing">
|
||||
<number>0</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="QTreeWidget" name="treeWidget">
|
||||
<property name="editTriggers">
|
||||
<set>QAbstractItemView::NoEditTriggers</set>
|
||||
</property>
|
||||
<property name="verticalScrollMode">
|
||||
<enum>QAbstractItemView::ScrollPerPixel</enum>
|
||||
</property>
|
||||
<property name="rootIsDecorated">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
<property name="itemsExpandable">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
<property name="allColumnsShowFocus">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<attribute name="headerVisible">
|
||||
<bool>false</bool>
|
||||
</attribute>
|
||||
<column>
|
||||
<property name="text">
|
||||
<string notr="true">1</string>
|
||||
</property>
|
||||
</column>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<resources/>
|
||||
<connections/>
|
||||
</ui>
|
32
retroshare-gui/src/gui/feeds/FeedItem.cpp
Normal file
32
retroshare-gui/src/gui/feeds/FeedItem.cpp
Normal file
@ -0,0 +1,32 @@
|
||||
/****************************************************************
|
||||
* RetroShare is distributed under the following license:
|
||||
*
|
||||
* Copyright (C) 2014 RetroShare Team
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor,
|
||||
* Boston, MA 02110-1301, USA.
|
||||
****************************************************************/
|
||||
|
||||
#include "FeedItem.h"
|
||||
|
||||
/** Constructor */
|
||||
FeedItem::FeedItem(QWidget *parent) : QWidget(parent)
|
||||
{
|
||||
}
|
||||
|
||||
FeedItem::~FeedItem()
|
||||
{
|
||||
emit feedItemDestroyed(this);
|
||||
}
|
44
retroshare-gui/src/gui/feeds/FeedItem.h
Normal file
44
retroshare-gui/src/gui/feeds/FeedItem.h
Normal file
@ -0,0 +1,44 @@
|
||||
/****************************************************************
|
||||
* RetroShare is distributed under the following license:
|
||||
*
|
||||
* Copyright (C) 2014 RetroShare Team
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor,
|
||||
* Boston, MA 02110-1301, USA.
|
||||
****************************************************************/
|
||||
|
||||
#ifndef _FEED_ITEM_H
|
||||
#define _FEED_ITEM_H
|
||||
|
||||
#include <QWidget>
|
||||
|
||||
class FeedItem : public QWidget
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
/** Default Constructor */
|
||||
FeedItem(QWidget *parent = 0);
|
||||
/** Default Destructor */
|
||||
virtual ~FeedItem();
|
||||
|
||||
virtual void expand(bool open) = 0;
|
||||
|
||||
signals:
|
||||
void sizeChanged(FeedItem *feedItem);
|
||||
void feedItemDestroyed(FeedItem *feedItem);
|
||||
};
|
||||
|
||||
#endif
|
@ -48,8 +48,8 @@
|
||||
#define SELF_LOAD 1
|
||||
#define DATA_PROVIDED 2
|
||||
|
||||
GxsChannelPostItem::GxsChannelPostItem(FeedHolder *parent, uint32_t feedId, const RsGxsGroupId &groupId, const RsGxsMessageId &messageId, bool isHome, bool autoUpdate) :
|
||||
GxsFeedItem(parent, feedId, groupId, messageId, isHome, rsGxsChannels, true, autoUpdate)
|
||||
GxsChannelPostItem::GxsChannelPostItem(FeedHolder *feedHolder, uint32_t feedId, const RsGxsGroupId &groupId, const RsGxsMessageId &messageId, bool isHome, bool autoUpdate) :
|
||||
GxsFeedItem(feedHolder, feedId, groupId, messageId, isHome, rsGxsChannels, true, autoUpdate)
|
||||
{
|
||||
mMode = SELF_LOAD;
|
||||
|
||||
@ -57,8 +57,8 @@ GxsChannelPostItem::GxsChannelPostItem(FeedHolder *parent, uint32_t feedId, cons
|
||||
}
|
||||
|
||||
/** Constructor */
|
||||
GxsChannelPostItem::GxsChannelPostItem(FeedHolder *parent, uint32_t feedId, const RsGxsChannelPost &post, uint32_t subFlags, bool isHome, bool autoUpdate) :
|
||||
GxsFeedItem(parent, feedId, post.mMeta.mGroupId, post.mMeta.mMsgId, isHome, rsGxsChannels, false, autoUpdate)
|
||||
GxsChannelPostItem::GxsChannelPostItem(FeedHolder *feedHolder, uint32_t feedId, const RsGxsChannelPost &post, uint32_t subFlags, bool isHome, bool autoUpdate) :
|
||||
GxsFeedItem(feedHolder, feedId, post.mMeta.mGroupId, post.mMeta.mMsgId, isHome, rsGxsChannels, false, autoUpdate)
|
||||
{
|
||||
std::cerr << "GxsChannelPostItem::GxsChannelPostItem() Direct Load";
|
||||
std::cerr << std::endl;
|
||||
@ -249,7 +249,7 @@ void GxsChannelPostItem::loadPost(const RsGxsChannelPost &post)
|
||||
}
|
||||
|
||||
// differences between Feed or Top of Comment.
|
||||
if (mParent)
|
||||
if (mFeedHolder)
|
||||
{
|
||||
ui->commentButton->show();
|
||||
|
||||
@ -348,7 +348,8 @@ void GxsChannelPostItem::setReadStatus(bool isNew, bool isUnread)
|
||||
ui->frame->style()->unpolish(ui->frame);
|
||||
|
||||
QPalette palette = ui->frame->palette();
|
||||
palette.setColor(ui->frame->backgroundRole(), isNew ? COLOR_NEW : COLOR_NORMAL);
|
||||
palette.setColor(ui->frame->backgroundRole(), isNew ? COLOR_NEW : COLOR_NORMAL); // QScrollArea
|
||||
palette.setColor(QPalette::Base, isNew ? COLOR_NEW : COLOR_NORMAL); // QTreeWidget
|
||||
ui->frame->setPalette(palette);
|
||||
|
||||
ui->frame->setProperty("new", isNew);
|
||||
@ -447,14 +448,14 @@ void GxsChannelPostItem::updateItem()
|
||||
//downloadButton->setEnabled(true);
|
||||
}
|
||||
|
||||
void GxsChannelPostItem::toggle()
|
||||
void GxsChannelPostItem::expand(bool open)
|
||||
{
|
||||
if (mParent)
|
||||
if (mFeedHolder)
|
||||
{
|
||||
mParent->lockLayout(this, true);
|
||||
mFeedHolder->lockLayout(this, true);
|
||||
}
|
||||
|
||||
if (ui->expandFrame->isHidden())
|
||||
if (open)
|
||||
{
|
||||
ui->expandFrame->show();
|
||||
ui->expandButton->setIcon(QIcon(QString(":/images/edit_remove24.png")));
|
||||
@ -469,12 +470,19 @@ void GxsChannelPostItem::toggle()
|
||||
ui->expandButton->setToolTip(tr("Expand"));
|
||||
}
|
||||
|
||||
if (mParent)
|
||||
emit sizeChanged(this);
|
||||
|
||||
if (mFeedHolder)
|
||||
{
|
||||
mParent->lockLayout(this, false);
|
||||
mFeedHolder->lockLayout(this, false);
|
||||
}
|
||||
}
|
||||
|
||||
void GxsChannelPostItem::toggle()
|
||||
{
|
||||
expand(ui->expandFrame->isHidden());
|
||||
}
|
||||
|
||||
/*********** SPECIFIC FUNCTIONS ***********************/
|
||||
|
||||
void GxsChannelPostItem::readAndClearItem()
|
||||
|
@ -44,8 +44,8 @@ class GxsChannelPostItem : public GxsFeedItem
|
||||
|
||||
public:
|
||||
/** Default Constructor */
|
||||
GxsChannelPostItem(FeedHolder *parent, uint32_t feedId, const RsGxsGroupId &groupId, const RsGxsMessageId &messageId, bool isHome, bool autoUpdate);
|
||||
GxsChannelPostItem(FeedHolder *parent, uint32_t feedId, const RsGxsChannelPost &post, uint32_t subscribeFlags, bool isHome, bool autoUpdate);
|
||||
GxsChannelPostItem(FeedHolder *feedHolder, uint32_t feedId, const RsGxsGroupId &groupId, const RsGxsMessageId &messageId, bool isHome, bool autoUpdate);
|
||||
GxsChannelPostItem(FeedHolder *feedHolder, uint32_t feedId, const RsGxsChannelPost &post, uint32_t subscribeFlags, bool isHome, bool autoUpdate);
|
||||
virtual ~GxsChannelPostItem();
|
||||
|
||||
virtual void setContent(const QVariant &content);
|
||||
@ -57,6 +57,9 @@ public:
|
||||
const QString getMsgLabel() {return RsHtml().formatText(NULL, QString::fromUtf8(mPost.mMsg.c_str()), RSHTML_FORMATTEXT_EMBED_SMILEYS | RSHTML_FORMATTEXT_EMBED_LINKS); }
|
||||
const std::list<SubFileItem *> &getFileItems() {return mFileItems; }
|
||||
|
||||
/* FeedItem */
|
||||
virtual void expand(bool open);
|
||||
|
||||
protected:
|
||||
virtual void loadMessage(const uint32_t &token);
|
||||
virtual RetroShareLink::enumType getLinkType() { return RetroShareLink::TYPE_CHANNEL; }
|
||||
|
@ -42,17 +42,17 @@ void GxsFeedItem::removeItem()
|
||||
std::cerr << std::endl;
|
||||
#endif
|
||||
|
||||
if (mParent)
|
||||
if (mFeedHolder)
|
||||
{
|
||||
mParent->lockLayout(this, true);
|
||||
mFeedHolder->lockLayout(this, true);
|
||||
}
|
||||
|
||||
hide();
|
||||
|
||||
if (mParent)
|
||||
if (mFeedHolder)
|
||||
{
|
||||
mParent->lockLayout(this, false);
|
||||
mParent->deleteFeedItem(this, mFeedId);
|
||||
mFeedHolder->lockLayout(this, false);
|
||||
mFeedHolder->deleteFeedItem(this, mFeedId);
|
||||
}
|
||||
}
|
||||
|
||||
@ -63,9 +63,9 @@ void GxsFeedItem::comments(const QString &title)
|
||||
std::cerr << std::endl;
|
||||
#endif
|
||||
|
||||
if (mParent)
|
||||
if (mFeedHolder)
|
||||
{
|
||||
mParent->openComments(mFeedId, mGroupId, mMessageId, title);
|
||||
mFeedHolder->openComments(mFeedId, mGroupId, mMessageId, title);
|
||||
}
|
||||
}
|
||||
|
||||
@ -131,14 +131,14 @@ void GxsFeedItem::updateItem()
|
||||
|
||||
/***********************************************************/
|
||||
|
||||
GxsFeedItem::GxsFeedItem(FeedHolder *parent, uint32_t feedId, const RsGxsGroupId &groupId, const RsGxsMessageId &messageId, bool isHome, RsGxsIfaceHelper *iface, bool loadData, bool autoUpdate) :
|
||||
QWidget(NULL)
|
||||
GxsFeedItem::GxsFeedItem(FeedHolder *feedHolder, uint32_t feedId, const RsGxsGroupId &groupId, const RsGxsMessageId &messageId, bool isHome, RsGxsIfaceHelper *iface, bool loadData, bool autoUpdate) :
|
||||
FeedItem(NULL)
|
||||
{
|
||||
std::cerr << "GxsFeedItem::GxsFeedItem()";
|
||||
std::cerr << std::endl;
|
||||
|
||||
/* this are just generally useful for all children */
|
||||
mParent = parent;
|
||||
mFeedHolder = feedHolder;
|
||||
mFeedId = feedId;
|
||||
mIsHome = isHome;
|
||||
|
||||
|
@ -24,7 +24,10 @@
|
||||
#ifndef _GXS_GENERIC_FEED_ITEM_H
|
||||
#define _GXS_GENERIC_FEED_ITEM_H
|
||||
|
||||
#include <QMetaType>
|
||||
|
||||
#include <retroshare/rsgxsifacehelper.h>
|
||||
#include "gui/feeds/FeedItem.h"
|
||||
#include "util/TokenQueue.h"
|
||||
#include "gui/RetroShareLink.h"
|
||||
|
||||
@ -33,13 +36,13 @@
|
||||
class FeedHolder;
|
||||
class RsGxsUpdateBroadcastBase;
|
||||
|
||||
class GxsFeedItem : public QWidget, public TokenResponse
|
||||
class GxsFeedItem : public FeedItem, public TokenResponse
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
/** Note parent can = NULL */
|
||||
GxsFeedItem(FeedHolder *parent, uint32_t feedId, const RsGxsGroupId &groupId, const RsGxsMessageId &messageId, bool isHome, RsGxsIfaceHelper *iface, bool loadData, bool autoUpdate);
|
||||
GxsFeedItem(FeedHolder *feedHolder, uint32_t feedId, const RsGxsGroupId &groupId, const RsGxsMessageId &messageId, bool isHome, RsGxsIfaceHelper *iface, bool loadData, bool autoUpdate);
|
||||
virtual ~GxsFeedItem();
|
||||
|
||||
RsGxsGroupId groupId() { return mGroupId; }
|
||||
@ -75,7 +78,7 @@ private slots:
|
||||
void fillDisplay(bool complete);
|
||||
|
||||
protected:
|
||||
FeedHolder *mParent;
|
||||
FeedHolder *mFeedHolder;
|
||||
uint32_t mFeedId;
|
||||
bool mIsHome;
|
||||
|
||||
@ -92,4 +95,7 @@ private:
|
||||
RsGxsUpdateBroadcastBase *mUpdateBroadcastBase;
|
||||
};
|
||||
|
||||
Q_DECLARE_METATYPE(RsGxsGroupId)
|
||||
Q_DECLARE_METATYPE(RsGxsMessageId)
|
||||
|
||||
#endif
|
||||
|
@ -116,26 +116,6 @@ void GxsMessageFramePostWidget::updateDisplay(bool complete)
|
||||
}
|
||||
}
|
||||
|
||||
void GxsMessageFramePostWidget::setAllMessagesRead(bool read)
|
||||
{
|
||||
if (mGroupId.isNull() || !IS_GROUP_SUBSCRIBED(mSubscribeFlags)) {
|
||||
return;
|
||||
}
|
||||
|
||||
foreach (GxsFeedItem *item, mPostItems) {
|
||||
setMessageRead(item, read);
|
||||
}
|
||||
}
|
||||
|
||||
void GxsMessageFramePostWidget::clearPosts()
|
||||
{
|
||||
/* clear all messages */
|
||||
foreach (GxsFeedItem *item, mPostItems) {
|
||||
delete(item);
|
||||
}
|
||||
mPostItems.clear();
|
||||
}
|
||||
|
||||
/**************************************************************/
|
||||
/** Request / Response of Data ********************************/
|
||||
/**************************************************************/
|
||||
|
@ -40,7 +40,6 @@ public:
|
||||
virtual void setGroupId(const RsGxsGroupId &groupId);
|
||||
virtual QString groupName(bool withUnreadCount);
|
||||
// virtual QIcon groupIcon() = 0;
|
||||
virtual void setAllMessagesRead(bool read);
|
||||
|
||||
/* GXS functions */
|
||||
uint32_t nextTokenType() { return ++mNextTokenType; }
|
||||
@ -52,8 +51,7 @@ protected:
|
||||
virtual void updateDisplay(bool complete);
|
||||
virtual void groupNameChanged(const QString &/*name*/) {}
|
||||
|
||||
virtual void setMessageRead(GxsFeedItem *item, bool read) = 0;
|
||||
virtual void clearPosts();
|
||||
virtual void clearPosts() = 0;
|
||||
|
||||
/* GXS functions */
|
||||
void requestGroupData();
|
||||
@ -74,7 +72,6 @@ protected:
|
||||
uint32_t mTokenTypePosts;
|
||||
uint32_t mTokenTypeRelatedPosts;
|
||||
UIStateHelper *mStateHelper;
|
||||
QList<GxsFeedItem*> mPostItems;
|
||||
|
||||
private:
|
||||
RsGxsGroupId mGroupId; /* current group */
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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);
|
||||
|
@ -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"/>
|
||||
|
@ -450,6 +450,7 @@ HEADERS += rshare.h \
|
||||
gui/common/RSPlainTextEdit.h \
|
||||
gui/common/RSTreeWidget.h \
|
||||
gui/common/RSTreeWidgetItem.h \
|
||||
gui/common/RSFeedWidget.h \
|
||||
gui/common/RSTabWidget.h \
|
||||
gui/common/RSItemDelegate.h \
|
||||
gui/common/PeerDefs.h \
|
||||
@ -495,6 +496,7 @@ HEADERS += rshare.h \
|
||||
gui/elastic/arrow.h \
|
||||
gui/elastic/node.h \
|
||||
gui/NewsFeed.h \
|
||||
gui/feeds/FeedItem.h \
|
||||
gui/feeds/FeedHolder.h \
|
||||
gui/feeds/PeerItem.h \
|
||||
gui/feeds/MsgItem.h \
|
||||
@ -615,6 +617,7 @@ FORMS += gui/StartDialog.ui \
|
||||
gui/common/RSImageBlockWidget.ui \
|
||||
gui/common/RsCollectionDialog.ui \
|
||||
gui/common/HeaderFrame.ui \
|
||||
gui/common/RSFeedWidget.ui \
|
||||
gui/style/StyleDialog.ui \
|
||||
gui/dht/DhtWindow.ui \
|
||||
gui/bwctrl/BwCtrlWindow.ui \
|
||||
@ -740,6 +743,7 @@ SOURCES += main.cpp \
|
||||
gui/common/RSPlainTextEdit.cpp \
|
||||
gui/common/RSTreeWidget.cpp \
|
||||
gui/common/RSTreeWidgetItem.cpp \
|
||||
gui/common/RSFeedWidget.cpp \
|
||||
gui/common/RSTabWidget.cpp \
|
||||
gui/common/RSItemDelegate.cpp \
|
||||
gui/common/PeerDefs.cpp \
|
||||
@ -816,6 +820,7 @@ SOURCES += main.cpp \
|
||||
gui/elastic/arrow.cpp \
|
||||
gui/elastic/node.cpp \
|
||||
gui/NewsFeed.cpp \
|
||||
gui/feeds/FeedItem.cpp \
|
||||
gui/feeds/FeedHolder.cpp \
|
||||
gui/feeds/PeerItem.cpp \
|
||||
gui/feeds/MsgItem.cpp \
|
||||
|
Loading…
Reference in New Issue
Block a user