Added read/unread state to channel service (copied from forum service).

Added new and missing tests of the RsItems.
Added new notifier on channel changes.
Reworked fill of channels in ChannelFeed. Now the channel tree is updated and not refilled.
Show unread message count in channels tree.
Fixed memory leak in context menu.
Show a new tray icon and action icon in MainWindow, when new channel messages are available.

Recompile of the GUI needed.

git-svn-id: http://svn.code.sf.net/p/retroshare/code/trunk@3626 b45a01b8-16f6-495d-af2f-9b41ad6348cc
This commit is contained in:
thunder2 2010-10-07 00:17:42 +00:00
parent df20d69b29
commit fc0ff38206
22 changed files with 1181 additions and 653 deletions

File diff suppressed because it is too large Load diff

View file

@ -22,6 +22,8 @@
#ifndef _CHANNEL_FEED_DIALOG_H
#define _CHANNEL_FEED_DIALOG_H
#include <retroshare/rschannels.h>
#include "mainpage.h"
#include "RsAutoUpdatePage.h"
@ -36,15 +38,16 @@
class ChanMsgItem;
class QStandardItemModel;
class QStandardItem;
class ChannelFeed : public RsAutoUpdatePage, public FeedHolder, private Ui::ChannelFeed
{
Q_OBJECT
Q_OBJECT
public:
/** Default Constructor */
ChannelFeed(QWidget *parent = 0);
/** Default Destructor */
/** Default Constructor */
ChannelFeed(QWidget *parent = 0);
/** Default Destructor */
virtual void deleteFeedItem(QWidget *item, uint32_t type);
@ -54,59 +57,46 @@ public:
virtual void updateDisplay();
public slots:
void selectChannel( std::string );
void selectChannel(const QModelIndex &);
void toggleSelection(const QModelIndex &);
void selectChannel(QModelIndex index);
private slots:
void channelListCustomPopupMenu( QPoint point );
void createChannel();
void createChannel();
void channelSelection();
void channelSelection();
void subscribeChannel();
void unsubscribeChannel();
void createMsg();
void subscribeChannel();
void unsubscribeChannel();
void setAllAsReadClicked();
void createMsg();
void showChannelDetails();
void restoreChannelKeys();
void editChannelDetail();
void shareKey();
void channelMsgReadSatusChanged(const QString& channelId, const QString& msgId, int status);
private:
void updateChannelList();
void fillChannelList(int channelItem, std::list<ChannelInfo> &channelInfos);
void updateChannelList();
void updateChannelListOwn(std::list<std::string> &ids);
void updateChannelListSub(std::list<std::string> &ids);
void updateChannelListPop(std::list<std::string> &ids);
void updateChannelListOther(std::list<std::string> &ids);
void updateChannelMsgs();
void updateMessageSummaryList(const std::string &channelId);
void updateChannelMsgs();
QStandardItemModel *model;
QStandardItemModel *model;
std::string mChannelId; /* current Channel */
std::string mChannelId; /* current Channel */
/* Layout Pointers */
QBoxLayout *mMsgLayout;
/* Layout Pointers */
QBoxLayout *mMsgLayout;
std::list<ChanMsgItem *> mChanMsgItems;
QFont mChannelFont;
QFont itemFont;
QAction* postchannelAct;
QAction* subscribechannelAct;
QAction* unsubscribechannelAct;
QAction* channeldetailsAct;
QAction* restoreKeysAct;
QAction* editChannelDetailAct;
QAction* shareKeyAct;
std::list<ChanMsgItem *> mChanMsgItems;
QFont mChannelFont;
QFont itemFont;
};

View file

@ -469,7 +469,7 @@ border-image: url(:/images/btn_26_pressed.png) 4;
</spacer>
</item>
<item row="0" column="4">
<widget class="QToolButton" name="setallreadtoolButton">
<widget class="QToolButton" name="setAllAsReadButton">
<property name="minimumSize">
<size>
<width>26</width>

View file

