New icon in system tray and a new icon with star in toolbar of MainWindow, when new forum messages are available.

New signal forumsChanged on NotifyQt.

git-svn-id: http://svn.code.sf.net/p/retroshare/code/trunk@3354 b45a01b8-16f6-495d-af2f-9b41ad6348cc
This commit is contained in:
thunder2 2010-08-09 21:20:34 +00:00
parent 32afd370bb
commit 3cfc08482f
14 changed files with 220 additions and 27 deletions

View File

@ -139,6 +139,9 @@ virtual bool getMessageStatus(const std::string& fId, const std::string& mId, ui
virtual bool ForumMessageSend(ForumMsgInfo &info) = 0;
virtual bool forumSubscribe(std::string fId, bool subscribe) = 0;
virtual bool getMessageCount(const std::string fId, unsigned int &newCount, unsigned int &unreadCount) = 0;
/****************************************/
};

View File

@ -220,7 +220,8 @@ const int NOTIFY_LIST_CHANNELLIST = 6;
const int NOTIFY_LIST_TRANSFERLIST = 7;
const int NOTIFY_LIST_CONFIG = 8;
const int NOTIFY_LIST_DIRLIST_LOCAL = 9;
const int NOTIFY_LIST_DIRLIST_FRIENDS = 10;
const int NOTIFY_LIST_DIRLIST_FRIENDS = 10;
const int NOTIFY_LIST_FORUMLIST_LOCKED = 11; // use connect with Qt::QueuedConnection
const int NOTIFY_TYPE_SAME = 0x01;
const int NOTIFY_TYPE_MOD = 0x02; /* general purpose, check all */

View File

