diff --git a/libretroshare/src/retroshare/rsevents.h b/libretroshare/src/retroshare/rsevents.h index 9b9fbf106..86080ffef 100644 --- a/libretroshare/src/retroshare/rsevents.h +++ b/libretroshare/src/retroshare/rsevents.h @@ -103,6 +103,9 @@ enum class RsEventType : uint32_t /// @see rspeers.h NETWORK = 16, + /// @see RsMailTagEvent + MAIL_TAG = 17, + /** Emitted to update library clients about file hashing being completed */ FILE_HASHING_COMPLETED = 20, diff --git a/libretroshare/src/retroshare/rsmsgs.h b/libretroshare/src/retroshare/rsmsgs.h index 6264af47a..5e317d4ae 100644 --- a/libretroshare/src/retroshare/rsmsgs.h +++ b/libretroshare/src/retroshare/rsmsgs.h @@ -308,6 +308,9 @@ enum class RsMailStatusEventCode: uint8_t /// An error occurred attempting to sign the message SIGNATURE_FAILED = 0x04, + + MESSAGE_CHANGED = 0x05, + TAG_CHANGED = 0x06, }; struct RsMailStatusEvent : RsEvent @@ -329,6 +332,32 @@ struct RsMailStatusEvent : RsEvent ~RsMailStatusEvent() override = default; }; +enum class RsMailTagEventCode: uint8_t +{ + TAG_ADDED = 0x00, + TAG_CHANGED = 0x01, + TAG_REMOVED = 0x02, +}; + +struct RsMailTagEvent : RsEvent +{ + RsMailTagEvent() : RsEvent(RsEventType::MAIL_TAG) {} + + RsMailTagEventCode mMailTagEventCode; + std::set mChangedMsgTagIds; + + /// @see RsEvent + void serial_process( RsGenericSerializer::SerializeJob j, + RsGenericSerializer::SerializeContext& ctx) override + { + RsEvent::serial_process(j, ctx); + RS_SERIAL_PROCESS(mChangedMsgTagIds); + RS_SERIAL_PROCESS(mMailTagEventCode); + } + + ~RsMailTagEvent() override = default; +}; + #define RS_CHAT_PUBLIC 0x0001 #define RS_CHAT_PRIVATE 0x0002 #define RS_CHAT_AVATAR_AVAILABLE 0x0004 diff --git a/libretroshare/src/retroshare/rsnotify.h b/libretroshare/src/retroshare/rsnotify.h index e8c9de614..aeb701066 100644 --- a/libretroshare/src/retroshare/rsnotify.h +++ b/libretroshare/src/retroshare/rsnotify.h @@ -128,14 +128,12 @@ const uint32_t RS_MESSAGE_CONNECT_ATTEMPT = 0x0001; const int NOTIFY_LIST_NEIGHBOURS = 1; const int NOTIFY_LIST_FRIENDS = 2; const int NOTIFY_LIST_SEARCHLIST = 4; -const int NOTIFY_LIST_MESSAGELIST = 5; 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_FORUMLIST_LOCKED = 11; // use connect with Qt::QueuedConnection -const int NOTIFY_LIST_MESSAGE_TAGS = 12; const int NOTIFY_LIST_PUBLIC_CHAT = 13; const int NOTIFY_LIST_PRIVATE_INCOMING_CHAT = 14; const int NOTIFY_LIST_PRIVATE_OUTGOING_CHAT = 15; diff --git a/libretroshare/src/services/p3msgservice.cc b/libretroshare/src/services/p3msgservice.cc index 5974d7bf3..44ad7e024 100644 --- a/libretroshare/src/services/p3msgservice.cc +++ b/libretroshare/src/services/p3msgservice.cc @@ -220,8 +220,6 @@ void p3MsgService::processIncomingMsg(RsMsgItem *mi) for(std::list::const_iterator it(mi->attachment.items.begin());it!=mi->attachment.items.end();++it) rsFiles->FileRequest((*it).name,(*it).hash,(*it).filesize,std::string(),RS_FILE_REQ_ANONYMOUS_ROUTING,srcIds) ; } - - RsServer::notify()->notifyListChange(NOTIFY_LIST_MESSAGELIST,NOTIFY_TYPE_ADD); } bool p3MsgService::checkAndRebuildPartialMessage(RsMsgItem *ci) @@ -283,16 +281,11 @@ int p3MsgService::incomingMsgs() void p3MsgService::handleIncomingItem(RsMsgItem *mi) { - bool changed = false ; - // only returns true when a msg is complete. if(checkAndRebuildPartialMessage(mi)) { processIncomingMsg(mi); - changed = true ; } - if(changed) - RsServer::notify()->notifyListChange(NOTIFY_LIST_MESSAGELIST,NOTIFY_TYPE_MOD); } void p3MsgService::statusChange(const std::list &plist) @@ -350,7 +343,6 @@ void p3MsgService::checkSizeAndSendMessage(RsMsgItem *msg) int p3MsgService::checkOutgoingMessages() { - bool changed = false; std::list output_queue; auto pEvent = std::make_shared(); @@ -400,7 +392,6 @@ int p3MsgService::checkOutgoingMessages() { (mit->second)->msgFlags &= ~RS_MSG_FLAGS_PENDING; toErase.push_back(mit->first); - changed = true; } else { @@ -442,9 +433,6 @@ int p3MsgService::checkOutgoingMessages() else checkSizeAndSendMessage(*it); - if(changed) - RsServer::notify()->notifyListChange(NOTIFY_LIST_MESSAGELIST,NOTIFY_TYPE_MOD); - if(rsEvents && !pEvent->mChangedMsgIds.empty()) rsEvents->postEvent(pEvent); @@ -954,8 +942,6 @@ bool p3MsgService::removeMsgId(const std::string &mid) setMessageTag(mid, 0, false); setMsgParentId(msgId, 0); - - RsServer::notify()->notifyListChange(NOTIFY_LIST_MESSAGELIST,NOTIFY_TYPE_MOD); } if(rsEvents && !pEvent->mChangedMsgIds.empty()) @@ -968,7 +954,6 @@ bool p3MsgService::markMsgIdRead(const std::string &mid, bool unreadByUser) { std::map::iterator mit; uint32_t msgId = atoi(mid.c_str()); - bool changed = false; { RsStackMutex stack(mMsgMtx); /********** STACK LOCKED MTX ******/ @@ -992,18 +977,18 @@ bool p3MsgService::markMsgIdRead(const std::string &mid, bool unreadByUser) if (mi->msgFlags != msgFlags) { - changed = true; IndicateConfigChanged(); /**** INDICATE MSG CONFIG CHANGED! *****/ + + auto pEvent = std::make_shared(); + pEvent->mMailStatusEventCode = RsMailStatusEventCode::MESSAGE_CHANGED; + pEvent->mChangedMsgIds.insert(mid); + rsEvents->postEvent(pEvent); } } else { return false; } } /* UNLOCKED */ - if (changed) { - RsServer::notify()->notifyListChange(NOTIFY_LIST_MESSAGELIST,NOTIFY_TYPE_MOD); - } - return true; } @@ -1012,8 +997,6 @@ bool p3MsgService::setMsgFlag(const std::string &mid, uint32_t flag, uint32_t std::map::iterator mit; uint32_t msgId = atoi(mid.c_str()); - bool changed = false; - { RsStackMutex stack(mMsgMtx); /********** STACK LOCKED MTX ******/ @@ -1033,15 +1016,15 @@ bool p3MsgService::setMsgFlag(const std::string &mid, uint32_t flag, uint32_t mit->second->msgFlags |= flag; if (mit->second->msgFlags != oldFlag) { - changed = true; IndicateConfigChanged(); /**** INDICATE MSG CONFIG CHANGED! *****/ + + auto pEvent = std::make_shared(); + pEvent->mMailStatusEventCode = RsMailStatusEventCode::MESSAGE_CHANGED; + pEvent->mChangedMsgIds.insert(mid); + rsEvents->postEvent(pEvent); } } /* UNLOCKED */ - if (changed) { - RsServer::notify()->notifyListChange(NOTIFY_LIST_MESSAGELIST,NOTIFY_TYPE_MOD); - } - return true; } @@ -1137,7 +1120,10 @@ uint32_t p3MsgService::sendMessage(RsMsgItem* item) IndicateConfigChanged(); /**** INDICATE MSG CONFIG CHANGED! *****/ - RsServer::notify()->notifyListChange(NOTIFY_LIST_MESSAGELIST, NOTIFY_TYPE_ADD); // deprecated + auto pEvent = std::make_shared(); + pEvent->mMailStatusEventCode = RsMailStatusEventCode::MESSAGE_SENT; + pEvent->mChangedMsgIds.insert(std::to_string(item->msgId)); + rsEvents->postEvent(pEvent); return item->msgId; } @@ -1175,8 +1161,11 @@ uint32_t p3MsgService::sendDistantMessage(RsMsgItem *item, const RsGxsId& from) IndicateConfigChanged(); /**** INDICATE MSG CONFIG CHANGED! *****/ - RsServer::notify()->notifyListChange( NOTIFY_LIST_MESSAGELIST, - NOTIFY_TYPE_ADD ); + auto pEvent = std::make_shared(); + pEvent->mMailStatusEventCode = RsMailStatusEventCode::MESSAGE_SENT; + pEvent->mChangedMsgIds.insert(std::to_string(item->msgId)); + rsEvents->postEvent(pEvent); + return item->msgId; } @@ -1210,8 +1199,6 @@ bool p3MsgService::MessageSend(MessageInfo &info) // Update info for caller info.msgId = std::to_string(msg->msgId); info .msgflags = msg->msgFlags; - - RsServer::notify()->notifyListChange(NOTIFY_LIST_MESSAGELIST,NOTIFY_TYPE_ADD);// deprecated. Should be removed. Oct. 28, 2020 } auto pEvent = std::make_shared(); @@ -1418,10 +1405,9 @@ bool p3MsgService::MessageToDraft(MessageInfo &info, const std::string &msgParen IndicateConfigChanged(); /**** INDICATE MSG CONFIG CHANGED! *****/ - // RsServer::notify()->notifyListChange(NOTIFY_LIST_MESSAGELIST,NOTIFY_TYPE_MOD); - auto pEvent = std::make_shared(); pEvent->mMailStatusEventCode = RsMailStatusEventCode::MESSAGE_SENT; + pEvent->mChangedMsgIds.insert(std::to_string(msg->msgId)); rsEvents->postEvent(pEvent); return true; @@ -1452,7 +1438,7 @@ bool p3MsgService::getMessageTagTypes(MsgTagType& tags) bool p3MsgService::setMessageTagType(uint32_t tagId, std::string& text, uint32_t rgb_color) { - int nNotifyType = 0; + auto ev = std::make_shared(); { RsStackMutex stack(mMsgMtx); /********** STACK LOCKED MTX ******/ @@ -1475,7 +1461,8 @@ bool p3MsgService::setMessageTagType(uint32_t tagId, std::string& text, uint32 mTags.insert(std::pair(tagId, tagType)); - nNotifyType = NOTIFY_TYPE_ADD; + ev->mMailTagEventCode = RsMailTagEventCode::TAG_ADDED; + ev->mChangedMsgTagIds.insert(std::to_string(tagId)); } else { if (mit->second->text != text || mit->second->rgb_color != rgb_color) { /* modify existing tag */ @@ -1489,17 +1476,18 @@ bool p3MsgService::setMessageTagType(uint32_t tagId, std::string& text, uint32 } mit->second->rgb_color = rgb_color; - nNotifyType = NOTIFY_TYPE_MOD; + ev->mMailTagEventCode = RsMailTagEventCode::TAG_CHANGED; + ev->mChangedMsgTagIds.insert(std::to_string(tagId)); } } } /* UNLOCKED */ - if (nNotifyType) { + if (!ev->mChangedMsgTagIds.empty()) { IndicateConfigChanged(); /**** INDICATE MSG CONFIG CHANGED! *****/ - RsServer::notify()->notifyListChange(NOTIFY_LIST_MESSAGE_TAGS, nNotifyType); - + rsEvents->postEvent(ev); + return true; } @@ -1513,6 +1501,9 @@ bool p3MsgService::removeMessageTagType(uint32_t tagId) return false; } + auto msgEvent = std::make_shared(); + msgEvent->mMailStatusEventCode = RsMailStatusEventCode::TAG_CHANGED; + { RsStackMutex stack(mMsgMtx); /********** STACK LOCKED MTX ******/ @@ -1540,7 +1531,10 @@ bool p3MsgService::removeMessageTagType(uint32_t tagId) delete(tag); mMsgTags.erase(mit1++); - continue; + } + + if (msgEvent->mChangedMsgIds.find(std::to_string(mit1->first)) == msgEvent->mChangedMsgIds.end()) { + msgEvent->mChangedMsgIds.insert(std::to_string(mit1->first)); } } ++mit1; @@ -1554,7 +1548,14 @@ bool p3MsgService::removeMessageTagType(uint32_t tagId) IndicateConfigChanged(); /**** INDICATE MSG CONFIG CHANGED! *****/ - RsServer::notify()->notifyListChange(NOTIFY_LIST_MESSAGE_TAGS, NOTIFY_TYPE_DEL); + auto ev = std::make_shared(); + ev->mMailTagEventCode = RsMailTagEventCode::TAG_REMOVED; + ev->mChangedMsgTagIds.insert(std::to_string(tagId)); + rsEvents->postEvent(ev); + + if (!msgEvent->mChangedMsgIds.empty()) { + rsEvents->postEvent(msgEvent); + } return true; } @@ -1595,7 +1596,8 @@ bool p3MsgService::setMessageTag(const std::string &msgId, uint32_t tagId, bool } } - int nNotifyType = 0; + auto ev = std::make_shared(); + ev->mMailStatusEventCode = RsMailStatusEventCode::TAG_CHANGED; { RsStackMutex stack(mMsgMtx); /********** STACK LOCKED MTX ******/ @@ -1614,7 +1616,7 @@ bool p3MsgService::setMessageTag(const std::string &msgId, uint32_t tagId, bool mMsgTags.insert(std::pair(tag->msgId, tag)); - nNotifyType = NOTIFY_TYPE_ADD; + ev->mChangedMsgIds.insert(msgId); } } else { RsMsgTags* tag = mit->second; @@ -1632,18 +1634,18 @@ bool p3MsgService::setMessageTag(const std::string &msgId, uint32_t tagId, bool tag->tagIds.push_back(tagId); /* keep the list sorted */ tag->tagIds.sort(); - nNotifyType = NOTIFY_TYPE_ADD; + ev->mChangedMsgIds.insert(msgId); } } else { if (tagId == 0) { /* remove all */ delete(tag); mMsgTags.erase(mit); - nNotifyType = NOTIFY_TYPE_DEL; + ev->mChangedMsgIds.insert(msgId); } else { if (lit != tag->tagIds.end()) { tag->tagIds.erase(lit); - nNotifyType = NOTIFY_TYPE_DEL; + ev->mChangedMsgIds.insert(msgId); if (tag->tagIds.empty()) { /* remove empty tag */ @@ -1657,10 +1659,10 @@ bool p3MsgService::setMessageTag(const std::string &msgId, uint32_t tagId, bool } /* UNLOCKED */ - if (nNotifyType) { + if (!ev->mChangedMsgIds.empty()) { IndicateConfigChanged(); /**** INDICATE MSG CONFIG CHANGED! *****/ - RsServer::notify()->notifyListChange(NOTIFY_LIST_MESSAGE_TAGS, nNotifyType); + rsEvents->postEvent(ev); return true; } @@ -1687,8 +1689,9 @@ bool p3MsgService::MessageToTrash(const std::string &mid, bool bTrash) std::map::iterator mit; uint32_t msgId = atoi(mid.c_str()); - bool bChanged = false; bool bFound = false; + auto pEvent = std::make_shared(); + pEvent->mMailStatusEventCode = RsMailStatusEventCode::MESSAGE_CHANGED; { RsStackMutex stack(mMsgMtx); /********** STACK LOCKED MTX ******/ @@ -1711,23 +1714,25 @@ bool p3MsgService::MessageToTrash(const std::string &mid, bool bTrash) if (bTrash) { if ((mi->msgFlags & RS_MSG_FLAGS_TRASH) == 0) { mi->msgFlags |= RS_MSG_FLAGS_TRASH; - bChanged = true; + pEvent->mChangedMsgIds.insert(std::to_string(mi->msgId)); } } else { if (mi->msgFlags & RS_MSG_FLAGS_TRASH) { mi->msgFlags &= ~RS_MSG_FLAGS_TRASH; - bChanged = true; + pEvent->mChangedMsgIds.insert(std::to_string(mi->msgId)); } } } } - if (bChanged) { + if (!pEvent->mChangedMsgIds.empty()) { IndicateConfigChanged(); /**** INDICATE MSG CONFIG CHANGED! *****/ checkOutgoingMessages(); - RsServer::notify()->notifyListChange(NOTIFY_LIST_MESSAGELIST,NOTIFY_TYPE_MOD); + if(rsEvents) { + rsEvents->postEvent(pEvent); + } } return bFound; @@ -2111,14 +2116,12 @@ void p3MsgService::notifyDataStatus( const GRouterMsgPropagationId& id, msgOutgoing.erase(it2); #endif - RsServer::notify()->notifyListChange( NOTIFY_LIST_MESSAGELIST, - NOTIFY_TYPE_ADD ); IndicateConfigChanged(); if(rsEvents) { auto pEvent = std::make_shared(); - pEvent->mMailStatusEventCode = RsMailStatusEventCode::NEW_MESSAGE; + pEvent->mMailStatusEventCode = RsMailStatusEventCode::MESSAGE_CHANGED; pEvent->mChangedMsgIds.insert(std::to_string(msg_id)); rsEvents->postEvent(pEvent); } @@ -2267,8 +2270,6 @@ bool p3MsgService::notifyGxsTransSendStatus( RsGxsTransId mailId, } } - RsServer::notify()->notifyListChange( NOTIFY_LIST_MESSAGELIST, - NOTIFY_TYPE_ADD ); IndicateConfigChanged(); } else if( status >= GxsTransSendStatus::FAILED_RECEIPT_SIGNATURE ) diff --git a/retroshare-gui/src/gui/feeds/MsgItem.cpp b/retroshare-gui/src/gui/feeds/MsgItem.cpp index 66ae5f49b..e0b3d2bf0 100644 --- a/retroshare-gui/src/gui/feeds/MsgItem.cpp +++ b/retroshare-gui/src/gui/feeds/MsgItem.cpp @@ -31,6 +31,7 @@ #include "gui/common/AvatarDefs.h" #include "gui/common/FilesDefs.h" #include "gui/notifyqt.h" +#include "util/qtthreadsutils.h" #include #include @@ -59,12 +60,13 @@ MsgItem::MsgItem(FeedHolder *parent, uint32_t feedId, const std::string &msgId, //connect( gotoButton, SIGNAL( clicked( void ) ), this, SLOT( gotoHome ( void ) ) ); /* specific ones */ - connect(NotifyQt::getInstance(), SIGNAL(messagesChanged()), this, SLOT(checkMessageReadStatus())); connect( playButton, SIGNAL( clicked( void ) ), this, SLOT( playMedia ( void ) ) ); connect( deleteButton, SIGNAL( clicked( void ) ), this, SLOT( deleteMsg ( void ) ) ); connect( replyButton, SIGNAL( clicked( void ) ), this, SLOT( replyMsg ( void ) ) ); connect( sendinviteButton, SIGNAL( clicked( void ) ), this, SLOT( sendInvite ( void ) ) ); + mEventHandlerId = 0; + rsEvents->registerEventsHandler( [this](std::shared_ptr event) { RsQThreadUtils::postToObject( [this,event]() { handleEvent_main_thread(event); }); }, mEventHandlerId, RsEventType::MAIL_STATUS ); expandFrame->hide(); info_Frame_Invite->hide(); @@ -73,6 +75,58 @@ MsgItem::MsgItem(FeedHolder *parent, uint32_t feedId, const std::string &msgId, updateItem(); } +MsgItem::~MsgItem() +{ + rsEvents->unregisterEventsHandler(mEventHandlerId); +} + +void MsgItem::handleEvent_main_thread(std::shared_ptr event) +{ + if(event->mType != RsEventType::MAIL_STATUS) { + return; + } + + const RsMailStatusEvent *fe = dynamic_cast(event.get()); + if (!fe) { + return; + } + + switch (fe->mMailStatusEventCode) { + case RsMailStatusEventCode::MESSAGE_CHANGED: + if (fe->mChangedMsgIds.find(mMsgId) != fe->mChangedMsgIds.end()) { + MessageInfo msgInfo; + + if (!rsMail->getMessage(mMsgId, msgInfo)) { + removeItem(); + break; + } + + if (!mCloseOnRead) { + break; + } + + if (msgInfo.msgflags & RS_MSG_NEW) { + /* Message status is still "new" */ + break; + } + + removeItem(); + } + break; + case RsMailStatusEventCode::MESSAGE_REMOVED: + if (fe->mChangedMsgIds.find(mMsgId) != fe->mChangedMsgIds.end()) { + removeItem(); + } + break; + case RsMailStatusEventCode::MESSAGE_SENT: + case RsMailStatusEventCode::NEW_MESSAGE: + case RsMailStatusEventCode::TAG_CHANGED: + case RsMailStatusEventCode::MESSAGE_RECEIVED_ACK: + case RsMailStatusEventCode::SIGNATURE_FAILED: + break; + } +} + void MsgItem::updateItemStatic() { /* fill in */ @@ -246,7 +300,6 @@ void MsgItem::doExpand(bool open) mCloseOnRead = false; rsMail->MessageRead(mMsgId, false); - mCloseOnRead = true; } else { @@ -332,26 +385,6 @@ void MsgItem::toggle() expand(expandFrame->isHidden()); } -void MsgItem::checkMessageReadStatus() -{ - if (!mCloseOnRead) { - return; - } - - MessageInfo msgInfo; - if (!rsMail->getMessage(mMsgId, msgInfo)) { - std::cerr << "MsgItem::checkMessageReadStatus() Couldn't find Msg" << std::endl; - return; - } - - if (msgInfo.msgflags & RS_MSG_NEW) { - /* Message status is still "new" */ - return; - } - - removeItem(); -} - void MsgItem::sendInvite() { MessageInfo mi; diff --git a/retroshare-gui/src/gui/feeds/MsgItem.h b/retroshare-gui/src/gui/feeds/MsgItem.h index 32824ca23..2cb8645ba 100644 --- a/retroshare-gui/src/gui/feeds/MsgItem.h +++ b/retroshare-gui/src/gui/feeds/MsgItem.h @@ -24,6 +24,7 @@ #include "ui_MsgItem.h" #include "FeedItem.h" #include +#include class FeedHolder; class SubFileItem; @@ -35,6 +36,7 @@ class MsgItem : public FeedItem, private Ui::MsgItem public: /** Default Constructor */ MsgItem(FeedHolder *parent, uint32_t feedId, const std::string &msgId, bool isHome); + virtual ~MsgItem(); void updateItemStatic(); @@ -46,6 +48,7 @@ protected: private: void fillExpandFrame(); + void handleEvent_main_thread(std::shared_ptr event); private slots: /* default stuff */ @@ -56,7 +59,6 @@ private slots: void deleteMsg(); void replyMsg(); void sendInvite(); - void checkMessageReadStatus(); void updateItem(); @@ -66,6 +68,7 @@ private: bool mIsHome; bool mCloseOnRead; + RsEventsHandlerId_t mEventHandlerId; std::list mFileItems; }; diff --git a/retroshare-gui/src/gui/msgs/MessageUserNotify.cpp b/retroshare-gui/src/gui/msgs/MessageUserNotify.cpp index 071f794ff..fddf2c8d5 100644 --- a/retroshare-gui/src/gui/msgs/MessageUserNotify.cpp +++ b/retroshare-gui/src/gui/msgs/MessageUserNotify.cpp @@ -22,13 +22,20 @@ #include "MessageUserNotify.h" #include "gui/notifyqt.h" #include "gui/MainWindow.h" +#include "util/qtthreadsutils.h" #include "gui/msgs/MessageInterface.h" MessageUserNotify::MessageUserNotify(QObject *parent) : UserNotify(parent) { - connect(NotifyQt::getInstance(), SIGNAL(messagesChanged()), this, SLOT(updateIcon())); + mEventHandlerId = 0; + rsEvents->registerEventsHandler( [this](std::shared_ptr event) { RsQThreadUtils::postToObject( [this,event]() { handleEvent_main_thread(event); }); }, mEventHandlerId, RsEventType::MAIL_STATUS ); +} + +MessageUserNotify::~MessageUserNotify() +{ + rsEvents->unregisterEventsHandler(mEventHandlerId); } bool MessageUserNotify::hasSetting(QString *name, QString *group) @@ -72,3 +79,28 @@ void MessageUserNotify::iconClicked() { MainWindow::showWindow(MainWindow::Messages); } + +void MessageUserNotify::handleEvent_main_thread(std::shared_ptr event) +{ + if(event->mType != RsEventType::MAIL_STATUS) { + return; + } + + const RsMailStatusEvent *fe = dynamic_cast(event.get()); + if (!fe) { + return; + } + + switch (fe->mMailStatusEventCode) { + case RsMailStatusEventCode::NEW_MESSAGE: + case RsMailStatusEventCode::MESSAGE_CHANGED: + case RsMailStatusEventCode::MESSAGE_REMOVED: + updateIcon(); + break; + case RsMailStatusEventCode::MESSAGE_SENT: + case RsMailStatusEventCode::TAG_CHANGED: + case RsMailStatusEventCode::MESSAGE_RECEIVED_ACK: + case RsMailStatusEventCode::SIGNATURE_FAILED: + break; + } +} diff --git a/retroshare-gui/src/gui/msgs/MessageUserNotify.h b/retroshare-gui/src/gui/msgs/MessageUserNotify.h index 58b30e8fc..f9b7458ab 100644 --- a/retroshare-gui/src/gui/msgs/MessageUserNotify.h +++ b/retroshare-gui/src/gui/msgs/MessageUserNotify.h @@ -21,6 +21,7 @@ #ifndef MESSAGEUSERNOTIFY_H #define MESSAGEUSERNOTIFY_H +#include #include "gui/common/UserNotify.h" class MessageUserNotify : public UserNotify @@ -29,6 +30,7 @@ class MessageUserNotify : public UserNotify public: MessageUserNotify(QObject *parent = 0); + virtual ~MessageUserNotify(); virtual bool hasSetting(QString *name, QString *group) override; @@ -41,6 +43,11 @@ private: virtual QString getNotifyMessage(bool plural) override; virtual void iconClicked() override; + + void handleEvent_main_thread(std::shared_ptr event); + +private: + RsEventsHandlerId_t mEventHandlerId; }; #endif // MESSAGEUSERNOTIFY_H diff --git a/retroshare-gui/src/gui/msgs/MessageWidget.cpp b/retroshare-gui/src/gui/msgs/MessageWidget.cpp index e614eeca0..d05d17446 100644 --- a/retroshare-gui/src/gui/msgs/MessageWidget.cpp +++ b/retroshare-gui/src/gui/msgs/MessageWidget.cpp @@ -46,6 +46,7 @@ #include "util/HandleRichText.h" #include "util/DateTime.h" #include "util/QtVersion.h" +#include "util/qtthreadsutils.h" #include #include @@ -159,9 +160,6 @@ MessageWidget::MessageWidget(bool controlled, QWidget *parent, Qt::WindowFlags f viewsource->setShortcut(QKeySequence("CTRL+O")); connect(viewsource, SIGNAL(triggered()), this, SLOT(viewSource())); - connect(NotifyQt::getInstance(), SIGNAL(messagesTagsChanged()), this, SLOT(messagesTagsChanged())); - connect(NotifyQt::getInstance(), SIGNAL(messagesChanged()), this, SLOT(messagesChanged())); - ui.imageBlockWidget->addButtonAction(tr("Load images always for this message"), this, SLOT(loadImagesAlways()), true); ui.msgText->setImageBlockWidget(ui.imageBlockWidget); @@ -211,6 +209,9 @@ MessageWidget::MessageWidget(bool controlled, QWidget *parent, Qt::WindowFlags f ui.dateText-> setText(""); ui.info_Frame_Invite->hide(); + + mEventHandlerId = 0; + rsEvents->registerEventsHandler( [this](std::shared_ptr event) { RsQThreadUtils::postToObject( [this,event]() { handleEvent_main_thread(event); }); }, mEventHandlerId, RsEventType::MAIL_STATUS ); } MessageWidget::~MessageWidget() @@ -218,6 +219,47 @@ MessageWidget::~MessageWidget() if (isControlled == false) { processSettings("MessageWidget", false); } + + rsEvents->unregisterEventsHandler(mEventHandlerId); +} + +void MessageWidget::handleEvent_main_thread(std::shared_ptr event) +{ + if(event->mType != RsEventType::MAIL_STATUS) { + return; + } + + const RsMailStatusEvent *fe = dynamic_cast(event.get()); + if (!fe) { + return; + } + + switch (fe->mMailStatusEventCode) { + case RsMailStatusEventCode::MESSAGE_REMOVED: + if (fe->mChangedMsgIds.find(currMsgId) != fe->mChangedMsgIds.end()) { + if (isControlled) { + /* processed by MessagesDialog */ + return; + } + + /* messages was removed */ + if (isWindow) { + window()->close(); + } else { + deleteLater(); + } + } + break; + case RsMailStatusEventCode::TAG_CHANGED: + messagesTagsChanged(); + break; + case RsMailStatusEventCode::MESSAGE_SENT: + case RsMailStatusEventCode::MESSAGE_CHANGED: + case RsMailStatusEventCode::NEW_MESSAGE: + case RsMailStatusEventCode::MESSAGE_RECEIVED_ACK: + case RsMailStatusEventCode::SIGNATURE_FAILED: + break; + } } void MessageWidget::connectAction(enumActionType actionType, QToolButton* button) @@ -407,25 +449,6 @@ void MessageWidget::messagesTagsChanged() showTagLabels(); } -void MessageWidget::messagesChanged() -{ - if (isControlled) { - /* processed by MessagesDialog */ - return; - } - - /* test Message */ - MessageInfo msgInfo; - if (rsMail->getMessage(currMsgId, msgInfo) == false) { - /* messages was removed */ - if (isWindow) { - window()->close(); - } else { - deleteLater(); - } - } -} - void MessageWidget::clearTagLabels() { /* clear all tags */ diff --git a/retroshare-gui/src/gui/msgs/MessageWidget.h b/retroshare-gui/src/gui/msgs/MessageWidget.h index 5acf627f6..12438e55c 100644 --- a/retroshare-gui/src/gui/msgs/MessageWidget.h +++ b/retroshare-gui/src/gui/msgs/MessageWidget.h @@ -22,6 +22,7 @@ #define _MESSAGEWIDGET_H #include +#include #include "ui_MessageWidget.h" class QToolButton; @@ -75,7 +76,6 @@ private slots: void msgfilelistWidgetCostumPopupMenu(QPoint); void messagesTagsChanged(); - void messagesChanged(); void togglefileview(bool noUpdate = false); void getcurrentrecommended(); @@ -93,11 +93,14 @@ private: void showTagLabels(); void setToolbarButtonStyle(Qt::ToolButtonStyle style); + void handleEvent_main_thread(std::shared_ptr event); + bool isControlled; bool isWindow; std::string currMsgId; unsigned int currMsgFlags; bool expandFiles; + RsEventsHandlerId_t mEventHandlerId; QList tagLabels; diff --git a/retroshare-gui/src/gui/msgs/MessagesDialog.cpp b/retroshare-gui/src/gui/msgs/MessagesDialog.cpp index ffc108a53..c5c3c543c 100644 --- a/retroshare-gui/src/gui/msgs/MessagesDialog.cpp +++ b/retroshare-gui/src/gui/msgs/MessagesDialog.cpp @@ -268,9 +268,6 @@ MessagesDialog::MessagesDialog(QWidget *parent) registerHelpButton(ui.helpButton,help_str,"MessagesDialog") ; - connect(NotifyQt::getInstance(), SIGNAL(messagesChanged()), mMessageModel, SLOT(updateMessages())); - connect(NotifyQt::getInstance(), SIGNAL(messagesTagsChanged()), this, SLOT(messagesTagsChanged())); - connect(ui.filterLineEdit, SIGNAL(textChanged(QString)), this, SLOT(filterChanged(QString))); connect(ui.filterLineEdit, SIGNAL(filterChanged(int)), this, SLOT(filterColumnChanged(int))); @@ -294,6 +291,9 @@ MessagesDialog::MessagesDialog(QWidget *parent) mEventHandlerId=0; rsEvents->registerEventsHandler( [this](std::shared_ptr event) { RsQThreadUtils::postToObject( [this,event]() { handleEvent_main_thread(event); }); }, mEventHandlerId, RsEventType::MAIL_STATUS ); + + mTagEventHandlerId = 0; + rsEvents->registerEventsHandler( [this](std::shared_ptr event) { RsQThreadUtils::postToObject( [this,event]() { handleTagEvent_main_thread(event); }); }, mEventHandlerId, RsEventType::MAIL_TAG ); } void MessagesDialog::handleEvent_main_thread(std::shared_ptr event) @@ -310,9 +310,34 @@ void MessagesDialog::handleEvent_main_thread(std::shared_ptr even case RsMailStatusEventCode::MESSAGE_SENT: case RsMailStatusEventCode::MESSAGE_REMOVED: case RsMailStatusEventCode::NEW_MESSAGE: + case RsMailStatusEventCode::MESSAGE_CHANGED: + case RsMailStatusEventCode::TAG_CHANGED: + mMessageModel->updateMessages(); updateMessageSummaryList(); break; - default: + case RsMailStatusEventCode::MESSAGE_RECEIVED_ACK: + case RsMailStatusEventCode::SIGNATURE_FAILED: + break; + } +} + +void MessagesDialog::handleTagEvent_main_thread(std::shared_ptr event) +{ + if (event->mType != RsEventType::MAIL_TAG) { + return; + } + + const RsMailTagEvent *fe = dynamic_cast(event.get()); + if (!fe) { + return; + } + + switch (fe->mMailTagEventCode) { + case RsMailTagEventCode::TAG_ADDED: + case RsMailTagEventCode::TAG_CHANGED: + case RsMailTagEventCode::TAG_REMOVED: + fillQuickView(); + mMessageModel->updateMessages(); break; } } @@ -324,6 +349,12 @@ void MessagesDialog::preModelUpdate() mTmpSavedSelectedIds.clear(); getSelectedMessages(mTmpSavedSelectedIds); + mTmpSavedCurrentId.clear(); + const QModelIndex& m = ui.messageTreeWidget->currentIndex(); + if (m.isValid()) { + mTmpSavedCurrentId = m.sibling(m.row(), RsMessageModel::COLUMN_THREAD_MSGID).data(RsMessageModel::MsgIdRole).toString(); + } + std::cerr << "Pre-change: saving selection for " << mTmpSavedSelectedIds.size() << " indexes" << std::endl; } @@ -341,6 +372,13 @@ void MessagesDialog::postModelUpdate() } ui.messageTreeWidget->selectionModel()->select(sel,QItemSelectionModel::SelectCurrent); + + if (!mTmpSavedCurrentId.isEmpty()) { + QModelIndex index = mMessageProxyModel->mapFromSource(mMessageModel->getIndexOfMessage(mTmpSavedCurrentId.toStdString())); + if (index.isValid()) { + ui.messageTreeWidget->selectionModel()->setCurrentIndex(index, QItemSelectionModel::Select); + } + } } void MessagesDialog::sortColumn(int col,Qt::SortOrder so) @@ -356,6 +394,9 @@ MessagesDialog::~MessagesDialog() { // save settings processSettings(false); + + rsEvents->unregisterEventsHandler(mEventHandlerId); + rsEvents->unregisterEventsHandler(mTagEventHandlerId); } UserNotify *MessagesDialog::createUserNotify(QObject *parent) @@ -921,13 +962,6 @@ void MessagesDialog::changeQuickView(int newrow) mMessageProxyModel->setFilterRegExp(QRegExp(RsMessageModel::FilterString)); // this triggers the update of the proxy model } -void MessagesDialog::messagesTagsChanged() -{ - fillQuickView(); - mMessageModel->updateMessages(); -} - - // click in messageTreeWidget void MessagesDialog::currentChanged(const QModelIndex& new_proxy_index,const QModelIndex& /*old_proxy_index*/) { diff --git a/retroshare-gui/src/gui/msgs/MessagesDialog.h b/retroshare-gui/src/gui/msgs/MessagesDialog.h index 497c7a06d..e2c3f4c6f 100644 --- a/retroshare-gui/src/gui/msgs/MessagesDialog.h +++ b/retroshare-gui/src/gui/msgs/MessagesDialog.h @@ -66,7 +66,6 @@ protected: public slots: //void insertMessages(); - void messagesTagsChanged(); void messageRemoved(); void preModelUpdate(); void postModelUpdate(); @@ -112,6 +111,7 @@ private slots: private: void handleEvent_main_thread(std::shared_ptr event); + void handleTagEvent_main_thread(std::shared_ptr event); void updateInterface(); @@ -159,9 +159,11 @@ private: Ui::MessagesDialog ui; QList mTmpSavedSelectedIds; + QString mTmpSavedCurrentId; QModelIndex lastSelectedIndex; RsEventsHandlerId_t mEventHandlerId; + RsEventsHandlerId_t mTagEventHandlerId; }; #endif diff --git a/retroshare-gui/src/gui/msgs/TagsMenu.cpp b/retroshare-gui/src/gui/msgs/TagsMenu.cpp index 357c37325..8ef4f7d93 100644 --- a/retroshare-gui/src/gui/msgs/TagsMenu.cpp +++ b/retroshare-gui/src/gui/msgs/TagsMenu.cpp @@ -30,6 +30,7 @@ #include "gui/common/TagDefs.h" #include "gui/settings/NewTag.h" #include "gui/notifyqt.h" +#include "util/qtthreadsutils.h" #include "gui/msgs/MessageInterface.h" @@ -46,11 +47,18 @@ TagsMenu::TagsMenu(const QString &title, QWidget *parent) : QMenu (title, parent) { connect(this, SIGNAL(triggered (QAction*)), this, SLOT(tagTriggered(QAction*))); - connect(NotifyQt::getInstance(), SIGNAL(messagesTagsChanged()), this, SLOT(fillTags())); + + mEventHandlerId = 0; + rsEvents->registerEventsHandler( [this](std::shared_ptr event) { RsQThreadUtils::postToObject( [this,event]() { handleEvent_main_thread(event); }); }, mEventHandlerId, RsEventType::MAIL_TAG ); fillTags(); } +TagsMenu::~TagsMenu() +{ + rsEvents->unregisterEventsHandler(mEventHandlerId); +} + void TagsMenu::paintEvent(QPaintEvent *e) { QMenu::paintEvent(e); @@ -89,6 +97,26 @@ void TagsMenu::paintEvent(QPaintEvent *e) } } +void TagsMenu::handleEvent_main_thread(std::shared_ptr event) +{ + if (event->mType != RsEventType::MAIL_TAG) { + return; + } + + const RsMailTagEvent *fe = dynamic_cast(event.get()); + if (!fe) { + return; + } + + switch (fe->mMailTagEventCode) { + case RsMailTagEventCode::TAG_ADDED: + case RsMailTagEventCode::TAG_CHANGED: + case RsMailTagEventCode::TAG_REMOVED: + fillTags(); + break; + } +} + void TagsMenu::fillTags() { clear(); diff --git a/retroshare-gui/src/gui/msgs/TagsMenu.h b/retroshare-gui/src/gui/msgs/TagsMenu.h index 279638aae..a3f2cdd55 100644 --- a/retroshare-gui/src/gui/msgs/TagsMenu.h +++ b/retroshare-gui/src/gui/msgs/TagsMenu.h @@ -24,6 +24,7 @@ #include #include +#include class TagsMenu : public QMenu { @@ -31,6 +32,7 @@ class TagsMenu : public QMenu public: TagsMenu(const QString &title, QWidget *parent); + virtual ~TagsMenu(); void activateActions(std::list& tagIds); @@ -42,8 +44,14 @@ protected: virtual void paintEvent(QPaintEvent *e); private slots: - void fillTags(); void tagTriggered(QAction *action); + +private: + void handleEvent_main_thread(std::shared_ptr event); + void fillTags(); + +private: + RsEventsHandlerId_t mEventHandlerId; }; #endif diff --git a/retroshare-gui/src/gui/notifyqt.cpp b/retroshare-gui/src/gui/notifyqt.cpp index d0fcea506..380f2382c 100644 --- a/retroshare-gui/src/gui/notifyqt.cpp +++ b/retroshare-gui/src/gui/notifyqt.cpp @@ -563,18 +563,6 @@ void NotifyQt::notifyListChange(int list, int type) break; case NOTIFY_LIST_SEARCHLIST: break; - case NOTIFY_LIST_MESSAGELIST: -#ifdef NOTIFY_DEBUG - std::cerr << "received msg changed" << std::endl ; -#endif - emit messagesChanged() ; - break; - case NOTIFY_LIST_MESSAGE_TAGS: -#ifdef NOTIFY_DEBUG - std::cerr << "received msg tags changed" << std::endl ; -#endif - emit messagesTagsChanged(); - break; case NOTIFY_LIST_CHANNELLIST: break; case NOTIFY_LIST_TRANSFERLIST: @@ -663,8 +651,6 @@ void NotifyQt::notifyListPreChange(int list, int /*type*/) break; case NOTIFY_LIST_SEARCHLIST: break; - case NOTIFY_LIST_MESSAGELIST: - break; case NOTIFY_LIST_CHANNELLIST: break; case NOTIFY_LIST_TRANSFERLIST: @@ -697,7 +683,6 @@ void NotifyQt::UpdateGUI() // the gui is running, then they get updated by callbacks. if(!already_updated) { - emit messagesChanged() ; emit neighboursChanged(); emit configChanged(); diff --git a/retroshare-gui/src/gui/notifyqt.h b/retroshare-gui/src/gui/notifyqt.h index 069ae8056..f4fc063c7 100644 --- a/retroshare-gui/src/gui/notifyqt.h +++ b/retroshare-gui/src/gui/notifyqt.h @@ -109,8 +109,6 @@ class NotifyQt: public QObject, public NotifyClient void lobbyListChanged() const ; void chatLobbyEvent(qulonglong,int,const RsGxsId&,const QString&) ; void neighboursChanged() const ; - void messagesChanged() const ; - void messagesTagsChanged() const; void configChanged() const ; void logInfoChanged(const QString&) const ; void chatStatusChanged(const ChatId&,const QString&) const ; diff --git a/retroshare-gui/src/gui/settings/MessagePage.cpp b/retroshare-gui/src/gui/settings/MessagePage.cpp index 91a24ab02..ff302317d 100644 --- a/retroshare-gui/src/gui/settings/MessagePage.cpp +++ b/retroshare-gui/src/gui/settings/MessagePage.cpp @@ -27,6 +27,7 @@ #include "gui/common/TagDefs.h" #include #include "NewTag.h" +#include "util/qtthreadsutils.h" MessagePage::MessagePage(QWidget * parent, Qt::WindowFlags flags) : ConfigPage(parent, flags) @@ -54,10 +55,14 @@ MessagePage::MessagePage(QWidget * parent, Qt::WindowFlags flags) connect(ui.loadEmbeddedImages, SIGNAL(toggled(bool)), this,SLOT(updateLoadEmbededImages() )); connect(ui.openComboBox, SIGNAL(currentIndexChanged(int)),this,SLOT(updateMsgOpen() )); connect(ui.emoticonscheckBox, SIGNAL(toggled(bool)), this,SLOT(updateLoadEmoticons() )); + + mTagEventHandlerId = 0; + rsEvents->registerEventsHandler( [this](std::shared_ptr event) { RsQThreadUtils::postToObject( [this,event]() { handleEvent_main_thread(event); }); }, mTagEventHandlerId, RsEventType::MAIL_TAG ); } MessagePage::~MessagePage() { + rsEvents->unregisterEventsHandler(mTagEventHandlerId); delete(m_pTags); } @@ -134,6 +139,27 @@ MessagePage::load() fillTags(); } +void MessagePage::handleEvent_main_thread(std::shared_ptr event) +{ + if (event->mType != RsEventType::MAIL_TAG) { + return; + } + + const RsMailTagEvent *fe = dynamic_cast(event.get()); + if (!fe) { + return; + } + + switch (fe->mMailTagEventCode) { + case RsMailTagEventCode::TAG_ADDED: + case RsMailTagEventCode::TAG_CHANGED: + case RsMailTagEventCode::TAG_REMOVED: + rsMail->getMessageTagTypes(*m_pTags); + fillTags(); + break; + } +} + // fill tags void MessagePage::fillTags() { diff --git a/retroshare-gui/src/gui/settings/MessagePage.h b/retroshare-gui/src/gui/settings/MessagePage.h index f3a4c12a7..774d31b95 100644 --- a/retroshare-gui/src/gui/settings/MessagePage.h +++ b/retroshare-gui/src/gui/settings/MessagePage.h @@ -62,11 +62,13 @@ private slots: void updateLoadEmoticons(); private: + void handleEvent_main_thread(std::shared_ptr event); void fillTags(); /* Pointer for not include of rsmsgs.h */ MsgTagType *m_pTags; std::list m_changedTagIds; + RsEventsHandlerId_t mTagEventHandlerId; Ui::MessagePage ui; };