@ -68,6 +68,7 @@
#include <retroshare/rspeers.h>
#include <retroshare/rsfiles.h>
#include <retroshare/rsforums.h>
#include <retroshare/rschannels.h>
#include <retroshare/rsnotify.h>
#include "gui/connect/ConnectFriendWizard.h"
@ -218,7 +219,7 @@ MainWindow::MainWindow(QWidget* parent, Qt::WFlags flags)
messageAction = createPageAction(QIcon(IMAGE_MESSAGES), tr("Messages"), grp));
ui.stackPages->add(channelFeed = new ChannelFeed(ui.stackPages),
createPageAction(QIcon(IMAGE_CHANNELS), tr("Channels"), grp));
channelAction = createPageAction(QIcon(IMAGE_CHANNELS), tr("Channels"), grp));
#ifdef BLOGS
ui.stackPages->add(blogsFeed = new BlogsDialog(ui.stackPages),
@ -308,6 +309,7 @@ MainWindow::MainWindow(QWidget* parent, Qt::WFlags flags)
/* call once */
updateMessages();
updateForums();
updateChannels(NOTIFY_TYPE_ADD);
privateChatChanged(NOTIFY_LIST_PRIVATE_INCOMING_CHAT, NOTIFY_TYPE_ADD);
idle = new Idle();
@ -403,6 +405,11 @@ void MainWindow::createTrayIcon()
trayIconForums->setIcon(QIcon(":/images/konversation16.png"));
connect(trayIconForums, SIGNAL(activated(QSystemTrayIcon::ActivationReason)), this, SLOT(trayIconForumsClicked(QSystemTrayIcon::ActivationReason)));
// Create the tray icon for channels
trayIconChannels = new QSystemTrayIcon(this);
trayIconChannels->setIcon(QIcon(":/images/channels16.png"));
connect(trayIconChannels, SIGNAL(activated(QSystemTrayIcon::ActivationReason)), this, SLOT(trayIconChannelsClicked(QSystemTrayIcon::ActivationReason)));
// Create the tray icon for chat
trayIconChat = new QSystemTrayIcon(this);
trayIconChat->setIcon(QIcon(":/images/chat.png"));
@ -458,9 +465,9 @@ void MainWindow::updateForums()
rsForums->getMessageCount("", newMessageCount, unreadMessageCount);
if (newMessageCount) {
forumAction->setIcon(QIcon(QPixmap(":/images/konversation_new.png"))) ;
forumAction->setIcon(QIcon(":/images/konversation_new.png")) ;
} else {
forumAction->setIcon(QIcon(QPixmap(":/images/konversation.png"))) ;
forumAction->setIcon(QIcon(IMAGE_FORUMS)) ;
}
if (newMessageCount) {
@ -475,6 +482,30 @@ void MainWindow::updateForums()
}
}
void MainWindow::updateChannels(int type)
{
unsigned int newMessageCount = 0;
unsigned int unreadMessageCount = 0;
rsChannels->getMessageCount("", newMessageCount, unreadMessageCount);
if (newMessageCount) {
channelAction->setIcon(QIcon(":/images/channels_new32.png")) ;
} else {
channelAction->setIcon(QIcon(IMAGE_CHANNELS)) ;
}
if (newMessageCount) {
if (newMessageCount > 1) {
trayIconChannels->setToolTip(tr("RetroShare") + "\n" + tr("You have %1 new messages").arg(newMessageCount));
} else {
trayIconChannels->setToolTip(tr("RetroShare") + "\n" + tr("You have %1 new message").arg(newMessageCount));
}
trayIconChannels->show();
} else {
trayIconChannels->hide();
}
}
void MainWindow::updateStatus()
{
// This call is essential to remove locks due to QEventLoop re-entrance while asking gpg passwds. Dont' remove it!
@ -831,6 +862,13 @@ void MainWindow::trayIconForumsClicked(QSystemTrayIcon::ActivationReason e)
}
}
void MainWindow::trayIconChannelsClicked(QSystemTrayIcon::ActivationReason e)
{
if(e == QSystemTrayIcon::Trigger || e == QSystemTrayIcon::DoubleClick) {
showWindow(MainWindow::Channels);
}
}
void MainWindow::trayIconChatClicked(QSystemTrayIcon::ActivationReason e)
{
if(e == QSystemTrayIcon::Trigger || e == QSystemTrayIcon::DoubleClick) {

View file

@ -141,6 +141,7 @@ public slots:
void checkAndSetIdle(int idleTime);
void updateMessages();
void updateForums();
void updateChannels(int type);
void privateChatChanged(int list, int type);
protected:
@ -161,6 +162,7 @@ private slots:
void toggleVisibilitycontextmenu();
void trayIconMessagesClicked(QSystemTrayIcon::ActivationReason e);
void trayIconForumsClicked(QSystemTrayIcon::ActivationReason e);
void trayIconChannelsClicked(QSystemTrayIcon::ActivationReason e);
void trayIconChatClicked(QSystemTrayIcon::ActivationReason e);
/** Toolbar fns. */
@ -225,6 +227,7 @@ private:
QSystemTrayIcon *trayIcon;
QSystemTrayIcon *trayIconMessages;
QSystemTrayIcon *trayIconForums;
QSystemTrayIcon *trayIconChannels;
QSystemTrayIcon *trayIconChat;
QAction *toggleVisibilityAction, *toolAct;
QMenu *trayMenu;
@ -238,6 +241,7 @@ private:
QAction *messageAction;
QAction *forumAction;
QAction *channelAction;
/* Status */
std::set <QObject*> m_apStatusObjects; // added objects for status
@ -254,4 +258,3 @@ private:
};
#endif

View file

@ -26,6 +26,7 @@
#include "FeedHolder.h"
#include "SubFileItem.h"
#include "gui/notifyqt.h"
#include <retroshare/rschannels.h>
@ -46,6 +47,8 @@ ChanMsgItem::ChanMsgItem(FeedHolder *parent, uint32_t feedId, std::string chanId
setAttribute ( Qt::WA_DeleteOnClose, true );
m_inUpdateItemStatic = false;
/* general ones */
connect( expandButton, SIGNAL( clicked( void ) ), this, SLOT( toggle ( void ) ) );
connect( clearButton, SIGNAL( clicked( void ) ), this, SLOT( removeItem ( void ) ) );
@ -55,13 +58,15 @@ ChanMsgItem::ChanMsgItem(FeedHolder *parent, uint32_t feedId, std::string chanId
connect( downloadButton, SIGNAL( clicked( void ) ), this, SLOT( download ( void ) ) );
connect( playButton, SIGNAL( clicked( void ) ), this, SLOT( play ( void ) ) );
connect( readButton, SIGNAL( toggled(bool) ), this, SLOT( readToggled(bool) ) );
connect( NotifyQt::getInstance(), SIGNAL(channelMsgReadSatusChanged(QString,QString,int)), this, SLOT(channelMsgReadSatusChanged(QString,QString,int)), Qt::QueuedConnection);
downloadButton->hide();
playButton->hide();
small();
updateItemStatic();
updateItem();
}
@ -81,12 +86,15 @@ void ChanMsgItem::updateItemStatic()
if (!rsChannels->getChannelMessage(mChanId, mMsgId, cmi))
return;
m_inUpdateItemStatic = true;
QString title;
ChannelInfo ci;
rsChannels->getChannelInfo(mChanId, ci);
if (!mIsHome)
{
ChannelInfo ci;
rsChannels->getChannelInfo(mChanId, ci);
title = "Channel Feed: ";
title += QString::fromStdWString(ci.channelName);
titleLabel->setText(title);
@ -97,6 +105,8 @@ void ChanMsgItem::updateItemStatic()
} else {
unsubscribeButton->setEnabled(false);
}
readButton->setVisible(false);
newLabel->setVisible(false);
}
else
{
@ -109,8 +119,32 @@ void ChanMsgItem::updateItemStatic()
unsubscribeButton->setEnabled(false);
clearButton->hide();
unsubscribeButton->hide();
if ((ci.channelFlags & RS_DISTRIB_SUBSCRIBED) || (ci.channelFlags & RS_DISTRIB_ADMIN)) {
readButton->setVisible(true);
uint32_t status = 0;
rsChannels->getMessageStatus(mChanId, mMsgId, status);
if ((status & CHANNEL_MSG_STATUS_READ) == 0 || (status & CHANNEL_MSG_STATUS_UNREAD_BY_USER)) {
readButton->setChecked(true);
readButton->setIcon(QIcon(":/images/message-state-unread.png"));
} else {
readButton->setChecked(false);
readButton->setIcon(QIcon(":/images/message-state-read.png"));
}
if (status & CHANNEL_MSG_STATUS_READ) {
newLabel->setVisible(false);
} else {
newLabel->setVisible(true);
}
} else {
readButton->setVisible(false);
newLabel->setVisible(false);
}
}
msgLabel->setText(QString::fromStdWString(cmi.msg));
QDateTime qtime;
@ -155,6 +189,8 @@ void ChanMsgItem::updateItemStatic()
label->setPixmap(thumbnail);
label->setStyleSheet("QLabel#label{border: 2px solid #D3D3D3;border-radius: 3px;}");
}
m_inUpdateItemStatic = false;
}
@ -311,3 +347,28 @@ void ChanMsgItem::play()
}
}
}
void ChanMsgItem::readToggled(bool checked)
{
if (m_inUpdateItemStatic) {
return;
}
/* set always as read ... */
uint32_t statusNew = CHANNEL_MSG_STATUS_READ;
if (checked) {
/* ... and as unread by user */
statusNew |= CHANNEL_MSG_STATUS_UNREAD_BY_USER;
} else {
/* ... and as read by user */
statusNew &= ~CHANNEL_MSG_STATUS_UNREAD_BY_USER;
}
rsChannels->setMessageStatus(mChanId, mMsgId, statusNew, CHANNEL_MSG_STATUS_READ | CHANNEL_MSG_STATUS_UNREAD_BY_USER);
}
void ChanMsgItem::channelMsgReadSatusChanged(const QString& channelId, const QString& msgId, int status)
{
if (channelId.toStdString() == mChanId && msgId.toStdString() == mMsgId) {
updateItemStatic();
}
}