@ -26,6 +26,7 @@
#include "services/p3forums.h"
#include "pqi/authssl.h"
#include "util/rsdir.h"
#include "retroshare/rsiface.h"
uint32_t convertToInternalFlags(uint32_t extFlags);
uint32_t convertToExternalFlags(uint32_t intFlags);
@ -271,34 +272,38 @@ bool p3Forums::ForumMessageSend(ForumMsgInfo &info)
bool p3Forums::setMessageStatus(const std::string& fId,const std::string& mId,const uint32_t status, const uint32_t statusMask)
{
RsStackMutex stack(distribMtx);
std::list<RsForumReadStatus *>::iterator lit = mReadStatus.begin();
for(; lit != mReadStatus.end(); lit++)
{
RsStackMutex stack(distribMtx); /***** STACK LOCKED MUTEX *****/
if((*lit)->forumId == fId)
std::list<RsForumReadStatus *>::iterator lit = mReadStatus.begin();
for(; lit != mReadStatus.end(); lit++)
{
RsForumReadStatus* rsi = *lit;
rsi->msgReadStatus[mId] &= ~statusMask;
rsi->msgReadStatus[mId] |= (status & statusMask);
break;
if((*lit)->forumId == fId)
{
RsForumReadStatus* rsi = *lit;
rsi->msgReadStatus[mId] &= ~statusMask;
rsi->msgReadStatus[mId] |= (status & statusMask);
break;
}
}
}
// if forum id does not exist create one
if(lit == mReadStatus.end())
{
RsForumReadStatus* rsi = new RsForumReadStatus();
rsi->forumId = fId;
rsi->msgReadStatus[mId] = status & statusMask;
mReadStatus.push_back(rsi);
mSaveList.push_back(rsi);
}
// if forum id does not exist create one
if(lit == mReadStatus.end())
{
RsForumReadStatus* rsi = new RsForumReadStatus();
rsi->forumId = fId;
rsi->msgReadStatus[mId] = status & statusMask;
mReadStatus.push_back(rsi);
mSaveList.push_back(rsi);
}
IndicateConfigChanged();
} /******* UNLOCKED ********/
IndicateConfigChanged();
rsicontrol->getNotify().notifyListChange(NOTIFY_LIST_FORUMLIST_LOCKED, NOTIFY_TYPE_MOD);
return true;
}
@ -436,6 +441,84 @@ bool p3Forums::forumSubscribe(std::string fId, bool subscribe)
return subscribeToGroup(fId, subscribe);
}
bool p3Forums::getMessageCount(const std::string fId, unsigned int &newCount, unsigned int &unreadCount)
{
newCount = 0;
unreadCount = 0;
std::list<std::string> grpIds;
if (fId.empty()) {
// count all messages of all subscribed forums
getAllGroupList(grpIds);
} else {
// count all messages of one forum
grpIds.push_back(fId);
}
std::list<std::string>::iterator git;
for (git = grpIds.begin(); git != grpIds.end(); git++) {
std::string fId = *git;
uint32_t grpFlags;
{
// only flag is needed
RsStackMutex stack(distribMtx); /***** STACK LOCKED MUTEX *****/
GroupInfo *gi = locked_getGroupInfo(fId);
if (gi == NULL) {
return false;
}
grpFlags = gi->flags;
} /******* UNLOCKED ********/
if (grpFlags & (RS_DISTRIB_ADMIN | RS_DISTRIB_SUBSCRIBED)) {
std::list<std::string> msgIds;
if (getAllMsgList(fId, msgIds)) {
std::list<std::string>::iterator mit;
RsStackMutex stack(distribMtx); /***** STACK LOCKED MUTEX *****/
std::list<RsForumReadStatus *>::iterator lit;
for(lit = mReadStatus.begin(); lit != mReadStatus.end(); lit++) {
if ((*lit)->forumId == fId) {
break;
}
}
if (lit == mReadStatus.end()) {
// no status available -> all messages are new
newCount += msgIds.size();
unreadCount += msgIds.size();
continue;
}
for (mit = msgIds.begin(); mit != msgIds.end(); mit++) {
std::map<std::string, uint32_t >::iterator rit = (*lit)->msgReadStatus.find(*mit);
if (rit == (*lit)->msgReadStatus.end()) {
// no status available -> message is new
newCount++;
unreadCount++;
continue;
}
if (rit->second & FORUM_MSG_STATUS_READ) {
// message is not new
if (rit->second & FORUM_MSG_STATUS_UNREAD_BY_USER) {
// message is unread
unreadCount++;
}
} else {
newCount++;
unreadCount++;
}
}
} /******* UNLOCKED ********/
}
}
return true;
}
/***************************************************************************************/
/****************** Event Feedback (Overloaded form p3distrib) *************************/
@ -453,13 +536,16 @@ void p3Forums::locked_notifyGroupChanged(GroupInfo &grp, uint32_t flags)
{
case GRP_NEW_UPDATE:
getPqiNotify()->AddFeedItem(RS_FEED_ITEM_FORUM_NEW, grpId, msgId, nullId);
rsicontrol->getNotify().notifyListChange(NOTIFY_LIST_FORUMLIST_LOCKED, NOTIFY_TYPE_ADD);
break;
case GRP_UPDATE:
getPqiNotify()->AddFeedItem(RS_FEED_ITEM_FORUM_UPDATE, grpId, msgId, nullId);
rsicontrol->getNotify().notifyListChange(NOTIFY_LIST_FORUMLIST_LOCKED, NOTIFY_TYPE_MOD);
break;
case GRP_LOAD_KEY:
break;
case GRP_NEW_MSG:
rsicontrol->getNotify().notifyListChange(NOTIFY_LIST_FORUMLIST_LOCKED, NOTIFY_TYPE_ADD);
break;
case GRP_SUBSCRIBED:
break;

View File

@ -60,6 +60,8 @@ virtual bool getMessageStatus(const std::string& fId, const std::string& mId, ui
virtual bool forumSubscribe(std::string fId, bool subscribe);
virtual bool getMessageCount(const std::string fId, unsigned int &newCount, unsigned int &unreadCount);
/***************************************************************************************/
/****************** Event Feedback (Overloaded form p3distrib) *************************/
/***************************************************************************************/

View File

@ -71,6 +71,9 @@
#define COLUMN_FORUM_DATA 0
#define ROLE_FORUM_ID Qt::UserRole
#define ROLE_FORUM_TITLE Qt::UserRole + 1
#define ROLE_FORUM_COUNT 2
/* Thread constants */
#define COLUMN_THREAD_COUNT 6
@ -554,6 +557,7 @@ void ForumsDialog::insertForums()
}
item -> setText(COLUMN_FORUM_TITLE, name);
item -> setData(COLUMN_FORUM_DATA, ROLE_FORUM_TITLE, name);
/* (1) Popularity */
{
@ -598,6 +602,7 @@ void ForumsDialog::insertForums()
}
item -> setText(COLUMN_FORUM_TITLE, name);
item -> setData(COLUMN_FORUM_DATA, ROLE_FORUM_TITLE, name);
/* (1) Popularity */
{
@ -678,6 +683,7 @@ void ForumsDialog::insertForums()
}
item -> setText(COLUMN_FORUM_TITLE, name);
item -> setData(COLUMN_FORUM_DATA, ROLE_FORUM_TITLE, name);
/* (1) Popularity */
@ -719,6 +725,8 @@ void ForumsDialog::insertForums()
CleanupItems (SubList);
CleanupItems (PopList);
CleanupItems (OtherList);
updateMessageSummaryList("");
}
void ForumsDialog::FillForums(QTreeWidgetItem *Forum, QList<QTreeWidgetItem *> &ChildList)
@ -755,9 +763,13 @@ void ForumsDialog::FillForums(QTreeWidgetItem *Forum, QList<QTreeWidgetItem *> &
Child->setIcon (COLUMN_FORUM_TITLE, (*NewChild)->icon (COLUMN_FORUM_TITLE));
Child->setToolTip (COLUMN_FORUM_TITLE, (*NewChild)->toolTip (COLUMN_FORUM_TITLE));
for (int i = 0; i < COLUMN_FORUM_COUNT; i++) {
int i;
for (i = 0; i < COLUMN_FORUM_COUNT; i++) {
Child->setText (i, (*NewChild)->text (i));
}
for (i = 0; i < ROLE_FORUM_COUNT; i++) {
Child->setData (COLUMN_FORUM_DATA, Qt::UserRole + i, (*NewChild)->data (COLUMN_FORUM_DATA, Qt::UserRole + i));
}
} else {
// insert new child
if (ChildIndexCur < ChildCount) {
@ -1521,6 +1533,7 @@ void ForumsDialog::setMsgAsReadUnread(QList<QTreeWidgetItem*> &Rows, bool bRead)
if (bChanged) {
CalculateIconsAndFonts();
updateMessageSummaryList(mCurrForumId);
}
}
@ -1853,3 +1866,39 @@ bool ForumsDialog::FilterItem(QTreeWidgetItem *pItem, QString &sPattern, int nFi
return (bVisible || nVisibleChildCount);
}
void ForumsDialog::updateMessageSummaryList(std::string forumId)
{
QTreeWidgetItem *apToplevelItem[2] = { YourForums, SubscribedForums };
int nToplevelItem;
for (nToplevelItem = 0; nToplevelItem < 2; nToplevelItem++) {
QTreeWidgetItem *pToplevelItem = apToplevelItem[nToplevelItem];
int nItem;
int nItemCount = pToplevelItem->childCount();
for (nItem = 0; nItem < nItemCount; nItem++) {
QTreeWidgetItem *pItem = pToplevelItem->child(nItem);
std::string fId = pItem->data(COLUMN_FORUM_DATA, ROLE_FORUM_ID).toString().toStdString();
if (forumId.empty() || fId == forumId) {
/* calculating the new messages */
unsigned int newMessageCount = 0;
unsigned int unreadMessageCount = 0;
rsForums->getMessageCount(fId, newMessageCount, unreadMessageCount);
QString sTitle = pItem->data(COLUMN_FORUM_DATA, ROLE_FORUM_TITLE).toString();
if (unreadMessageCount) {
sTitle += " (" + QString::number(unreadMessageCount) + ")";
}
pItem->setText(COLUMN_FORUM_TITLE, sTitle);
if (forumId.empty() == false) {
/* calculate only this forum */
break;
}
}
}
}
}

View File

@ -83,6 +83,7 @@ private:
void insertForums();
void insertThreads();
void insertPost();
void updateMessageSummaryList(std::string forumId);
void loadForumEmoticons();

View File

@ -67,6 +67,7 @@
#include <retroshare/rsiface.h>
#include <retroshare/rspeers.h>
#include <retroshare/rsfiles.h>
#include <retroshare/rsforums.h>
#include "gui/connect/ConnectFriendWizard.h"
#include "util/rsversion.h"
@ -223,7 +224,7 @@ MainWindow::MainWindow(QWidget* parent, Qt::WFlags flags)
#endif
ui.stackPages->add(forumsDialog = new ForumsDialog(ui.stackPages),
createPageAction(QIcon(IMAGE_FORUMS), tr("Forums"), grp));
forumAction = createPageAction(QIcon(IMAGE_FORUMS), tr("Forums"), grp));
#ifndef RS_RELEASE_VERSION
ui.stackPages->add(linksDialog = new LinksDialog(ui.stackPages),
@ -309,6 +310,7 @@ MainWindow::MainWindow(QWidget* parent, Qt::WFlags flags)
/* call once */
updateMessages();
updateForums();
idle = new Idle();
idle->start();
@ -397,6 +399,11 @@ void MainWindow::createTrayIcon()
trayIconMessages = new QSystemTrayIcon(this);
trayIconMessages->setIcon(QIcon(":/images/newmsg.png"));
connect(trayIconMessages, SIGNAL(activated(QSystemTrayIcon::ActivationReason)), this, SLOT(trayIconMessagesClicked(QSystemTrayIcon::ActivationReason)));
// Create the tray icon for forums
trayIconForums = new QSystemTrayIcon(this);
trayIconForums->setIcon(QIcon(":/images/konversation16.png"));
connect(trayIconForums, SIGNAL(activated(QSystemTrayIcon::ActivationReason)), this, SLOT(trayIconForumsClicked(QSystemTrayIcon::ActivationReason)));
}
/*static*/ void MainWindow::installGroupChatNotifier()
@ -441,6 +448,30 @@ void MainWindow::updateMessages()
}
}
void MainWindow::updateForums()
{
unsigned int newMessageCount = 0;
unsigned int unreadMessageCount = 0;
rsForums->getMessageCount("", newMessageCount, unreadMessageCount);
if (newMessageCount) {
forumAction->setIcon(QIcon(QPixmap(":/images/konversation_new.png"))) ;
} else {
forumAction->setIcon(QIcon(QPixmap(":/images/konversation.png"))) ;
}
if (newMessageCount) {
if (newMessageCount > 1) {
trayIconForums->setToolTip(tr("RetroShare") + "\n" + tr("You have %1 new messages").arg(newMessageCount));
} else {
trayIconForums->setToolTip(tr("RetroShare") + "\n" + tr("You have %1 new message").arg(newMessageCount));
}
trayIconForums->show();
} else {
trayIconForums->hide();
}
}
void MainWindow::updateStatus()
{
// This call is essential to remove locks due to QEventLoop re-entrance while asking gpg passwds. Dont' remove it!
@ -774,6 +805,13 @@ void MainWindow::trayIconMessagesClicked(QSystemTrayIcon::ActivationReason e)
}
}
void MainWindow::trayIconForumsClicked(QSystemTrayIcon::ActivationReason e)
{
if(e == QSystemTrayIcon::Trigger || e == QSystemTrayIcon::DoubleClick) {
showWindow(MainWindow::Forums);
}
}
void MainWindow::toggleVisibilitycontextmenu()
{
if (isVisible())

View File

@ -142,6 +142,7 @@ public slots:
void displayDiskSpaceWarning(int loc,int size_limit_mb) ;
void checkAndSetIdle(int idleTime);
void updateMessages();
void updateForums();
protected:
/** Default Constructor */
@ -160,6 +161,7 @@ private slots:
void toggleVisibility(QSystemTrayIcon::ActivationReason e);
void toggleVisibilitycontextmenu();
void trayIconMessagesClicked(QSystemTrayIcon::ActivationReason e);
void trayIconForumsClicked(QSystemTrayIcon::ActivationReason e);
/** Toolbar fns. */
void addFriend();
@ -222,6 +224,7 @@ private:
QSystemTrayIcon *trayIcon;
QSystemTrayIcon *trayIconMessages;
QSystemTrayIcon *trayIconForums;
QAction *toggleVisibilityAction, *toolAct;
QMenu *trayMenu;
@ -232,7 +235,8 @@ private:
QLabel *_hashing_info_label ;
QAction *messageAction ;
QAction *messageAction;
QAction *forumAction;
/* Status */
std::set <QObject*> m_apStatusObjects; // added objects for status

View File

@ -53,7 +53,6 @@ public:
// replaced by shortcut
// virtual void keyPressEvent(QKeyEvent *) ;
void updateMessageSummaryList();
public slots:
void insertMessages();
@ -127,6 +126,7 @@ private:
class QStandardItemModel *MessagesModel;
QSortFilterProxyModel *proxyModel;
void updateMessageSummaryList();
void insertMsgTxtAndFiles(QModelIndex index = QModelIndex(), bool bSetToRead = true);
bool getCurrentMsg(std::string &cid, std::string &mid);

View File

@ -223,6 +223,7 @@
<file>images/konqsidebar_news16.png</file>
<file>images/konqsidebar_news24.png</file>
<file>images/konversation.png</file>
<file>images/konversation_new.png</file>
<file>images/konversation16.png</file>
<file>images/konversation128.png</file>
<file>images/konv_message2.png</file>

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.3 KiB

View File

@ -192,6 +192,12 @@ void NotifyQt::notifyListChange(int list, int type)
#endif
emit configChanged() ;
break ;
case NOTIFY_LIST_FORUMLIST_LOCKED:
#ifdef NOTIFY_DEBUG
std::cerr << "received forum msg changed" << std::endl ;
#endif
emit forumsChanged(); // use connect with Qt::QueuedConnection
break;
default:
break;
}

View File

@ -55,6 +55,7 @@ class NotifyQt: public QObject, public NotifyBase
void friendsChanged() const ;
void neighborsChanged() const ;
void messagesChanged() const ;
void forumsChanged() const ; // use connect with Qt::QueuedConnection
void configChanged() const ;
void logInfoChanged(const QString&) const ;
void chatStatusChanged(const QString&,const QString&,bool) const ;

View File

@ -178,6 +178,7 @@ int main(int argc, char *argv[])
QObject::connect(notify,SIGNAL(neighborsChanged()) ,w->networkDialog ,SLOT(insertConnect() )) ;
QObject::connect(notify,SIGNAL(messagesChanged()) ,w->messagesDialog ,SLOT(insertMessages() )) ;
QObject::connect(notify,SIGNAL(messagesChanged()) ,w ,SLOT(updateMessages() )) ;
QObject::connect(notify,SIGNAL(forumsChanged()) ,w ,SLOT(updateForums() ), 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(peerHasNewCustomStateString(const QString&)),w->peersDialog,SLOT(updatePeersCustomStateString(const QString&)));