mirror of
https://github.com/RetroShare/RetroShare.git
synced 2025-01-11 23:49:38 -05:00
Added waiting indicator to group tree for channels/posted when using "Mark all as read/unread".
git-svn-id: http://svn.code.sf.net/p/retroshare/code/trunk@8020 b45a01b8-16f6-495d-af2f-9b41ad6348cc
This commit is contained in:
parent
c811d71738
commit
d6ca3ffc27
3
TODO.txt
3
TODO.txt
@ -83,6 +83,9 @@ H [ ] valgrind pass for memory leaks
|
||||
H [ ] valgrind pass for memory errors
|
||||
H [ ] valgrind pass for performance
|
||||
E [ ] remove mktemp => use mkstemp
|
||||
H [ ] RsGxsDataAccess::processRequests locks mDataMutex until all requests are processed.
|
||||
Adding a new request or poll for the request status are freezing until the mutex is available.
|
||||
|
||||
|
||||
Packaging
|
||||
[X] check compilation on debian
|
||||
|
@ -578,7 +578,7 @@ void PostedListWidget::insertRelatedPosts(const uint32_t &token)
|
||||
applyRanking();
|
||||
}
|
||||
|
||||
void PostedListWidget::setAllMessagesRead(bool read)
|
||||
void PostedListWidget::setAllMessagesReadDo(bool read, uint32_t &token)
|
||||
{
|
||||
if (groupId().isNull() || !IS_GROUP_SUBSCRIBED(subscribeFlags())) {
|
||||
return;
|
||||
@ -587,7 +587,6 @@ void PostedListWidget::setAllMessagesRead(bool read)
|
||||
foreach (PostedItem *item, mPostItems) {
|
||||
RsGxsGrpMsgIdPair msgPair = std::make_pair(item->groupId(), item->messageId());
|
||||
|
||||
uint32_t token;
|
||||
rsPosted->setMessageReadStatus(token, msgPair, read);
|
||||
}
|
||||
}
|
||||
|
@ -47,7 +47,6 @@ public:
|
||||
|
||||
/* GxsMessageFrameWidget */
|
||||
virtual QIcon groupIcon();
|
||||
virtual void setAllMessagesRead(bool read);
|
||||
|
||||
/* FeedHolder */
|
||||
virtual QScrollArea *getScrollArea();
|
||||
@ -66,6 +65,9 @@ protected:
|
||||
virtual void clearPosts();
|
||||
virtual bool navigatePostItem(const RsGxsMessageId& msgId);
|
||||
|
||||
/* GxsMessageFrameWidget */
|
||||
virtual void setAllMessagesReadDo(bool read, uint32_t &token);
|
||||
|
||||
private slots:
|
||||
void newPost();
|
||||
|
||||
|
@ -21,6 +21,8 @@
|
||||
|
||||
#include <QMenu>
|
||||
#include <QToolButton>
|
||||
#include <QLabel>
|
||||
#include <QMovie>
|
||||
|
||||
#include "retroshare/rsgxsflags.h"
|
||||
#include "GroupTreeWidget.h"
|
||||
@ -47,6 +49,7 @@
|
||||
#define ROLE_SEARCH_SCORE Qt::UserRole + 5
|
||||
#define ROLE_SUBSCRIBE_FLAGS Qt::UserRole + 6
|
||||
#define ROLE_COLOR Qt::UserRole + 7
|
||||
#define ROLE_SAVED_ICON Qt::UserRole + 8
|
||||
|
||||
#define FILTER_NAME_INDEX 0
|
||||
#define FILTER_DESC_INDEX 1
|
||||
@ -351,7 +354,12 @@ void GroupTreeWidget::fillGroupItems(QTreeWidgetItem *categoryItem, const QList<
|
||||
item->setData(COLUMN_DATA, ROLE_LASTPOST, -lastPost); // negative for correct sorting
|
||||
|
||||
/* Set icon */
|
||||
item->setIcon(COLUMN_NAME, itemInfo.icon);
|
||||
if (ui->treeWidget->itemWidget(item, COLUMN_NAME)) {
|
||||
/* Item is waiting, save icon in role */
|
||||
item->setData(COLUMN_DATA, ROLE_SAVED_ICON, itemInfo.icon);
|
||||
} else {
|
||||
item->setIcon(COLUMN_NAME, itemInfo.icon);
|
||||
}
|
||||
|
||||
/* Set popularity */
|
||||
QString tooltip = PopularityDefs::tooltip(itemInfo.popularity);
|
||||
@ -465,6 +473,50 @@ QTreeWidgetItem *GroupTreeWidget::activateId(const QString &id, bool focus)
|
||||
return item;
|
||||
}
|
||||
|
||||
bool GroupTreeWidget::setWaiting(const QString &id, bool wait)
|
||||
{
|
||||
QTreeWidgetItem *item = getItemFromId(id);
|
||||
if (!item) {
|
||||
return false;
|
||||
}
|
||||
|
||||
QWidget *w = ui->treeWidget->itemWidget(item, COLUMN_NAME);
|
||||
if (wait) {
|
||||
if (w) {
|
||||
/* Allready waiting */
|
||||
} else {
|
||||
/* Save icon in role */
|
||||
QIcon icon = item->icon(COLUMN_NAME);
|
||||
item->setData(COLUMN_DATA, ROLE_SAVED_ICON, icon);
|
||||
|
||||
/* Create empty icon of the same size */
|
||||
QPixmap pixmap(ui->treeWidget->iconSize());
|
||||
pixmap.fill(Qt::transparent);
|
||||
|
||||
item->setIcon(COLUMN_NAME, QIcon(pixmap));
|
||||
|
||||
QLabel *label = new QLabel(this);
|
||||
QMovie *movie = new QMovie(":/images/loader/circleball-16.gif");
|
||||
label->setMovie(movie);
|
||||
|
||||
ui->treeWidget->setItemWidget(item, COLUMN_NAME, label);
|
||||
|
||||
movie->start();
|
||||
}
|
||||
} else {
|
||||
if (w) {
|
||||
ui->treeWidget->setItemWidget(item, COLUMN_NAME, NULL);
|
||||
delete(w);
|
||||
|
||||
/* Set icon saved in role */
|
||||
item->setIcon(COLUMN_NAME, item->data(COLUMN_DATA, ROLE_SAVED_ICON).value<QIcon>());
|
||||
item->setData(COLUMN_DATA, ROLE_SAVED_ICON, QIcon());
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
RSTreeWidget *GroupTreeWidget::treeWidget()
|
||||
{
|
||||
return ui->treeWidget;
|
||||
|
@ -94,6 +94,8 @@ public:
|
||||
QTreeWidgetItem *getItemFromId(const QString &id);
|
||||
QTreeWidgetItem *activateId(const QString &id, bool focus);
|
||||
|
||||
bool setWaiting(const QString &id, bool wait);
|
||||
|
||||
RSTreeWidget *treeWidget();
|
||||
|
||||
QColor textColorCategory() const { return mTextColor[GROUPTREEWIDGET_COLOR_CATEGORY]; }
|
||||
|
@ -534,6 +534,7 @@ GxsMessageFrameWidget *GxsGroupFrameDialog::createMessageWidget(const RsGxsGroup
|
||||
ui->messageTabWidget->setTabIcon(index, msgWidget->groupIcon());
|
||||
|
||||
connect(msgWidget, SIGNAL(groupChanged(QWidget*)), this, SLOT(messageTabInfoChanged(QWidget*)));
|
||||
connect(msgWidget, SIGNAL(waitingChanged(QWidget*)), this, SLOT(messageTabWaitingChanged(QWidget*)));
|
||||
connect(msgWidget, SIGNAL(loadComment(RsGxsGroupId,RsGxsMessageId,QString)), this, SLOT(loadComment(RsGxsGroupId,RsGxsMessageId,QString)));
|
||||
|
||||
return msgWidget;
|
||||
@ -644,6 +645,21 @@ void GxsGroupFrameDialog::messageTabInfoChanged(QWidget *widget)
|
||||
ui->messageTabWidget->setTabIcon(index, msgWidget->groupIcon());
|
||||
}
|
||||
|
||||
void GxsGroupFrameDialog::messageTabWaitingChanged(QWidget *widget)
|
||||
{
|
||||
int index = ui->messageTabWidget->indexOf(widget);
|
||||
if (index < 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
GxsMessageFrameWidget *msgWidget = dynamic_cast<GxsMessageFrameWidget*>(ui->messageTabWidget->widget(index));
|
||||
if (!msgWidget) {
|
||||
return;
|
||||
}
|
||||
|
||||
ui->groupTreeWidget->setWaiting(QString::fromStdString(msgWidget->groupId().toStdString()), msgWidget->isWaiting());
|
||||
}
|
||||
|
||||
///***** INSERT GROUP LISTS *****/
|
||||
void GxsGroupFrameDialog::groupInfoToGroupItemInfo(const RsGroupMetaData &groupInfo, GroupItemInfo &groupItemInfo, const RsUserdata */*userdata*/)
|
||||
{
|
||||
|
@ -109,6 +109,7 @@ private slots:
|
||||
void messageTabCloseRequested(int index);
|
||||
void messageTabChanged(int index);
|
||||
void messageTabInfoChanged(QWidget *widget);
|
||||
void messageTabWaitingChanged(QWidget *widget);
|
||||
|
||||
void copyGroupLink();
|
||||
|
||||
|
@ -86,6 +86,15 @@ bool GxsMessageFramePostWidget::navigate(const RsGxsMessageId &msgId)
|
||||
return navigatePostItem(msgId);
|
||||
}
|
||||
|
||||
bool GxsMessageFramePostWidget::isLoading()
|
||||
{
|
||||
if (mStateHelper->isLoading(mTokenTypePosts) || mStateHelper->isLoading(mTokenTypeRelatedPosts)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return GxsMessageFrameWidget::isLoading();
|
||||
}
|
||||
|
||||
void GxsMessageFramePostWidget::updateDisplay(bool complete)
|
||||
{
|
||||
if (complete) {
|
||||
|
@ -43,6 +43,7 @@ public:
|
||||
virtual QString groupName(bool withUnreadCount);
|
||||
// virtual QIcon groupIcon() = 0;
|
||||
virtual bool navigate(const RsGxsMessageId& msgId);
|
||||
virtual bool isLoading();
|
||||
|
||||
/* GXS functions */
|
||||
virtual void loadRequest(const TokenQueue *queue, const TokenRequest &req);
|
||||
@ -50,7 +51,9 @@ public:
|
||||
int subscribeFlags() { return mSubscribeFlags; }
|
||||
|
||||
protected:
|
||||
/* RsGxsUpdateBroadcastWidget */
|
||||
virtual void updateDisplay(bool complete);
|
||||
|
||||
virtual void groupNameChanged(const QString &/*name*/) {}
|
||||
|
||||
virtual void clearPosts() = 0;
|
||||
|
@ -31,10 +31,23 @@ GxsMessageFrameWidget::GxsMessageFrameWidget(RsGxsIfaceHelper *ifaceImpl, QWidge
|
||||
|
||||
mTokenQueue = new TokenQueue(ifaceImpl->getTokenService(), this);
|
||||
mStateHelper = new UIStateHelper(this);
|
||||
|
||||
/* Set read status */
|
||||
mTokenTypeAcknowledgeReadStatus = nextTokenType();
|
||||
mAcknowledgeReadStatusToken = 0;
|
||||
|
||||
/* Add dummy entry to store waiting status */
|
||||
mStateHelper->addWidget(mTokenTypeAcknowledgeReadStatus, NULL, 0);
|
||||
}
|
||||
|
||||
GxsMessageFrameWidget::~GxsMessageFrameWidget()
|
||||
{
|
||||
if (mStateHelper->isLoading(mTokenTypeAcknowledgeReadStatus)) {
|
||||
mStateHelper->setLoading(mTokenTypeAcknowledgeReadStatus, false);
|
||||
|
||||
emit waitingChanged(this);
|
||||
}
|
||||
|
||||
delete(mTokenQueue);
|
||||
}
|
||||
|
||||
@ -43,6 +56,20 @@ const RsGxsGroupId &GxsMessageFrameWidget::groupId()
|
||||
return mGroupId;
|
||||
}
|
||||
|
||||
bool GxsMessageFrameWidget::isLoading()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
bool GxsMessageFrameWidget::isWaiting()
|
||||
{
|
||||
if (mStateHelper->isLoading(mTokenTypeAcknowledgeReadStatus)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
void GxsMessageFrameWidget::setGroupId(const RsGxsGroupId &groupId)
|
||||
{
|
||||
if (mGroupId == groupId) {
|
||||
@ -51,13 +78,47 @@ void GxsMessageFrameWidget::setGroupId(const RsGxsGroupId &groupId)
|
||||
}
|
||||
}
|
||||
|
||||
mGroupId = groupId;
|
||||
mAcknowledgeReadStatusToken = 0;
|
||||
if (mStateHelper->isLoading(mTokenTypeAcknowledgeReadStatus)) {
|
||||
mStateHelper->setLoading(mTokenTypeAcknowledgeReadStatus, false);
|
||||
|
||||
emit waitingChanged(this);
|
||||
}
|
||||
|
||||
mGroupId = groupId;
|
||||
groupIdChanged();
|
||||
}
|
||||
|
||||
void GxsMessageFrameWidget::loadRequest(const TokenQueue */*queue*/, const TokenRequest &/*req*/)
|
||||
void GxsMessageFrameWidget::setAllMessagesRead(bool read)
|
||||
{
|
||||
uint32_t token = 0;
|
||||
setAllMessagesReadDo(read, token);
|
||||
|
||||
if (token) {
|
||||
/* Wait for acknowlegde of the token */
|
||||
mAcknowledgeReadStatusToken = token;
|
||||
mTokenQueue->queueRequest(mAcknowledgeReadStatusToken, 0, 0, mTokenTypeAcknowledgeReadStatus);
|
||||
mStateHelper->setLoading(mTokenTypeAcknowledgeReadStatus, true);
|
||||
|
||||
emit waitingChanged(this);
|
||||
}
|
||||
}
|
||||
|
||||
void GxsMessageFrameWidget::loadRequest(const TokenQueue *queue, const TokenRequest &req)
|
||||
{
|
||||
if (queue == mTokenQueue)
|
||||
{
|
||||
if (req.mUserType == mTokenTypeAcknowledgeReadStatus) {
|
||||
if (mAcknowledgeReadStatusToken == req.mToken) {
|
||||
/* Set read status is finished */
|
||||
mStateHelper->setLoading(mTokenTypeAcknowledgeReadStatus, false);
|
||||
|
||||
emit waitingChanged(this);
|
||||
}
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
std::cerr << "GxsMessageFrameWidget::loadRequest() ERROR: INVALID TYPE";
|
||||
std::cerr << std::endl;
|
||||
}
|
||||
|
@ -38,12 +38,14 @@ public:
|
||||
|
||||
const RsGxsGroupId &groupId();
|
||||
void setGroupId(const RsGxsGroupId &groupId);
|
||||
void setAllMessagesRead(bool read);
|
||||
|
||||
virtual void groupIdChanged() = 0;
|
||||
virtual QString groupName(bool withUnreadCount) = 0;
|
||||
virtual QIcon groupIcon() = 0;
|
||||
virtual void setAllMessagesRead(bool read) = 0;
|
||||
virtual bool navigate(const RsGxsMessageId& msgId) = 0;
|
||||
virtual bool isLoading();
|
||||
virtual bool isWaiting();
|
||||
|
||||
/* GXS functions */
|
||||
uint32_t nextTokenType() { return ++mNextTokenType; }
|
||||
@ -51,12 +53,20 @@ public:
|
||||
|
||||
signals:
|
||||
void groupChanged(QWidget *widget);
|
||||
void waitingChanged(QWidget *widget);
|
||||
void loadComment(const RsGxsGroupId &groupId, const RsGxsMessageId &msgId, const QString &title);
|
||||
|
||||
protected:
|
||||
virtual void setAllMessagesReadDo(bool read, uint32_t &token) = 0;
|
||||
|
||||
protected:
|
||||
TokenQueue *mTokenQueue;
|
||||
UIStateHelper *mStateHelper;
|
||||
|
||||
/* Set read status */
|
||||
uint32_t mTokenTypeAcknowledgeReadStatus;
|
||||
uint32_t mAcknowledgeReadStatusToken;
|
||||
|
||||
private:
|
||||
RsGxsGroupId mGroupId; /* current group */
|
||||
uint32_t mNextTokenType;
|
||||
|
@ -503,29 +503,45 @@ void GxsChannelPostsWidget::insertRelatedPosts(const uint32_t &token)
|
||||
insertChannelPosts(posts, 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;
|
||||
}
|
||||
GxsChannelPostItem *channelPostItem = dynamic_cast<GxsChannelPostItem*>(feedItem);
|
||||
if (!channelPostItem) {
|
||||
return;
|
||||
}
|
||||
|
||||
bool is_not_new = !channelPostItem->isUnread() ;
|
||||
GxsChannelPostsReadData *readData = (GxsChannelPostsReadData*) data;
|
||||
bool is_not_new = !channelPostItem->isUnread() ;
|
||||
|
||||
if(is_not_new == *(bool*)data)
|
||||
return ;
|
||||
if(is_not_new == readData->mRead)
|
||||
return ;
|
||||
|
||||
RsGxsGrpMsgIdPair msgPair = std::make_pair(channelPostItem->groupId(), channelPostItem->messageId());
|
||||
|
||||
uint32_t token;
|
||||
rsGxsChannels->setMessageReadStatus(token, msgPair, *((bool*) data));
|
||||
RsGxsGrpMsgIdPair msgPair = std::make_pair(channelPostItem->groupId(), channelPostItem->messageId());
|
||||
rsGxsChannels->setMessageReadStatus(readData->mLastToken, msgPair, readData->mRead);
|
||||
}
|
||||
|
||||
void GxsChannelPostsWidget::setAllMessagesRead(bool read)
|
||||
void GxsChannelPostsWidget::setAllMessagesReadDo(bool read, uint32_t &token)
|
||||
{
|
||||
if (groupId().isNull() || !IS_GROUP_SUBSCRIBED(subscribeFlags())) {
|
||||
return;
|
||||
}
|
||||
|
||||
ui->feedWidget->withAll(setAllMessagesReadCallback, &read);
|
||||
GxsChannelPostsReadData data(read);
|
||||
ui->feedWidget->withAll(setAllMessagesReadCallback, &data);
|
||||
|
||||
token = data.mLastToken;
|
||||
}
|
||||
|
@ -56,7 +56,6 @@ public:
|
||||
|
||||
/* GxsMessageFrameWidget */
|
||||
virtual QIcon groupIcon();
|
||||
virtual void setAllMessagesRead(bool read);
|
||||
|
||||
/* FeedHolder */
|
||||
virtual QScrollArea *getScrollArea();
|
||||
@ -75,6 +74,9 @@ protected:
|
||||
virtual void fillThreadCreatePost(const QVariant &post, bool related, int current, int count);
|
||||
virtual bool navigatePostItem(const RsGxsMessageId& msgId);
|
||||
|
||||
/* GxsMessageFrameWidget */
|
||||
virtual void setAllMessagesReadDo(bool read, uint32_t &token);
|
||||
|
||||
private slots:
|
||||
void createMsg();
|
||||
void toggleAutoDownload();
|
||||
|
@ -1511,7 +1511,7 @@ void GxsForumThreadWidget::markMsgAsUnreadChildren()
|
||||
markMsgAsReadUnread(false, true, false);
|
||||
}
|
||||
|
||||
void GxsForumThreadWidget::setAllMessagesRead(bool read)
|
||||
void GxsForumThreadWidget::setAllMessagesReadDo(bool read, uint32_t &/*token*/)
|
||||
{
|
||||
markMsgAsReadUnread(read, true, true);
|
||||
}
|
||||
@ -1543,6 +1543,15 @@ bool GxsForumThreadWidget::navigate(const RsGxsMessageId &msgId)
|
||||
return false;
|
||||
}
|
||||
|
||||
bool GxsForumThreadWidget::isLoading()
|
||||
{
|
||||
if (mStateHelper->isLoading(mTokenTypeGroupData) || mFillThread) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return GxsMessageFrameWidget::isLoading();
|
||||
}
|
||||
|
||||
void GxsForumThreadWidget::copyMessageLink()
|
||||
{
|
||||
if (groupId().isNull() || mThreadId.isNull()) {
|
||||
|
@ -43,8 +43,8 @@ public:
|
||||
virtual void groupIdChanged();
|
||||
virtual QString groupName(bool withUnreadCount);
|
||||
virtual QIcon groupIcon();
|
||||
virtual void setAllMessagesRead(bool read);
|
||||
virtual bool navigate(const RsGxsMessageId& msgId);
|
||||
virtual bool isLoading();
|
||||
|
||||
unsigned int newCount() { return mNewCount; }
|
||||
unsigned int unreadCount() { return mUnreadCount; }
|
||||
@ -58,8 +58,13 @@ public:
|
||||
protected:
|
||||
bool eventFilter(QObject *obj, QEvent *ev);
|
||||
void changeEvent(QEvent *e);
|
||||
|
||||
/* RsGxsUpdateBroadcastWidget */
|
||||
virtual void updateDisplay(bool complete);
|
||||
|
||||
/* GxsMessageFrameWidget */
|
||||
virtual void setAllMessagesReadDo(bool read, uint32_t &token);
|
||||
|
||||
private slots:
|
||||
/** Create the context popup menu and it's submenus */
|
||||
void threadListCustomPopupMenu(QPoint point);
|
||||
|
@ -462,8 +462,9 @@
|
||||
<file>images/trustsettings.png</file>
|
||||
<file>images/uploads.png</file>
|
||||
<file>images/headerFrame.png</file>
|
||||
<file>images/loader/16-loader.gif</file>
|
||||
<file>images/loader/32-loader.gif</file>
|
||||
<file>images/loader/indicator-16.gif</file>
|
||||
<file>images/loader/indicator-32.gif</file>
|
||||
<file>images/loader/circleball-16.gif</file>
|
||||
<file>images/loader/progress.gif</file>
|
||||
<file>images/mimetypes/pdf.png</file>
|
||||
<file>images/mimetypes/rscollection-16.png</file>
|
||||
|
BIN
retroshare-gui/src/gui/images/loader/circleball-16.gif
Normal file
BIN
retroshare-gui/src/gui/images/loader/circleball-16.gif
Normal file
Binary file not shown.
After Width: | Height: | Size: 673 B |
Before Width: | Height: | Size: 1.8 KiB After Width: | Height: | Size: 1.8 KiB |
Before Width: | Height: | Size: 3.1 KiB After Width: | Height: | Size: 3.1 KiB |
2
retroshare-gui/src/gui/images/loader/readme.txt
Normal file
2
retroshare-gui/src/gui/images/loader/readme.txt
Normal file
@ -0,0 +1,2 @@
|
||||
More at
|
||||
http://ajaxload.info/
|
@ -34,7 +34,7 @@ HashingStatus::HashingStatus(QWidget *parent)
|
||||
hbox->setMargin(0);
|
||||
hbox->setSpacing(6);
|
||||
|
||||
movie = new QMovie(":/images/loader/16-loader.gif");
|
||||
movie = new QMovie(":/images/loader/indicator-16.gif");
|
||||
movie->setSpeed(80); // 2x speed
|
||||
hashloader = new QLabel(this);
|
||||
hashloader->setMovie(movie);
|
||||
|
Loading…
Reference in New Issue
Block a user