View file

@ -51,6 +51,9 @@ private slots:
void download();
void play();
void readToggled(bool checked);
void channelMsgReadSatusChanged(const QString& channelId, const QString& msgId, int status);
void updateItem();
private:
@ -61,11 +64,10 @@ private:
std::string mMsgId;
bool mIsHome;
bool m_inUpdateItemStatic;
std::list<SubFileItem *> mFileItems;
};
#endif

View file

@ -87,7 +87,7 @@ border-radius: 10px;}</string>
<string/>
</property>
<property name="pixmap">
<pixmap resource="../images.qrc">:/images/thumb-default-video.png</pixmap>
<pixmap>:/images/thumb-default-video.png</pixmap>
</property>
<property name="scaledContents">
<bool>true</bool>
@ -114,7 +114,7 @@ border-radius: 10px;}</string>
</item>
<item row="0" column="1">
<layout class="QGridLayout" name="gridLayout">
<item row="0" column="0" colspan="7">
<item row="0" column="0" colspan="8">
<widget class="QLabel" name="titleLabel">
<property name="sizePolicy">
<sizepolicy hsizetype="Minimum" vsizetype="Minimum">
@ -139,7 +139,7 @@ p, li { white-space: pre-wrap; }
</property>
</widget>
</item>
<item row="0" column="7" colspan="3">
<item row="0" column="8" colspan="3">
<widget class="QLabel" name="datetimelabel">
<property name="font">
<font>
@ -156,7 +156,7 @@ p, li { white-space: pre-wrap; }
</property>
</widget>
</item>
<item row="1" column="0" colspan="10">
<item row="1" column="0" colspan="11">
<widget class="QLabel" name="subjectLabel">
<property name="sizePolicy">
<sizepolicy hsizetype="MinimumExpanding" vsizetype="Expanding">
@ -182,7 +182,7 @@ p, li { white-space: pre-wrap; }
</property>
</widget>
</item>
<item row="2" column="6" colspan="2">
<item row="2" column="7" colspan="2">
<widget class="QPushButton" name="unsubscribeButton">
<property name="sizePolicy">
<sizepolicy hsizetype="Fixed" vsizetype="Fixed">
@ -197,12 +197,12 @@ p, li { white-space: pre-wrap; }
<string/>
</property>
<property name="icon">
<iconset resource="../images.qrc">
<iconset>
<normaloff>:/images/mail_delete.png</normaloff>:/images/mail_delete.png</iconset>
</property>
</widget>
</item>
<item row="2" column="8">
<item row="2" column="9">
<widget class="QPushButton" name="clearButton">
<property name="sizePolicy">
<sizepolicy hsizetype="Fixed" vsizetype="Fixed">
@ -217,12 +217,12 @@ p, li { white-space: pre-wrap; }
<string/>
</property>
<property name="icon">
<iconset resource="../images.qrc">
<iconset>
<normaloff>:/images/close_normal.png</normaloff>:/images/close_normal.png</iconset>
</property>
</widget>
</item>
<item row="2" column="9">
<item row="2" column="10">
<widget class="QPushButton" name="expandButton">
<property name="sizePolicy">
<sizepolicy hsizetype="Fixed" vsizetype="Fixed">
@ -240,7 +240,7 @@ p, li { white-space: pre-wrap; }
<string/>
</property>
<property name="icon">
<iconset resource="../images.qrc">
<iconset>
<normaloff>:/images/edit_add24.png</normaloff>:/images/edit_add24.png</iconset>
</property>
</widget>
@ -248,33 +248,33 @@ p, li { white-space: pre-wrap; }
<item row="2" column="1">
<widget class="QLabel" name="filelabel">
<property name="text">
<string notr="true">TextLabel</string>
<string notr="true">fileLabel</string>
</property>
</widget>
</item>
<item row="2" column="3">
<item row="2" column="4">
<widget class="QPushButton" name="downloadButton">
<property name="text">
<string>Download</string>
</property>
<property name="icon">
<iconset resource="../images.qrc">
<iconset>
<normaloff>:/images/download16.png</normaloff>:/images/download16.png</iconset>
</property>
</widget>
</item>
<item row="2" column="4">
<item row="2" column="5">
<widget class="QPushButton" name="playButton">
<property name="text">
<string>Play</string>
</property>
<property name="icon">
<iconset resource="../images.qrc">
<iconset>
<normaloff>:/images/player_play.png</normaloff>:/images/player_play.png</iconset>
</property>
</widget>
</item>
<item row="2" column="5">
<item row="2" column="6">
<spacer>
<property name="orientation">
<enum>Qt::Horizontal</enum>
@ -290,6 +290,30 @@ p, li { white-space: pre-wrap; }
</property>
</spacer>
</item>
<item row="2" column="2">
<widget class="QPushButton" name="readButton">
<property name="icon">
<iconset>
<normaloff>:/images/message-state-unread.png</normaloff>:/images/message-state-unread.png</iconset>
</property>
<property name="checkable">
<bool>true</bool>
</property>
<property name="checked">
<bool>false</bool>
</property>
<property name="flat">
<bool>false</bool>
</property>
</widget>
</item>
<item row="2" column="3">
<widget class="QLabel" name="newLabel">
<property name="text">
<string>New</string>
</property>
</widget>
</item>
</layout>
</item>
</layout>
@ -349,15 +373,6 @@ border-radius: 10px;}</string>
</item>
</layout>
</widget>
<resources>
<include location="../images.qrc"/>
<include location="../images.qrc"/>
<include location="../images.qrc"/>
<include location="../images.qrc"/>
<include location="../images.qrc"/>
<include location="../images.qrc"/>
<include location="../images.qrc"/>
<include location="../images.qrc"/>
</resources>
<resources/>
<connections/>
</ui>

