diff --git a/libretroshare/src/retroshare/rsiface.h b/libretroshare/src/retroshare/rsiface.h index 9aba35f2e..5a5393dfc 100644 --- a/libretroshare/src/retroshare/rsiface.h +++ b/libretroshare/src/retroshare/rsiface.h @@ -227,7 +227,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_CHAT = 13; +const int NOTIFY_LIST_PUBLIC_CHAT = 13; +const int NOTIFY_LIST_PRIVATE_CHAT = 14; const int NOTIFY_TYPE_SAME = 0x01; const int NOTIFY_TYPE_MOD = 0x02; /* general purpose, check all */ diff --git a/libretroshare/src/retroshare/rsmsgs.h b/libretroshare/src/retroshare/rsmsgs.h index e2cb48f9f..baf22490f 100644 --- a/libretroshare/src/retroshare/rsmsgs.h +++ b/libretroshare/src/retroshare/rsmsgs.h @@ -174,8 +174,12 @@ virtual bool resetMessageStandardTagTypes(MsgTagType& tags) = 0; /****************************************/ /* Chat */ -virtual bool ChatSend(ChatInfo &ci) = 0; -virtual bool getNewChat(std::list &chats) = 0; +virtual bool sendPublicChat(std::wstring msg) = 0; +virtual bool sendPrivateChat(std::string id, std::wstring msg) = 0; +virtual int getChatQueueCount(bool privateQueue) = 0; +virtual bool getPublicChatQueue(std::list &chats) = 0; +virtual bool getPrivateChatQueueIds(std::list &ids) = 0; +virtual bool getPrivateChatQueue(std::string id, std::list &chats) = 0; virtual void sendStatusString(const std::string& id,const std::string& status_string) = 0 ; virtual void sendGroupChatStatusString(const std::string& status_string) = 0 ; diff --git a/libretroshare/src/rsserver/p3msgs.cc b/libretroshare/src/rsserver/p3msgs.cc index a854490db..9f2bf212c 100644 --- a/libretroshare/src/rsserver/p3msgs.cc +++ b/libretroshare/src/rsserver/p3msgs.cc @@ -135,19 +135,16 @@ bool p3Msgs::resetMessageStandardTagTypes(MsgTagType& tags) /****************************************/ /****************************************/ -bool p3Msgs::ChatSend(ChatInfo &ci) +bool p3Msgs::sendPublicChat(std::wstring msg) { /* send a message to all for now */ - if (ci.chatflags & RS_CHAT_PRIVATE) - { - mChatSrv -> sendPrivateChat(ci.msg, ci.rsid); - } - else - { - /* global */ - mChatSrv -> sendChat(ci.msg); - } - return true; + return mChatSrv -> sendPublicChat(msg); +} + +bool p3Msgs::sendPrivateChat(std::string id, std::wstring msg) +{ + /* send a message to peer */ + return mChatSrv -> sendPrivateChat(id, msg); } void p3Msgs::sendGroupChatStatusString(const std::string& status_string) @@ -159,9 +156,24 @@ void p3Msgs::sendStatusString(const std::string& peer_id,const std::string& stat mChatSrv->sendStatusString(peer_id,status_string); } -bool p3Msgs::getNewChat(std::list &chats) +int p3Msgs::getChatQueueCount(bool privateQueue) { - return mChatSrv->getChatQueue(chats); + return mChatSrv->getChatQueueCount(privateQueue); +} + +bool p3Msgs::getPublicChatQueue(std::list &chats) +{ + return mChatSrv->getPublicChatQueue(chats); +} + +bool p3Msgs::getPrivateChatQueueIds(std::list &ids) +{ + return mChatSrv->getPrivateChatQueueIds(ids); +} + +bool p3Msgs::getPrivateChatQueue(std::string id, std::list &chats) +{ + return mChatSrv->getPrivateChatQueue(id, chats); } void p3Msgs::getOwnAvatarData(unsigned char *& data,int& size) diff --git a/libretroshare/src/rsserver/p3msgs.h b/libretroshare/src/rsserver/p3msgs.h index e46f028f5..d9b926116 100644 --- a/libretroshare/src/rsserver/p3msgs.h +++ b/libretroshare/src/rsserver/p3msgs.h @@ -104,19 +104,38 @@ class p3Msgs: public RsMsgs virtual std::string getCustomStateString(const std::string& peer_id) ; - /****************************************/ - /* Chat */ /*! - * sends chat (public and private) - * @param ci chat info + * public chat sent to all peers */ - virtual bool ChatSend(ChatInfo &ci); + virtual bool sendPublicChat(std::wstring msg); /*! - * @param chats ref to list of received chats is stored here + * chat is sent to specifc peer + * @param id peer to send chat msg to */ - virtual bool getNewChat(std::list &chats); + virtual bool sendPrivateChat(std::string id, std::wstring msg); + /*! + * returns the count of messages in public or private queue + * @param public or private queue + */ + virtual int getChatQueueCount(bool privateQueue); + + /*! + * @param chats ref to list of received public chats is stored here + */ + virtual bool getPublicChatQueue(std::list &chats); + + /*! + * @param id's of available private chat messages + */ + virtual bool getPrivateChatQueueIds(std::list &ids); + + + /*! + * @param chats ref to list of received private chats is stored here + */ + virtual bool getPrivateChatQueue(std::string id, std::list &chats); /*! * sends immediate status string to a specific peer, e.g. in a private chat * @param peer_id peer to send status string to diff --git a/libretroshare/src/services/p3chatservice.cc b/libretroshare/src/services/p3chatservice.cc index 5d9a548ec..e23a85d50 100644 --- a/libretroshare/src/services/p3chatservice.cc +++ b/libretroshare/src/services/p3chatservice.cc @@ -66,7 +66,7 @@ int p3ChatService::status() /***************** Chat Stuff **********************/ -int p3ChatService::sendChat(std::wstring msg) +int p3ChatService::sendPublicChat(std::wstring &msg) { /* go through all the peers */ @@ -203,7 +203,7 @@ void p3ChatService::sendStatusString( const std::string& id , const std::string& sendItem(cs); } -int p3ChatService::sendPrivateChat( std::wstring msg, std::string id) +int p3ChatService::sendPrivateChat(std::string &id, std::wstring &msg) { // make chat item.... #ifdef CHAT_DEBUG @@ -283,7 +283,8 @@ int p3ChatService::sendPrivateChat( std::wstring msg, std::string id) void p3ChatService::receiveChatQueue() { - bool changed = false; + bool publicChanged = false; + bool privateChanged = false; time_t now = time(NULL); RsItem *item ; @@ -334,6 +335,7 @@ void p3ChatService::receiveChatQueue() } if ((ci->chatFlags & RS_CHAT_FLAG_PRIVATE) == 0) { + /* notify public chat message */ std::string message; message.assign(ci->message.begin(), ci->message.end()); getPqiNotify()->AddFeedItem(RS_FEED_ITEM_CHAT_NEW, ci->PeerId(), message, ""); @@ -343,10 +345,15 @@ void p3ChatService::receiveChatQueue() RsStackMutex stack(mChatMtx); /********** STACK LOCKED MTX ******/ ci->recvTime = now; - ilist.push_back(ci); // don't delete the item !! - } /* UNLOCK */ - changed = true; + if (ci->chatFlags & RS_CHAT_FLAG_PRIVATE) { + privateChanged = true; + privateList.push_back(ci); // don't delete the item !! + } else { + publicChanged = true; + publicList.push_back(ci); // don't delete the item !! + } + } /* UNLOCK */ } continue ; @@ -402,35 +409,121 @@ void p3ChatService::receiveChatQueue() } } - if (changed) { - rsicontrol->getNotify().notifyListChange(NOTIFY_LIST_CHAT, NOTIFY_TYPE_ADD); + if (publicChanged) { + rsicontrol->getNotify().notifyListChange(NOTIFY_LIST_PUBLIC_CHAT, NOTIFY_TYPE_ADD); + } + if (privateChanged) { + rsicontrol->getNotify().notifyListChange(NOTIFY_LIST_PRIVATE_CHAT, NOTIFY_TYPE_ADD); } } -bool p3ChatService::getChatQueue(std::list &chats) +int p3ChatService::getChatQueueCount(bool privateQueue) { - /* get any messages and push them to iface */ + RsStackMutex stack(mChatMtx); /********** STACK LOCKED MTX ******/ + + if (privateQueue) { + return privateList.size(); + } + + return publicList.size(); +} + +bool p3ChatService::getPublicChatQueue(std::list &chats) +{ + bool changed = false; + + { + RsStackMutex stack(mChatMtx); /********** STACK LOCKED MTX ******/ + + // get the items from the public list. + if (publicList.size() == 0) { + return false; + } + + std::list::iterator it; + while (publicList.size()) { + RsChatMsgItem *c = publicList.front(); + publicList.pop_front(); + + ChatInfo ci; + initRsChatInfo(c, ci); + chats.push_back(ci); + + changed = true; + + delete c; + } + } /* UNLOCKED */ + + if (changed) { + rsicontrol->getNotify().notifyListChange(NOTIFY_LIST_PUBLIC_CHAT, NOTIFY_TYPE_DEL); + } + + return true; +} + +bool p3ChatService::getPrivateChatQueueIds(std::list &ids) +{ + ids.clear(); RsStackMutex stack(mChatMtx); /********** STACK LOCKED MTX ******/ - // get the items from the list. - if (ilist.size() == 0) - { + // get the items from the private list. + if (privateList.size() == 0) { return false; } std::list::iterator it; - while (ilist.size()) - { - RsChatMsgItem *c = ilist.front(); - ilist.pop_front(); + for (it = privateList.begin(); it != privateList.end(); it++) { + RsChatMsgItem *c = *it; - ChatInfo ci; - initRsChatInfo(c, ci); - chats.push_back(ci); - - delete c; + if (std::find(ids.begin(), ids.end(), c->PeerId()) == ids.end()) { + ids.push_back(c->PeerId()); + } } + + return true; +} + +bool p3ChatService::getPrivateChatQueue(std::string id, std::list &chats) +{ + bool changed = false; + + { + RsStackMutex stack(mChatMtx); /********** STACK LOCKED MTX ******/ + + // get the items from the private list. + if (privateList.size() == 0) { + return false; + } + + std::list::iterator it = privateList.begin(); + while (it != privateList.end()) { + RsChatMsgItem *c = *it; + + if (c->PeerId() == id) { + ChatInfo ci; + initRsChatInfo(c, ci); + chats.push_back(ci); + + changed = true; + + delete c; + + std::list::iterator it1 = it; + it++; + privateList.erase(it1); + continue; + } + + it++; + } + } /* UNLOCKED */ + + if (changed) { + rsicontrol->getNotify().notifyListChange(NOTIFY_LIST_PRIVATE_CHAT, NOTIFY_TYPE_DEL); + } + return true; } diff --git a/libretroshare/src/services/p3chatservice.h b/libretroshare/src/services/p3chatservice.h index 7e88869ef..99f011534 100644 --- a/libretroshare/src/services/p3chatservice.h +++ b/libretroshare/src/services/p3chatservice.h @@ -61,13 +61,13 @@ class p3ChatService: public p3Service, public p3Config /*! * public chat sent to all peers */ - int sendChat(std::wstring msg); + int sendPublicChat(std::wstring &msg); /*! * chat is sent to specifc peer - * @param id peer to send caht msg to + * @param id peer to send chat msg to */ - int sendPrivateChat(std::wstring msg, std::string id); + int sendPrivateChat(std::string &id, std::wstring &msg); /*! * can be used to send 'immediate' status msgs, these status updates are meant for immediate use by peer (not saved by rs) @@ -117,9 +117,25 @@ class p3ChatService: public p3Service, public p3Config /*! - * This retrieves all chat msg items + * returns the count of messages in public or private queue + * @param public or private queue */ - bool getChatQueue(std::list &chats); + int getChatQueueCount(bool privateQueue); + + /*! + * This retrieves all public chat msg items + */ + bool getPublicChatQueue(std::list &chats); + + /*! + * @param id's of available private chat messages + */ + bool getPrivateChatQueueIds(std::list &ids); + + /*! + * This retrieves all private chat msg items for peer + */ + bool getPrivateChatQueue(std::string id, std::list &chats); /************* from p3Config *******************/ virtual RsSerialiser *setupSerialiser() ; @@ -163,7 +179,8 @@ class p3ChatService: public p3Service, public p3Config p3ConnectMgr *mConnMgr; - std::list ilist; + std::list publicList; + std::list privateList; AvatarInfo *_own_avatar ; std::map _avatars ; diff --git a/retroshare-gui/src/gui/MainWindow.cpp b/retroshare-gui/src/gui/MainWindow.cpp index ab78dd231..bd410f5c3 100644 --- a/retroshare-gui/src/gui/MainWindow.cpp +++ b/retroshare-gui/src/gui/MainWindow.cpp @@ -50,6 +50,7 @@ #include "ChannelFeed.h" #include "bwgraph/bwgraph.h" #include "help/browser/helpbrowser.h" +#include "chat/PopupChatDialog.h" #ifdef UNFINISHED #include "unfinished/ApplicationWindow.h" @@ -67,6 +68,7 @@ #include #include #include +#include #include "gui/connect/ConnectFriendWizard.h" #include "util/rsversion.h" @@ -398,6 +400,11 @@ void MainWindow::createTrayIcon() trayIconForums = new QSystemTrayIcon(this); trayIconForums->setIcon(QIcon(":/images/konversation16.png")); connect(trayIconForums, SIGNAL(activated(QSystemTrayIcon::ActivationReason)), this, SLOT(trayIconForumsClicked(QSystemTrayIcon::ActivationReason))); + + // Create the tray icon for chat + trayIconChat = new QSystemTrayIcon(this); + trayIconChat->setIcon(QIcon(":/images/chat.png")); + connect(trayIconChat, SIGNAL(activated(QSystemTrayIcon::ActivationReason)), this, SLOT(trayIconChatClicked(QSystemTrayIcon::ActivationReason))); } /*static*/ void MainWindow::installGroupChatNotifier() @@ -503,6 +510,21 @@ void MainWindow::updateStatus() } } +void MainWindow::privateChatChanged(int type) +{ + /* first process the chat messages */ + PopupChatDialog::privateChatChanged(); + + /* than count the chat messages */ + int chatCount = rsMsgs->getChatQueueCount(true); + + if (chatCount) { + trayIconChat->show(); + } else { + trayIconChat->hide(); + } +} + void MainWindow::updateHashingInfo(const QString& s) { if(s == "") @@ -766,7 +788,6 @@ void MainWindow::closeEvent(QCloseEvent *e) } - void MainWindow::updateMenu() { toggleVisibilityAction->setText(isVisible() ? tr("Hide") : tr("Show")); @@ -806,6 +827,21 @@ void MainWindow::trayIconForumsClicked(QSystemTrayIcon::ActivationReason e) } } +void MainWindow::trayIconChatClicked(QSystemTrayIcon::ActivationReason e) +{ + if(e == QSystemTrayIcon::Trigger || e == QSystemTrayIcon::DoubleClick) { + PopupChatDialog *pcd = NULL; + std::list ids; + if (rsMsgs->getPrivateChatQueueIds(ids) && ids.size()) { + pcd = PopupChatDialog::getPrivateChat(ids.front(), RS_CHAT_OPEN_NEW | RS_CHAT_REOPEN | RS_CHAT_FOCUS); + } + + if (pcd == NULL) { + showWindow(MainWindow::Friends); + } + } +} + void MainWindow::toggleVisibilitycontextmenu() { if (isVisible()) diff --git a/retroshare-gui/src/gui/MainWindow.h b/retroshare-gui/src/gui/MainWindow.h index f35eb9755..ffa691af2 100644 --- a/retroshare-gui/src/gui/MainWindow.h +++ b/retroshare-gui/src/gui/MainWindow.h @@ -141,6 +141,7 @@ public slots: void checkAndSetIdle(int idleTime); void updateMessages(); void updateForums(); + void privateChatChanged(int type); protected: /** Default Constructor */ @@ -160,6 +161,7 @@ private slots: void toggleVisibilitycontextmenu(); void trayIconMessagesClicked(QSystemTrayIcon::ActivationReason e); void trayIconForumsClicked(QSystemTrayIcon::ActivationReason e); + void trayIconChatClicked(QSystemTrayIcon::ActivationReason e); /** Toolbar fns. */ void addFriend(); @@ -223,6 +225,7 @@ private: QSystemTrayIcon *trayIcon; QSystemTrayIcon *trayIconMessages; QSystemTrayIcon *trayIconForums; + QSystemTrayIcon *trayIconChat; QAction *toggleVisibilityAction, *toolAct; QMenu *trayMenu; diff --git a/retroshare-gui/src/gui/MessengerWindow.cpp b/retroshare-gui/src/gui/MessengerWindow.cpp index 87507b67c..fccd490eb 100644 --- a/retroshare-gui/src/gui/MessengerWindow.cpp +++ b/retroshare-gui/src/gui/MessengerWindow.cpp @@ -460,6 +460,9 @@ void MessengerWindow::insertPeers() return; } + std::list privateChatIds; + rsMsgs->getPrivateChatQueueIds(privateChatIds); + rsPeers->getGPGAcceptedList(gpgFriends); std::string sOwnId = rsPeers->getGPGOwnId(); @@ -546,6 +549,7 @@ void MessengerWindow::insertPeers() //update the childs (ssl certs) bool gpg_connected = false; bool gpg_online = false; + bool gpg_hasPrivateChat = false; std::list sslContacts; rsPeers->getSSLChildListOfGPGId(detail.gpg_id, sslContacts); for(std::list::iterator sslIt = sslContacts.begin(); sslIt != sslContacts.end(); sslIt++) { @@ -598,6 +602,7 @@ void MessengerWindow::insertPeers() /* not displayed, used to find back the item */ //sslItem -> setText(1, QString::fromStdString(sslDetail.autoconnect)); + QIcon sslIcon; int i; if (sslDetail.state & RS_PEER_STATE_CONNECTED) { sslItem->setHidden(false); @@ -619,7 +624,7 @@ void MessengerWindow::insertPeers() #endif // MINIMAL_RSGUI /* change color and icon */ - sslItem -> setIcon(COLUMN_NAME,(QIcon(":/images/connect_established.png"))); + sslIcon = QIcon(":/images/connect_established.png"); QFont font; font.setBold(true); for(i = 0; i < COLUMN_COUNT; i++) { @@ -639,9 +644,9 @@ void MessengerWindow::insertPeers() } else { sslItem->setHidden(ui.actionHide_Offline_Friends->isChecked()); if (sslDetail.autoconnect !="Offline") { - sslItem -> setIcon(COLUMN_NAME, (QIcon(":/images/connect_creating.png"))); + sslIcon = QIcon(":/images/connect_creating.png"); } else { - sslItem -> setIcon(COLUMN_NAME, (QIcon(":/images/connect_no.png"))); + sslIcon = QIcon(":/images/connect_no.png"); } QFont font; @@ -652,6 +657,13 @@ void MessengerWindow::insertPeers() } } + if (std::find(privateChatIds.begin(), privateChatIds.end(), sslDetail.id) != privateChatIds.end()) { + // private chat is available + sslIcon = QIcon(":/images/chat.png"); + gpg_hasPrivateChat = true; + } + sslItem -> setIcon(COLUMN_NAME, sslIcon); + #ifdef PEERS_DEBUG std::cerr << "PeersDialog::insertPeers() inserting sslItem." << std::endl; #endif @@ -663,6 +675,7 @@ void MessengerWindow::insertPeers() } int i = 0; + QIcon gpgIcon; if (gpg_connected) { gpg_item->setHidden(false); //gpg_item -> setText(COLUMN_STATE, tr("Online")); // set to online regardless on update @@ -695,8 +708,7 @@ void MessengerWindow::insertPeers() QPixmap avatar ; avatar.loadFromData(data,size,"PNG") ; QIcon avatar_icon(avatar); - QSize av_icon_size(32, 32); - gpg_item-> setIcon(1, avatar_icon); + gpg_item-> setIcon(COLUMN_STATE, avatar_icon); delete[] data; } else { @@ -705,7 +717,7 @@ void MessengerWindow::insertPeers() switch (it->status) { case RS_STATUS_INACTIVE: - gpg_item -> setIcon(COLUMN_NAME,(QIcon(IMAGE_INACTIVE))); + gpgIcon = QIcon(IMAGE_INACTIVE); gpg_item -> setToolTip(COLUMN_NAME, tr("Peer Idle")); gpg_item->setData(COLUMN_NAME, ROLE_SORT, BuildStateSortString(bSortState, gpg_item->text(COLUMN_NAME), PEER_STATE_INACTIVE)); @@ -716,7 +728,7 @@ void MessengerWindow::insertPeers() break; case RS_STATUS_ONLINE: - gpg_item -> setIcon(COLUMN_NAME,(QIcon(IMAGE_ONLINE))); + gpgIcon = QIcon(IMAGE_ONLINE); gpg_item -> setToolTip(COLUMN_NAME, tr("Peer Online")); gpg_item->setData(COLUMN_NAME, ROLE_SORT, BuildStateSortString(bSortState, gpg_item->text(COLUMN_NAME), PEER_STATE_ONLINE)); @@ -727,7 +739,7 @@ void MessengerWindow::insertPeers() break; case RS_STATUS_AWAY: - gpg_item -> setIcon(COLUMN_NAME,(QIcon(IMAGE_AWAY))); + gpgIcon = QIcon(IMAGE_AWAY); gpg_item -> setToolTip(COLUMN_NAME, tr("Peer Away")); gpg_item->setData(COLUMN_NAME, ROLE_SORT, BuildStateSortString(bSortState, gpg_item->text(COLUMN_NAME), PEER_STATE_AWAY)); @@ -738,7 +750,7 @@ void MessengerWindow::insertPeers() break; case RS_STATUS_BUSY: - gpg_item -> setIcon(COLUMN_NAME,(QIcon(IMAGE_BUSY))); + gpgIcon = QIcon(IMAGE_BUSY); gpg_item -> setToolTip(COLUMN_NAME, tr("Peer Busy")); gpg_item->setData(COLUMN_NAME, ROLE_SORT, BuildStateSortString(bSortState, gpg_item->text(COLUMN_NAME), PEER_STATE_BUSY)); @@ -754,7 +766,7 @@ void MessengerWindow::insertPeers() #endif // MINIMAL_RSGUI } else if (gpg_online) { gpg_item->setHidden(ui.actionHide_Offline_Friends->isChecked()); - gpg_item -> setIcon(COLUMN_NAME,(QIcon(IMAGE_AVAIBLE))); + gpgIcon = QIcon(IMAGE_AVAIBLE); gpg_item->setData(COLUMN_NAME, ROLE_SORT, BuildStateSortString(bSortState, gpg_item->text(COLUMN_NAME), PEER_STATE_ONLINE)); //gpg_item -> setText(COLUMN_STATE, tr("Available")); QFont font; @@ -765,7 +777,7 @@ void MessengerWindow::insertPeers() } } else { gpg_item->setHidden(ui.actionHide_Offline_Friends->isChecked()); - gpg_item -> setIcon(COLUMN_NAME,(QIcon(IMAGE_OFFLINE))); + gpgIcon = QIcon(IMAGE_OFFLINE); gpg_item->setData(COLUMN_NAME, ROLE_SORT, BuildStateSortString(bSortState, gpg_item->text(COLUMN_NAME), PEER_STATE_OFFLINE)); //gpg_item -> setText(COLUMN_STATE, tr("Offline")); QFont font; @@ -776,6 +788,12 @@ void MessengerWindow::insertPeers() } } + if (gpg_hasPrivateChat) { + gpgIcon = QIcon(":/images/chat.png"); + } + + gpg_item -> setIcon(COLUMN_NAME, gpgIcon); + /* add gpg item to the list. If item is already in the list, it won't be duplicated thanks to Qt */ peertreeWidget->addTopLevelItem(gpg_item); diff --git a/retroshare-gui/src/gui/PeersDialog.cpp b/retroshare-gui/src/gui/PeersDialog.cpp index dc5d2dc41..02d581f5f 100644 --- a/retroshare-gui/src/gui/PeersDialog.cpp +++ b/retroshare-gui/src/gui/PeersDialog.cpp @@ -500,6 +500,9 @@ void PeersDialog::insertPeers() bool bHideUnconnected = ui.action_Hide_Offline_Friends->isChecked(); + std::list privateChatIds; + rsMsgs->getPrivateChatQueueIds(privateChatIds); + rsPeers->getGPGAcceptedList(gpgFriends); //add own gpg id, if we have more than on location (ssl client) @@ -588,6 +591,7 @@ void PeersDialog::insertPeers() //update the childs (ssl certs) bool gpg_connected = false; bool gpg_online = false; + bool gpg_hasPrivateChat = false; std::list sslContacts; rsPeers->getSSLChildListOfGPGId(detail.gpg_id, sslContacts); for(std::list::iterator sslIt = sslContacts.begin(); sslIt != sslContacts.end(); sslIt++) { @@ -641,12 +645,13 @@ void PeersDialog::insertPeers() sslItem -> setData(COLUMN_STATE, ROLE_SORT, sText); /* change color and icon */ + QIcon sslIcon; int i; if (sslDetail.state & RS_PEER_STATE_CONNECTED) { sslItem->setHidden(false); gpg_connected = true; - sslItem -> setIcon(COLUMN_NAME,(QIcon(":/images/connect_established.png"))); + sslIcon = QIcon(":/images/connect_established.png"); sslItem -> setIcon(COLUMN_STATE,(QIcon(":/images/encrypted32.png"))); QFont font; font.setBold(true); @@ -667,9 +672,9 @@ void PeersDialog::insertPeers() } else { sslItem->setHidden(bHideUnconnected); if (sslDetail.autoconnect != "Offline") { - sslItem -> setIcon(COLUMN_NAME, (QIcon(":/images/connect_creating.png"))); + sslIcon = QIcon(":/images/connect_creating.png"); } else { - sslItem -> setIcon(COLUMN_NAME, (QIcon(":/images/connect_no.png"))); + sslIcon = QIcon(":/images/connect_no.png"); } QFont font; @@ -680,6 +685,13 @@ void PeersDialog::insertPeers() } } + if (std::find(privateChatIds.begin(), privateChatIds.end(), sslDetail.id) != privateChatIds.end()) { + // private chat is available + sslIcon = QIcon(":/images/chat.png"); + gpg_hasPrivateChat = true; + } + sslItem -> setIcon(COLUMN_NAME, sslIcon); + #ifdef PEERS_DEBUG std::cerr << "PeersDialog::insertPeers() inserting sslItem." << std::endl; #endif @@ -691,9 +703,10 @@ void PeersDialog::insertPeers() } int i = 0; + QIcon gpgIcon; if (gpg_connected) { gpg_item->setHidden(false); - gpg_item -> setIcon(COLUMN_NAME,(QIcon(IMAGE_ONLINE))); + gpgIcon = QIcon(IMAGE_ONLINE); gpg_item -> setText(COLUMN_STATE, tr("Online")); gpg_item -> setData(COLUMN_STATE, ROLE_SORT, BuildStateSortString(true, gpg_item->text(COLUMN_NAME), PEER_STATE_ONLINE)); @@ -764,7 +777,7 @@ void PeersDialog::insertPeers() } } else if (gpg_online) { gpg_item->setHidden(bHideUnconnected); - gpg_item -> setIcon(COLUMN_NAME,(QIcon(IMAGE_AVAIBLE))); + gpgIcon = QIcon(IMAGE_AVAIBLE); gpg_item -> setText(COLUMN_STATE, tr("Available")); gpg_item -> setData(COLUMN_STATE, ROLE_SORT, BuildStateSortString(true, gpg_item->text(COLUMN_NAME), PEER_STATE_AVAILABLE)); QFont font; @@ -775,7 +788,7 @@ void PeersDialog::insertPeers() } } else { gpg_item->setHidden(bHideUnconnected); - gpg_item -> setIcon(COLUMN_NAME,(QIcon(IMAGE_OFFLINE))); + gpgIcon = QIcon(IMAGE_OFFLINE); gpg_item -> setText(COLUMN_STATE, tr("Offline")); gpg_item -> setData(COLUMN_STATE, ROLE_SORT, BuildStateSortString(true, gpg_item->text(COLUMN_NAME), PEER_STATE_OFFLINE)); QFont font; @@ -786,6 +799,12 @@ void PeersDialog::insertPeers() } } + if (gpg_hasPrivateChat) { + gpgIcon = QIcon(":/images/chat.png"); + } + + gpg_item -> setIcon(COLUMN_NAME, gpgIcon); + if (bNew) { /* add gpg item to the list */ peertreeWidget->addTopLevelItem(gpg_item); @@ -1044,20 +1063,24 @@ void PeersDialog::updatePeersCustomStateString(const QString& peer_id) void PeersDialog::updatePeersAvatar(const QString& peer_id) { - #ifdef PEERS_DEBUG - std::cerr << "PeersDialog: Got notified of new avatar for peer " << peer_id.toStdString() << std::endl ; - #endif +#ifdef PEERS_DEBUG + std::cerr << "PeersDialog: Got notified of new avatar for peer " << peer_id.toStdString() << std::endl ; +#endif - PopupChatDialog *pcd = PopupChatDialog::getPrivateChat(peer_id.toStdString(),rsPeers->getPeerName(peer_id.toStdString()), 0); - pcd->updatePeerAvatar(peer_id.toStdString()); + PopupChatDialog *pcd = PopupChatDialog::getPrivateChat(peer_id.toStdString(), 0); + if (pcd) { + pcd->updatePeerAvatar(peer_id.toStdString()); + } } void PeersDialog::updatePeerStatusString(const QString& peer_id,const QString& status_string,bool is_private_chat) { if(is_private_chat) { - PopupChatDialog *pcd = PopupChatDialog::getPrivateChat(peer_id.toStdString(),rsPeers->getPeerName(peer_id.toStdString()), 0); - pcd->updateStatusString(peer_id, status_string); + PopupChatDialog *pcd = PopupChatDialog::getPrivateChat(peer_id.toStdString(), 0); + if (pcd) { + pcd->updateStatusString(peer_id, status_string); + } } else { @@ -1069,10 +1092,17 @@ void PeersDialog::updatePeerStatusString(const QString& peer_id,const QString& s } } +void PeersDialog::publicChatChanged(int type) +{ + if (type == NOTIFY_TYPE_ADD) { + insertChat(); + } +} + void PeersDialog::insertChat() { std::list newchat; - if (!rsMsgs->getNewChat(newchat)) + if (!rsMsgs->getPublicChatQueue(newchat)) { #ifdef PEERS_DEBUG std::cerr << "no chat available." << std::endl ; @@ -1085,8 +1115,6 @@ void PeersDialog::insertChat() QTextEdit *msgWidget = ui.msgText; std::list::iterator it; - uint chatflags = Settings->getChatFlags(); - /* add in lines at the bottom */ for(it = newchat.begin(); it != newchat.end(); it++) { @@ -1100,10 +1128,7 @@ void PeersDialog::insertChat() /* are they private? */ if (it->chatflags & RS_CHAT_PRIVATE) { - PopupChatDialog *pcd = PopupChatDialog::getPrivateChat(it->rsid, peer_name, chatflags); - pcd->addChatMsg(&(*it)); - playsound(); - QApplication::alert(pcd); + /* this should not happen */ continue; } @@ -1192,25 +1217,22 @@ void PeersDialog::sendMsg() { QTextEdit *lineWidget = ui.lineEdit; - ChatInfo ci; - //ci.msg = lineWidget->Text().toStdWString(); - ci.msg = lineWidget->toHtml().toStdWString(); - ci.chatflags = RS_CHAT_PUBLIC; + //ci.msg = lineWidget->Text().toStdWString(); + std::wstring message = lineWidget->toHtml().toStdWString(); //historyKeeper.addMessage("THIS", "ALL", lineWidget->toHtml() ); - std::string msg(ci.msg.begin(), ci.msg.end()); - #ifdef PEERS_DEBUG - std::cerr << "PeersDialog::sendMsg(): " << msg << std::endl; - #endif +#ifdef PEERS_DEBUG + std::string msg(ci.msg.begin(), ci.msg.end()); + std::cerr << "PeersDialog::sendMsg(): " << msg << std::endl; +#endif - rsMsgs -> ChatSend(ci); - ui.lineEdit->clear(); - setFont(); - - /* redraw send list */ - insertSendList(); + rsMsgs->sendPublicChat(message); + ui.lineEdit->clear(); + setFont(); + /* redraw send list */ + insertSendList(); } void PeersDialog::insertSendList() @@ -1668,64 +1690,35 @@ void PeersDialog::addAttachment(std::string filePath) { } } -void PeersDialog::fileHashingFinished(AttachFileItem* file) { - std::cerr << "PeersDialog::fileHashingFinished() started." << std::endl; +void PeersDialog::fileHashingFinished(AttachFileItem* file) +{ + std::cerr << "PeersDialog::fileHashingFinished() started." << std::endl; - //check that the file is ok tos end - if (file->getState() == AFI_STATE_ERROR) { - #ifdef PEERS_DEBUG - std::cerr << "PopupChatDialog::fileHashingFinished error file is not hashed." << std::endl; - #endif - return; - } - - ChatInfo ci; - - - { - rsiface->lockData(); /* Lock Interface */ - const RsConfig &conf = rsiface->getConfig(); - - ci.rsid = conf.ownId; - - rsiface->unlockData(); /* Unlock Interface */ - } - - //convert fileSize from uint_64 to string for html link -// char fileSizeChar [100]; -// sprintf(fileSizeChar, "%lld", file->FileSize()); -// std::string fileSize = *(&fileSizeChar); - - std::string mesgString = RetroShareLink(QString::fromStdString(file->FileName()), - file->FileSize(), - QString::fromStdString(file->FileHash())).toHtml().toStdString() ; - -// std::string mesgString = "" -// + "retroshare://file|" + (file->FileName()) + "|" + fileSize + "|" + (file->FileHash()) + ""; + //check that the file is ok tos end + if (file->getState() == AFI_STATE_ERROR) { #ifdef PEERS_DEBUG - std::cerr << "PeersDialog::fileHashingFinished mesgString : " << mesgString << std::endl; + std::cerr << "PopupChatDialog::fileHashingFinished error file is not hashed." << std::endl; +#endif + return; + } + + //convert fileSize from uint_64 to string for html link + // char fileSizeChar [100]; + // sprintf(fileSizeChar, "%lld", file->FileSize()); + // std::string fileSize = *(&fileSizeChar); + + std::string mesgString = RetroShareLink(QString::fromStdString(file->FileName()), + file->FileSize(), + QString::fromStdString(file->FileHash())).toHtml().toStdString() ; + + // std::string mesgString = "" + // + "retroshare://file|" + (file->FileName()) + "|" + fileSize + "|" + (file->FileHash()) + ""; +#ifdef PEERS_DEBUG + std::cerr << "PeersDialog::fileHashingFinished mesgString : " << mesgString << std::endl; #endif - const char * messageString = mesgString.c_str (); - - //convert char massageString to w_char - wchar_t* message; - size_t requiredSize = mbstowcs(NULL, messageString, 0); // C4996 - /* Add one to leave room for the NULL terminator */ - message = (wchar_t *)malloc( (requiredSize + 1) * sizeof( wchar_t )); - if (! message) { - std::cerr << ("Memory allocation failure.\n"); - } - size_t size = mbstowcs( message, messageString, requiredSize + 1); // C4996 - if (size == (size_t) (-1)) { - printf("Couldn't convert string--invalid multibyte character.\n"); - } - - ci.msg = message; - ci.chatflags = RS_CHAT_PUBLIC; - - rsMsgs -> ChatSend(ci); - setFont(); + rsMsgs->sendPublicChat(QString::fromStdString(mesgString).toStdWString()); + setFont(); } void PeersDialog::anchorClicked (const QUrl& link ) diff --git a/retroshare-gui/src/gui/PeersDialog.h b/retroshare-gui/src/gui/PeersDialog.h index c8e285cbf..665145905 100644 --- a/retroshare-gui/src/gui/PeersDialog.h +++ b/retroshare-gui/src/gui/PeersDialog.h @@ -70,6 +70,7 @@ public: public slots: void insertPeers(); + void publicChatChanged(int type); void toggleSendItem( QTreeWidgetItem *item, int col ); void insertChat(); @@ -173,7 +174,7 @@ private: class QSpacerItem *spacerItem; ///play the sound when recv a message - void playsound(); + void playsound(); QString fileName; diff --git a/retroshare-gui/src/gui/SendLinkDialog.cpp b/retroshare-gui/src/gui/SendLinkDialog.cpp index 7ac679cdd..2b137d6cb 100644 --- a/retroshare-gui/src/gui/SendLinkDialog.cpp +++ b/retroshare-gui/src/gui/SendLinkDialog.cpp @@ -65,12 +65,6 @@ void SendLinkDialog::insertHtmlText(std::string msg) void SendLinkDialog::sendLinktoChat() { - ChatInfo ci; - ci.msg = ui.linkText->toHtml().toStdWString(); - ci.chatflags = RS_CHAT_PUBLIC; - - rsMsgs -> ChatSend(ci); + rsMsgs->sendPublicChat(ui.linkText->toHtml().toStdWString()); close(); } - - diff --git a/retroshare-gui/src/gui/chat/PopupChatDialog.cpp b/retroshare-gui/src/gui/chat/PopupChatDialog.cpp index 14385f85d..41a46d826 100644 --- a/retroshare-gui/src/gui/chat/PopupChatDialog.cpp +++ b/retroshare-gui/src/gui/chat/PopupChatDialog.cpp @@ -32,6 +32,7 @@ #include #include #include +#include #include #include "PopupChatDialog.h" @@ -65,6 +66,25 @@ static std::map chatDialogs; +// play sound when recv a message +void playsound() +{ + Settings->beginGroup("Sound"); + Settings->beginGroup("SoundFilePath"); + QString OnlineSound = Settings->value("NewChatMessage","").toString(); + Settings->endGroup(); + Settings->beginGroup("Enable"); + bool flag = Settings->value("NewChatMessage",false).toBool(); + Settings->endGroup(); + Settings->endGroup(); + + if (!OnlineSound.isEmpty() && flag) { + if (QSound::isAvailable()) { + QSound::play(OnlineSound); + } + } +} + /** Default constructor */ PopupChatDialog::PopupChatDialog(std::string id, std::string name, QWidget *parent, Qt::WFlags flags) @@ -78,6 +98,7 @@ PopupChatDialog::PopupChatDialog(std::string id, std::string name, Settings->loadWidgetInformation(this); this->move(qrand()%100, qrand()%100); //avoid to stack multiple popup chat windows on the same position + m_bInsertOnVisible = true; loadEmoticons(); @@ -202,46 +223,49 @@ void PopupChatDialog::processSettings(bool bLoad) Settings->endGroup(); } -/*static*/ PopupChatDialog *PopupChatDialog::getPrivateChat(std::string id, std::string name, uint chatflags) +/*static*/ PopupChatDialog *PopupChatDialog::getPrivateChat(std::string id, uint chatflags) { - /* see if it exists already */ - PopupChatDialog *popupchatdialog = NULL; - bool show = false; + /* see if it exists already */ + PopupChatDialog *popupchatdialog = NULL; + bool show = false; - if (chatflags & RS_CHAT_REOPEN) - { + if (chatflags & RS_CHAT_REOPEN) + { show = true; - #ifdef PEERS_DEBUG +#ifdef PEERS_DEBUG std::cerr << "reopen flag so: enable SHOW popupchatdialog()" << std::endl; - #endif - } +#endif + } - std::map::iterator it; - if (chatDialogs.end() != (it = chatDialogs.find(id))) - { + std::map::iterator it; + if (chatDialogs.end() != (it = chatDialogs.find(id))) + { /* exists already */ popupchatdialog = it->second; - } - else - { - popupchatdialog = new PopupChatDialog(id, name); - chatDialogs[id] = popupchatdialog; + } + else + { if (chatflags & RS_CHAT_OPEN_NEW) { - #ifdef PEERS_DEBUG + RsPeerDetails sslDetails; + if (rsPeers->getPeerDetails(id, sslDetails)) { + popupchatdialog = new PopupChatDialog(id, sslDetails.name + " - " + sslDetails.location); + chatDialogs[id] = popupchatdialog; +#ifdef PEERS_DEBUG std::cerr << "new chat so: enable SHOW popupchatdialog()" << std::endl; - #endif +#endif show = true; + } } - } + } - if (show) - { - #ifdef PEERS_DEBUG + if (show && popupchatdialog) + { +#ifdef PEERS_DEBUG std::cerr << "SHOWING popupchatdialog()" << std::endl; - #endif +#endif if (popupchatdialog->isVisible() == false) { if (chatflags & RS_CHAT_FOCUS) { @@ -250,36 +274,36 @@ void PopupChatDialog::processSettings(bool bLoad) popupchatdialog->showMinimized(); } } - } + } - /* now only do these if the window is visible */ - if (popupchatdialog->isVisible()) - { - if (chatflags & RS_CHAT_FOCUS) - { - #ifdef PEERS_DEBUG - std::cerr << "focus chat flag so: GETFOCUS popupchatdialog()" << std::endl; - #endif + /* now only do these if the window is visible */ + if (popupchatdialog && popupchatdialog->isVisible()) + { + if (chatflags & RS_CHAT_FOCUS) + { +#ifdef PEERS_DEBUG + std::cerr << "focus chat flag so: GETFOCUS popupchatdialog()" << std::endl; +#endif - popupchatdialog->getfocus(); - } - else - { - #ifdef PEERS_DEBUG - std::cerr << "no focus chat flag so: FLASH popupchatdialog()" << std::endl; - #endif + popupchatdialog->getfocus(); + } + else + { +#ifdef PEERS_DEBUG + std::cerr << "no focus chat flag so: FLASH popupchatdialog()" << std::endl; +#endif - popupchatdialog->flash(); - } - } - else - { - #ifdef PEERS_DEBUG + popupchatdialog->flash(); + } + } + else + { +#ifdef PEERS_DEBUG std::cerr << "not visible ... so leave popupchatdialog()" << std::endl; - #endif - } +#endif + } - return popupchatdialog; + return popupchatdialog; } /*static*/ void PopupChatDialog::cleanupChat() @@ -294,6 +318,28 @@ void PopupChatDialog::processSettings(bool bLoad) chatDialogs.clear(); } +/*static*/ void PopupChatDialog::privateChatChanged() +{ + std::list ids; + if (!rsMsgs->getPrivateChatQueueIds(ids)) { +#ifdef PEERS_DEBUG + std::cerr << "no chat available." << std::endl ; +#endif + return; + } + + uint chatflags = Settings->getChatFlags(); + + std::list::iterator id; + for (id = ids.begin(); id != ids.end(); id++) { + PopupChatDialog *pcd = getPrivateChat(*id, chatflags); + + if (pcd) { + pcd->insertChatMsgs(); + } + } +} + void PopupChatDialog::chatFriend(std::string id) { if (id.empty()){ @@ -316,14 +362,14 @@ void PopupChatDialog::chatFriend(std::string id) if (rsPeers->getPeerDetails(*it, sslDetails)) { if (sslDetails.state & RS_PEER_STATE_CONNECTED) { oneLocationConnected = true; - getPrivateChat(*it, sslDetails.name + " - " + sslDetails.location, RS_CHAT_REOPEN | RS_CHAT_FOCUS); + getPrivateChat(*it, RS_CHAT_OPEN_NEW | RS_CHAT_REOPEN | RS_CHAT_FOCUS); } } } } else { if (detail.state & RS_PEER_STATE_CONNECTED) { oneLocationConnected = true; - getPrivateChat(id, detail.name + " - " + detail.location, RS_CHAT_REOPEN | RS_CHAT_FOCUS); + getPrivateChat(id, RS_CHAT_OPEN_NEW | RS_CHAT_REOPEN | RS_CHAT_FOCUS); } } @@ -426,6 +472,13 @@ void PopupChatDialog::flash() } +void PopupChatDialog::showEvent(QShowEvent *event) +{ + if (m_bInsertOnVisible) { + insertChatMsgs(); + } +} + void PopupChatDialog::closeEvent (QCloseEvent * event) { Settings->saveWidgetInformation(this); @@ -442,74 +495,95 @@ void PopupChatDialog::updateChat() } -void PopupChatDialog::addChatMsg(ChatInfo *ci) +void PopupChatDialog::insertChatMsgs() { + if (isVisible() == false) { + m_bInsertOnVisible = true; + return; + } - { - RsPeerDetails detail; - if (!rsPeers->getPeerDetails(dialogId, detail)) - { -#ifdef CHAT_DEBUG - std::cerr << "WARNING CANNOT GET PEER INFO!!!!" << std::endl; + m_bInsertOnVisible = false; + + std::list newchat; + if (!rsMsgs->getPrivateChatQueue(dialogId, newchat)) + { +#ifdef PEERS_DEBUG + std::cerr << "no chat for " << dialogId << " available." << std::endl ; #endif - } + return; + } - } - - QString timestamp = "[" + QDateTime::currentDateTime().toString("hh:mm:ss") + "]"; - QString name = QString::fromStdString(rsPeers->getPeerName(ci->rsid)); - QString message = QString::fromStdWString(ci -> msg); - - //replace http://, https:// and www. with links - QRegExp rx("(retroshare://[^ <>]*)|(https?://[^ <>]*)|(www\\.[^ <>]*)"); - int count = 0; - int pos = 100; //ignore the first 100 char because of the standard DTD ref - while ( (pos = rx.indexIn(message, pos)) != -1 ) { - //we need to look ahead to see if it's already a well formed link - if (message.mid(pos - 6, 6) != "href=\"" && message.mid(pos - 6, 6) != "href='" && message.mid(pos - 6, 6) != "ttp://" ) { - QString tempMessg = message.left(pos) + "" + rx.cap(count) + "" + message.mid(pos + rx.matchedLength(), -1); - message = tempMessg; - } - pos += rx.matchedLength() + 15; - count ++; + std::list::iterator it; + for(it = newchat.begin(); it != newchat.end(); it++) { + /* are they public? */ + if ((it->chatflags & RS_CHAT_PRIVATE) == 0) { + /* this should not happen */ + continue; } + addChatMsg(it->rsid, it->msg); + } + + playsound(); + QApplication::alert(this); +} + +void PopupChatDialog::addChatMsg(std::string &id, std::wstring &msg) +{ + QString timestamp = "[" + QDateTime::currentDateTime().toString("hh:mm:ss") + "]"; + QString name = QString::fromStdString(rsPeers->getPeerName(id)); + QString message = QString::fromStdWString(msg); + + //replace http://, https:// and www. with links + QRegExp rx("(retroshare://[^ <>]*)|(https?://[^ <>]*)|(www\\.[^ <>]*)"); + int count = 0; + int pos = 100; //ignore the first 100 char because of the standard DTD ref + while ( (pos = rx.indexIn(message, pos)) != -1 ) { + //we need to look ahead to see if it's already a well formed link + if (message.mid(pos - 6, 6) != "href=\"" && message.mid(pos - 6, 6) != "href='" && message.mid(pos - 6, 6) != "ttp://" ) { + QString tempMessg = message.left(pos) + "" + rx.cap(count) + "" + message.mid(pos + rx.matchedLength(), -1); + message = tempMessg; + } + pos += rx.matchedLength() + 15; + count ++; + } + #ifdef CHAT_DEBUG -std::cout << "PopupChatDialog:addChatMsg message : " << message.toStdString() << std::endl; + std::cout << "PopupChatDialog:addChatMsg message : " << message.toStdString() << std::endl; #endif - if (Settings->valueFromGroup(QString("Chat"), QString::fromUtf8("Emoteicons_PrivatChat"), true).toBool()) - { + if (Settings->valueFromGroup(QString("Chat"), QString::fromUtf8("Emoteicons_PrivatChat"), true).toBool()) + { QHashIterator i(smileys); while(i.hasNext()) { - i.next(); - foreach(QString code, i.key().split("|")) - message.replace(code, ""); + i.next(); + foreach(QString code, i.key().split("|")) + message.replace(code, ""); } - } - history /*<< nickColor << color << font << fontSize*/ << timestamp << name << message; - - - QString formatMsg = loadEmptyStyle()/*.replace(nickColor) + } + history /*<< nickColor << color << font << fontSize*/ << timestamp << name << message; + + + QString formatMsg = loadEmptyStyle()/*.replace(nickColor) .replace(color) .replace(font) .replace(fontSize)*/ - .replace("%timestamp%", timestamp) - .replace("%name%", name) - .replace("%message%", message); - + .replace("%timestamp%", timestamp) + .replace("%name%", name) + .replace("%message%", message); - if ((ui.textBrowser->verticalScrollBar()->maximum() - 30) < ui.textBrowser->verticalScrollBar()->value() ) { - ui.textBrowser->append(formatMsg + "\n"); - } else { - //the vertical scroll is not at the bottom, so just update the text, the scroll will stay at the current position - int scroll = ui.textBrowser->verticalScrollBar()->value(); - ui.textBrowser->setHtml(ui.textBrowser->toHtml() + formatMsg + "\n"); - ui.textBrowser->verticalScrollBar()->setValue(scroll); - ui.textBrowser->update(); - } - resetStatusBar() ; + + if ((ui.textBrowser->verticalScrollBar()->maximum() - 30) < ui.textBrowser->verticalScrollBar()->value() ) { + ui.textBrowser->append(formatMsg + "\n"); + } else { + //the vertical scroll is not at the bottom, so just update the text, the scroll will stay at the current position + int scroll = ui.textBrowser->verticalScrollBar()->value(); + ui.textBrowser->setHtml(ui.textBrowser->toHtml() + formatMsg + "\n"); + ui.textBrowser->verticalScrollBar()->setValue(scroll); + ui.textBrowser->update(); + } + resetStatusBar() ; } void PopupChatDialog::checkChat() @@ -527,36 +601,32 @@ void PopupChatDialog::checkChat() void PopupChatDialog::sendChat() { - QTextEdit *chatWidget = ui.chattextEdit; + QTextEdit *chatWidget = ui.chattextEdit; - ChatInfo ci; + std::string ownId; - { - rsiface->lockData(); /* Lock Interface */ - const RsConfig &conf = rsiface->getConfig(); + { + rsiface->lockData(); /* Lock Interface */ + const RsConfig &conf = rsiface->getConfig(); - ci.rsid = conf.ownId; + ownId = conf.ownId; - rsiface->unlockData(); /* Unlock Interface */ - } + rsiface->unlockData(); /* Unlock Interface */ + } - ci.msg = chatWidget->toHtml().toStdWString(); - ci.chatflags = RS_CHAT_PRIVATE; + std::wstring msg = chatWidget->toHtml().toStdWString(); #ifdef CHAT_DEBUG -std::cout << "PopupChatDialog:sendChat " << styleHtm.toStdString() << std::endl; + std::cout << "PopupChatDialog:sendChat " << styleHtm.toStdString() << std::endl; #endif - addChatMsg(&ci); + addChatMsg(ownId, msg); - /* put proper destination */ - ci.rsid = dialogId; + rsMsgs->sendPrivateChat(dialogId, msg); + chatWidget->clear(); + setFont(); - rsMsgs -> ChatSend(ci); - chatWidget ->clear(); - setFont(); - - /* redraw send list */ + /* redraw send list */ } /** @@ -982,53 +1052,48 @@ void PopupChatDialog::addAttachment(std::string filePath,int flag) void PopupChatDialog::fileHashingFinished(AttachFileItem* file) { - std::cerr << "PopupChatDialog::fileHashingFinished() started."; - std::cerr << std::endl; + std::cerr << "PopupChatDialog::fileHashingFinished() started."; + std::cerr << std::endl; - //check that the file is ok tos end - if (file->getState() == AFI_STATE_ERROR) { - #ifdef CHAT_DEBUG - std::cerr << "PopupChatDialog::fileHashingFinished error file is not hashed."; - #endif - return; - } + //check that the file is ok tos end + if (file->getState() == AFI_STATE_ERROR) { +#ifdef CHAT_DEBUG + std::cerr << "PopupChatDialog::fileHashingFinished error file is not hashed."; +#endif + return; + } - ChatInfo ci; + std::string ownId; - { - rsiface->lockData(); /* Lock Interface */ - const RsConfig &conf = rsiface->getConfig(); + { + rsiface->lockData(); /* Lock Interface */ + const RsConfig &conf = rsiface->getConfig(); - ci.rsid = conf.ownId; + ownId = conf.ownId; + + rsiface->unlockData(); /* Unlock Interface */ + } + + QString message; - rsiface->unlockData(); /* Unlock Interface */ - } - - QString message; - if(file->getPicFlag()==1){ - message+="FilePath().c_str(); - message+="\" width=\"100\" height=\"100\">"; + message+="FilePath().c_str(); + message+="\" width=\"100\" height=\"100\">"; message+="
"; - } + } message+= RetroShareLink(QString::fromStdString(file->FileName()),file->FileSize(),QString::fromStdString(file->FileHash())).toHtmlSize(); #ifdef CHAT_DEBUG - std::cerr << "PopupChatDialog::anchorClicked message : " << message.toStdString() << std::endl; + std::cerr << "PopupChatDialog::anchorClicked message : " << message.toStdString() << std::endl; #endif + std::wstring msg = message.toStdWString(); - ci.msg = message.toStdWString(); - ci.chatflags = RS_CHAT_PRIVATE; + addChatMsg(ownId, msg); - addChatMsg(&ci); - - /* put proper destination */ - ci.rsid = dialogId; - - rsMsgs -> ChatSend(ci); + rsMsgs->sendPrivateChat(dialogId, msg); } void PopupChatDialog::anchorClicked (const QUrl& link ) diff --git a/retroshare-gui/src/gui/chat/PopupChatDialog.h b/retroshare-gui/src/gui/chat/PopupChatDialog.h index 992bd48ad..cf168016a 100644 --- a/retroshare-gui/src/gui/chat/PopupChatDialog.h +++ b/retroshare-gui/src/gui/chat/PopupChatDialog.h @@ -36,23 +36,14 @@ class PopupChatDialog : public QMainWindow Q_OBJECT public: - static PopupChatDialog *getPrivateChat(std::string id, std::string name, uint chatflags); + static PopupChatDialog *getPrivateChat(std::string id, uint chatflags); static void cleanupChat(); static void chatFriend(std::string id); static void updateAllAvatars(); + static void privateChatChanged(); void updateChat(); void updatePeerAvatar(const std::string&); - void addChatMsg(ChatInfo *ci); - - void loadEmoticons(); - void loadEmoticons2(); - - void updateAvatar(); - - QString loadEmptyStyle(); - QPixmap picture; - public slots: /** Overloaded QWidget.show */ @@ -84,9 +75,20 @@ protected: ~PopupChatDialog(); void closeEvent (QCloseEvent * event); + void showEvent (QShowEvent * event); virtual void dragEnterEvent(QDragEnterEvent *event); virtual void dropEvent(QDropEvent *event); + void insertChatMsgs(); + void addChatMsg(std::string &id, std::wstring &msg); + + void loadEmoticons(); + void loadEmoticons2(); + + void updateAvatar(); + + QString loadEmptyStyle(); + QPixmap picture; private slots: void addExtraFile(); @@ -135,7 +137,9 @@ private: QStringList history; QString wholeChat; QString fileName; - + + bool m_bInsertOnVisible; + /** Qt Designer generated object */ Ui::PopupChatDialog ui; diff --git a/retroshare-gui/src/gui/notifyqt.cpp b/retroshare-gui/src/gui/notifyqt.cpp index a22da9173..6cfb4f673 100644 --- a/retroshare-gui/src/gui/notifyqt.cpp +++ b/retroshare-gui/src/gui/notifyqt.cpp @@ -226,11 +226,17 @@ void NotifyQt::notifyListChange(int list, int type) #endif emit forumsChanged(); // use connect with Qt::QueuedConnection break; - case NOTIFY_LIST_CHAT: + case NOTIFY_LIST_PUBLIC_CHAT: #ifdef NOTIFY_DEBUG - std::cerr << "received chat changed" << std::endl ; + std::cerr << "received public chat changed" << std::endl ; #endif - emit chatChanged(); + emit publicChatChanged(type); + break; + case NOTIFY_LIST_PRIVATE_CHAT: +#ifdef NOTIFY_DEBUG + std::cerr << "received private chat changed" << std::endl ; +#endif + emit privateChatChanged(type); break; default: break; diff --git a/retroshare-gui/src/gui/notifyqt.h b/retroshare-gui/src/gui/notifyqt.h index 68d63bad7..5f7ac3b37 100644 --- a/retroshare-gui/src/gui/notifyqt.h +++ b/retroshare-gui/src/gui/notifyqt.h @@ -72,7 +72,8 @@ class NotifyQt: public QObject, public NotifyBase void diskFull(int,int) const ; void peerStatusChanged(const QString& /* peer_id */, int /* status */); void peerStatusChangedSummary() const; - void chatChanged() const ; + void publicChatChanged(int type) const ; + void privateChatChanged(int type) const ; public slots: diff --git a/retroshare-gui/src/main.cpp b/retroshare-gui/src/main.cpp index 4dbf7fa8e..f459ccdd3 100644 --- a/retroshare-gui/src/main.cpp +++ b/retroshare-gui/src/main.cpp @@ -181,7 +181,8 @@ int main(int argc, char *argv[]) QObject::connect(notify,SIGNAL(filesPostModChanged(bool)) ,w ,SLOT(postModDirectories(bool) )) ; QObject::connect(notify,SIGNAL(transfersChanged()) ,w->transfersDialog ,SLOT(insertTransfers() )) ; QObject::connect(notify,SIGNAL(friendsChanged()) ,w->peersDialog ,SLOT(insertPeers() )) ; - QObject::connect(notify,SIGNAL(chatChanged()) ,w->peersDialog ,SLOT(insertChat() )); + QObject::connect(notify,SIGNAL(publicChatChanged(int)) ,w->peersDialog ,SLOT(publicChatChanged(int) )); + QObject::connect(notify,SIGNAL(privateChatChanged(int)) ,w ,SLOT(privateChatChanged(int) )); QObject::connect(notify,SIGNAL(neighborsChanged()) ,w->networkDialog ,SLOT(insertConnect() )) ; QObject::connect(notify,SIGNAL(messagesChanged()) ,w->messagesDialog ,SLOT(insertMessages() )) ; QObject::connect(notify,SIGNAL(messagesTagsChanged()) ,w->messagesDialog ,SLOT(messagesTagsChanged() )) ;