View file

@ -58,6 +58,7 @@
<file>images/channels16.png</file>
<file>images/channels24.png</file>
<file>images/channels32.png</file>
<file>images/channels_new32.png</file>
<file>images/copyrslink.png</file>
<file>images/contacts24.png</file>
<file>images/connection.png</file>

Binary file not shown.

After

Width:  |  Height:  |  Size: 2 KiB

View file

@ -98,6 +98,11 @@ void NotifyQt::notifyPeerStatusChangedSummary()
emit peerStatusChangedSummary();
}
void NotifyQt::notifyChannelMsgReadSatusChanged(const std::string& channelId, const std::string& msgId, uint32_t status)
{
emit channelMsgReadSatusChanged(QString::fromStdString(channelId), QString::fromStdString(msgId), status);
}
void NotifyQt::notifyOwnStatusMessageChanged()
{
#ifdef NOTIFY_DEBUG
@ -226,6 +231,12 @@ void NotifyQt::notifyListChange(int list, int type)
#endif
emit forumsChanged(); // use connect with Qt::QueuedConnection
break;
case NOTIFY_LIST_CHANNELLIST_LOCKED:
#ifdef NOTIFY_DEBUG
std::cerr << "received channel msg changed" << std::endl ;
#endif
emit channelsChanged(type); // use connect with Qt::QueuedConnection
break;
case NOTIFY_LIST_PUBLIC_CHAT:
#ifdef NOTIFY_DEBUG
std::cerr << "received public chat changed" << std::endl ;

View file

@ -44,7 +44,8 @@ class NotifyQt: public QObject, public NotifyBase
virtual void notifyPeerStatusChanged(const std::string& peer_id, uint32_t state);
/* one or more peers has changed the states */
virtual void notifyPeerStatusChangedSummary();
virtual void notifyChannelMsgReadSatusChanged(const std::string& channelId, const std::string& msgId, uint32_t status);
virtual std::string askForPassword(const std::string& key_details,bool prev_is_bad) ;
/* Notify from GUI */
@ -63,6 +64,7 @@ class NotifyQt: public QObject, public NotifyBase
void messagesChanged() const ;
void messagesTagsChanged() const;
void forumsChanged() const ; // use connect with Qt::QueuedConnection
void channelsChanged(int type) const ; // use connect with Qt::QueuedConnection
void configChanged() const ;
void logInfoChanged(const QString&) const ;
void chatStatusChanged(const QString&,const QString&,bool) const ;
@ -78,6 +80,7 @@ class NotifyQt: public QObject, public NotifyBase
void publicChatChanged(int type) const ;
void privateChatChanged(int list, int type) const ;
void groupsChanged(int type) const ;
void channelMsgReadSatusChanged(const QString& channelId, const QString& msgId, int status);
/* Notify from GUI */
void chatStyleChanged(int /*ChatStyle::enumStyleType*/ styleType);

View file

@ -196,6 +196,7 @@ int main(int argc, char *argv[])
QObject::connect(notify,SIGNAL(messagesTagsChanged()) ,w->messagesDialog ,SLOT(messagesTagsChanged() )) ;
QObject::connect(notify,SIGNAL(messagesChanged()) ,w ,SLOT(updateMessages() )) ;
QObject::connect(notify,SIGNAL(forumsChanged()) ,w ,SLOT(updateForums() ), Qt::QueuedConnection);
QObject::connect(notify,SIGNAL(channelsChanged(int)) ,w ,SLOT(updateChannels(int) ), Qt::QueuedConnection);
QObject::connect(notify,SIGNAL(chatStatusChanged(const QString&,const QString&,bool)),w->peersDialog,SLOT(updatePeerStatusString(const QString&,const QString&,bool)));
QObject::connect(notify,SIGNAL(peerHasNewAvatar(const QString&)),w->peersDialog,SLOT(updatePeersAvatar(const QString&)));