diff --git a/RetroShare.pro b/RetroShare.pro index cc99ed775..43ebc6f68 100644 --- a/RetroShare.pro +++ b/RetroShare.pro @@ -1,5 +1,7 @@ TEMPLATE = subdirs +CONFIG += ordered + SUBDIRS += \ openpgpsdk/src/openpgpsdk.pro \ supportlibs/pegmarkdown/pegmarkdown.pro \ diff --git a/libretroshare/src/chat/distantchat.cc b/libretroshare/src/chat/distantchat.cc index 6c2853bb6..7782380f8 100644 --- a/libretroshare/src/chat/distantchat.cc +++ b/libretroshare/src/chat/distantchat.cc @@ -293,7 +293,7 @@ void DistantChatService::removeVirtualPeer(const TurtleFileHash& hash,const Turt if(tunnel_dn) { - RsServer::notify()->notifyChatStatus(virtual_peer_id.toStdString(),"tunnel is down...",true) ; + RsServer::notify()->notifyChatStatus(ChatId(RsGxsId(virtual_peer_id)),"tunnel is down...") ; RsServer::notify()->notifyPeerStatusChanged(virtual_peer_id.toStdString(),RS_STATUS_OFFLINE) ; } } diff --git a/libretroshare/src/chat/distributedchat.cc b/libretroshare/src/chat/distributedchat.cc index 3f119ca52..18d9f0eb9 100644 --- a/libretroshare/src/chat/distributedchat.cc +++ b/libretroshare/src/chat/distributedchat.cc @@ -896,7 +896,7 @@ bool DistributedChatService::locked_initLobbyBouncableObject(const ChatLobbyId& return true ; } -bool DistributedChatService::sendLobbyChat(const RsPeerId &id, const std::string& msg, const ChatLobbyId& lobby_id) +bool DistributedChatService::sendLobbyChat(const ChatLobbyId& lobby_id, const std::string& msg) { #ifdef CHAT_DEBUG std::cerr << "Sending chat lobby message to lobby " << std::hex << lobby_id << std::dec << std::endl; @@ -923,7 +923,17 @@ bool DistributedChatService::sendLobbyChat(const RsPeerId &id, const std::string RsPeerId ownId = rsPeers->getOwnId(); - mHistMgr->addMessage(false, id, ownId, &item); + ChatMessage message; + message.chatflags = 0; + message.chat_id = ChatId(lobby_id); + message.msg = msg; + message.lobby_peer_nickname = item.nick; + message.recvTime = item.recvTime; + message.sendTime = item.sendTime; + message.incoming = false; + message.online = true; + RsServer::notify()->notifyChatMessage(message); + mHistMgr->addMessage(message); bounceLobbyObject(&item, ownId) ; diff --git a/libretroshare/src/chat/distributedchat.h b/libretroshare/src/chat/distributedchat.h index 80eabe00a..9854fb48e 100644 --- a/libretroshare/src/chat/distributedchat.h +++ b/libretroshare/src/chat/distributedchat.h @@ -91,7 +91,7 @@ class DistributedChatService bool locked_checkAndRebuildPartialLobbyMessage(RsChatLobbyMsgItem *) ; void checkSizeAndSendLobbyMessage(RsChatLobbyMsgItem *) ; - bool sendLobbyChat(const RsPeerId &id, const std::string&, const ChatLobbyId&) ; + bool sendLobbyChat(const ChatLobbyId &lobby_id, const std::string&) ; bool handleRecvChatLobbyMsgItem(RsChatMsgItem *item) ; private: diff --git a/libretroshare/src/chat/p3chatservice.cc b/libretroshare/src/chat/p3chatservice.cc index c34ce69f8..ee5531805 100644 --- a/libretroshare/src/chat/p3chatservice.cc +++ b/libretroshare/src/chat/p3chatservice.cc @@ -91,14 +91,9 @@ int p3ChatService::tick() return 0; } -int p3ChatService::status() -{ - return 1; -} - /***************** Chat Stuff **********************/ -int p3ChatService::sendPublicChat(const std::string &msg) +void p3ChatService::sendPublicChat(const std::string &msg) { /* go through all the peers */ @@ -133,12 +128,16 @@ int p3ChatService::sendPublicChat(const std::string &msg) #endif if (*it == ownId) { - mHistoryMgr->addMessage(false, RsPeerId(), ownId, ci); + //mHistoryMgr->addMessage(false, RsPeerId(), ownId, ci); + ChatMessage message; + initChatMessage(ci, message); + message.incoming = false; + message.online = true; + RsServer::notify()->notifyChatMessage(message); + mHistoryMgr->addMessage(message); } sendItem(ci); } - - return 1; } @@ -212,25 +211,36 @@ void p3ChatService::sendGroupChatStatusString(const std::string& status_string) } } -void p3ChatService::sendStatusString( const RsPeerId& id , const std::string& status_string) +void p3ChatService::sendStatusString(const ChatId& id , const std::string& status_string) { - ChatLobbyId lobby_id ; - if(isLobbyId(id,lobby_id)) - sendLobbyStatusString(lobby_id,status_string) ; - else + if(id.isLobbyId()) + sendLobbyStatusString(id.toLobbyId(),status_string) ; + else if(id.isBroadcast()) + sendGroupChatStatusString(status_string); + else if(id.isPeerId() || id.isGxsId()) { RsChatStatusItem *cs = new RsChatStatusItem ; cs->status_string = status_string ; cs->flags = RS_CHAT_FLAG_PRIVATE ; - cs->PeerId(id); + RsPeerId vpid; + if(id.isGxsId()) + vpid = RsPeerId(id.toGxsId()); + else + vpid = id.toPeerId(); + cs->PeerId(vpid); #ifdef CHAT_DEBUG std::cerr << "sending chat status packet:" << std::endl ; cs->print(std::cerr) ; #endif sendChatItem(cs); - } + } + else + { + std::cerr << "p3ChatService::sendStatusString() Error: chat id of this type is not handled, is it empty?" << std::endl; + return; + } } void p3ChatService::sendChatItem(RsChatItem *item) @@ -275,116 +285,134 @@ void p3ChatService::checkSizeAndSendMessage(RsChatMsgItem *msg) bool p3ChatService::isOnline(const RsPeerId& pid) { // check if the id is a tunnel id or a peer id. - uint32_t status ; - if(getDistantChatStatus(RsGxsId(pid),status)) return status == RS_DISTANT_CHAT_STATUS_CAN_TALK ; - else - return mServiceCtrl->isPeerConnected(getServiceInfo().mServiceType, pid); + else + return mServiceCtrl->isPeerConnected(getServiceInfo().mServiceType, pid); } -bool p3ChatService::sendPrivateChat(const RsPeerId &id, const std::string &msg) +bool p3ChatService::sendChat(ChatId destination, std::string msg) { - // look into ID. Is it a peer, or a chat lobby? - - ChatLobbyId lobby_id ; - - if(isLobbyId(id,lobby_id)) - return sendLobbyChat(id,msg,lobby_id) ; - - // make chat item.... + if(destination.isLobbyId()) + return DistributedChatService::sendLobbyChat(destination.toLobbyId(), msg); + else if(destination.isBroadcast()) + { + sendPublicChat(msg); + return true; + } + else if(destination.isPeerId()==false && destination.isGxsId()==false) + { + std::cerr << "p3ChatService::sendChat() Error: chat id type not handled. Is it empty?" << std::endl; + return false; + } + // destination is peer or distant #ifdef CHAT_DEBUG - std::cerr << "p3ChatService::sendPrivateChat()"; - std::cerr << std::endl; + std::cerr << "p3ChatService::sendChat()"; + std::cerr << std::endl; #endif - RsChatMsgItem *ci = new RsChatMsgItem(); + RsPeerId vpid; + if(destination.isGxsId()) + vpid = RsPeerId(destination.toGxsId()); // convert to virtual peer id + else + vpid = destination.toPeerId(); - ci->PeerId(id); - ci->chatFlags = RS_CHAT_FLAG_PRIVATE; - ci->sendTime = time(NULL); - ci->recvTime = ci->sendTime; - ci->message = msg; + RsChatMsgItem *ci = new RsChatMsgItem(); + ci->PeerId(vpid); + ci->chatFlags = RS_CHAT_FLAG_PRIVATE; + ci->sendTime = time(NULL); + ci->recvTime = ci->sendTime; + ci->message = msg; - if(!isOnline(id)) - { - /* peer is offline, add to outgoing list */ - { - RsStackMutex stack(mChatMtx); /********** STACK LOCKED MTX ******/ - privateOutgoingList.push_back(ci); - } + ChatMessage message; + initChatMessage(ci, message); + message.incoming = false; + message.online = true; - RsServer::notify()->notifyListChange(NOTIFY_LIST_PRIVATE_OUTGOING_CHAT, NOTIFY_TYPE_ADD); + if(!isOnline(vpid)) + { + /* peer is offline, add to outgoing list */ + { + RsStackMutex stack(mChatMtx); /********** STACK LOCKED MTX ******/ + privateOutgoingList.push_back(ci); + } - IndicateConfigChanged(); + message.online = false; + RsServer::notify()->notifyChatMessage(message); - return false; - } + // use the history to load pending messages to the gui + // this is not very nice, because the user may think the message was send, while it is still in the queue + mHistoryMgr->addMessage(message); - { - RsStackMutex stack(mChatMtx); /********** STACK LOCKED MTX ******/ - std::map::iterator it = _avatars.find(id) ; + IndicateConfigChanged(); + return false; + } - if(it == _avatars.end()) - { - _avatars[id] = new AvatarInfo ; - it = _avatars.find(id) ; - } - if(it->second->_own_is_new) - { + { + RsStackMutex stack(mChatMtx); /********** STACK LOCKED MTX ******/ + std::map::iterator it = _avatars.find(vpid) ; + + if(it == _avatars.end()) + { + _avatars[vpid] = new AvatarInfo ; + it = _avatars.find(vpid) ; + } + if(it->second->_own_is_new) + { #ifdef CHAT_DEBUG - std::cerr << "p3ChatService::sendPrivateChat: new avatar never sent to peer " << id << ". Setting flag to packet." << std::endl; + std::cerr << "p3ChatService::sendChat: new avatar never sent to peer " << id << ". Setting flag to packet." << std::endl; #endif - ci->chatFlags |= RS_CHAT_FLAG_AVATAR_AVAILABLE ; - it->second->_own_is_new = false ; - } - } + ci->chatFlags |= RS_CHAT_FLAG_AVATAR_AVAILABLE ; + it->second->_own_is_new = false ; + } + } #ifdef CHAT_DEBUG - std::cerr << "Sending msg to peer " << id << ", flags = " << ci->chatFlags << std::endl ; - std::cerr << "p3ChatService::sendPrivateChat() Item:"; - std::cerr << std::endl; - ci->print(std::cerr); - std::cerr << std::endl; + std::cerr << "Sending msg to (maybe virtual) peer " << id << ", flags = " << ci->chatFlags << std::endl ; + std::cerr << "p3ChatService::sendChat() Item:"; + std::cerr << std::endl; + ci->print(std::cerr); + std::cerr << std::endl; #endif - mHistoryMgr->addMessage(false, id, mServiceCtrl->getOwnId(), ci); + RsServer::notify()->notifyChatMessage(message); + mHistoryMgr->addMessage(message); checkSizeAndSendMessage(ci); - // Check if custom state string has changed, in which case it should be sent to the peer. - bool should_send_state_string = false ; - { - RsStackMutex stack(mChatMtx); /********** STACK LOCKED MTX ******/ + // Check if custom state string has changed, in which case it should be sent to the peer. + bool should_send_state_string = false ; + { + RsStackMutex stack(mChatMtx); /********** STACK LOCKED MTX ******/ - std::map::iterator it = _state_strings.find(id) ; + std::map::iterator it = _state_strings.find(vpid) ; - if(it == _state_strings.end()) - { - _state_strings[id] = StateStringInfo() ; - it = _state_strings.find(id) ; - it->second._own_is_new = true ; - } - if(it->second._own_is_new) - { - should_send_state_string = true ; - it->second._own_is_new = false ; - } - } + if(it == _state_strings.end()) + { + _state_strings[vpid] = StateStringInfo() ; + it = _state_strings.find(vpid) ; + it->second._own_is_new = true ; + } + if(it->second._own_is_new) + { + should_send_state_string = true ; + it->second._own_is_new = false ; + } + } - if(should_send_state_string) - { + if(should_send_state_string) + { #ifdef CHAT_DEBUG - std::cerr << "own status string is new for peer " << id << ": sending it." << std::endl ; + std::cerr << "own status string is new for peer " << id << ": sending it." << std::endl ; #endif - RsChatStatusItem *cs = makeOwnCustomStateStringItem() ; - cs->PeerId(id) ; - sendChatItem(cs) ; - } + RsChatStatusItem *cs = makeOwnCustomStateStringItem() ; + cs->PeerId(vpid) ; + sendChatItem(cs) ; + } - return true; + return true; } bool p3ChatService::locked_checkAndRebuildPartialMessage(RsChatMsgItem *ci) @@ -636,12 +664,12 @@ bool p3ChatService::handleRecvChatMsgItem(RsChatMsgItem *ci) { RsStackMutex stack(mChatMtx); /********** STACK LOCKED MTX ******/ - // This crap is because chat lobby messages use a different method for chunking messages using an additional - // subpacket ID, and a list of lobbies. We cannot just collapse the two because it would make the normal chat - // (and chat lobbies) not backward compatible. + // This crap is because chat lobby messages use a different method for chunking messages using an additional + // subpacket ID, and a list of lobbies. We cannot just collapse the two because it would make the normal chat + // (and chat lobbies) not backward compatible. - if(!DistributedChatService::locked_checkAndRebuildPartialLobbyMessage(dynamic_cast(ci))) - return true ; + if(!DistributedChatService::locked_checkAndRebuildPartialLobbyMessage(dynamic_cast(ci))) + return true ; if(!locked_checkAndRebuildPartialMessage(ci)) return true ; @@ -706,6 +734,7 @@ bool p3ChatService::handleRecvChatMsgItem(RsChatMsgItem *ci) std::string message = ci->message; if(!(ci->chatFlags & RS_CHAT_FLAG_LOBBY)) + { if(ci->chatFlags & RS_CHAT_FLAG_PRIVATE) RsServer::notify()->AddPopupMessage(popupChatFlag, ci->PeerId().toStdString(), name, message); /* notify private chat message */ else @@ -714,46 +743,24 @@ bool p3ChatService::handleRecvChatMsgItem(RsChatMsgItem *ci) RsServer::notify()->AddPopupMessage(RS_POPUP_GROUPCHAT, ci->PeerId().toStdString(), "", message); RsServer::notify()->AddFeedItem(RS_FEED_ITEM_CHAT_NEW, ci->PeerId().toStdString(), message, ""); } - - { - RsStackMutex stack(mChatMtx); /********** STACK LOCKED MTX ******/ - - ci->recvTime = now; - - if (ci->chatFlags & RS_CHAT_FLAG_PRIVATE) { -#ifdef CHAT_DEBUG - std::cerr << "Adding msg " << std::hex << (void*)ci << std::dec << " to private chat incoming list from " << ci->PeerId() << "." << std::endl; -#endif - privateChanged = true; - locked_storeIncomingMsg(ci); // don't delete the item !! - } else { -#ifdef CHAT_DEBUG - std::cerr << "Adding msg " << std::hex << (void*)ci << std::dec << " to public chat incoming list." << std::endl; -#endif - publicChanged = true; - publicList.push_back(ci); // don't delete the item !! - - if (ci->PeerId() != mServiceCtrl->getOwnId()) { - /* not from loop back */ - mHistoryMgr->addMessage(true, RsPeerId(), ci->PeerId(), ci); - } - } - } /* UNLOCK */ - - if (publicChanged) - RsServer::notify()->notifyListChange(NOTIFY_LIST_PUBLIC_CHAT, NOTIFY_TYPE_ADD); - - if (privateChanged) - { - RsServer::notify()->notifyListChange(NOTIFY_LIST_PRIVATE_INCOMING_CHAT, NOTIFY_TYPE_ADD); - IndicateConfigChanged(); // only private chat messages are saved } + + ci->recvTime = now; + + ChatMessage cm; + initChatMessage(ci, cm); + cm.incoming = true; + cm.online = true; + RsServer::notify()->notifyChatMessage(cm); + mHistoryMgr->addMessage(cm); return true ; } void p3ChatService::locked_storeIncomingMsg(RsChatMsgItem *item) { +#ifdef REMOVE privateIncomingList.push_back(item) ; +#endif } void p3ChatService::handleRecvChatStatusItem(RsChatStatusItem *cs) @@ -762,6 +769,8 @@ void p3ChatService::handleRecvChatStatusItem(RsChatStatusItem *cs) std::cerr << "Received status string \"" << cs->status_string << "\"" << std::endl ; #endif + uint32_t status; + if(cs->flags & RS_CHAT_FLAG_REQUEST_CUSTOM_STATE) // no state here just a request. sendCustomState(cs->PeerId()) ; else if(cs->flags & RS_CHAT_FLAG_CUSTOM_STATE) // Check if new custom string is available at peer's. @@ -776,198 +785,52 @@ void p3ChatService::handleRecvChatStatusItem(RsChatStatusItem *cs) #endif sendCustomStateRequest(cs->PeerId()) ; } + else if(DistantChatService::getDistantChatStatus(RsGxsId(cs->PeerId()), status)) + { + RsServer::notify()->notifyChatStatus(ChatId(RsGxsId(cs->PeerId())), cs->status_string) ; + } else if(cs->flags & RS_CHAT_FLAG_PRIVATE) { - RsServer::notify()->notifyChatStatus(cs->PeerId().toStdString(),cs->status_string,true) ; + RsServer::notify()->notifyChatStatus(ChatId(cs->PeerId()),cs->status_string) ; } else if(cs->flags & RS_CHAT_FLAG_PUBLIC) - RsServer::notify()->notifyChatStatus(cs->PeerId().toStdString(),cs->status_string,false) ; + { + ChatId id = ChatId::makeBroadcastId(); + id.broadcast_status_peer_id = cs->PeerId(); + RsServer::notify()->notifyChatStatus(id, cs->status_string) ; + } DistantChatService::handleRecvChatStatusItem(cs) ; } - -int p3ChatService::getPublicChatQueueCount() +void p3ChatService::initChatMessage(RsChatMsgItem *c, ChatMessage &m) { - RsStackMutex stack(mChatMtx); /********** STACK LOCKED MTX ******/ + m.chat_id = ChatId(c->PeerId()); + m.chatflags = 0; + m.sendTime = c->sendTime; + m.recvTime = c->recvTime; + m.msg = c->message; - return publicList.size(); -} + RsChatLobbyMsgItem *lobbyItem = dynamic_cast(c) ; + if(lobbyItem != NULL) + { + m.lobby_peer_nickname = lobbyItem->nick; + m.chat_id = ChatId(lobbyItem->lobby_id); + return; + } -bool p3ChatService::getPublicChatQueue(std::list &chats) -{ - bool changed = false; + uint32_t status; + if(DistantChatService::getDistantChatStatus(RsGxsId(c->PeerId()), status)) + m.chat_id = ChatId(RsGxsId(c->PeerId())); - { - RsStackMutex stack(mChatMtx); /********** STACK LOCKED MTX ******/ - - // get the items from the public list. - if (publicList.empty()) { - 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) { - RsServer::notify()->notifyListChange(NOTIFY_LIST_PUBLIC_CHAT, NOTIFY_TYPE_DEL); - } - - return true; -} - -int p3ChatService::getPrivateChatQueueCount(bool incoming) -{ - RsStackMutex stack(mChatMtx); /********** STACK LOCKED MTX ******/ - - if (incoming) { - return privateIncomingList.size(); - } - - return privateOutgoingList.size(); -} - -bool p3ChatService::getPrivateChatQueueIds(bool incoming, std::list &ids) -{ - ids.clear(); - - RsStackMutex stack(mChatMtx); /********** STACK LOCKED MTX ******/ - - std::list *list; - - if (incoming) { - list = &privateIncomingList; - } else { - list = &privateOutgoingList; - } - - // get the items from the private list. - if (list->size() == 0) { - return false; - } - - std::list::iterator it; - for (it = list->begin(); it != list->end(); ++it) { - RsChatMsgItem *c = *it; - - if (std::find(ids.begin(), ids.end(), c->PeerId()) == ids.end()) { - ids.push_back(c->PeerId()); - } - } - - return true; -} - -bool p3ChatService::getPrivateChatQueue(bool incoming, const RsPeerId &id, std::list &chats) -{ - RsStackMutex stack(mChatMtx); /********** STACK LOCKED MTX ******/ - - std::list *list; - - if (incoming) { - list = &privateIncomingList; - } else { - list = &privateOutgoingList; - } - - // get the items from the private list. - if (list->size() == 0) { - return false; - } - - std::list::iterator it; - for (it = list->begin(); it != list->end(); ++it) { - RsChatMsgItem *c = *it; - - if (c->PeerId() == id) { - ChatInfo ci; - initRsChatInfo(c, ci); - chats.push_back(ci); - } - } - - return (chats.size() > 0); -} - -bool p3ChatService::clearPrivateChatQueue(bool incoming, const RsPeerId &id) -{ - bool changed = false; - - { - RsStackMutex stack(mChatMtx); /********** STACK LOCKED MTX ******/ - - std::list *list; - - if (incoming) { - list = &privateIncomingList; - } else { - list = &privateOutgoingList; - } - - // get the items from the private list. - if (list->size() == 0) { - return false; - } - - std::list::iterator it = list->begin(); - while (it != list->end()) { - RsChatMsgItem *c = *it; - - if (c->PeerId() == id) { - if (incoming) { - mHistoryMgr->addMessage(true, c->PeerId(), c->PeerId(), c); - } - - delete c; - changed = true; - - it = list->erase(it); - - continue; - } - - ++it; - } - } /* UNLOCKED */ - - if (changed) { - RsServer::notify()->notifyListChange(incoming ? NOTIFY_LIST_PRIVATE_INCOMING_CHAT : NOTIFY_LIST_PRIVATE_OUTGOING_CHAT, NOTIFY_TYPE_DEL); - - IndicateConfigChanged(); - } - - return true; -} - -void p3ChatService::initRsChatInfo(RsChatMsgItem *c, ChatInfo &i) -{ - i.rsid = c->PeerId(); - i.chatflags = 0; - i.sendTime = c->sendTime; - i.recvTime = c->recvTime; - i.msg = c->message; - - RsChatLobbyMsgItem *lobbyItem = dynamic_cast(c) ; - - if(lobbyItem != NULL) - i.peer_nickname = lobbyItem->nick; - - if (c -> chatFlags & RS_CHAT_FLAG_PRIVATE) - i.chatflags |= RS_CHAT_PRIVATE; - else - i.chatflags |= RS_CHAT_PUBLIC; + if (c -> chatFlags & RS_CHAT_FLAG_PRIVATE) + m.chatflags |= RS_CHAT_PRIVATE; + else + { + m.chat_id = ChatId::makeBroadcastId(); + m.broadcast_peer_id = c->PeerId(); + m.chatflags |= RS_CHAT_PUBLIC; + } } void p3ChatService::setOwnCustomStateString(const std::string& s) @@ -1353,19 +1216,8 @@ bool p3ChatService::saveList(bool& cleanup, std::list& list) list.push_back(di) ; - /* save incoming private chat messages */ - - std::list::iterator it; - for (it = privateIncomingList.begin(); it != privateIncomingList.end(); it++) { - RsPrivateChatMsgConfigItem *ci = new RsPrivateChatMsgConfigItem; - - ci->set(*it, (*it)->PeerId(), RS_CHATMSG_CONFIGFLAG_INCOMING); - - list.push_back(ci); - } - /* save outgoing private chat messages */ - + std::list::iterator it; for (it = privateOutgoingList.begin(); it != privateOutgoingList.end(); it++) { RsPrivateChatMsgConfigItem *ci = new RsPrivateChatMsgConfigItem; @@ -1418,7 +1270,7 @@ void p3ChatService::statusChange(const std::list &plist) RsChatMsgItem *c = *cit; if (c->PeerId() == it->id) { - mHistoryMgr->addMessage(false, c->PeerId(), ownId, c); + //mHistoryMgr->addMessage(false, c->PeerId(), ownId, c); to_send.push_back(c) ; @@ -1434,7 +1286,15 @@ void p3ChatService::statusChange(const std::list &plist) } /* UNLOCKED */ for(uint32_t i=0;inotifyChatMessage(message); + checkSizeAndSendMessage(to_send[i]); // delete item + } if (changed) { RsServer::notify()->notifyListChange(NOTIFY_LIST_PRIVATE_OUTGOING_CHAT, NOTIFY_TYPE_DEL); @@ -1445,18 +1305,18 @@ void p3ChatService::statusChange(const std::list &plist) else if (it->actions & RS_SERVICE_PEER_REMOVED) { /* now handle remove */ - clearPrivateChatQueue(true, it->id); - clearPrivateChatQueue(false, it->id); - mHistoryMgr->clear(it->id); + mHistoryMgr->clear(ChatId(it->id)); + + std::list::iterator cit = privateOutgoingList.begin(); + while (cit != privateOutgoingList.end()) { + RsChatMsgItem *c = *cit; + if (c->PeerId() == it->id) { + cit = privateOutgoingList.erase(cit); + continue; + } + ++cit; + } + IndicateConfigChanged(); } } } - - - - - - - - - diff --git a/libretroshare/src/chat/p3chatservice.h b/libretroshare/src/chat/p3chatservice.h index ce5d5341f..76b1c4e18 100644 --- a/libretroshare/src/chat/p3chatservice.h +++ b/libretroshare/src/chat/p3chatservice.h @@ -67,7 +67,6 @@ class p3ChatService: public p3Service, public DistantChatService, public Distrib * @see NotifyBase */ virtual int tick(); - virtual int status(); /*************** pqiMonitor callback ***********************/ virtual void statusChange(const std::list &plist); @@ -75,9 +74,17 @@ class p3ChatService: public p3Service, public DistantChatService, public Distrib /*! * public chat sent to all peers */ - int sendPublicChat(const std::string &msg); + void sendPublicChat(const std::string &msg); /********* RsMsgs ***********/ + /*! + * Send a chat message. + * @param destination where to send the chat message + * @param msg the message + * @see ChatId + */ + bool sendChat(ChatId destination, std::string msg); + /*! * chat is sent to specifc peer * @param id peer to send chat msg to @@ -88,7 +95,7 @@ class p3ChatService: public p3Service, public DistantChatService, public Distrib * can be used to send 'immediate' status msgs, these status updates are meant for immediate use by peer (not saved by rs) * e.g currently used to update user when a peer 'is typing' during a chat */ - void sendStatusString(const RsPeerId& peer_id,const std::string& status_str) ; + void sendStatusString(const ChatId& peer_id,const std::string& status_str) ; /*! * send to all peers online @@ -130,33 +137,6 @@ class p3ChatService: public p3Service, public DistantChatService, public Distrib */ void getOwnAvatarJpegData(unsigned char *& data,int& size) ; - /*! - * returns the count of messages in public queue - * @param public or private queue - */ - int getPublicChatQueueCount(); - - /*! - * This retrieves all public chat msg items - */ - bool getPublicChatQueue(std::list &chats); - - /*! - * returns the count of messages in private queue - * @param public or private queue - */ - int getPrivateChatQueueCount(bool incoming); - - /*! - * @param id's of available private chat messages - */ - bool getPrivateChatQueueIds(bool incoming, std::list &ids); - - /*! - * This retrieves all private chat msg items for peer - */ - bool getPrivateChatQueue(bool incoming, const RsPeerId &id, std::list &chats); - /*! * Return the max message size for security forwarding * @param type RS_CHAT_TYPE_... @@ -186,7 +166,8 @@ class p3ChatService: public p3Service, public DistantChatService, public Distrib virtual void saveDone(); virtual bool loadList(std::list& load) ; - bool isOnline(const RsPeerId& id) ; + // accepts virtual peer id + bool isOnline(const RsPeerId &pid) ; /// This is to be used by subclasses/parents to call IndicateConfigChanged() virtual void triggerConfigSave() { IndicateConfigChanged() ; } @@ -205,7 +186,7 @@ class p3ChatService: public p3Service, public DistantChatService, public Distrib virtual void sendChatItem(RsChatItem *) ; - void initRsChatInfo(RsChatMsgItem *c, ChatInfo &i); + void initChatMessage(RsChatMsgItem *c, ChatMessage& msg); /// Send avatar info to peer in jpeg format. void sendAvatarJpegData(const RsPeerId& peer_id) ; @@ -242,9 +223,7 @@ class p3ChatService: public p3Service, public DistantChatService, public Distrib p3LinkMgr *mLinkMgr; p3HistoryMgr *mHistoryMgr; - std::list publicList; - std::list privateIncomingList; - std::list privateOutgoingList; + std::list privateOutgoingList; // messages waiting to be send when peer comes online AvatarInfo *_own_avatar ; std::map _avatars ; diff --git a/libretroshare/src/ft/ftserver.h b/libretroshare/src/ft/ftserver.h index 99ee5e849..1f8a9af19 100644 --- a/libretroshare/src/ft/ftserver.h +++ b/libretroshare/src/ft/ftserver.h @@ -68,8 +68,6 @@ class ftFileSearch; class ftDataMultiplex; class p3turtle; -class ftDwlQueue; - class p3PeerMgr; class p3ServiceControl; @@ -287,8 +285,6 @@ class ftServer: public p3Service, public RsFiles, public ftDataSend, public RsTu ftFileSearch *mFtSearch; - ftDwlQueue *mFtDwlQueue; - RsMutex srvMutex; std::string mConfigPath; std::string mDownloadPath; diff --git a/libretroshare/src/pqi/p3historymgr.cc b/libretroshare/src/pqi/p3historymgr.cc index 0b260433e..ee2cc0e7b 100644 --- a/libretroshare/src/pqi/p3historymgr.cc +++ b/libretroshare/src/pqi/p3historymgr.cc @@ -63,7 +63,8 @@ p3HistoryMgr::~p3HistoryMgr() /***** p3HistoryMgr *****/ -void p3HistoryMgr::addMessage(bool incoming, const RsPeerId &chatPeerId, const RsPeerId &peerId, const RsChatMsgItem *chatItem) +//void p3HistoryMgr::addMessage(bool incoming, const RsPeerId &chatPeerId, const RsPeerId &peerId, const RsChatMsgItem *chatItem) +void p3HistoryMgr::addMessage(const ChatMessage& cm) { uint32_t addMsgId = 0; @@ -78,38 +79,48 @@ void p3HistoryMgr::addMessage(bool incoming, const RsPeerId &chatPeerId, const R { RsStackMutex stack(mHistoryMtx); /********** STACK LOCKED MTX ******/ - if (mPublicEnable == false && chatPeerId.isNull()) { - // public chat not enabled - return; - } - const RsChatLobbyMsgItem *cli = dynamic_cast(chatItem); + RsPeerId peerId; // id of sending peer + RsPeerId chatPeerId; // id of chat endpoint + std::string peerName; //name of sending peer - if (cli) - { - if (mLobbyEnable == false && !chatPeerId.isNull()) // lobby chat not enabled - return; - } - else - { - if (mPrivateEnable == false && !chatPeerId.isNull()) // private chat not enabled - return; + bool enabled = false; + if (cm.chat_id.isBroadcast() && mPublicEnable == true) { + peerName = rsPeers->getPeerName(cm.broadcast_peer_id); + enabled = true; } + if (cm.chat_id.isPeerId() && mPrivateEnable == true) { + peerId = cm.incoming ? cm.chat_id.toPeerId() : rsPeers->getOwnId(); + peerName = rsPeers->getPeerName(peerId); + enabled = true; + } + if (cm.chat_id.isLobbyId() && mLobbyEnable == true) { + peerName = cm.lobby_peer_nickname; + enabled = true; + } + + // not handled: private distant chat + + if(enabled == false) + return; + + if(!chatIdToVirtualPeerId(cm.chat_id, chatPeerId)) + return; RsHistoryMsgItem* item = new RsHistoryMsgItem; item->chatPeerId = chatPeerId; - item->incoming = incoming; + item->incoming = cm.incoming; item->peerId = peerId; - item->peerName = cli ? cli->nick : rsPeers->getPeerName(RsPeerId(item->peerId)); - item->sendTime = chatItem->sendTime; - item->recvTime = chatItem->recvTime; + item->peerName = peerName; + item->sendTime = cm.sendTime; + item->recvTime = cm.recvTime; - if (cli) { + if (cm.chat_id.isLobbyId()) { // disable save to disc for chat lobbies until they are saved item->saveToDisc = false; } - item->message = chatItem->message ; + item->message = cm.msg ; //librs::util::ConvertUtf16ToUtf8(chatItem->message, item->message); std::map >::iterator mit = mMessages.find(item->chatPeerId); @@ -122,7 +133,7 @@ void p3HistoryMgr::addMessage(bool incoming, const RsPeerId &chatPeerId, const R uint32_t limit; if (chatPeerId.isNull()) limit = mPublicSaveCount; - else if (cli) + else if (cm.chat_id.isLobbyId()) limit = mLobbySaveCount; else limit = mPrivateSaveCount; @@ -357,6 +368,35 @@ bool p3HistoryMgr::loadList(std::list& load) return true; } +// have to convert to virtual peer id, to be able to use existing serialiser and file format +bool p3HistoryMgr::chatIdToVirtualPeerId(ChatId chat_id, RsPeerId &peer_id) +{ + if (chat_id.isBroadcast()) { + peer_id = RsPeerId(); + return true; + } + if (chat_id.isPeerId()) { + peer_id = chat_id.toPeerId(); + return true; + } + if (chat_id.isLobbyId()) { + if(sizeof(ChatLobbyId) > RsPeerId::SIZE_IN_BYTES){ + std::cerr << "p3HistoryMgr::chatIdToVirtualPeerId() ERROR: ChatLobbyId does not fit into virtual peer id. Please report this error." << std::endl; + return false; + } + uint8_t bytes[RsPeerId::SIZE_IN_BYTES] ; + memset(bytes,0,RsPeerId::SIZE_IN_BYTES) ; + ChatLobbyId lobby_id = chat_id.toLobbyId(); + memcpy(bytes,&lobby_id,sizeof(ChatLobbyId)); + peer_id = RsPeerId(bytes); + return true; + } + + // not handled: private distant chat + + return false; +} + /***** p3History *****/ static void convertMsg(const RsHistoryMsgItem* item, HistoryMsg &msg) @@ -371,24 +411,31 @@ static void convertMsg(const RsHistoryMsgItem* item, HistoryMsg &msg) msg.message = item->message; } -bool p3HistoryMgr::getMessages(const RsPeerId &chatPeerId, std::list &msgs, uint32_t loadCount) +bool p3HistoryMgr::getMessages(const ChatId &chatId, std::list &msgs, uint32_t loadCount) { msgs.clear(); RsStackMutex stack(mHistoryMtx); /********** STACK LOCKED MTX ******/ - std::cerr << "Getting history for peer " << chatPeerId << std::endl; + RsPeerId chatPeerId; + bool enabled = false; + if (chatId.isBroadcast() && mPublicEnable == true) { + enabled = true; + } + if (chatId.isPeerId() && mPrivateEnable == true) { + enabled = true; + } + if (chatId.isLobbyId() && mLobbyEnable == true) { + enabled = true; + } - if (mPublicEnable == false && chatPeerId.isNull()) { // chatPeerId.empty() means it's public chat - // public chat not enabled - return false; - } + if(enabled == false) + return false; - if (mPrivateEnable == false && chatPeerId.isNull() == false) // private chat not enabled - return false; + if(!chatIdToVirtualPeerId(chatId, chatPeerId)) + return false; - if (mLobbyEnable == false && chatPeerId.isNull() == false) // private chat not enabled - return false; + std::cerr << "Getting history for virtual peer " << chatPeerId << std::endl; uint32_t foundCount = 0; @@ -430,12 +477,16 @@ bool p3HistoryMgr::getMessage(uint32_t msgId, HistoryMsg &msg) return false; } -void p3HistoryMgr::clear(const RsPeerId &chatPeerId) +void p3HistoryMgr::clear(const ChatId &chatId) { { RsStackMutex stack(mHistoryMtx); /********** STACK LOCKED MTX ******/ - std::cerr << "********** p3History::clear()called for peer id " << chatPeerId << std::endl; + RsPeerId chatPeerId; + if(!chatIdToVirtualPeerId(chatId, chatPeerId)) + return; + + std::cerr << "********** p3History::clear()called for virtual peer id " << chatPeerId << std::endl; std::map >::iterator mit = mMessages.find(chatPeerId); if (mit == mMessages.end()) { diff --git a/libretroshare/src/pqi/p3historymgr.h b/libretroshare/src/pqi/p3historymgr.h index 70f07bb67..98d7b6eed 100644 --- a/libretroshare/src/pqi/p3historymgr.h +++ b/libretroshare/src/pqi/p3historymgr.h @@ -34,6 +34,7 @@ #include "pqi/p3cfgmgr.h" class RsChatMsgItem; +class ChatMessage; //! handles history /*! @@ -48,13 +49,13 @@ public: /******** p3HistoryMgr *********/ - void addMessage(bool incoming, const RsPeerId &chatPeerId, const RsPeerId &peerId, const RsChatMsgItem *chatItem); + void addMessage(const ChatMessage &cm); /********* RsHistory ***********/ - bool getMessages(const RsPeerId &chatPeerId, std::list &msgs, uint32_t loadCount); + bool getMessages(const ChatId &chatPeerId, std::list &msgs, uint32_t loadCount); bool getMessage(uint32_t msgId, HistoryMsg &msg); - void clear(const RsPeerId &chatPeerId); + void clear(const ChatId &chatPeerId); void removeMessages(const std::list &msgIds); virtual bool getEnable(uint32_t chat_type); @@ -72,6 +73,8 @@ public: virtual bool loadList(std::list& load); private: + static bool chatIdToVirtualPeerId(ChatId chat_id, RsPeerId& peer_id); + uint32_t nextMsgId; std::map > mMessages; diff --git a/libretroshare/src/pqi/p3notify.cc b/libretroshare/src/pqi/p3notify.cc index 80ea867de..c047962e3 100644 --- a/libretroshare/src/pqi/p3notify.cc +++ b/libretroshare/src/pqi/p3notify.cc @@ -223,8 +223,8 @@ void p3Notify::notifyListPreChange(int list, int type) { FOR_ALL_NOTIFY_CLIENTS void p3Notify::notifyListChange (int list, int type) { FOR_ALL_NOTIFY_CLIENTS (*it)->notifyListChange (list,type) ; } void p3Notify::notifyErrorMsg (int list, int sev, std::string msg) { FOR_ALL_NOTIFY_CLIENTS (*it)->notifyErrorMsg(list,sev,msg) ; } -void p3Notify::notifyChatStatus (const std::string& peer_id , const std::string& status_string ,bool is_private) { FOR_ALL_NOTIFY_CLIENTS (*it)->notifyChatStatus(peer_id,status_string,is_private) ; } -void p3Notify::notifyChatShow (const std::string& peer_id) { FOR_ALL_NOTIFY_CLIENTS (*it)->notifyChatShow(peer_id) ; } +void p3Notify::notifyChatMessage (const ChatMessage &msg) { FOR_ALL_NOTIFY_CLIENTS (*it)->notifyChatMessage(msg) ; } +void p3Notify::notifyChatStatus (const ChatId& chat_id, const std::string& status_string) { FOR_ALL_NOTIFY_CLIENTS (*it)->notifyChatStatus(chat_id,status_string) ; } void p3Notify::notifyChatLobbyTimeShift (int time_shift) { FOR_ALL_NOTIFY_CLIENTS (*it)->notifyChatLobbyTimeShift(time_shift) ; } void p3Notify::notifyCustomState (const std::string& peer_id , const std::string& status_string ) { FOR_ALL_NOTIFY_CLIENTS (*it)->notifyCustomState (peer_id,status_string) ; } @@ -238,10 +238,10 @@ void p3Notify::notifyPeerStatusChanged (const std::string& peer_id , uint void p3Notify::notifyPeerStatusChangedSummary () { FOR_ALL_NOTIFY_CLIENTS (*it)->notifyPeerStatusChangedSummary() ; } void p3Notify::notifyDiscInfoChanged () { FOR_ALL_NOTIFY_CLIENTS (*it)->notifyDiscInfoChanged () ; } - +#ifdef REMOVE void p3Notify::notifyForumMsgReadSatusChanged (const std::string& channelId, const std::string& msgId, uint32_t status) { FOR_ALL_NOTIFY_CLIENTS (*it)->notifyForumMsgReadSatusChanged (channelId,msgId,status) ; } void p3Notify::notifyChannelMsgReadSatusChanged (const std::string& channelId, const std::string& msgId, uint32_t status) { FOR_ALL_NOTIFY_CLIENTS (*it)->notifyChannelMsgReadSatusChanged (channelId,msgId,status) ; } - +#endif void p3Notify::notifyDownloadComplete (const std::string& fileHash ) { FOR_ALL_NOTIFY_CLIENTS (*it)->notifyDownloadComplete (fileHash) ; } void p3Notify::notifyDownloadCompleteCount (uint32_t count ) { FOR_ALL_NOTIFY_CLIENTS (*it)->notifyDownloadCompleteCount (count) ; } void p3Notify::notifyHistoryChanged (uint32_t msgId , int type) { FOR_ALL_NOTIFY_CLIENTS (*it)->notifyHistoryChanged (msgId,type) ; } diff --git a/libretroshare/src/pqi/p3notify.h b/libretroshare/src/pqi/p3notify.h index 7ba96af74..6130d8f42 100644 --- a/libretroshare/src/pqi/p3notify.h +++ b/libretroshare/src/pqi/p3notify.h @@ -98,8 +98,8 @@ class p3Notify: public RsNotify void notifyListPreChange (int /* list */, int /* type */) ; void notifyListChange (int /* list */, int /* type */) ; void notifyErrorMsg (int /* list */, int /* sev */, std::string /* msg */) ; - void notifyChatStatus (const std::string& /* peer_id */, const std::string& /* status_string */ ,bool /* is_private */) ; - void notifyChatShow (const std::string& /* peer_id */) ; + void notifyChatMessage (const ChatMessage& /* msg */) ; + void notifyChatStatus (const ChatId& /* chat_id */, const std::string& /* status_string */) ; void notifyChatLobbyEvent (uint64_t /* lobby id */, uint32_t /* event type */ ,const std::string& /* nickname */,const std::string& /* any string */) ; void notifyChatLobbyTimeShift (int /* time_shift*/) ; void notifyCustomState (const std::string& /* peer_id */, const std::string& /* status_string */) ; @@ -113,8 +113,10 @@ class p3Notify: public RsNotify void notifyPeerStatusChangedSummary () ; void notifyDiscInfoChanged () ; +#ifdef REMOVE void notifyForumMsgReadSatusChanged (const std::string& /* channelId */, const std::string& /* msgId */, uint32_t /* status */) ; void notifyChannelMsgReadSatusChanged (const std::string& /* channelId */, const std::string& /* msgId */, uint32_t /* status */) ; +#endif bool askForDeferredSelfSignature (const void * /* data */, const uint32_t /* len */, unsigned char * /* sign */, unsigned int * /* signlen */,int& signature_result ) ; void notifyDownloadComplete (const std::string& /* fileHash */) ; void notifyDownloadCompleteCount (uint32_t /* count */) ; diff --git a/libretroshare/src/retroshare/rshistory.h b/libretroshare/src/retroshare/rshistory.h index 034b2da68..77e30b35d 100644 --- a/libretroshare/src/retroshare/rshistory.h +++ b/libretroshare/src/retroshare/rshistory.h @@ -27,6 +27,7 @@ */ class RsHistory; +class ChatId; extern RsHistory *rsHistory; @@ -72,10 +73,10 @@ public: class RsHistory { public: - virtual bool getMessages(const RsPeerId &chatPeerId, std::list &msgs, uint32_t loadCount) = 0; + virtual bool getMessages(const ChatId &chatPeerId, std::list &msgs, uint32_t loadCount) = 0; virtual bool getMessage(uint32_t msgId, HistoryMsg &msg) = 0; virtual void removeMessages(const std::list &msgIds) = 0; - virtual void clear(const RsPeerId &chatPeerId) = 0; + virtual void clear(const ChatId &chatPeerId) = 0; virtual bool getEnable(uint32_t chat_type) = 0; virtual void setEnable(uint32_t chat_type, bool enable) = 0; diff --git a/libretroshare/src/retroshare/rsmsgs.h b/libretroshare/src/retroshare/rsmsgs.h index ffa6c194c..369d5fcde 100644 --- a/libretroshare/src/retroshare/rsmsgs.h +++ b/libretroshare/src/retroshare/rsmsgs.h @@ -254,15 +254,64 @@ public: #define RS_DISTANT_CHAT_FLAG_SIGNED 0x0001 #define RS_DISTANT_CHAT_FLAG_SIGNATURE_OK 0x0002 -class ChatInfo +// Identifier for an chat endpoint like +// neighbour peer, distant peer, chatlobby, broadcast +class ChatId { - public: - RsPeerId rsid; - std::string peer_nickname; - unsigned int chatflags; - uint32_t sendTime; - uint32_t recvTime; - std::string msg; +public: + ChatId(); + explicit ChatId(RsPeerId id); + explicit ChatId(RsGxsId id); + explicit ChatId(ChatLobbyId id); + explicit ChatId(std::string str); + static ChatId makeBroadcastId(); + + std::string toStdString() const; + bool operator<(const ChatId& other) const; + bool isSameEndpoint(const ChatId& other) const; + + bool isNotSet() const; + bool isPeerId() const; + bool isGxsId() const; + bool isLobbyId() const; + bool isBroadcast() const; + + RsPeerId toPeerId() const; + RsGxsId toGxsId() const; + ChatLobbyId toLobbyId() const; + + // for the very specific case of transfering a status string + // from the chatservice to the gui, + // this defines from which peer the status string came from + RsPeerId broadcast_status_peer_id; +private: + enum Type { TYPE_NOT_SET, + TYPE_PRIVATE, // private chat with directly connected friend, peer_id is valid + TYPE_PRIVATE_DISTANT, // private chat with distant peer, gxs_id is valid + TYPE_LOBBY, // chat lobby id, lobby_id is valid + TYPE_BROADCAST // message to/from all connected peers + }; + + Type type; + RsPeerId peer_id; + RsGxsId gxs_id; + ChatLobbyId lobby_id; +}; + +class ChatMessage +{ +public: + ChatId chat_id; // id of chat endpoint + RsPeerId broadcast_peer_id; // only used for broadcast chat: source peer id + std::string lobby_peer_nickname; // only used for lobbys: nickname of message author + + unsigned int chatflags; + uint32_t sendTime; + uint32_t recvTime; + std::string msg; + bool incoming; + bool online; // for outgoing messages: was this message send? + //bool system_message; }; class ChatLobbyInvite @@ -315,9 +364,6 @@ struct DistantChatInviteInfo }; std::ostream &operator<<(std::ostream &out, const MessageInfo &info); -std::ostream &operator<<(std::ostream &out, const ChatInfo &info); - -bool operator==(const ChatInfo&, const ChatInfo&); class RsMsgs; extern RsMsgs *rsMsgs; @@ -381,18 +427,13 @@ virtual bool distantMessagingEnabled() = 0; /****************************************/ /* Chat */ /****************************************/ -virtual bool sendPublicChat(const std::string& msg) = 0; -virtual bool sendPrivateChat(const RsPeerId& id, const std::string& msg) = 0; -virtual int getPublicChatQueueCount() = 0; -virtual bool getPublicChatQueue(std::list &chats) = 0; -virtual int getPrivateChatQueueCount(bool incoming) = 0; -virtual bool getPrivateChatQueueIds(bool incoming, std::list &ids) = 0; -virtual bool getPrivateChatQueue(bool incoming, const RsPeerId& id, std::list &chats) = 0; -virtual bool clearPrivateChatQueue(bool incoming, const RsPeerId& id) = 0; -virtual uint32_t getMaxMessageSecuritySize(int type) = 0; +// sendChat for broadcast, private, lobby and private distant chat +// note: for lobby chat, you first have to subscribe to a lobby +// for private distant chat, it is reqired to have an active distant chat session +virtual bool sendChat(ChatId id, std::string msg) = 0; +virtual uint32_t getMaxMessageSecuritySize(int type) = 0; -virtual void sendStatusString(const RsPeerId& id,const std::string& status_string) = 0 ; -virtual void sendGroupChatStatusString(const std::string& status_string) = 0 ; +virtual void sendStatusString(const ChatId& id,const std::string& status_string) = 0 ; virtual void setCustomStateString(const std::string& status_string) = 0 ; virtual std::string getCustomStateString() = 0 ; diff --git a/libretroshare/src/retroshare/rsnotify.h b/libretroshare/src/retroshare/rsnotify.h index fff82e4a8..efa8f7d33 100644 --- a/libretroshare/src/retroshare/rsnotify.h +++ b/libretroshare/src/retroshare/rsnotify.h @@ -35,6 +35,9 @@ #include "rsturtle.h" +class ChatId; +class ChatMessage; + class RsNotify; extern RsNotify *rsNotify; @@ -198,8 +201,8 @@ class NotifyClient virtual void notifyListPreChange (int /* list */, int /* type */) {} virtual void notifyListChange (int /* list */, int /* type */) {} virtual void notifyErrorMsg (int /* list */, int /* sev */, std::string /* msg */) {} - virtual void notifyChatStatus (const std::string& /* peer_id */, const std::string& /* status_string */ ,bool /* is_private */) {} - virtual void notifyChatShow (const std::string& /* peer_id */) {} + virtual void notifyChatMessage (const ChatMessage& /* msg */) {} + virtual void notifyChatStatus (const ChatId& /* chat_id */, const std::string& /* status_string */) {} virtual void notifyChatLobbyEvent (uint64_t /* lobby id */, uint32_t /* event type */ ,const std::string& /* nickname */,const std::string& /* any string */) {} virtual void notifyChatLobbyTimeShift (int /* time_shift*/) {} virtual void notifyCustomState (const std::string& /* peer_id */, const std::string& /* status_string */) {} @@ -214,8 +217,10 @@ class NotifyClient /* one or more peers has changed the states */ virtual void notifyPeerStatusChangedSummary () {} virtual void notifyDiscInfoChanged () {} +#ifdef REMOVE virtual void notifyForumMsgReadSatusChanged (const std::string& /* channelId */, const std::string& /* msgId */, uint32_t /* status */) {} virtual void notifyChannelMsgReadSatusChanged (const std::string& /* channelId */, const std::string& /* msgId */, uint32_t /* status */) {} +#endif virtual bool askForDeferredSelfSignature (const void * /* data */, const uint32_t /* len */, unsigned char * /* sign */, unsigned int * /* signlen */,int& signature_result ) { signature_result = false ;return true; } virtual void notifyDownloadComplete (const std::string& /* fileHash */) {} virtual void notifyDownloadCompleteCount (uint32_t /* count */) {} diff --git a/libretroshare/src/rsserver/p3history.cc b/libretroshare/src/rsserver/p3history.cc index a7a225ae2..6c631ef43 100644 --- a/libretroshare/src/rsserver/p3history.cc +++ b/libretroshare/src/rsserver/p3history.cc @@ -44,7 +44,7 @@ uint32_t p3History::getMaxStorageDuration() { return mHistoryMgr->getMaxStorageDuration() ; } -bool p3History::getMessages(const RsPeerId &chatPeerId, std::list &msgs, const uint32_t loadCount) +bool p3History::getMessages(const ChatId &chatPeerId, std::list &msgs, const uint32_t loadCount) { return mHistoryMgr->getMessages(chatPeerId, msgs, loadCount); } @@ -59,7 +59,7 @@ void p3History::removeMessages(const std::list &msgIds) mHistoryMgr->removeMessages(msgIds); } -void p3History::clear(const RsPeerId &chatPeerId) +void p3History::clear(const ChatId &chatPeerId) { mHistoryMgr->clear(chatPeerId); } diff --git a/libretroshare/src/rsserver/p3history.h b/libretroshare/src/rsserver/p3history.h index 9a4bc8837..70b7c701b 100644 --- a/libretroshare/src/rsserver/p3history.h +++ b/libretroshare/src/rsserver/p3history.h @@ -41,10 +41,10 @@ public: p3History(p3HistoryMgr* historyMgr); virtual ~p3History(); - virtual bool getMessages(const RsPeerId &chatPeerId, std::list &msgs, uint32_t loadCount); + virtual bool getMessages(const ChatId &chatPeerId, std::list &msgs, uint32_t loadCount); virtual bool getMessage(uint32_t msgId, HistoryMsg &msg); virtual void removeMessages(const std::list &msgIds); - virtual void clear(const RsPeerId &chatPeerId); + virtual void clear(const ChatId &chatPeerId); virtual bool getEnable(uint32_t chat_type); virtual void setEnable(uint32_t chat_type, bool enable); virtual uint32_t getSaveCount(uint32_t chat_type); diff --git a/libretroshare/src/rsserver/p3msgs.cc b/libretroshare/src/rsserver/p3msgs.cc index 20afa09de..46c09e7ed 100644 --- a/libretroshare/src/rsserver/p3msgs.cc +++ b/libretroshare/src/rsserver/p3msgs.cc @@ -49,26 +49,223 @@ RsMsgs *rsMsgs = NULL; /****************************************/ /****************************************/ -std::ostream &operator<<(std::ostream &out, const ChatInfo &info) +ChatId::ChatId(): + type(TYPE_NOT_SET), + lobby_id(0) { - out << "ChatInfo: rsid: " << info.rsid << std::endl; - out << "chatflags: " << info.chatflags << std::endl; - out << "sendTime: " << info.sendTime << std::endl; - out << "recvTime: " << info.recvTime << std::endl; - std::string message; - message.assign(info.msg.begin(), info.msg.end()); - out << "msg: " << message; - return out; + } -bool operator==(const ChatInfo& info1, const ChatInfo& info2) +ChatId::ChatId(RsPeerId id): + lobby_id(0) { - return info1.rsid == info2.rsid && - info1.chatflags == info2.chatflags && - info1.sendTime == info2.sendTime && - info1.recvTime == info2.recvTime && - info1.msg == info2.msg; + type = TYPE_PRIVATE; + peer_id = id; +} +ChatId::ChatId(RsGxsId id): + lobby_id(0) +{ + type = TYPE_PRIVATE_DISTANT; + gxs_id = id; +} + +ChatId::ChatId(ChatLobbyId id): + lobby_id(0) +{ + type = TYPE_LOBBY; + lobby_id = id; +} + +ChatId::ChatId(std::string str): + lobby_id(0) +{ + type = TYPE_NOT_SET; + if(str.empty()) + return; + if(str[0] == 'P') + { + type = TYPE_PRIVATE; + peer_id = RsPeerId(str.substr(1)); + } + else if(str[0] == 'D') + { + type = TYPE_PRIVATE_DISTANT; + gxs_id == GXSId(str.substr(1)); + } + else if(str[0] == 'L') + { + if(sizeof(ChatLobbyId) != 8) + { + std::cerr << "ChatId::ChatId(std::string) Error: sizeof(ChatLobbyId) != 8. please report this" << std::endl; + return; + } + str = str.substr(1); + if(str.size() != 16) + return; + ChatLobbyId id = 0; + for(int i = 0; i<16; i++) + { + uint8_t c = str[i]; + if(c <= '9') + c -= '9'; + else + c -= 'A'; + id = id << 4; + id |= c; + } + type = TYPE_LOBBY; + lobby_id = id; + } + else if(str[0] == 'B') + { + type = TYPE_BROADCAST; + } +} + +ChatId ChatId::makeBroadcastId() +{ + ChatId id; + id.type = TYPE_BROADCAST; + return id; +} + +std::string ChatId::toStdString() const +{ + std::string str; + if(type == TYPE_PRIVATE) + { + str += "P"; + str += peer_id.toStdString(); + } + else if(type == TYPE_PRIVATE_DISTANT) + { + str += "D"; + str += gxs_id.toStdString(); + } + else if(type == TYPE_LOBBY) + { + if(sizeof(ChatLobbyId) != 8) + { + std::cerr << "ChatId::toStdString() Error: sizeof(ChatLobbyId) != 8. please report this" << std::endl; + return ""; + } + ChatLobbyId id = lobby_id; + for(int i = 0; i<16; i++) + { + uint8_t c = id >>(64-4); + if(c > 9) + c += 'A'; + else + c += '1'; + str += c; + id = id << 4; + } + } + else if(type == TYPE_BROADCAST) + { + str += "B"; + } + return str; +} + +bool ChatId::operator <(const ChatId& other) const +{ + if(type != other.type) + return type < other.type; + else + { + switch(type) + { + case TYPE_NOT_SET: + return false; + case TYPE_PRIVATE: + return peer_id < other.peer_id; + case TYPE_PRIVATE_DISTANT: + return gxs_id < other.gxs_id; + case TYPE_LOBBY: + return lobby_id < other.lobby_id; + case TYPE_BROADCAST: + return false; + default: + return false; + } + } +} + +bool ChatId::isSameEndpoint(const ChatId &other) const +{ + if(type != other.type) + return false; + else + { + switch(type) + { + case TYPE_NOT_SET: + return false; + case TYPE_PRIVATE: + return peer_id == other.peer_id; + case TYPE_PRIVATE_DISTANT: + return gxs_id == other.gxs_id; + case TYPE_LOBBY: + return lobby_id == other.lobby_id; + case TYPE_BROADCAST: + return true; + default: + return false; + } + } +} + +bool ChatId::isNotSet() const +{ + return type == TYPE_NOT_SET; +} +bool ChatId::isPeerId() const +{ + return type == TYPE_PRIVATE; +} +bool ChatId::isGxsId() const +{ + return type == TYPE_PRIVATE_DISTANT; +} +bool ChatId::isLobbyId() const +{ + return type == TYPE_LOBBY; +} +bool ChatId::isBroadcast() const +{ + return type == TYPE_BROADCAST; +} +RsPeerId ChatId::toPeerId() const +{ + if(type == TYPE_PRIVATE) + return peer_id; + else + { + std::cerr << "ChatId Warning: conversation to RsPeerId requested, but type is different." << std::endl; + return RsPeerId(); + } +} +RsGxsId ChatId::toGxsId() const +{ + if(type == TYPE_PRIVATE_DISTANT) + return gxs_id; + else + { + std::cerr << "ChatId Warning: conversation to RsGxsId requested, but type is different." << std::endl; + return RsGxsId(); + } +} +ChatLobbyId ChatId::toLobbyId() const +{ + if(type == TYPE_LOBBY) + return lobby_id; + else + { + std::cerr << "ChatId Warning: conversation to ChatLobbyId requested, but type is different." << std::endl; + return 0; + } } bool p3Msgs::getMessageSummaries(std::list &msgList) @@ -200,56 +397,9 @@ bool p3Msgs::resetMessageStandardTagTypes(MsgTagType& tags) /****************************************/ /****************************************/ -bool p3Msgs::sendPublicChat(const std::string& msg) +bool p3Msgs::sendChat(ChatId destination, std::string msg) { - /* send a message to all for now */ - return mChatSrv -> sendPublicChat(msg); -} - -bool p3Msgs::sendPrivateChat(const RsPeerId& id, const std::string& msg) -{ - /* send a message to peer */ - return mChatSrv -> sendPrivateChat(id, msg); -} - -void p3Msgs::sendGroupChatStatusString(const std::string& status_string) -{ - mChatSrv->sendGroupChatStatusString(status_string); -} - -void p3Msgs::sendStatusString(const RsPeerId& peer_id, const std::string& status_string) -{ - mChatSrv->sendStatusString(peer_id, status_string); -} - -int p3Msgs::getPublicChatQueueCount() -{ - return mChatSrv->getPublicChatQueueCount(); -} - -bool p3Msgs::getPublicChatQueue(std::list &chats) -{ - return mChatSrv->getPublicChatQueue(chats); -} - -int p3Msgs::getPrivateChatQueueCount(bool incoming) -{ - return mChatSrv->getPrivateChatQueueCount(incoming); -} - -bool p3Msgs::getPrivateChatQueueIds(bool incoming, std::list &ids) -{ - return mChatSrv->getPrivateChatQueueIds(incoming, ids); -} - -bool p3Msgs::getPrivateChatQueue(bool incoming, const RsPeerId& id, std::list &chats) -{ - return mChatSrv->getPrivateChatQueue(incoming, id, chats); -} - -bool p3Msgs::clearPrivateChatQueue(bool incoming, const RsPeerId& id) -{ - return mChatSrv->clearPrivateChatQueue(incoming, id); + return mChatSrv->sendChat(destination, msg); } uint32_t p3Msgs::getMaxMessageSecuritySize(int type) @@ -257,6 +407,11 @@ uint32_t p3Msgs::getMaxMessageSecuritySize(int type) return mChatSrv->getMaxMessageSecuritySize(type); } +void p3Msgs::sendStatusString(const ChatId& peer_id, const std::string& status_string) +{ + mChatSrv->sendStatusString(peer_id, status_string); +} + void p3Msgs::getOwnAvatarData(unsigned char *& data,int& size) { mChatSrv->getOwnAvatarJpegData(data,size) ; diff --git a/libretroshare/src/rsserver/p3msgs.h b/libretroshare/src/rsserver/p3msgs.h index 0bbaf393d..166021537 100644 --- a/libretroshare/src/rsserver/p3msgs.h +++ b/libretroshare/src/rsserver/p3msgs.h @@ -116,47 +116,12 @@ class p3Msgs: public RsMsgs /*! - * public chat sent to all peers + * Send a chat message. + * @param destination where to send the chat message + * @param msg the message + * @see ChatId */ - virtual bool sendPublicChat(const std::string& msg); - - /*! - * chat is sent to specifc peer - * @param id peer to send chat msg to - */ - virtual bool sendPrivateChat(const RsPeerId& id, const std::string& msg); - - /*! - * returns the count of messages in public or private queue - * @param public or private queue - */ - virtual int getPublicChatQueueCount(); - - /*! - * @param chats ref to list of received public chats is stored here - */ - virtual bool getPublicChatQueue(std::list &chats); - - /*! - * returns the count of messages in private queue - * @param public or private queue - */ - virtual int getPrivateChatQueueCount(bool incoming); - - /*! - * @param id's of available private chat messages - */ - virtual bool getPrivateChatQueueIds(bool incoming, std::list &ids); - - /*! - * @param chats ref to list of received private chats is stored here - */ - virtual bool getPrivateChatQueue(bool incoming, const RsPeerId& id, std::list &chats); - - /*! - * @param clear private chat queue - */ - virtual bool clearPrivateChatQueue(bool incoming, const RsPeerId& id); + virtual bool sendChat(ChatId destination, std::string msg) ; /*! * Return the max message size for security forwarding @@ -165,16 +130,10 @@ class p3Msgs: public RsMsgs /*! * sends immediate status string to a specific peer, e.g. in a private chat - * @param peer_id peer to send status string to + * @param chat_id chat id to send status string to * @param status_string immediate status to send */ - virtual void sendStatusString(const RsPeerId& peer_id, const std::string& status_string) ; - - /*! - * sends immediate status to all peers - * @param status_string immediate status to send - */ - virtual void sendGroupChatStatusString(const std::string& status_string) ; + virtual void sendStatusString(const ChatId& chat_id, const std::string& status_string) ; /****************************************/ diff --git a/plugins/plugins.pro b/plugins/plugins.pro index 4db3505c2..15fe71c56 100644 --- a/plugins/plugins.pro +++ b/plugins/plugins.pro @@ -1,5 +1,5 @@ TEMPLATE = subdirs SUBDIRS += \ - VOIP \ - FeedReader + #VOIP \ + #FeedReader diff --git a/retroshare-gui/src/gui/ChatLobbyWidget.cpp b/retroshare-gui/src/gui/ChatLobbyWidget.cpp index 465ebf8de..bf7f8d304 100644 --- a/retroshare-gui/src/gui/ChatLobbyWidget.cpp +++ b/retroshare-gui/src/gui/ChatLobbyWidget.cpp @@ -491,9 +491,9 @@ void ChatLobbyWidget::updateDisplay() { if (item == ui.lobbyTreeWidget->currentItem()) { - ChatDialog::chatFriend(vpid) ; + ChatDialog::chatFriend(ChatId(lobby.lobby_id)) ; }else{ - ChatDialog::chatFriend(vpid,false) ; + ChatDialog::chatFriend(ChatId(lobby.lobby_id),false) ; } } } @@ -590,10 +590,7 @@ static void subscribeLobby(QTreeWidgetItem *item) ChatLobbyId id = item->data(COLUMN_DATA, ROLE_ID).toULongLong(); if (rsMsgs->joinVisibleChatLobby(id)) { - RsPeerId vpeer_id; - if (rsMsgs->getVirtualPeerId(id, vpeer_id)) { - ChatDialog::chatFriend(vpeer_id,true) ; - } + ChatDialog::chatFriend(ChatId(id),true) ; } } @@ -755,10 +752,7 @@ void ChatLobbyWidget::unsubscribeChatLobby(ChatLobbyId id) } // Unsubscribe the chat lobby - RsPeerId vpeer_id; - if (rsMsgs->getVirtualPeerId(id, vpeer_id)) - ChatDialog::closeChat(vpeer_id); - + ChatDialog::closeChat(ChatId(id)); rsMsgs->unsubscribeChatLobby(id); bool isAutoSubscribe = rsMsgs->getLobbyAutoSubscribe(id); if (isAutoSubscribe) rsMsgs->setLobbyAutoSubscribe(id, !isAutoSubscribe); @@ -834,12 +828,9 @@ void ChatLobbyWidget::itemDoubleClicked(QTreeWidgetItem *item, int /*column*/) void ChatLobbyWidget::displayChatLobbyEvent(qulonglong lobby_id, int event_type, const QString& nickname, const QString& str) { - RsPeerId vpid; - if (rsMsgs->getVirtualPeerId(lobby_id, vpid)) { - if (ChatLobbyDialog *cld = dynamic_cast(ChatDialog::getExistingChat(vpid))) { - cld->displayLobbyEvent(event_type, nickname, str); - } - } + if (ChatLobbyDialog *cld = dynamic_cast(ChatDialog::getExistingChat(ChatId(lobby_id)))) { + cld->displayLobbyEvent(event_type, nickname, str); + } } void ChatLobbyWidget::readChatLobbyInvites() @@ -855,7 +846,7 @@ void ChatLobbyWidget::readChatLobbyInvites() RsPeerId vpid; if(rsMsgs->getVirtualPeerId((*it).lobby_id,vpid )) { - ChatDialog::chatFriend(vpid,true); + ChatDialog::chatFriend(ChatId((*it).lobby_id),true); } else { std::cerr << "No lobby known with id 0x" << std::hex << (*it).lobby_id << std::dec << std::endl; } diff --git a/retroshare-gui/src/gui/FriendsDialog.cpp b/retroshare-gui/src/gui/FriendsDialog.cpp index a25a3b12c..d0608dbd5 100644 --- a/retroshare-gui/src/gui/FriendsDialog.cpp +++ b/retroshare-gui/src/gui/FriendsDialog.cpp @@ -21,26 +21,17 @@ #include -#include #include -#include #include -#include -#include -#include #include #include -#include -#include "retroshare/rspeers.h" +#include #include -#include "common/Emoticons.h" -#include "common/PeerDefs.h" #include "chat/ChatUserNotify.h" #include "connect/ConnectFriendWizard.h" #include "groups/CreateGroup.h" -#include "im_history/ImHistoryBrowser.h" #include "MainWindow.h" #include "NewsFeed.h" #include "notifyqt.h" @@ -49,7 +40,6 @@ #include "RetroShareLink.h" #include "settings/rsharesettings.h" #include "util/misc.h" -#include "util/HandleRichText.h" #include "util/DateTime.h" #include "FriendsDialog.h" #include "NetworkView.h" @@ -82,15 +72,20 @@ FriendsDialog::FriendsDialog(QWidget *parent) if (instance == NULL) { instance = this; } + QString msg = tr("Retroshare broadcast chat: messages are sent to all connected friends."); + // "" + DateTime::formatTime(QTime::currentTime()) + " - + msg = QString("" + msg + ""); + ui.chatWidget->setWelcomeMessage(msg); + ui.chatWidget->init(ChatId::makeBroadcastId(), tr("Broadcast")); - last_status_send_time = 0 ; - inChatCharFormatChanged = false; + connect(NotifyQt::getInstance(), SIGNAL(chatMessageReceived(ChatMessage)), + this, SLOT(chatMessageReceived(ChatMessage))); + connect(NotifyQt::getInstance(), SIGNAL(chatStatusChanged(ChatId,QString)), + this, SLOT(chatStatusReceived(ChatId,QString))); connect( ui.mypersonalstatusLabel, SIGNAL(clicked()), SLOT(statusmessage())); connect( ui.actionSet_your_Avatar, SIGNAL(triggered()), this, SLOT(getAvatar())); connect( ui.actionSet_your_Personal_Message, SIGNAL(triggered()), this, SLOT(statusmessage())); - connect( ui.addfileButton, SIGNAL(clicked() ), this , SLOT(addExtraFile())); - //connect( ui.actionAdd_Friend, SIGNAL(triggered()), this, SLOT(addFriend())); ui.avatar->setFrameType(AvatarWidget::STATUS_FRAME); ui.avatar->setOwnId(); @@ -116,58 +111,6 @@ FriendsDialog::FriendsDialog(QWidget *parent) //connect(newsFeed, SIGNAL(newsFeedChanged(int)), this, SLOT(newsFeedChanged(int))); - connect(ui.Sendbtn, SIGNAL(clicked()), this, SLOT(sendMsg())); - connect(ui.emoticonBtn, SIGNAL(clicked()), this, SLOT(smileyWidgetgroupchat())); - - connect(ui.msgText,SIGNAL(customContextMenuRequested(QPoint)),this,SLOT(contextMenuMsgText(QPoint))); - - connect(ui.lineEdit,SIGNAL(customContextMenuRequested(QPoint)),this,SLOT(contextMenu(QPoint))); - // reset text and color after removing all characters from the QTextEdit and after calling QTextEdit::clear - connect(ui.lineEdit, SIGNAL(currentCharFormatChanged(QTextCharFormat)), this, SLOT(chatCharFormatChanged())); - - connect(ui.textboldChatButton, SIGNAL(clicked()), this, SLOT(setFont())); - connect(ui.textunderlineChatButton, SIGNAL(clicked()), this, SLOT(setFont())); - connect(ui.textitalicChatButton, SIGNAL(clicked()), this, SLOT(setFont())); - connect(ui.fontsButton, SIGNAL(clicked()), this, SLOT(chooseFont())); - connect(ui.colorChatButton, SIGNAL(clicked()), this, SLOT(chooseColor())); - connect(ui.attachPictureButton, SIGNAL(clicked()), this, SLOT(addExtraPicture())); - connect(ui.actionSave_History, SIGNAL(triggered()), this, SLOT(fileSaveAs())); - - connect(ui.hashBox, SIGNAL(fileHashingFinished(QList)), this, SLOT(fileHashingFinished(QList))); - - ui.fontsButton->setIcon(QIcon(QString(":/images/fonts.png"))); - - mCurrentColor = Qt::black; - mCurrentFont.fromString(Settings->getChatScreenFont()); - - colorChanged(); - fontChanged(); - setColorAndFont(); - - style.setStyleFromSettings(ChatStyle::TYPE_PUBLIC); - - setChatInfo(tr("Retroshare broadcast chat: messages are sent to all connected friends."), QString::fromUtf8("blue")); - - if (rsHistory->getEnable(true)) { - int messageCount = Settings->getPublicChatHistoryCount(); - if (messageCount > 0) { - std::list historyMsgs; - rsHistory->getMessages(RsPeerId(), historyMsgs, messageCount); - - std::list::iterator it; - for (it = historyMsgs.begin(); it != historyMsgs.end(); ++it) { - addChatMsg(it->incoming, true, QString::fromUtf8(it->peerName.c_str()), QDateTime::fromTime_t(it->sendTime), QDateTime::fromTime_t(it->recvTime), QString::fromUtf8(it->message.c_str())); - } - } - } - - QMenu *menu = new QMenu(); - menu->addAction(ui.actionClear_Chat_History); - menu->addAction(ui.actionDelete_Chat_History); - menu->addAction(ui.actionSave_History); - menu->addAction(ui.actionMessageHistory); - ui.menuButton->setMenu(menu); - // menu = new QMenu(); // menu->addAction(ui.actionAdd_Friend); // menu->addAction(ui.actionAdd_Group); @@ -185,17 +128,13 @@ FriendsDialog::FriendsDialog(QWidget *parent) connect(addFriendButton, SIGNAL(clicked()), this, SLOT(addFriend())); ui.friendList->addToolButton(addFriendButton);*/ - setAcceptDrops(true); - ui.lineEdit->setAcceptDrops(false); - ui.hashBox->setDropWidget(this); - ui.hashBox->setAutoHide(true); - /* Set initial size the splitter */ ui.splitter->setStretchFactor(0, 0); ui.splitter->setStretchFactor(1, 1); - QList sizes; + /*remove +QList sizes; sizes << height() << 100; // Qt calculates the right sizes - ui.splitter_2->setSizes(sizes); + ui.splitter_2->setSizes(sizes);*/ loadmypersonalstatus(); @@ -212,7 +151,6 @@ FriendsDialog::FriendsDialog(QWidget *parent) processSettings(true); RsAutoUpdatePage::unlockAllEvents(); - ui.lineEdit->installEventFilter(this); // add self nick and Avatar to Friends. RsPeerDetails pd ; @@ -240,11 +178,6 @@ FriendsDialog::FriendsDialog(QWidget *parent) #ifdef Q_WS_WIN #endif - -#if QT_VERSION < 0x040700 - // embedded images are not supported before QT 4.7.0 - ui.attachPictureButton->setVisible(false); -#endif } FriendsDialog::~FriendsDialog () @@ -290,13 +223,13 @@ void FriendsDialog::processSettings(bool bLoad) // state of splitter ui.splitter->restoreState(Settings->value("Splitter").toByteArray()); - ui.splitter_2->restoreState(Settings->value("GroupChatSplitter").toByteArray()); + //remove ui.splitter_2->restoreState(Settings->value("GroupChatSplitter").toByteArray()); } else { // save settings // state of splitter Settings->setValue("Splitter", ui.splitter->saveState()); - Settings->setValue("GroupChatSplitter", ui.splitter_2->saveState()); + //remove Settings->setValue("GroupChatSplitter", ui.splitter_2->saveState()); } ui.friendList->processSettings(bLoad); @@ -310,59 +243,35 @@ void FriendsDialog::showEvent(QShowEvent *event) if (first) { // Workaround: now the scroll position is correct calculated first = false; + /* remove QScrollBar *scrollbar = ui.msgText->verticalScrollBar(); scrollbar->setValue(scrollbar->maximum()); + */ } RsAutoUpdatePage::showEvent(event); } -void FriendsDialog::pasteLink() +void FriendsDialog::chatMessageReceived(const ChatMessage &msg) { - ui.lineEdit->insertHtml(RSLinkClipboard::toHtml()) ; -} + if(msg.chat_id.isBroadcast()) + { + QDateTime sendTime = QDateTime::fromTime_t(msg.sendTime); + QDateTime recvTime = QDateTime::fromTime_t(msg.recvTime); + QString message = QString::fromUtf8(msg.msg.c_str()); + QString name = QString::fromUtf8(rsPeers->getPeerName(msg.broadcast_peer_id).c_str()); -void FriendsDialog::contextMenuMsgText(QPoint point) -{ - QMatrix matrix; - matrix.translate(ui.msgText->horizontalScrollBar()->value(), ui.msgText->verticalScrollBar()->value()); - - QMenu *contextMnu = ui.msgText->createStandardContextMenu(matrix.map(point)); - - contextMnu->addSeparator(); - contextMnu->addAction(ui.actionClear_Chat_History); - - contextMnu->exec(ui.msgText->viewport()->mapToGlobal(point)); - delete(contextMnu); -} - -void FriendsDialog::contextMenu(QPoint point) -{ - QMenu *contextMnu = ui.lineEdit->createStandardContextMenu(point); - - contextMnu->addSeparator(); - QAction *action = contextMnu->addAction(QIcon(":/images/pasterslink.png"), tr("Paste RetroShare Link"), this, SLOT(pasteLink())); - action->setDisabled(RSLinkClipboard::empty()); - - contextMnu->exec(QCursor::pos()); - delete(contextMnu); -} - -void FriendsDialog::chatCharFormatChanged() -{ - if (inChatCharFormatChanged) { - return; + ui.chatWidget->addChatMsg(msg.incoming, name, sendTime, recvTime, message, ChatWidget::MSGTYPE_NORMAL); } +} - inChatCharFormatChanged = true; - - // Reset font and color before inserting a character if edit box is empty - // (color info disappears when the user deletes all text) - if (ui.lineEdit->toPlainText().isEmpty()) { - setColorAndFont(); +void FriendsDialog::chatStatusReceived(const ChatId &chat_id, const QString &status_string) +{ + if(chat_id.isBroadcast()) + { + QString name = QString::fromUtf8(rsPeers->getPeerName(chat_id.broadcast_status_peer_id).c_str()); + ui.chatWidget->updateStatusString(name + " %1", status_string); } - - inChatCharFormatChanged = false; } void FriendsDialog::updateDisplay() @@ -382,415 +291,6 @@ void FriendsDialog::addFriend() connwiz.exec (); } -void FriendsDialog::resetStatusBar() -{ -#ifdef FRIENDS_DEBUG - std::cerr << "FriendsDialog: reseting status bar." << std::endl ; -#endif - - ui.statusStringLabel->setText(QString("")) ; -} - -void FriendsDialog::updateStatusTyping() -{ - if(time(NULL) - last_status_send_time > 5) // limit 'peer is typing' packets to at most every 10 sec - { -#ifdef FRIENDS_DEBUG - std::cerr << "FriendsDialog: sending group chat typing info." << std::endl ; -#endif - -#ifdef ONLY_FOR_LINGUIST - tr("is typing..."); -#endif - - rsMsgs->sendGroupChatStatusString("is typing..."); - last_status_send_time = time(NULL) ; - } -} - -// Called by libretroshare through notifyQt to display the peer's status -// -void FriendsDialog::updateStatusString(const QString& peer_id, const QString& status_string) -{ -#ifdef FRIENDS_DEBUG - std::cerr << "FriendsDialog: received group chat typing info. updating gui." << std::endl ; -#endif - - QString status = QString::fromUtf8(rsPeers->getPeerName(RsPeerId(peer_id.toStdString())).c_str()) + " " + tr(status_string.toLatin1()); - ui.statusStringLabel->setText(status) ; // displays info for 5 secs. - - QTimer::singleShot(5000,this,SLOT(resetStatusBar())) ; -} - -void FriendsDialog::updatePeerStatusString(const QString& peer_id,const QString& status_string,bool is_private_chat) -{ - if (!is_private_chat) { -#ifdef FRIENDS_DEBUG - std::cerr << "Updating public chat msg from peer " << rsPeers->getPeerName(peer_id.toStdString()) << ": " << status_string.toStdString() << std::endl ; -#endif - - updateStatusString(peer_id, status_string); - } -} - -void FriendsDialog::publicChatChanged(int type) -{ - if (type == NOTIFY_TYPE_ADD) { - insertChat(); - } -} - -void FriendsDialog::addChatMsg(bool incoming, bool history, const QString &name, const QDateTime &sendTime, const QDateTime &recvTime, const QString &message) -{ - unsigned int formatTextFlag = RSHTML_FORMATTEXT_EMBED_LINKS | RSHTML_FORMATTEXT_OPTIMIZE; - - // embed smileys ? - if (Settings->valueFromGroup("Chat", "Emoteicons_GroupChat", true).toBool()) { - formatTextFlag |= RSHTML_FORMATTEXT_EMBED_SMILEYS; - } - - // Always fix colors - formatTextFlag |= RSHTML_FORMATTEXT_FIX_COLORS; - qreal desiredContrast = Settings->valueFromGroup("Chat", "MinimumContrast", 4.5).toDouble(); - QColor backgroundColor = ui.groupChatTab->palette().base().color(); - - // Remove font name, size, bold, italics? - if (!Settings->valueFromGroup("Chat", "EnableCustomFonts", true).toBool()) { - formatTextFlag |= RSHTML_FORMATTEXT_REMOVE_FONT_FAMILY; - } - if (!Settings->valueFromGroup("Chat", "EnableCustomFontSize", true).toBool()) { - formatTextFlag |= RSHTML_FORMATTEXT_REMOVE_FONT_SIZE; - } - if (!Settings->valueFromGroup("Chat", "EnableBold", true).toBool()) { - formatTextFlag |= RSHTML_FORMATTEXT_REMOVE_FONT_WEIGHT; - } - if (!Settings->valueFromGroup("Chat", "EnableItalics", true).toBool()) { - formatTextFlag |= RSHTML_FORMATTEXT_REMOVE_FONT_STYLE; - } - - ChatStyle::enumFormatMessage type; - if (incoming) { - if (history) { - type = ChatStyle::FORMATMSG_HINCOMING; - } else { - type = ChatStyle::FORMATMSG_INCOMING; - } - } else { - if (history) { - type = ChatStyle::FORMATMSG_HOUTGOING; - } else { - type = ChatStyle::FORMATMSG_OUTGOING; - } - } - - QString formattedMessage = RsHtml().formatText(ui.msgText->document(), message, formatTextFlag, backgroundColor, desiredContrast); - QString formatMsg = style.formatMessage(type, name, incoming ? recvTime : sendTime, formattedMessage); - - ui.msgText->textCursor().setBlockFormat(QTextBlockFormat ()); - ui.msgText->append(formatMsg); -} - -void FriendsDialog::insertChat() -{ - std::list newchat; - if (!rsMsgs->getPublicChatQueue(newchat)) - { -#ifdef FRIENDS_DEBUG - std::cerr << "no chat available." << std::endl ; -#endif - return; - } -#ifdef FRIENDS_DEBUG - std::cerr << "got new chat." << std::endl; -#endif - std::list::iterator it; - - /* add in lines at the bottom */ - for(it = newchat.begin(); it != newchat.end(); ++it) - { - /* are they private? */ - if (it->chatflags & RS_CHAT_PRIVATE) - { - /* this should not happen */ - continue; - } - - QDateTime sendTime = QDateTime::fromTime_t(it->sendTime); - QDateTime recvTime = QDateTime::fromTime_t(it->recvTime); - QString name = QString::fromUtf8(rsPeers->getPeerName(it->rsid).c_str()); - QString msg = QString::fromUtf8(it->msg.c_str()); - -#ifdef FRIENDS_DEBUG - std::cerr << "FriendsDialog::insertChat(): " << msg.toStdString() << std::endl; -#endif - - bool incoming = false; - - // notify with a systray icon msg - if(it->rsid != rsPeers->getOwnId()) - { - incoming = true; - - // This is a trick to translate HTML into text. - QTextEdit editor; - editor.setHtml(msg); - QString notifyMsg = name + ": " + editor.toPlainText(); - - if(notifyMsg.length() > 30) - emit notifyGroupChat(tr("New group chat"), notifyMsg.left(30) + QString("...")); - else - emit notifyGroupChat(tr("New group chat"), notifyMsg); - } - - addChatMsg(incoming, false, name, sendTime, recvTime, msg); - } -} - -bool FriendsDialog::eventFilter(QObject *obj, QEvent *event) -{ - if (obj == ui.lineEdit) { - if (event->type() == QEvent::KeyPress) { - updateStatusTyping() ; - - QKeyEvent *keyEvent = static_cast(event); - if (keyEvent && (keyEvent->key() == Qt::Key_Enter || keyEvent->key() == Qt::Key_Return)) { - // Enter pressed - if (Settings->getChatSendMessageWithCtrlReturn()) { - if (keyEvent->modifiers() & Qt::ControlModifier) { - // send message with Ctrl+Enter - sendMsg(); - return true; // eat event - } - } else { - if (keyEvent->modifiers() & Qt::ControlModifier) { - // insert return - ui.lineEdit->textCursor().insertText("\n"); - } else { - // send message with Enter - sendMsg(); - } - return true; // eat event - } - } - } - } - // pass the event on to the parent class - return RsAutoUpdatePage::eventFilter(obj, event); -} - -void FriendsDialog::sendMsg() -{ - QTextEdit *lineWidget = ui.lineEdit; - - if (lineWidget->toPlainText().isEmpty()) { - // nothing to send - return; - } - - QString text; - RsHtml::optimizeHtml(lineWidget, text); - std::string message = text.toUtf8().constData(); - -#ifdef FRIENDS_DEBUG - std::string msg(message.begin(), message.end()); - std::cerr << "FriendsDialog::sendMsg(): " << msg << std::endl; -#endif - - if (rsMsgs->sendPublicChat(message)) { - QString name = ui.nicknameLabel->text(); - QDateTime currentTime = QDateTime::currentDateTime(); - addChatMsg(false, false, name, currentTime, currentTime, text); - }//if (rsMsgs->sendPublicChat(message)) - ui.lineEdit->clear(); - // workaround for Qt bug - http://bugreports.qt.nokia.com/browse/QTBUG-2533 - // QTextEdit::clear() does not reset the CharFormat if document contains hyperlinks that have been accessed. - ui.lineEdit->setCurrentCharFormat(QTextCharFormat ()); - - /* redraw send list */ - insertSendList(); -} - -void FriendsDialog::insertSendList() -{ -#ifdef false - std::list peers; - std::list::iterator it; - - if (!rsPeers) - { - /* not ready yet! */ - return; - } - - rsPeers->getOnlineList(peers); - - /* get a link to the table */ - //QTreeWidget *sendWidget = ui.msgSendList; - QList items; - - for(it = peers.begin(); it != peers.end(); ++it) - { - - RsPeerDetails details; - if (!rsPeers->getPeerDetails(*it, details)) - { - continue; /* BAD */ - } - - /* make a widget per friend */ - QTreeWidgetItem *item = new QTreeWidgetItem((QTreeWidget*)0); - - /* add all the labels */ - /* (0) Person */ - item -> setText(0, QString::fromUtf8(details.name.c_str())); - - item -> setFlags(Qt::ItemIsUserCheckable | Qt::ItemIsEnabled); - //item -> setFlags(Qt::ItemIsUserCheckable); - - item -> setCheckState(0, Qt::Checked); - - if (rsicontrol->IsInChat(*it)) - { - item -> setCheckState(0, Qt::Checked); - } - else - { - item -> setCheckState(0, Qt::Unchecked); - } - - /* disable for the moment */ - item -> setFlags(Qt::ItemIsUserCheckable); - item -> setCheckState(0, Qt::Checked); - - /* add to the list */ - items.append(item); - } - - /* remove old items */ - //sendWidget->clear(); - //sendWidget->setColumnCount(1); - - /* add the items in! */ - //sendWidget->insertTopLevelItems(0, items); - - //sendWidget->update(); /* update display */ -#endif -} - - -/* to toggle the state */ - - -//void FriendsDialog::toggleSendItem( QTreeWidgetItem *item, int col ) -//{ -//#ifdef FRIENDS_DEBUG -// std::cerr << "ToggleSendItem()" << std::endl; -//#endif -// -// /* extract id */ -// std::string id = (item -> text(4)).toStdString(); -// -// /* get state */ -// bool inChat = (Qt::Checked == item -> checkState(0)); /* alway column 0 */ -// -// /* call control fns */ -// -// rsicontrol -> SetInChat(id, inChat); -// return; -//} - -//============================================================================ - -void FriendsDialog::chooseColor() -{ - bool ok; - QRgb color = QColorDialog::getRgba(ui.lineEdit->textColor().rgba(), &ok, this); - if (ok) { - mCurrentColor = QColor(color); - colorChanged(); - setColorAndFont(); - } -} - -void FriendsDialog::colorChanged() -{ - QPixmap pxm(16,16); - pxm.fill(mCurrentColor); - ui.colorChatButton->setIcon(pxm); -} - -void FriendsDialog::chooseFont() -{ - bool ok; - QFont font = QFontDialog::getFont(&ok, mCurrentFont, this); - if (ok) { - mCurrentFont = font; - fontChanged(); - setFont(); - } -} - -void FriendsDialog::fontChanged() -{ - ui.textboldChatButton->setChecked(mCurrentFont.bold()); - ui.textunderlineChatButton->setChecked(mCurrentFont.underline()); - ui.textitalicChatButton->setChecked(mCurrentFont.italic()); -} - -void FriendsDialog::setColorAndFont() -{ - mCurrentFont.setBold(ui.textboldChatButton->isChecked()); - mCurrentFont.setUnderline(ui.textunderlineChatButton->isChecked()); - mCurrentFont.setItalic(ui.textitalicChatButton->isChecked()); - - ui.lineEdit->setFont(mCurrentFont); - ui.lineEdit->setTextColor(mCurrentColor); - - ui.lineEdit->setFocus(); -} - -void FriendsDialog::setFont() -{ - setColorAndFont(); - Settings->setChatScreenFont(mCurrentFont.toString()); -} - -// Update Chat Info information -void FriendsDialog::setChatInfo(QString info, QColor color) -{ - static unsigned int nbLines = 0; - ++nbLines; - // Check log size, clear it if too big - if(nbLines > 200) { - ui.msgText->clear(); - nbLines = 1; - } - ui.msgText->append("" + DateTime::formatTime(QTime::currentTime()) + " - " + info + ""); -} - -void FriendsDialog::on_actionClear_Chat_History_triggered() -{ - ui.msgText->clear(); -} - -void FriendsDialog::on_actionDelete_Chat_History_triggered() -{ - if ((QMessageBox::question(this, "RetroShare", tr("Do you really want to physically delete the history?"), QMessageBox::Yes | QMessageBox::No, QMessageBox::Yes)) == QMessageBox::Yes) { - on_actionClear_Chat_History_triggered(); - rsHistory->clear(RsPeerId()); - } -} - -void FriendsDialog::smileyWidgetgroupchat() -{ - Emoticons::showSmileyWidget(this, ui.emoticonBtn, SLOT(addSmileys()), true); -} - -void FriendsDialog::addSmileys() -{ - ui.lineEdit->textCursor().insertText(qobject_cast(sender())->toolTip().split("|").first()); -} - void FriendsDialog::getAvatar() { QByteArray ba; @@ -825,94 +325,6 @@ void FriendsDialog::statusmessage() statusmsgdialog.exec(); } -void FriendsDialog::addExtraFile() -{ - QStringList files; - if (misc::getOpenFileNames(this, RshareSettings::LASTDIR_EXTRAFILE, tr("Add Extra File"), "", files)) { - ui.hashBox->addAttachments(files,TransferRequestFlags(0u)); // no anonymous routing, because it is for friends only! - } -} - -void FriendsDialog::addExtraPicture() -{ - // select a picture file - QString file; - if (misc::getOpenFileName(window(), RshareSettings::LASTDIR_IMAGES, tr("Load Picture File"), "Pictures (*.png *.xpm *.jpg *.jpeg)", file)) { - QString encodedImage; - if (RsHtml::makeEmbeddedImage(file, encodedImage, 640*480)) { - QTextDocumentFragment fragment = QTextDocumentFragment::fromHtml(encodedImage); - ui.lineEdit->textCursor().insertFragment(fragment); - } - } -} - -void FriendsDialog::fileHashingFinished(QList hashedFiles) -{ - std::cerr << "FriendsDialog::fileHashingFinished() started." << std::endl; - - QString mesgString; - - QList::iterator it; - for (it = hashedFiles.begin(); it != hashedFiles.end(); ++it) { - HashedFile& hashedFile = *it; - RetroShareLink link; - - if (!link.createExtraFile(hashedFile.filename, hashedFile.size, QString::fromStdString(hashedFile.hash.toStdString()),QString::fromStdString(rsPeers->getOwnId().toStdString()))) - continue; - - mesgString += link.toHtmlSize(); - if (it!= hashedFiles.end()) { - mesgString += "
"; - } - } - -#ifdef FRIENDS_DEBUG - std::cerr << "FriendsDialog::fileHashingFinished mesgString : " << mesgString.toStdString() << std::endl; -#endif - - ui.lineEdit->insertHtml(mesgString); -} - -bool FriendsDialog::fileSave() -{ - if (fileName.isEmpty()) - return fileSaveAs(); - - QFile file(fileName); - if (!file.open(QFile::WriteOnly)) - return false; - QTextStream ts(&file); - ts.setCodec(QTextCodec::codecForName("UTF-8")); - ts << ui.msgText->document()->toPlainText(); - ui.msgText->document()->setModified(false); - return true; -} - -bool FriendsDialog::fileSaveAs() -{ - QString fn; - if (misc::getSaveFileName(this, RshareSettings::LASTDIR_HISTORY, tr("Save as..."), tr("Text File (*.txt );;All Files (*)"), fn)) { - setCurrentFileName(fn); - return fileSave(); - } - - return false; -} - -void FriendsDialog::setCurrentFileName(const QString &fileName) -{ - this->fileName = fileName; - ui.msgText->document()->setModified(false); - - setWindowModified(false); -} - -void FriendsDialog::on_actionMessageHistory_triggered() -{ - ImHistoryBrowser imBrowser(RsPeerId(), ui.lineEdit, this); - imBrowser.exec(); -} - /*static*/ bool FriendsDialog::isGroupChatActive() { FriendsDialog *friendsDialog = dynamic_cast(MainWindow::getPage(MainWindow::Friends)); @@ -936,5 +348,5 @@ void FriendsDialog::on_actionMessageHistory_triggered() MainWindow::showWindow(MainWindow::Friends); friendsDialog->ui.tabWidget->setCurrentWidget(friendsDialog->ui.groupChatTab); - friendsDialog->ui.lineEdit->setFocus(); + friendsDialog->ui.chatWidget->focusDialog(); } diff --git a/retroshare-gui/src/gui/FriendsDialog.h b/retroshare-gui/src/gui/FriendsDialog.h index e3a04e1f2..fc7374d7e 100644 --- a/retroshare-gui/src/gui/FriendsDialog.h +++ b/retroshare-gui/src/gui/FriendsDialog.h @@ -22,18 +22,13 @@ #ifndef _FRIENDSDIALOG_H #define _FRIENDSDIALOG_H -#include "chat/ChatStyle.h" #include "retroshare-gui/RsAutoUpdatePage.h" #include "ui_FriendsDialog.h" #define IMAGE_PEERS ":/images/groupchat.png" -class QFont; class QAction; -class QTextEdit; -class QTextCharFormat; -class ChatTabWidget; class NetworkDialog; class NetworkView; class IdDialog; @@ -82,68 +77,21 @@ public: #endif IdDialog *idDialog; -public slots: - - void publicChatChanged(int type); -// void toggleSendItem( QTreeWidgetItem *item, int col ); - - void insertChat(); - void setChatInfo(QString info, QColor color=QApplication::palette().color(QPalette::WindowText)); - void resetStatusBar() ; - - void fileHashingFinished(QList hashedFiles); - - void smileyWidgetgroupchat(); - void addSmileys(); - - // called by notifyQt when another peer is typing (in group chant and private chat) - void updatePeerStatusString(const QString& peer_id,const QString& status_string,bool is_private_chat) ; - protected: - bool eventFilter(QObject *obj, QEvent *ev); void showEvent (QShowEvent *event); private slots: - void pasteLink() ; - void contextMenu(QPoint) ; - void contextMenuMsgText(QPoint); - void chatCharFormatChanged(); - - void on_actionClear_Chat_History_triggered(); - void on_actionDelete_Chat_History_triggered(); - void on_actionMessageHistory_triggered(); - - void updateStatusString(const QString& peer_id, const QString& statusString) ; // called when a peer is typing in group chat - void updateStatusTyping() ; // called each time a key is hit - - //void updatePeerStatusString(const QString& peer_id,const QString& chat_status) ; + void chatMessageReceived(const ChatMessage& msg); + void chatStatusReceived(const ChatId& chat_id, const QString& status_string); void addFriend(); - void chooseColor(); - void insertSendList(); - void sendMsg(); - void statusmessage(); - void setFont(); - void chooseFont(); - void getAvatar(); -// void on_actionAdd_Group_activated(); - void loadmypersonalstatus(); - void addExtraFile(); - - void addExtraPicture(); - - bool fileSave(); - bool fileSaveAs(); - - void setCurrentFileName(const QString &fileName); - //void newsFeedChanged(int count); signals: @@ -151,25 +99,6 @@ signals: private: void processSettings(bool bLoad); - void addChatMsg(bool incoming, bool history, const QString &name, const QDateTime &sendTime, const QDateTime &recvTime, const QString &message); - - void colorChanged(); - void fontChanged(); - void setColorAndFont(); - - QString fileName; - - ChatStyle style; - - QColor mCurrentColor; - time_t last_status_send_time ; - - QFont mCurrentFont; /* how the text will come out */ - - //QWidget *newsFeed; - //QColor newsFeedTabColor; - //QString newsFeedText; - bool inChatCharFormatChanged; /** Qt Designer generated object */ Ui::FriendsDialog ui; diff --git a/retroshare-gui/src/gui/FriendsDialog.ui b/retroshare-gui/src/gui/FriendsDialog.ui index 644f623a5..8de4ebdb4 100644 --- a/retroshare-gui/src/gui/FriendsDialog.ui +++ b/retroshare-gui/src/gui/FriendsDialog.ui @@ -223,463 +223,8 @@ Broadcast - - - - - 16777215 - 38 - - - - QFrame::Box - - - QFrame::Sunken - - - - 6 - - - - - - 0 - 0 - - - - - 24 - 24 - - - - - 24 - 24 - - - - Qt::NoFocus - - - - :/images/emoticons/kopete/kopete020.png:/images/emoticons/kopete/kopete020.png - - - - 24 - 24 - - - - true - - - - - - - - 0 - 0 - - - - - 24 - 24 - - - - - 24 - 24 - - - - Qt::NoFocus - - - Bold - - - - :/images/edit-bold.png:/images/edit-bold.png - - - true - - - true - - - - - - - - 0 - 0 - - - - - 24 - 24 - - - - - 24 - 24 - - - - Qt::NoFocus - - - Underline - - - - - - - :/images/edit-underline.png:/images/edit-underline.png - - - true - - - true - - - - - - - - 0 - 0 - - - - - 24 - 24 - - - - - 24 - 24 - - - - Qt::NoFocus - - - Italic - - - - :/images/edit-italic.png:/images/edit-italic.png - - - true - - - true - - - - - - - - 0 - 0 - - - - - 24 - 24 - - - - - 24 - 24 - - - - Qt::NoFocus - - - Font - - - - :/images/fonts.png:/images/fonts.png - - - true - - - - - - - - 0 - 0 - - - - - 24 - 24 - - - - - 24 - 24 - - - - Qt::NoFocus - - - Text Color - - - true - - - - - - - - 28 - 28 - - - - - 28 - 28 - - - - Qt::NoFocus - - - Attach a Picture - - - - :/images/add_image24.png:/images/add_image24.png - - - - 24 - 24 - - - - true - - - - - - - - 0 - 0 - - - - - 26 - 26 - - - - - 26 - 26 - - - - Qt::NoFocus - - - Attach File - - - - :/images/add-share24.png:/images/add-share24.png - - - - 24 - 24 - - - - true - - - - - - - - 0 - 0 - - - - - 24 - 24 - - - - - 24 - 24 - - - - Qt::NoFocus - - - - :/images/configure.png:/images/configure.png - - - - 22 - 22 - - - - QToolButton::InstantPopup - - - true - - - - - - - Qt::Horizontal - - - QSizePolicy::Expanding - - - - 321 - 20 - - - - - - - - Send - - - - - - - - - Qt::Vertical - - - 5 - - - false - - - - - 0 - 0 - - - - - 0 - 60 - - - - Qt::CustomContextMenu - - - true - - - - - - 0 - - - - - - - - - - - - - 0 - 30 - - - - Qt::CustomContextMenu - - - Messages entered here are sent to all connected friends - - - - - - - - - - - - 0 - 0 - - - - true - - + @@ -798,11 +343,6 @@ QLabel
gui/common/StyledLabel.h
- - RSTextBrowser - QTextBrowser -
gui/common/RSTextBrowser.h
-
AvatarWidget QLabel @@ -815,12 +355,6 @@
gui/common/FriendList.h
1
- - HashBox - QScrollArea -
gui/common/HashBox.h
- 1 -
ChatTabWidget QTabWidget @@ -832,6 +366,12 @@ QLabel
gui/common/StyledElidedLabel.h
+ + ChatWidget + QWidget +
gui/chat/ChatWidget.h
+ 1 +
diff --git a/retroshare-gui/src/gui/NewsFeed.cpp b/retroshare-gui/src/gui/NewsFeed.cpp index 5b74f9337..aaad6ea19 100644 --- a/retroshare-gui/src/gui/NewsFeed.cpp +++ b/retroshare-gui/src/gui/NewsFeed.cpp @@ -1175,7 +1175,7 @@ void NewsFeed::openChat(const RsPeerId &peerId) std::cerr << std::endl; #endif - ChatDialog::chatFriend(peerId); + ChatDialog::chatFriend(ChatId(peerId)); } void NewsFeed::openComments(uint32_t /*type*/, const RsGxsGroupId &/*groupId*/, const RsGxsMessageId &/*msgId*/, const QString &/*title*/) diff --git a/retroshare-gui/src/gui/chat/ChatDialog.cpp b/retroshare-gui/src/gui/chat/ChatDialog.cpp index 801b8ad9a..a8763faf0 100644 --- a/retroshare-gui/src/gui/chat/ChatDialog.cpp +++ b/retroshare-gui/src/gui/chat/ChatDialog.cpp @@ -36,7 +36,7 @@ #include #include -static std::map chatDialogs; +static std::map chatDialogs2; ChatDialog::ChatDialog(QWidget *parent, Qt::WindowFlags flags) : QWidget(parent, flags) @@ -46,9 +46,9 @@ ChatDialog::ChatDialog(QWidget *parent, Qt::WindowFlags flags) : ChatDialog::~ChatDialog() { - std::map::iterator it; - if (chatDialogs.end() != (it = chatDialogs.find(getPeerId()))) { - chatDialogs.erase(it); + std::map::iterator it; + if (chatDialogs2.end() != (it = chatDialogs2.find(mChatId))) { + chatDialogs2.erase(it); } } @@ -61,85 +61,72 @@ void ChatDialog::closeEvent(QCloseEvent *event) emit dialogClose(this); } -void ChatDialog::init(const RsPeerId &peerId, const QString &title) +void ChatDialog::init(ChatId id, const QString &title) { - this->peerId = peerId; - + mChatId = id; ChatWidget *cw = getChatWidget(); if (cw) { - cw->init(peerId, title); + cw->init(id, title); connect(cw, SIGNAL(infoChanged(ChatWidget*)), this, SLOT(chatInfoChanged(ChatWidget*))); connect(cw, SIGNAL(newMessage(ChatWidget*)), this, SLOT(chatNewMessage(ChatWidget*))); } } -/*static*/ ChatDialog *ChatDialog::getExistingChat(const RsPeerId &peerId) +/*static*/ ChatDialog* ChatDialog::getExistingChat(ChatId id) { - std::map::iterator it; - if (chatDialogs.end() != (it = chatDialogs.find(peerId))) { - /* exists already */ - return it->second; - } + std::map::iterator it; + if (chatDialogs2.end() != (it = chatDialogs2.find(id))) { + /* exists already */ + return it->second; + } - return NULL; + return NULL; } -/*static*/ ChatDialog *ChatDialog::getChat(const RsPeerId &peerId, uint chatflags) +/*static*/ ChatDialog* ChatDialog::getChat(ChatId id, uint chatflags) { - /* see if it already exists */ - ChatDialog *cd = getExistingChat(peerId); + if(id.isBroadcast() || id.isNotSet()) + return NULL; // broadcast is not handled by a chat dialog - if (cd == NULL) { - ChatLobbyId lobby_id = 0; + /* see if it already exists */ + ChatDialog *cd = getExistingChat(id); - if (rsMsgs->isLobbyId(peerId, lobby_id)) { - // chatflags = RS_CHAT_OPEN | RS_CHAT_FOCUS; // use own flags - } + if (cd == NULL) { - uint32_t distant_peer_status ; + if(id.isGxsId()) + chatflags = RS_CHAT_OPEN | RS_CHAT_FOCUS; // force open for distant chat - if(rsMsgs->getDistantChatStatus(RsGxsId(peerId),distant_peer_status)) - chatflags = RS_CHAT_OPEN | RS_CHAT_FOCUS; // use own flags + if (chatflags & RS_CHAT_OPEN) { + if (id.isLobbyId()) { + ChatLobbyDialog* cld = new ChatLobbyDialog(id.toLobbyId()); + cld->init(); + cd = cld; + } else if(id.isGxsId()) { + PopupDistantChatDialog* pdcd = new PopupDistantChatDialog(); + QString peer_name = pdcd->getPeerName(id) ; + pdcd->init(id.toGxsId(), tr("Talking to ")+peer_name) ; + cd = pdcd; + } else { + RsPeerDetails sslDetails; + if (rsPeers->getPeerDetails(id.toPeerId(), sslDetails)) { + PopupChatDialog* pcd = new PopupChatDialog(); + pcd->init(id, PeerDefs::nameWithLocation(sslDetails)); + cd = pcd; + } + } + if(cd) + chatDialogs2[id] = cd; + } + } - if (chatflags & RS_CHAT_OPEN) { - if (lobby_id) { - std::list linfos; - rsMsgs->getChatLobbyList(linfos); + if (cd == NULL) { + return NULL; + } - for (std::list::const_iterator it(linfos.begin()); it != linfos.end(); ++it) { - if ((*it).lobby_id == lobby_id) { - cd = new ChatLobbyDialog(lobby_id); - chatDialogs[peerId] = cd; - cd->init(peerId, QString::fromUtf8((*it).lobby_name.c_str())); - } - } - } else if(distant_peer_status > 0) { - cd = new PopupDistantChatDialog(); - chatDialogs[peerId] = cd; - QString peer_name = cd->getPeerName(peerId) ; - cd->init(peerId, tr("Talking to ")+peer_name+" (GXS id="+QString::fromStdString(peerId.toStdString())+")") ; + cd->showDialog(chatflags); - } else { - RsPeerDetails sslDetails; - if (rsPeers->getPeerDetails(peerId, sslDetails)) { - cd = new PopupChatDialog(); - - chatDialogs[peerId] = cd; - cd->init(peerId, PeerDefs::nameWithLocation(sslDetails)); - } - } - } - } - - if (cd == NULL) { - return NULL; - } - - cd->insertChatMsgs(); - cd->showDialog(chatflags); - - return cd; + return cd; } /*static*/ void ChatDialog::cleanupChat() @@ -149,14 +136,14 @@ void ChatDialog::init(const RsPeerId &peerId, const QString &title) /* ChatDialog destuctor removes the entry from the map */ std::list list; - std::map::iterator it; - for (it = chatDialogs.begin(); it != chatDialogs.end(); ++it) { + std::map::iterator it; + for (it = chatDialogs2.begin(); it != chatDialogs2.end(); ++it) { if (it->second) { list.push_back(it->second); } } - chatDialogs.clear(); + chatDialogs2.clear(); std::list::iterator it1; for (it1 = list.begin(); it1 != list.end(); ++it1) { @@ -164,47 +151,40 @@ void ChatDialog::init(const RsPeerId &peerId, const QString &title) } } -/*static*/ void ChatDialog::chatChanged(int list, int type) +/*static*/ void ChatDialog::closeChat(const ChatId &chat_id) { - if (list == NOTIFY_LIST_PRIVATE_INCOMING_CHAT && type == NOTIFY_TYPE_ADD) { - // play sound when recv a message - soundManager->play(SOUND_NEW_CHAT_MESSAGE); - - std::list ids; - if (rsMsgs->getPrivateChatQueueIds(true, ids)) { - uint chatflags = Settings->getChatFlags(); - - std::list::iterator id; - for (id = ids.begin(); id != ids.end(); ++id) { - ChatDialog *cd = getChat(*id, chatflags); - - if (cd) { - cd->insertChatMsgs(); - } - } - } - } - - /* now notify all open priavate chat windows */ - std::map::iterator it; - for (it = chatDialogs.begin (); it != chatDialogs.end(); ++it) { - if (it->second) { - it->second->onChatChanged(list, type); - } - } -} - -/*static*/ void ChatDialog::closeChat(const RsPeerId &peerId) -{ - ChatDialog *chatDialog = getExistingChat(peerId); + ChatDialog *chatDialog = getExistingChat(chat_id); if (chatDialog) { - delete(chatDialog); + //delete chatDialog; // ChatDialog removes itself from the map + chatDialog->deleteLater(); } } -/*static*/ void ChatDialog::chatFriend(const RsPeerId &peerId, const bool forceFocus) +/*static*/ void ChatDialog::chatMessageReceived(ChatMessage msg) { + if(msg.chat_id.isBroadcast()) + return; // broadcast is not handled by a chat dialog + + if(msg.incoming && (msg.chat_id.isPeerId() || msg.chat_id.isGxsId())) + // play sound when recv a message + soundManager->play(SOUND_NEW_CHAT_MESSAGE); + + ChatDialog *cd = getChat(msg.chat_id, Settings->getChatFlags()); + if(cd) + cd->addChatMsg(msg); + else + std::cerr << "ChatDialog::chatMessageReceived(): no ChatDialog for this message. Ignoring Message: " << msg.msg << std::endl; +} + +/*static*/ void ChatDialog::chatFriend(const ChatId &peerId, const bool forceFocus) +{ + getChat(peerId, forceFocus ? RS_CHAT_OPEN | RS_CHAT_FOCUS : RS_CHAT_OPEN); + + // below is the old code witch does lots of error checking. + // because there are many different chat types, there are also different ways to check if the id is valid + // i think the chatservice should offer a method bool isChatAvailable(ChatId) + /* if (peerId.isNull()){ return; } @@ -227,12 +207,13 @@ void ChatDialog::init(const RsPeerId &peerId, const QString &title) return; if (detail.isOnlyGPGdetail) { - /* Should not happen */ + // Should not happen //chatFriend(detail.gpg_id, forceFocus); return; } getChat(peerId, forceFocus ? RS_CHAT_OPEN | RS_CHAT_FOCUS : RS_CHAT_OPEN); + */ } /*static*/ void ChatDialog::chatFriend(const RsPgpId &gpgId, const bool forceFocus) @@ -255,7 +236,7 @@ void ChatDialog::init(const RsPeerId &peerId, const QString &title) if (sslIds.size() == 1) { // chat with the one ssl id (online or offline) - chatFriend(sslIds.front(), forceFocus); + chatFriend(ChatId(sslIds.front()), forceFocus); return; } @@ -269,7 +250,7 @@ void ChatDialog::init(const RsPeerId &peerId, const QString &title) if (onlineIds.size() == 1) { // chat with the online ssl id - chatFriend(onlineIds.front(), forceFocus); + chatFriend(ChatId(onlineIds.front()), forceFocus); return; } @@ -313,16 +294,37 @@ bool ChatDialog::hasNewMessages() return false; } -QString ChatDialog::getPeerName(const RsPeerId& id) const +QString ChatDialog::getPeerName(const ChatId& id) const { - return QString::fromUtf8( rsPeers->getPeerName(id).c_str() ) ; + if(id.isPeerId()) + return QString::fromUtf8(rsPeers->getPeerName(id.toPeerId()).c_str()) ; + else + return "ChatDialog::getPeerName(): invalid id type passed (RsPeerId is required). This is a bug."; +} + +QString ChatDialog::getOwnName() const +{ + if(mChatId.isPeerId()) + return QString::fromUtf8(rsPeers->getPeerName(rsPeers->getOwnId()).c_str()); + else + return "ChatDialog::getOwnName(): invalid id type passed (RsPeerId is required). This is a bug."; } void ChatDialog::setPeerStatus(uint32_t status) { ChatWidget *cw = getChatWidget(); - if (cw) - cw->updateStatus(QString::fromStdString(getPeerId().toStdString()), status); + if (cw) + { + // convert to virtual peer id + // this is only required for private and distant chat, + // because lobby and broadcast does not have a status + RsPeerId vpid; + if(mChatId.isPeerId()) + vpid = mChatId.toPeerId(); + if(mChatId.isGxsId()) + vpid = RsPeerId(mChatId.toGxsId()); + cw->updateStatus(QString::fromStdString(vpid.toStdString()), status); + } } int ChatDialog::getPeerStatus() { @@ -381,27 +383,3 @@ void ChatDialog::chatNewMessage(ChatWidget*) { emit newMessage(this); } - -void ChatDialog::insertChatMsgs() -{ - RsPeerId peerId = getPeerId(); - - std::list newchat; - if (!rsMsgs->getPrivateChatQueue(true, peerId, newchat)) { - return; - } - - 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; - } - - addIncomingChatMsg(*it); - } - - rsMsgs->clearPrivateChatQueue(true, peerId); -} diff --git a/retroshare-gui/src/gui/chat/ChatDialog.h b/retroshare-gui/src/gui/chat/ChatDialog.h index 913e6619d..86c3ccba3 100644 --- a/retroshare-gui/src/gui/chat/ChatDialog.h +++ b/retroshare-gui/src/gui/chat/ChatDialog.h @@ -34,13 +34,13 @@ class ChatDialog : public QWidget Q_OBJECT public: - static ChatDialog *getExistingChat(const RsPeerId &peerId); - static ChatDialog *getChat(const RsPeerId &peerId, uint chatflags); + static ChatDialog *getExistingChat(ChatId id); + static ChatDialog *getChat(ChatId id, uint chatflags = 0); static void cleanupChat(); - static void chatFriend(const RsPeerId &peerId, bool forceFocus = true); + static void chatFriend(const ChatId &peerId, bool forceFocus = true); static void chatFriend(const RsPgpId &gpgId, bool forceFocus = true); - static void closeChat(const RsPeerId &peerId); - static void chatChanged(int list, int type); + static void closeChat(const ChatId &chat_id); + static void chatMessageReceived(ChatMessage msg); virtual void showDialog(uint /*chatflags*/) {} @@ -51,7 +51,6 @@ public: void addToParent(QWidget *newParent); void removeFromParent(QWidget *oldParent); - RsPeerId getPeerId() { return peerId; } QString getTitle(); bool hasNewMessages(); bool isTyping(); @@ -59,12 +58,13 @@ public: bool setStyle(); const RSStyle *getStyle(); - void insertChatMsgs(); int getPeerStatus(); void setPeerStatus(uint32_t state); void focusDialog(); + ChatId getChatId(){ return mChatId; } + signals: void infoChanged(ChatDialog *dialog); void newMessage(ChatDialog *dialog); @@ -81,14 +81,13 @@ protected: void closeEvent(QCloseEvent *event); virtual bool canClose() { return true; } - virtual QString getPeerName(const RsPeerId &sslid) const ; // can be overloaded for chat dialogs that have specific peers + virtual QString getPeerName(const ChatId &sslid) const ; // can be overloaded for chat dialogs that have specific peers + virtual QString getOwnName() const; - virtual void init(const RsPeerId &peerId, const QString &title); - virtual void onChatChanged(int /*list*/, int /*type*/) {} + virtual void init(ChatId id, const QString &title); + virtual void addChatMsg(const ChatMessage& msg) = 0; - virtual void addIncomingChatMsg(const ChatInfo& info) = 0; - - RsPeerId peerId; + ChatId mChatId; }; #endif // CHATDIALOG_H diff --git a/retroshare-gui/src/gui/chat/ChatLobbyDialog.cpp b/retroshare-gui/src/gui/chat/ChatLobbyDialog.cpp index f37ee161d..e01e3f3b1 100644 --- a/retroshare-gui/src/gui/chat/ChatLobbyDialog.cpp +++ b/retroshare-gui/src/gui/chat/ChatLobbyDialog.cpp @@ -119,15 +119,14 @@ void ChatLobbyDialog::inviteFriends() std::cerr << "Inviting these friends:" << std::endl; - ChatLobbyId lobby_id; - if (!rsMsgs->isLobbyId(getPeerId(), lobby_id)) + if (!mChatId.isLobbyId()) return ; for(std::list::const_iterator it(ids.begin());it!=ids.end();++it) { std::cerr << " " << *it << std::endl; - rsMsgs->invitePeerToLobby(lobby_id,*it) ; + rsMsgs->invitePeerToLobby(mChatId.toLobbyId(),*it) ; } } @@ -162,28 +161,28 @@ void ChatLobbyDialog::participantsTreeWidgetCustomPopupMenu(QPoint) contextMnu.exec(QCursor::pos()); } -void ChatLobbyDialog::init(const RsPeerId &peerId, const QString &title) +void ChatLobbyDialog::init() { std::list lobbies; rsMsgs->getChatLobbyList(lobbies); + QString title; + std::list::const_iterator lobbyIt; for (lobbyIt = lobbies.begin(); lobbyIt != lobbies.end(); ++lobbyIt) { - RsPeerId vpid; - if (rsMsgs->getVirtualPeerId(lobbyIt->lobby_id, vpid)) { - if (vpid == peerId) { - QString msg = tr("Welcome to lobby %1").arg(RsHtml::plainText(lobbyIt->lobby_name)); - _lobby_name = QString::fromUtf8(lobbyIt->lobby_name.c_str()) ; - if (!lobbyIt->lobby_topic.empty()) { - msg += "\n" + tr("Topic: %1").arg(RsHtml::plainText(lobbyIt->lobby_topic)); - } - ui.chatWidget->setWelcomeMessage(msg); - break; - } - } + if (lobbyIt->lobby_id == lobbyId) { + title = QString::fromUtf8((*lobbyIt).lobby_name.c_str()); + QString msg = tr("Welcome to lobby %1").arg(RsHtml::plainText(lobbyIt->lobby_name)); + _lobby_name = QString::fromUtf8(lobbyIt->lobby_name.c_str()) ; + if (!lobbyIt->lobby_topic.empty()) { + msg += "\n" + tr("Topic: %1").arg(RsHtml::plainText(lobbyIt->lobby_topic)); + } + ui.chatWidget->setWelcomeMessage(msg); + break; + } } - ChatDialog::init(peerId, title); + ChatDialog::init(ChatId(lobbyId), title); std::string nickName; rsMsgs->getNickNameForChatLobby(lobbyId, nickName); @@ -194,8 +193,8 @@ void ChatLobbyDialog::init(const RsPeerId &peerId, const QString &title) lastUpdateListTime = 0; - /* Hide or show the participants frames */ - showParticipantsFrame(PeerSettings->getShowParticipantsFrame(peerId)); + /* Hide or show the participants frames */ + showParticipantsFrame(PeerSettings->getShowParticipantsFrame(ChatId(lobbyId))); // add to window @@ -214,9 +213,8 @@ ChatLobbyDialog::~ChatLobbyDialog() // announce leaving of lobby // check that the lobby still exists. - ChatLobbyId lid; - if (rsMsgs->isLobbyId(getPeerId(), lid)) { - rsMsgs->unsubscribeChatLobby(lobbyId); + if (mChatId.isLobbyId()) { + rsMsgs->unsubscribeChatLobby(mChatId.toLobbyId()); } // save settings @@ -285,18 +283,15 @@ void ChatLobbyDialog::changeNickname() * * - Ignore Messages from muted chat participants */ -void ChatLobbyDialog::addIncomingChatMsg(const ChatInfo& info) +void ChatLobbyDialog::addChatMsg(const ChatMessage& msg) { - QDateTime sendTime = QDateTime::fromTime_t(info.sendTime); - QDateTime recvTime = QDateTime::fromTime_t(info.recvTime); - QString message = QString::fromUtf8(info.msg.c_str()); - QString name = QString::fromUtf8(info.peer_nickname.c_str()); - QString rsid = QString::fromUtf8(info.rsid.toStdString().c_str()); - - //std::cerr << "message from rsid " << info.rsid.c_str() << std::endl; + QDateTime sendTime = QDateTime::fromTime_t(msg.sendTime); + QDateTime recvTime = QDateTime::fromTime_t(msg.recvTime); + QString message = QString::fromUtf8(msg.msg.c_str()); + QString name = QString::fromUtf8(msg.lobby_peer_nickname.c_str()); if(!isParticipantMuted(name)) { - ui.chatWidget->addChatMsg(true, name, sendTime, recvTime, message, ChatWidget::MSGTYPE_NORMAL); + ui.chatWidget->addChatMsg(msg.incoming, name, sendTime, recvTime, message, ChatWidget::MSGTYPE_NORMAL); emit messageReceived(id()) ; } @@ -567,10 +562,12 @@ void ChatLobbyDialog::displayLobbyEvent(int event_type, const QString& nickname, bool ChatLobbyDialog::canClose() { // check that the lobby still exists. + /* TODO ChatLobbyId lid; if (!rsMsgs->isLobbyId(getPeerId(), lid)) { return true; } + */ if (QMessageBox::Yes == QMessageBox::question(this, tr("Unsubscribe to lobby"), tr("Do you want to unsubscribe to this chat lobby?"), QMessageBox::Yes | QMessageBox::No)) { return true; @@ -601,5 +598,5 @@ void ChatLobbyDialog::showParticipantsFrame(bool show) ui.participantsFrameButton->setIcon(QIcon(":images/show_toolbox_frame.png")); } - PeerSettings->setShowParticipantsFrame(getPeerId(), show); + PeerSettings->setShowParticipantsFrame(ChatId(lobbyId), show); } diff --git a/retroshare-gui/src/gui/chat/ChatLobbyDialog.h b/retroshare-gui/src/gui/chat/ChatLobbyDialog.h index d321ac332..a3c7b03d5 100644 --- a/retroshare-gui/src/gui/chat/ChatLobbyDialog.h +++ b/retroshare-gui/src/gui/chat/ChatLobbyDialog.h @@ -66,10 +66,9 @@ protected: virtual ~ChatLobbyDialog(); void processSettings(bool load); - - virtual void init(const RsPeerId &peerId, const QString &title); + virtual void init(); virtual bool canClose(); - virtual void addIncomingChatMsg(const ChatInfo& info); + virtual void addChatMsg(const ChatMessage &msg); protected slots: void changeNickname(); diff --git a/retroshare-gui/src/gui/chat/ChatUserNotify.cpp b/retroshare-gui/src/gui/chat/ChatUserNotify.cpp index 0d1ddc913..25095f45a 100644 --- a/retroshare-gui/src/gui/chat/ChatUserNotify.cpp +++ b/retroshare-gui/src/gui/chat/ChatUserNotify.cpp @@ -23,14 +23,15 @@ #include "gui/notifyqt.h" #include "gui/MainWindow.h" #include "gui/chat/ChatDialog.h" +#include "gui/settings/rsharesettings.h" #include #include ChatUserNotify::ChatUserNotify(QObject *parent) : - UserNotify(parent) + UserNotify(parent) { - connect(NotifyQt::getInstance(), SIGNAL(privateChatChanged(int, int)), this, SLOT(privateChatChanged(int, int))); + connect(NotifyQt::getInstance(), SIGNAL(chatMessageReceived(ChatMessage)), this, SLOT(chatMessageReceived(ChatMessage))); } bool ChatUserNotify::hasSetting(QString *name, QString *group) @@ -53,29 +54,46 @@ QIcon ChatUserNotify::getMainIcon(bool hasNew) unsigned int ChatUserNotify::getNewCount() { - return rsMsgs->getPrivateChatQueueCount(true); + int sum = 0; + for(std::map::iterator mit = mWaitingChats.begin(); mit != mWaitingChats.end(); ++mit) + { + sum += mit->second; + } + return sum; } void ChatUserNotify::iconClicked() { ChatDialog *chatDialog = NULL; - std::list ids; - if (rsMsgs->getPrivateChatQueueIds(true, ids) && ids.size()) { - chatDialog = ChatDialog::getChat(ids.front(), RS_CHAT_OPEN | RS_CHAT_FOCUS); + if (mWaitingChats.empty() == false) { + chatDialog = ChatDialog::getChat(mWaitingChats.begin()->first, RS_CHAT_OPEN | RS_CHAT_FOCUS); + mWaitingChats.erase(mWaitingChats.begin()); } if (chatDialog == NULL) { MainWindow::showWindow(MainWindow::Friends); } + updateIcon(); } -void ChatUserNotify::privateChatChanged(int list, int type) +void ChatUserNotify::chatMessageReceived(ChatMessage msg) { - /* first process the chat messages */ - ChatDialog::chatChanged(list, type); - - if (list == NOTIFY_LIST_PRIVATE_INCOMING_CHAT) { - updateIcon(); - } + if(ChatDialog::getExistingChat(msg.chat_id) || (Settings->getChatFlags() & RS_CHAT_OPEN) || msg.chat_id.isGxsId()) + ChatDialog::chatMessageReceived(msg); + else + { + // this implicitly counts broadcast messages, because broadcast messages are not handled by chat dialog + bool found = false; + for(std::map::iterator mit = mWaitingChats.begin(); mit != mWaitingChats.end(); ++mit) + { + if(msg.chat_id.isSameEndpoint(mit->first)) + { + mit->second++; + found = true; + } + } + if(!found) + mWaitingChats[msg.chat_id] = 1; + updateIcon(); + } } - diff --git a/retroshare-gui/src/gui/chat/ChatUserNotify.h b/retroshare-gui/src/gui/chat/ChatUserNotify.h index 48555898a..66fdf969d 100644 --- a/retroshare-gui/src/gui/chat/ChatUserNotify.h +++ b/retroshare-gui/src/gui/chat/ChatUserNotify.h @@ -22,6 +22,7 @@ #ifndef CHATUSERNOTIFY_H #define CHATUSERNOTIFY_H +#include #include "gui/common/UserNotify.h" class ChatUserNotify : public UserNotify @@ -34,13 +35,15 @@ public: virtual bool hasSetting(QString *name, QString *group); private slots: - void privateChatChanged(int list, int type); + void chatMessageReceived(ChatMessage msg); private: virtual QIcon getIcon(); virtual QIcon getMainIcon(bool hasNew); virtual unsigned int getNewCount(); virtual void iconClicked(); + + std::map mWaitingChats; }; #endif // CHATUSERNOTIFY_H diff --git a/retroshare-gui/src/gui/chat/ChatWidget.cpp b/retroshare-gui/src/gui/chat/ChatWidget.cpp index b919b15cb..71e5b5321 100644 --- a/retroshare-gui/src/gui/chat/ChatWidget.cpp +++ b/retroshare-gui/src/gui/chat/ChatWidget.cpp @@ -68,7 +68,6 @@ ChatWidget::ChatWidget(QWidget *parent) : newMessages = false; typing = false; peerStatus = 0; - mChatType = CHATTYPE_UNKNOWN; firstShow = true; firstSearch = true; inChatCharFormatChanged = false; @@ -217,9 +216,9 @@ void ChatWidget::addVOIPBarWidget(QWidget *w) } -void ChatWidget::init(const RsPeerId &peerId, const QString &title) +void ChatWidget::init(const ChatId &chat_id, const QString &title) { - this->peerId = peerId; + this->chatId = chat_id; this->title = title; ui->titleLabel->setText(RsHtml::plainText(title)); @@ -227,37 +226,19 @@ void ChatWidget::init(const RsPeerId &peerId, const QString &title) RsPeerId ownId = rsPeers->getOwnId(); setName(QString::fromUtf8(rsPeers->getPeerName(ownId).c_str())); - ChatLobbyId lid; - if (rsMsgs->isLobbyId(peerId, lid)) { - mChatType = CHATTYPE_LOBBY; - } else { - uint32_t status; - if (rsMsgs->getDistantChatStatus(RsGxsId(peerId), status)) { - mChatType = CHATTYPE_DISTANT; - } else { - mChatType = CHATTYPE_PRIVATE; - } - } + if(chatId.isPeerId() || chatId.isGxsId()) + chatStyle.setStyleFromSettings(ChatStyle::TYPE_PRIVATE); + if(chatId.isBroadcast() || chatId.isLobbyId()) + chatStyle.setStyleFromSettings(ChatStyle::TYPE_PUBLIC); - switch (mChatType) { - case CHATTYPE_UNKNOWN: - case CHATTYPE_PRIVATE: - case CHATTYPE_DISTANT: - chatStyle.setStyleFromSettings(ChatStyle::TYPE_PRIVATE); - break; - case CHATTYPE_LOBBY: - chatStyle.setStyleFromSettings(ChatStyle::TYPE_PUBLIC); - break; - } - - currentColor.setNamedColor(PeerSettings->getPrivateChatColor(peerId)); - currentFont.fromString(PeerSettings->getPrivateChatFont(peerId)); + currentColor.setNamedColor(PeerSettings->getPrivateChatColor(chatId)); + currentFont.fromString(PeerSettings->getPrivateChatFont(chatId)); colorChanged(); setColorAndFont(); // load style - PeerSettings->getStyle(peerId, "ChatWidget", style); + PeerSettings->getStyle(chatId, "ChatWidget", style); /* Add plugin functions */ int pluginCount = rsPlugins->nbPlugins(); @@ -271,7 +252,7 @@ void ChatWidget::init(const RsPeerId &peerId, const QString &title) } } - uint32_t hist_chat_type; + uint32_t hist_chat_type = 0xFFFF; // a value larger than the biggest RS_HISTORY_TYPE_* value int messageCount; if (chatType() == CHATTYPE_LOBBY) { @@ -281,21 +262,25 @@ void ChatWidget::init(const RsPeerId &peerId, const QString &title) ui->statusLabel->hide(); updateTitle(); - } else { + } else if (chatType() == CHATTYPE_PRIVATE){ hist_chat_type = RS_HISTORY_TYPE_PRIVATE ; messageCount = Settings->getPrivateChatHistoryCount(); // initialize first status StatusInfo peerStatusInfo; // No check of return value. Non existing status info is handled as offline. - rsStatus->getStatus(peerId, peerStatusInfo); - updateStatus(QString::fromStdString(peerId.toStdString()), peerStatusInfo.status); + rsStatus->getStatus(chatId.toPeerId(), peerStatusInfo); + updateStatus(QString::fromStdString(chatId.toPeerId().toStdString()), peerStatusInfo.status); // initialize first custom state string - QString customStateString = QString::fromUtf8(rsMsgs->getCustomStateString(peerId).c_str()); - updatePeersCustomStateString(QString::fromStdString(peerId.toStdString()), customStateString); - } + QString customStateString = QString::fromUtf8(rsMsgs->getCustomStateString(chatId.toPeerId()).c_str()); + updatePeersCustomStateString(QString::fromStdString(chatId.toPeerId().toStdString()), customStateString); + } else if(chatId.isBroadcast()){ + hist_chat_type = RS_HISTORY_TYPE_PUBLIC; + messageCount = Settings->getPublicChatHistoryCount(); + ui->titleBarFrame->setVisible(false); + } if (rsHistory->getEnable(hist_chat_type)) { @@ -304,17 +289,40 @@ void ChatWidget::init(const RsPeerId &peerId, const QString &title) if (messageCount > 0) { - rsHistory->getMessages(peerId, historyMsgs, messageCount); + rsHistory->getMessages(chatId, historyMsgs, messageCount); std::list::iterator historyIt; for (historyIt = historyMsgs.begin(); historyIt != historyMsgs.end(); ++historyIt) - addChatMsg(historyIt->incoming, QString::fromUtf8(historyIt->peerName.c_str()), QDateTime::fromTime_t(historyIt->sendTime), QDateTime::fromTime_t(historyIt->recvTime), QString::fromUtf8(historyIt->message.c_str()), MSGTYPE_HISTORY); + { + // it can happen that a message is first added to the message history + // and later the gui receives the message through notify + // avoid this by not adding history entries if their age is < 2secs + if((time(NULL)-2) > historyIt->recvTime) + addChatMsg(historyIt->incoming, QString::fromUtf8(historyIt->peerName.c_str()), QDateTime::fromTime_t(historyIt->sendTime), QDateTime::fromTime_t(historyIt->recvTime), QString::fromUtf8(historyIt->message.c_str()), MSGTYPE_HISTORY); + } } } processSettings(true); } +ChatWidget::ChatType ChatWidget::chatType() +{ + // transformation from ChatId::Type to ChatWidget::ChatType + // we don't use the type in ChatId directly, because of historic reasons + // ChatWidget::ChatType existed before ChatId::Type was introduced + // TODO: check if can change all code to use the type in ChatId directly + // but maybe it is good to have separate types in libretroshare and gui + if(chatId.isPeerId()) + return CHATTYPE_PRIVATE; + if(chatId.isGxsId()) + return CHATTYPE_DISTANT; + if(chatId.isLobbyId()) + return CHATTYPE_LOBBY; + + return CHATTYPE_UNKNOWN; +} + void ChatWidget::processSettings(bool load) { Settings->beginGroup(QString("ChatWidget")); @@ -499,13 +507,10 @@ void ChatWidget::completeNickname(bool reverse) std::list::const_iterator lobbyIt; for (lobbyIt = lobbies.begin(); lobbyIt != lobbies.end(); ++lobbyIt) { - RsPeerId vpid; - if (rsMsgs->getVirtualPeerId(lobbyIt->lobby_id, vpid)) { - if (vpid == peerId) { - lobby = &*lobbyIt; - break; - } - } + if (chatId.toLobbyId() == lobbyIt->lobby_id) { + lobby = &*lobbyIt; + break; + } } if (!lobby) @@ -605,13 +610,10 @@ QAbstractItemModel *ChatWidget::modelFromPeers() std::list::const_iterator lobbyIt; for (lobbyIt = lobbies.begin(); lobbyIt != lobbies.end(); ++lobbyIt) { - RsPeerId vpid; - if (rsMsgs->getVirtualPeerId(lobbyIt->lobby_id, vpid)) { - if (vpid == peerId) { - lobby = &*lobbyIt; - break; - } - } + if (chatId.toLobbyId() == lobbyIt->lobby_id) { + lobby = &*lobbyIt; + break; + } } if (!lobby) @@ -847,7 +849,7 @@ void ChatWidget::updateStatusTyping() tr("is typing..."); #endif - rsMsgs->sendStatusString(peerId, "is typing..."); + rsMsgs->sendStatusString(chatId, "is typing..."); lastStatusSendTime = time(NULL) ; } } @@ -911,11 +913,7 @@ void ChatWidget::sendChat() #ifdef CHAT_DEBUG std::cout << "ChatWidget:sendChat " << std::endl; #endif - - if (rsMsgs->sendPrivateChat(peerId, msg)) { - QDateTime currentTime = QDateTime::currentDateTime(); - addChatMsg(false, name, currentTime, currentTime, text, MSGTYPE_NORMAL); - } + rsMsgs->sendChat(chatId, msg); chatWidget->clear(); // workaround for Qt bug - http://bugreports.qt.nokia.com/browse/QTBUG-2533 @@ -1130,7 +1128,7 @@ void ChatWidget::chooseColor() QRgb color = QColorDialog::getRgba(ui->chatTextEdit->textColor().rgba(), &ok, window()); if (ok) { currentColor = QColor(color); - PeerSettings->setPrivateChatColor(peerId, currentColor.name()); + PeerSettings->setPrivateChatColor(chatId, currentColor.name()); colorChanged(); setColorAndFont(); } @@ -1171,7 +1169,7 @@ void ChatWidget::setColorAndFont() void ChatWidget::setFont() { setColorAndFont(); - PeerSettings->setPrivateChatFont(peerId, currentFont.toString()); + PeerSettings->setPrivateChatFont(chatId, currentFont.toString()); } void ChatWidget::smileyWidget() @@ -1195,13 +1193,13 @@ void ChatWidget::deleteChatHistory() { if ((QMessageBox::question(this, "RetroShare", tr("Do you really want to physically delete the history?"), QMessageBox::Yes | QMessageBox::No, QMessageBox::Yes)) == QMessageBox::Yes) { clearChatHistory(); - rsHistory->clear(peerId); + rsHistory->clear(chatId); } } void ChatWidget::messageHistory() { - ImHistoryBrowser imBrowser(peerId, ui->chatTextEdit, window()); + ImHistoryBrowser imBrowser(chatId, ui->chatTextEdit, window()); imBrowser.exec(); } @@ -1318,23 +1316,28 @@ void ChatWidget::updateStatus(const QString &peer_id, int status) return; } + // make virtual peer id from gxs id in case of distant chat + RsPeerId vpid; + if(chatId.isGxsId()) + vpid = RsPeerId(chatId.toGxsId()); + else + vpid = chatId.toPeerId(); + /* set font size for status */ - if (RsPeerId(peer_id.toStdString()) == peerId) { + if (peer_id.toStdString() == vpid.toStdString()) { // the peers status has changed QString peerName ; - uint32_t stts ; - - if(rsMsgs->getDistantChatStatus(RsGxsId(peerId),stts)) + if(chatId.isGxsId()) { RsIdentityDetails details ; - if(rsIdentity->getIdDetails(RsGxsId(peerId),details)) + if(rsIdentity->getIdDetails(chatId.toGxsId(),details)) peerName = QString::fromUtf8( details.mNickname.c_str() ) ; else - peerName = QString::fromStdString(peerId.toStdString()) ; + peerName = QString::fromStdString(chatId.toGxsId().toStdString()) ; } else - peerName = QString::fromUtf8(rsPeers->getPeerName(peerId).c_str()); + peerName = QString::fromUtf8(rsPeers->getPeerName(chatId.toPeerId()).c_str()); // is scrollbar at the end? QScrollBar *scrollbar = ui->textBrowser->verticalScrollBar(); @@ -1404,6 +1407,8 @@ void ChatWidget::updatePeersCustomStateString(const QString& peer_id, const QStr { QString status_text; + // TODO: fix peer_id and types and eveyrhing + /* if (RsPeerId(peer_id.toStdString()) == peerId) { // the peers status string has changed if (status_string.isEmpty()) { @@ -1419,6 +1424,7 @@ void ChatWidget::updatePeersCustomStateString(const QString& peer_id, const QStr ui->statusLabel->setAlignment ( Qt::AlignVCenter ); } } + */ } void ChatWidget::updateStatusString(const QString &statusMask, const QString &statusString) @@ -1444,7 +1450,7 @@ void ChatWidget::setName(const QString &name) bool ChatWidget::setStyle() { if (style.showDialog(window())) { - PeerSettings->setStyle(peerId, "PopupChatDialog", style); + PeerSettings->setStyle(chatId, "PopupChatDialog", style); return true; } diff --git a/retroshare-gui/src/gui/chat/ChatWidget.h b/retroshare-gui/src/gui/chat/ChatWidget.h index 33416b104..26dd4a458 100644 --- a/retroshare-gui/src/gui/chat/ChatWidget.h +++ b/retroshare-gui/src/gui/chat/ChatWidget.h @@ -71,8 +71,8 @@ public: explicit ChatWidget(QWidget *parent = 0); ~ChatWidget(); - void init(const RsPeerId &peerId, const QString &title); - ChatType chatType() { return mChatType; } + void init(const ChatId &chat_id, const QString &title); + ChatType chatType(); bool hasNewMessages() { return newMessages; } bool isTyping() { return typing; } @@ -87,7 +87,6 @@ public: void addToolsAction(QAction *action); - RsPeerId getPeerId() { return peerId; } QString getTitle() { return title; } int getPeerStatus() { return peerStatus; } void setName(const QString &name); @@ -101,7 +100,7 @@ public: void addVOIPBarWidget(QWidget *w); -; + // Adds a new horizonal widget in the layout of the chat window. void addChatHorizontalWidget(QWidget *w) ; @@ -184,7 +183,7 @@ private: void completeNickname(bool reverse); QAbstractItemModel *modelFromPeers(); - RsPeerId peerId; + ChatId chatId; QString title; QString name; QString completionWord; @@ -198,7 +197,6 @@ private: bool newMessages; bool typing; int peerStatus; - ChatType mChatType; time_t lastStatusSendTime; diff --git a/retroshare-gui/src/gui/chat/CreateLobbyDialog.cpp b/retroshare-gui/src/gui/chat/CreateLobbyDialog.cpp index b43938580..41ea4dc29 100644 --- a/retroshare-gui/src/gui/chat/CreateLobbyDialog.cpp +++ b/retroshare-gui/src/gui/chat/CreateLobbyDialog.cpp @@ -124,10 +124,7 @@ void CreateLobbyDialog::createLobby() rsMsgs->setNickNameForChatLobby(id,ui->nickName_LE->text().toUtf8().constData()) ; // open chat window !! - RsPeerId vpid ; - - if(rsMsgs->getVirtualPeerId(id,vpid)) - ChatDialog::chatFriend(vpid) ; + ChatDialog::chatFriend(ChatId(id)) ; close(); } diff --git a/retroshare-gui/src/gui/chat/PopupChatDialog.cpp b/retroshare-gui/src/gui/chat/PopupChatDialog.cpp index c092e0b3d..b23c953eb 100644 --- a/retroshare-gui/src/gui/chat/PopupChatDialog.cpp +++ b/retroshare-gui/src/gui/chat/PopupChatDialog.cpp @@ -48,27 +48,25 @@ PopupChatDialog::PopupChatDialog(QWidget *parent, Qt::WindowFlags flags) connect(ui.avatarFrameButton, SIGNAL(toggled(bool)), this, SLOT(showAvatarFrame(bool))); connect(ui.actionClearOfflineMessages, SIGNAL(triggered()), this, SLOT(clearOfflineMessages())); - connect(NotifyQt::getInstance(), SIGNAL(chatStatusChanged(const QString&, const QString&, bool)), this, SLOT(chatStatusChanged(const QString&, const QString&, bool))); + connect(NotifyQt::getInstance(), SIGNAL(chatStatusChanged(ChatId,QString)), this, SLOT(chatStatusChanged(ChatId,QString))); } -void PopupChatDialog::init(const RsPeerId &peerId, const QString &title) +void PopupChatDialog::init(const ChatId &chat_id, const QString &title) { - ChatDialog::init(peerId, title); + ChatDialog::init(chat_id, title); /* Hide or show the avatar frames */ - showAvatarFrame(PeerSettings->getShowAvatarFrame(peerId)); + showAvatarFrame(PeerSettings->getShowAvatarFrame(chat_id)); ui.avatarWidget->setFrameType(AvatarWidget::STATUS_FRAME); - ui.avatarWidget->setId(peerId); + ui.avatarWidget->setId(chat_id.toPeerId()); // not 100% correct, since this code is also used for distant chat + // but distance peers don't have a status anyway ui.ownAvatarWidget->setFrameType(AvatarWidget::STATUS_FRAME); ui.ownAvatarWidget->setOwnId(); ui.chatWidget->addToolsAction(ui.actionClearOfflineMessages); - // add offline chat messages - onChatChanged(NOTIFY_LIST_PRIVATE_OUTGOING_CHAT, NOTIFY_TYPE_ADD); - // add to window PopupChatWindow *window = PopupChatWindow::getWindow(false); if (window) { @@ -119,87 +117,23 @@ void PopupChatDialog::showDialog(uint chatflags) // Called by libretroshare through notifyQt to display the peer's status // -void PopupChatDialog::chatStatusChanged(const QString &peerId, const QString& statusString, bool isPrivateChat) +void PopupChatDialog::chatStatusChanged(const ChatId &chat_id, const QString& statusString) { - if (isPrivateChat && this->peerId == RsPeerId(peerId.toStdString())) { - ui.chatWidget->updateStatusString(getPeerName(RsPeerId(peerId.toStdString())) + " %1", statusString); + if (mChatId.isSameEndpoint(chat_id)) { + ui.chatWidget->updateStatusString(getPeerName(chat_id) + " %1", statusString); } } -void PopupChatDialog::addIncomingChatMsg(const ChatInfo& info) +void PopupChatDialog::addChatMsg(const ChatMessage &msg) { ChatWidget *cw = getChatWidget(); if (cw) { - QDateTime sendTime = QDateTime::fromTime_t(info.sendTime); - QDateTime recvTime = QDateTime::fromTime_t(info.recvTime); - QString message = QString::fromUtf8(info.msg.c_str()); - QString name = getPeerName(info.rsid) ; + QDateTime sendTime = QDateTime::fromTime_t(msg.sendTime); + QDateTime recvTime = QDateTime::fromTime_t(msg.recvTime); + QString message = QString::fromUtf8(msg.msg.c_str()); + QString name = msg.incoming? getPeerName(msg.chat_id): getOwnName(); - cw->addChatMsg(true, name, sendTime, recvTime, message, ChatWidget::MSGTYPE_NORMAL); - } -} - -void PopupChatDialog::onChatChanged(int list, int type) -{ - if (list == NOTIFY_LIST_PRIVATE_OUTGOING_CHAT) { - switch (type) { - case NOTIFY_TYPE_ADD: - { - std::list savedOfflineChatNew; - - QString name = getPeerName(rsPeers->getOwnId()) ; - - std::list offlineChat; - if (rsMsgs->getPrivateChatQueueCount(false) && rsMsgs->getPrivateChatQueue(false, peerId, offlineChat)) { - ui.actionClearOfflineMessages->setEnabled(true); - - std::list::iterator it; - for(it = offlineChat.begin(); it != offlineChat.end(); ++it) { - /* are they public? */ - if ((it->chatflags & RS_CHAT_PRIVATE) == 0) { - /* this should not happen */ - continue; - } - - savedOfflineChatNew.push_back(*it); - - if (std::find(savedOfflineChat.begin(), savedOfflineChat.end(), *it) != savedOfflineChat.end()) { - continue; - } - - QDateTime sendTime = QDateTime::fromTime_t(it->sendTime); - QDateTime recvTime = QDateTime::fromTime_t(it->recvTime); - QString message = QString::fromUtf8(it->msg.c_str()); - - ui.chatWidget->addChatMsg(false, name, sendTime, recvTime, message, ChatWidget::MSGTYPE_OFFLINE); - } - } - - savedOfflineChat = savedOfflineChatNew; - } - break; - case NOTIFY_TYPE_DEL: - { - if (manualDelete == false) { - QString name = getPeerName(rsPeers->getOwnId()) ; - - // now show saved offline chat messages as sent - std::list::iterator it; - for(it = savedOfflineChat.begin(); it != savedOfflineChat.end(); ++it) { - QDateTime sendTime = QDateTime::fromTime_t(it->sendTime); - QDateTime recvTime = QDateTime::fromTime_t(it->recvTime); - QString message = QString::fromUtf8(it->msg.c_str()); - - ui.chatWidget->addChatMsg(false, name, sendTime, recvTime, message, ChatWidget::MSGTYPE_NORMAL); - } - } - - savedOfflineChat.clear(); - } - break; - } - - ui.actionClearOfflineMessages->setEnabled(!savedOfflineChat.empty()); + cw->addChatMsg(msg.incoming, name, sendTime, recvTime, message, ChatWidget::MSGTYPE_NORMAL); } } @@ -219,12 +153,15 @@ void PopupChatDialog::showAvatarFrame(bool show) ui.avatarFrameButton->setIcon(QIcon(":images/show_toolbox_frame.png")); } - PeerSettings->setShowAvatarFrame(getPeerId(), show); + PeerSettings->setShowAvatarFrame(mChatId, show); } void PopupChatDialog::clearOfflineMessages() { manualDelete = true; + // TODO +#ifdef REMOVE rsMsgs->clearPrivateChatQueue(false, peerId); +#endif manualDelete = false; } diff --git a/retroshare-gui/src/gui/chat/PopupChatDialog.h b/retroshare-gui/src/gui/chat/PopupChatDialog.h index 769b342ff..dd5afbaa5 100644 --- a/retroshare-gui/src/gui/chat/PopupChatDialog.h +++ b/retroshare-gui/src/gui/chat/PopupChatDialog.h @@ -34,10 +34,11 @@ class PopupChatDialog : public ChatDialog friend class ChatDialog; +protected slots: + void showAvatarFrame(bool show); private slots: - void showAvatarFrame(bool show); void clearOfflineMessages(); - void chatStatusChanged(const QString &peerId, const QString &statusString, bool isPrivateChat); + void chatStatusChanged(const ChatId &chat_id, const QString &statusString); protected: /** Default constructor */ @@ -45,7 +46,7 @@ protected: /** Default destructor */ virtual ~PopupChatDialog(); - virtual void init(const RsPeerId &peerId, const QString &title); + virtual void init(const ChatId &chat_id, const QString &title); virtual void showDialog(uint chatflags); virtual ChatWidget *getChatWidget(); virtual bool hasPeerStatus() { return true; } @@ -56,12 +57,11 @@ protected: void processSettings(bool load); protected: - virtual void addIncomingChatMsg(const ChatInfo& info); - virtual void onChatChanged(int list, int type); + virtual void addChatMsg(const ChatMessage& msg); + //virtual void onChatChanged(int list, int type); private: bool manualDelete; - std::list savedOfflineChat; /** Qt Designer generated object */ Ui::PopupChatDialog ui; diff --git a/retroshare-gui/src/gui/chat/PopupChatWindow.cpp b/retroshare-gui/src/gui/chat/PopupChatWindow.cpp index adb576afc..4893ab94e 100644 --- a/retroshare-gui/src/gui/chat/PopupChatWindow.cpp +++ b/retroshare-gui/src/gui/chat/PopupChatWindow.cpp @@ -123,10 +123,10 @@ void PopupChatWindow::saveSettings() Settings->setValueToGroup("ChatWindow", "OnTop", ui.actionSetOnTop->isChecked()); } else { - if (!peerId.isNull()) { - PeerSettings->saveWidgetInformation(peerId, this); - PeerSettings->setPrivateChatOnTop(peerId, ui.actionSetOnTop->isChecked()); - } + if (!chatId.isNotSet()) { + PeerSettings->saveWidgetInformation(chatId, this); + PeerSettings->setPrivateChatOnTop(chatId, ui.actionSetOnTop->isChecked()); + } } } @@ -139,7 +139,7 @@ void PopupChatWindow::showEvent(QShowEvent */*event*/) Settings->loadWidgetInformation(this); } else { this->move(qrand()%100, qrand()%100); //avoid to stack multiple popup chat windows on the same position - PeerSettings->loadWidgetInformation(peerId, this); + PeerSettings->loadWidgetInformation(chatId, this); } } } @@ -182,12 +182,12 @@ void PopupChatWindow::addDialog(ChatDialog *dialog) ui.horizontalLayout->addWidget(dialog); dialog->addToParent(this); ui.horizontalLayout->setContentsMargins(0, 0, 0, 0); - peerId = dialog->getPeerId(); + chatId = dialog->getChatId(); chatDialog = dialog; calculateStyle(dialog); /* signal toggled is called */ - ui.actionSetOnTop->setChecked(PeerSettings->getPrivateChatOnTop(peerId)); + ui.actionSetOnTop->setChecked(PeerSettings->getPrivateChatOnTop(chatId)); QObject::connect(dialog, SIGNAL(dialogClose(ChatDialog*)), this, SLOT(dialogClose(ChatDialog*))); } @@ -215,7 +215,7 @@ void PopupChatWindow::removeDialog(ChatDialog *dialog) dialog->removeFromParent(this); ui.horizontalLayout->removeWidget(dialog); chatDialog = NULL; - peerId.clear(); + chatId = ChatId(); deleteLater(); } } diff --git a/retroshare-gui/src/gui/chat/PopupChatWindow.h b/retroshare-gui/src/gui/chat/PopupChatWindow.h index 41c784604..1c822fa1d 100644 --- a/retroshare-gui/src/gui/chat/PopupChatWindow.h +++ b/retroshare-gui/src/gui/chat/PopupChatWindow.h @@ -26,6 +26,7 @@ #include #include "ui_PopupChatWindow.h" #include +#include class ChatDialog; @@ -69,7 +70,7 @@ private slots: private: bool tabbedWindow; bool firstShow; - RsPeerId peerId; + ChatId chatId; ChatDialog *chatDialog; QIcon mBlinkIcon; QIcon *mEmptyIcon; diff --git a/retroshare-gui/src/gui/chat/PopupDistantChatDialog.cpp b/retroshare-gui/src/gui/chat/PopupDistantChatDialog.cpp index 3bce85c57..348c4774d 100644 --- a/retroshare-gui/src/gui/chat/PopupDistantChatDialog.cpp +++ b/retroshare-gui/src/gui/chat/PopupDistantChatDialog.cpp @@ -58,10 +58,13 @@ PopupDistantChatDialog::PopupDistantChatDialog(QWidget *parent, Qt::WindowFlags updateDisplay() ; } -void PopupDistantChatDialog::init(const RsPeerId &pid,const QString & title) +void PopupDistantChatDialog::init(const RsGxsId &gxs_id,const QString & title) { - _pid = RsGxsId(pid) ; - PopupChatDialog::init(pid,title) ; + _pid = gxs_id ; + PopupChatDialog::init(ChatId(gxs_id), title) ; + + // hide avatar frame, because it does not have funcntionality for gxs + showAvatarFrame(false); } void PopupDistantChatDialog::updateDisplay() @@ -137,15 +140,16 @@ void PopupDistantChatDialog::closeEvent(QCloseEvent *e) PopupChatDialog::closeEvent(e) ; } -QString PopupDistantChatDialog::getPeerName(const RsPeerId& id) const +QString PopupDistantChatDialog::getPeerName(const ChatId &id) const { - uint32_t status ; - RsIdentityDetails details ; - - if(rsIdentity->getIdDetails(RsGxsId(id),details)) + if(rsIdentity->getIdDetails(id.toGxsId(),details)) return QString::fromUtf8( details.mNickname.c_str() ) ; else - return QString::fromStdString(id.toStdString()) ; + return QString::fromStdString(id.toGxsId().toStdString()) ; } +QString PopupDistantChatDialog::getOwnName() const +{ + return QString("me (TODO: gxs-name)"); +} diff --git a/retroshare-gui/src/gui/chat/PopupDistantChatDialog.h b/retroshare-gui/src/gui/chat/PopupDistantChatDialog.h index baa8341ea..62c17a5c0 100644 --- a/retroshare-gui/src/gui/chat/PopupDistantChatDialog.h +++ b/retroshare-gui/src/gui/chat/PopupDistantChatDialog.h @@ -37,10 +37,11 @@ class PopupDistantChatDialog: public PopupChatDialog /** Default destructor */ virtual ~PopupDistantChatDialog(); - virtual void init(const RsPeerId &pid, const QString &title); + virtual void init(const RsGxsId &gxs_id, const QString &title); virtual void closeEvent(QCloseEvent *e) ; - virtual QString getPeerName(const RsPeerId &id) const ; + virtual QString getPeerName(const ChatId &id) const ; + virtual QString getOwnName() const; protected slots: void updateDisplay() ; // overloads RsAutoUpdatePage diff --git a/retroshare-gui/src/gui/common/FriendList.cpp b/retroshare-gui/src/gui/common/FriendList.cpp index f6c2a0220..54d9550aa 100644 --- a/retroshare-gui/src/gui/common/FriendList.cpp +++ b/retroshare-gui/src/gui/common/FriendList.cpp @@ -600,7 +600,8 @@ void FriendList::insertPeers() // get ids of existing private chat messages std::list privateChatIds; - rsMsgs->getPrivateChatQueueIds(true, privateChatIds); + // TODO + //rsMsgs->getPrivateChatQueueIds(true, privateChatIds); // get existing groups std::list groupInfoList; @@ -1292,7 +1293,7 @@ void FriendList::chatfriend(QTreeWidgetItem *item) ChatDialog::chatFriend(RsPgpId(getRsId(item))); break; case TYPE_SSL: - ChatDialog::chatFriend(RsPeerId(getRsId(item))); + ChatDialog::chatFriend(ChatId(RsPeerId(getRsId(item)))); break; } } diff --git a/retroshare-gui/src/gui/feeds/PeerItem.cpp b/retroshare-gui/src/gui/feeds/PeerItem.cpp index 8f1357868..50b6abd00 100644 --- a/retroshare-gui/src/gui/feeds/PeerItem.cpp +++ b/retroshare-gui/src/gui/feeds/PeerItem.cpp @@ -59,7 +59,7 @@ PeerItem::PeerItem(FeedHolder *parent, uint32_t feedId, const RsPeerId &peerId, connect(NotifyQt::getInstance(), SIGNAL(friendsChanged()), this, SLOT(updateItem())); - avatar->setId(RsPeerId(mPeerId)); + avatar->setId(RsPeerId(mPeerId));// TODO: remove unnecesary converstation expandFrame->hide(); diff --git a/retroshare-gui/src/gui/im_history/ImHistoryBrowser.cpp b/retroshare-gui/src/gui/im_history/ImHistoryBrowser.cpp index ca3023ef5..95bc76af2 100644 --- a/retroshare-gui/src/gui/im_history/ImHistoryBrowser.cpp +++ b/retroshare-gui/src/gui/im_history/ImHistoryBrowser.cpp @@ -43,10 +43,10 @@ #define ROLE_PLAINTEXT Qt::UserRole + 1 #define ROLE_OFFLINE Qt::UserRole + 2 -ImHistoryBrowserCreateItemsThread::ImHistoryBrowserCreateItemsThread(ImHistoryBrowser *parent, const RsPeerId& peerId) +ImHistoryBrowserCreateItemsThread::ImHistoryBrowserCreateItemsThread(ImHistoryBrowser *parent, const ChatId& peerId) : QThread(parent) { - m_peerId = peerId; + m_chatId = peerId; m_historyBrowser = parent; stopped = false; } @@ -72,7 +72,7 @@ void ImHistoryBrowserCreateItemsThread::stop() void ImHistoryBrowserCreateItemsThread::run() { std::list historyMsgs; - rsHistory->getMessages(m_peerId, historyMsgs, 0); + rsHistory->getMessages(m_chatId, historyMsgs, 0); int count = historyMsgs.size(); int current = 0; @@ -91,7 +91,7 @@ void ImHistoryBrowserCreateItemsThread::run() } /** Default constructor */ -ImHistoryBrowser::ImHistoryBrowser(const RsPeerId &peerId, QTextEdit *edit, QWidget *parent) +ImHistoryBrowser::ImHistoryBrowser(const ChatId &chatId, QTextEdit *edit, QWidget *parent) : QDialog(parent, Qt::WindowSystemMenuHint | Qt::WindowTitleHint | Qt::WindowCloseButtonHint) { /* Invoke Qt Designer generated QObject setup routine */ @@ -100,8 +100,7 @@ ImHistoryBrowser::ImHistoryBrowser(const RsPeerId &peerId, QTextEdit *edit, QWid ui.headerFrame->setHeaderImage(QPixmap(":/images/user/agt_forum64.png")); ui.headerFrame->setHeaderText(tr("Message History")); - m_peerId = peerId; - m_isPrivateChat = !m_peerId.isNull(); + m_chatId = chatId; textEdit = edit; connect(NotifyQt::getInstance(), SIGNAL(historyChanged(uint, int)), this, SLOT(historyChanged(uint, int))); @@ -117,7 +116,7 @@ ImHistoryBrowser::ImHistoryBrowser(const RsPeerId &peerId, QTextEdit *edit, QWid ui.filterLineEdit->showFilterIcon(); // embed smileys ? - if (m_isPrivateChat) { + if (m_chatId.isPeerId() || m_chatId.isGxsId()) { embedSmileys = Settings->valueFromGroup("Chat", "Emoteicons_PrivatChat", true).toBool(); } else { embedSmileys = Settings->valueFromGroup("Chat", "Emoteicons_GroupChat", true).toBool(); @@ -137,7 +136,7 @@ ImHistoryBrowser::ImHistoryBrowser(const RsPeerId &peerId, QTextEdit *edit, QWid ui.listWidget->installEventFilter(this); - m_createThread = new ImHistoryBrowserCreateItemsThread(this, m_peerId); + m_createThread = new ImHistoryBrowserCreateItemsThread(this, m_chatId); connect(m_createThread, SIGNAL(finished()), this, SLOT(createThreadFinished())); connect(m_createThread, SIGNAL(progress(int,int)), this, SLOT(createThreadProgress(int,int))); m_createThread->start(); @@ -430,7 +429,7 @@ void ImHistoryBrowser::removeMessages() void ImHistoryBrowser::clearHistory() { - rsHistory->clear(m_peerId); + rsHistory->clear(m_chatId); } void ImHistoryBrowser::sendMessage() diff --git a/retroshare-gui/src/gui/im_history/ImHistoryBrowser.h b/retroshare-gui/src/gui/im_history/ImHistoryBrowser.h index ee964f7ca..f8c7eb1d0 100644 --- a/retroshare-gui/src/gui/im_history/ImHistoryBrowser.h +++ b/retroshare-gui/src/gui/im_history/ImHistoryBrowser.h @@ -43,7 +43,7 @@ class ImHistoryBrowser : public QDialog public: /** Default constructor */ - ImHistoryBrowser(const RsPeerId &peerId, QTextEdit *edit, QWidget *parent = 0); + ImHistoryBrowser(const ChatId &chatId, QTextEdit *edit, QWidget *parent = 0); /** Default destructor */ virtual ~ImHistoryBrowser(); @@ -78,8 +78,7 @@ private: ImHistoryBrowserCreateItemsThread *m_createThread; - RsPeerId m_peerId; - bool m_isPrivateChat; + ChatId m_chatId; QTextEdit *textEdit; bool embedSmileys; ChatStyle style; @@ -95,7 +94,7 @@ class ImHistoryBrowserCreateItemsThread : public QThread Q_OBJECT public: - ImHistoryBrowserCreateItemsThread(ImHistoryBrowser *parent, const RsPeerId &peerId); + ImHistoryBrowserCreateItemsThread(ImHistoryBrowser *parent, const ChatId &peerId); ~ImHistoryBrowserCreateItemsThread(); void run(); @@ -110,7 +109,7 @@ public: private: ImHistoryBrowser *m_historyBrowser; - RsPeerId m_peerId; + ChatId m_chatId; volatile bool stopped; }; diff --git a/retroshare-gui/src/gui/notifyqt.cpp b/retroshare-gui/src/gui/notifyqt.cpp index 5e54135ee..7bf3c62a3 100644 --- a/retroshare-gui/src/gui/notifyqt.cpp +++ b/retroshare-gui/src/gui/notifyqt.cpp @@ -137,7 +137,9 @@ NotifyQt::NotifyQt() : cDialog(NULL) _enabled = false ; } - connect(this,SIGNAL(raiseChatWindow(QString)),this,SLOT(raiseChatWindow_slot(QString)),Qt::QueuedConnection) ; + // register to allow sending over Qt::QueuedConnection + qRegisterMetaType("ChatId"); + qRegisterMetaType("ChatMessage"); } void NotifyQt::notifyErrorMsg(int list, int type, std::string msg) @@ -150,6 +152,20 @@ void NotifyQt::notifyErrorMsg(int list, int type, std::string msg) emit errorOccurred(list,type,QString::fromUtf8(msg.c_str())) ; } +void NotifyQt::notifyChatMessage(const ChatMessage &msg) +{ + { + QMutexLocker m(&_mutex) ; + if(!_enabled) + return ; + } + +#ifdef NOTIFY_DEBUG + std::cerr << "notifyQt: Received chat message " << std::endl ; +#endif + emit chatMessageReceived(msg); +} + void NotifyQt::notifyOwnAvatarChanged() { { @@ -401,7 +417,7 @@ void NotifyQt::notifyPeerStatusChangedSummary() emit peerStatusChangedSummary(); } - +#ifdef REMOVE void NotifyQt::notifyForumMsgReadSatusChanged(const std::string& forumId, const std::string& msgId, uint32_t status) { { @@ -423,7 +439,7 @@ void NotifyQt::notifyChannelMsgReadSatusChanged(const std::string& channelId, co emit channelMsgReadSatusChanged(QString::fromStdString(channelId), QString::fromStdString(msgId), status); } - +#endif void NotifyQt::notifyOwnStatusMessageChanged() { { @@ -508,12 +524,7 @@ void NotifyQt::notifyChatLobbyEvent(uint64_t lobby_id,uint32_t event_type,const emit chatLobbyEvent(lobby_id,event_type,QString::fromUtf8(nickname.c_str()),QString::fromUtf8(str.c_str())) ; } -void NotifyQt::notifyChatShow(const std::string& peer_id) -{ - emit raiseChatWindow(QString::fromStdString(peer_id)) ; -} - -void NotifyQt::notifyChatStatus(const std::string& peer_id,const std::string& status_string,bool is_private) +void NotifyQt::notifyChatStatus(const ChatId& chat_id,const std::string& status_string) { { QMutexLocker m(&_mutex) ; @@ -524,12 +535,7 @@ void NotifyQt::notifyChatStatus(const std::string& peer_id,const std::string& st #ifdef NOTIFY_DEBUG std::cerr << "notifyQt: Received chat status string: " << status_string << std::endl ; #endif - emit chatStatusChanged(QString::fromStdString(peer_id),QString::fromUtf8(status_string.c_str()),is_private) ; -} - -void NotifyQt::raiseChatWindow_slot(const QString& peer_str) -{ - ChatDialog::chatFriend(RsPeerId(peer_str.toStdString())) ; + emit chatStatusChanged(chat_id, QString::fromUtf8(status_string.c_str())); } void NotifyQt::notifyTurtleSearchResult(uint32_t search_id,const std::list& files) @@ -666,6 +672,8 @@ void NotifyQt::notifyListChange(int list, int type) #endif emit configChanged() ; break ; + +#ifdef REMOVE case NOTIFY_LIST_FORUMLIST_LOCKED: #ifdef NOTIFY_DEBUG std::cerr << "received forum msg changed" << std::endl ; @@ -691,6 +699,8 @@ void NotifyQt::notifyListChange(int list, int type) #endif emit privateChatChanged(list, type); break; +#endif + case NOTIFY_LIST_CHAT_LOBBY_LIST: #ifdef NOTIFY_DEBUG std::cerr << "received notify chat lobby list" << std::endl; @@ -837,13 +847,14 @@ void NotifyQt::UpdateGUI() case RS_POPUP_CHAT: if ((popupflags & RS_POPUP_CHAT) && !_disableAllToaster) { - ChatDialog *chatDialog = ChatDialog::getChat(RsPeerId(id), 0); + // TODO: fix for distant chat, look up if dstant chat uses RS_POPUP_CHAT + ChatDialog *chatDialog = ChatDialog::getChat(ChatId(RsPeerId(id))); ChatWidget *chatWidget; if (chatDialog && (chatWidget = chatDialog->getChatWidget()) && chatWidget->isActive()) { // do not show when active break; } - toaster = new Toaster(new ChatToaster(RsPeerId(id), QString::fromUtf8(msg.c_str()))); + toaster = new Toaster(new ChatToaster(RsPeerId(id), QString::fromUtf8(msg.c_str()))); } break; case RS_POPUP_GROUPCHAT: @@ -864,18 +875,28 @@ void NotifyQt::UpdateGUI() case RS_POPUP_CHATLOBBY: if ((popupflags & RS_POPUP_CHATLOBBY) && !_disableAllToaster) { - ChatDialog *chatDialog = ChatDialog::getChat(RsPeerId(id), 0); - ChatWidget *chatWidget; - if (chatDialog && (chatWidget = chatDialog->getChatWidget()) && chatWidget->isActive()) { - // do not show when active - break; - } - ChatLobbyDialog *chatLobbyDialog = dynamic_cast(chatDialog); - if (!chatLobbyDialog || chatLobbyDialog->isParticipantMuted(QString::fromUtf8(title.c_str()))) { - // participant is muted - break; - } - toaster = new Toaster(new ChatLobbyToaster(RsPeerId(id), QString::fromUtf8(title.c_str()), QString::fromUtf8(msg.c_str()))); + if(RsPeerId::SIZE_IN_BYTES < sizeof(ChatLobbyId)) + { + std::cerr << "NotifyQt::UpdateGUI() Error: ChatLobbyId does not fit into a RsPeerId, this should not happen!" << std::endl; + break; + } + RsPeerId vpid(id); // create virtual peer id + ChatLobbyId lobby_id; + // copy first bytes of virtual peer id, to make a chat lobby id + memcpy(&lobby_id, vpid.toByteArray(), sizeof(ChatLobbyId)); + + ChatDialog *chatDialog = ChatDialog::getChat(ChatId(lobby_id)); + ChatWidget *chatWidget; + if (chatDialog && (chatWidget = chatDialog->getChatWidget()) && chatWidget->isActive()) { + // do not show when active + break; + } + ChatLobbyDialog *chatLobbyDialog = dynamic_cast(chatDialog); + if (!chatLobbyDialog || chatLobbyDialog->isParticipantMuted(QString::fromUtf8(title.c_str()))) { + // participant is muted + break; + } + toaster = new Toaster(new ChatLobbyToaster(lobby_id, QString::fromUtf8(title.c_str()), QString::fromUtf8(msg.c_str()))); } break; case RS_POPUP_CONNECT_ATTEMPT: @@ -973,13 +994,13 @@ void NotifyQt::testToaster(uint notifyFlags, /*RshareSettings::enumToasterPositi toaster = new Toaster(new DownloadToaster(RsFileHash::random(), title)); break; case RS_POPUP_CHAT: - toaster = new Toaster(new ChatToaster(id, message)); + toaster = new Toaster(new ChatToaster(id, message)); break; case RS_POPUP_GROUPCHAT: toaster = new Toaster(new GroupChatToaster(id, message)); break; case RS_POPUP_CHATLOBBY: - toaster = new Toaster(new ChatLobbyToaster(id, title, message)); + toaster = new Toaster(new ChatLobbyToaster(0, title, message)); break; case RS_POPUP_CONNECT_ATTEMPT: toaster = new Toaster(new FriendRequestToaster(pgpid, title, id)); diff --git a/retroshare-gui/src/gui/notifyqt.h b/retroshare-gui/src/gui/notifyqt.h index 9634b796c..04d73ab73 100644 --- a/retroshare-gui/src/gui/notifyqt.h +++ b/retroshare-gui/src/gui/notifyqt.h @@ -4,6 +4,7 @@ #include #include #include +#include #include #include #include @@ -24,7 +25,6 @@ class Toaster; class SignatureEventData ; struct TurtleFileInfo; -//class NotifyQt: public NotifyBase, public QObject class NotifyQt: public QObject, public NotifyClient { Q_OBJECT @@ -41,8 +41,8 @@ class NotifyQt: public QObject, public NotifyClient virtual void notifyListPreChange(int list, int type); virtual void notifyListChange(int list, int type); virtual void notifyErrorMsg(int list, int sev, std::string msg); - virtual void notifyChatStatus(const std::string& peer_id,const std::string& status_string,bool is_private); - virtual void notifyChatShow(const std::string& peer_id) ; + virtual void notifyChatMessage(const ChatMessage& /* msg */); + virtual void notifyChatStatus(const ChatId &chat_id,const std::string& status_string); virtual void notifyCustomState(const std::string& peer_id, const std::string& status_string); virtual void notifyHashingInfo(uint32_t type, const std::string& fileinfo); virtual void notifyTurtleSearchResult(uint32_t search_id,const std::list& found_files); @@ -57,8 +57,10 @@ class NotifyQt: public QObject, public NotifyClient virtual void notifyPeerStatusChanged(const std::string& peer_id, uint32_t state); /* one or more peers has changed the states */ virtual void notifyPeerStatusChangedSummary(); +#ifdef REMOVE virtual void notifyForumMsgReadSatusChanged(const std::string& forumId, const std::string& msgId, uint32_t status); virtual void notifyChannelMsgReadSatusChanged(const std::string& channelId, const std::string& msgId, uint32_t status); +#endif virtual void notifyHistoryChanged(uint32_t msgId, int type); virtual void notifyDiscInfoChanged() ; @@ -102,11 +104,13 @@ class NotifyQt: public QObject, public NotifyClient void neighboursChanged() const ; void messagesChanged() const ; void messagesTagsChanged() const; +#ifdef REMOVE void forumsChanged() const ; // use connect with Qt::QueuedConnection void channelsChanged(int type) const ; // use connect with Qt::QueuedConnection +#endif void configChanged() const ; void logInfoChanged(const QString&) const ; - void chatStatusChanged(const QString&,const QString&,bool) const ; + void chatStatusChanged(const ChatId&,const QString&) const ; void peerHasNewCustomStateString(const QString& /* peer_id */, const QString& /* status_string */) const ; void gotTurtleSearchResult(qulonglong search_id,FileDetail file) const ; void peerHasNewAvatar(const QString& peer_id) const ; @@ -116,15 +120,19 @@ class NotifyQt: public QObject, public NotifyClient void diskFull(int,int) const ; void peerStatusChanged(const QString& /* peer_id */, int /* status */); void peerStatusChangedSummary() const; +#ifdef REMOVE void publicChatChanged(int type) const ; void privateChatChanged(int list, int type) const ; - void raiseChatWindow(const QString&) const ; +#endif + void chatMessageReceived(ChatMessage msg); void groupsChanged(int type) const ; void discInfoChanged() const ; void downloadComplete(const QString& /* fileHash */); void downloadCompleteCountChanged(int /* count */); +#ifdef REMOVE void forumMsgReadSatusChanged(const QString& forumId, const QString& msgId, int status); void channelMsgReadSatusChanged(const QString& channelId, const QString& msgId, int status); +#endif void historyChanged(uint msgId, int type); void chatLobbyInviteReceived() ; void deferredSignatureHandlingRequested() ; @@ -143,7 +151,6 @@ class NotifyQt: public QObject, public NotifyClient void runningTick(); void handleSignatureEvent() ; void handleChatLobbyTimeShift(int) ; - void raiseChatWindow_slot(const QString&) ; private: NotifyQt(); diff --git a/retroshare-gui/src/gui/settings/RsharePeerSettings.cpp b/retroshare-gui/src/gui/settings/RsharePeerSettings.cpp index d43038bf3..ef545546c 100644 --- a/retroshare-gui/src/gui/settings/RsharePeerSettings.cpp +++ b/retroshare-gui/src/gui/settings/RsharePeerSettings.cpp @@ -29,7 +29,6 @@ #include #include -#include #include "RsharePeerSettings.h" #include "rsharesettings.h" @@ -77,11 +76,11 @@ void RsharePeerSettings::cleanDeadIds() continue; } - ChatLobbyId lid; - if (rsMsgs->isLobbyId(RsPeerId((*group).toStdString()), lid)) { - continue; - } - if (rsPeers->isGPGAccepted(RsPgpId((*group).toStdString())) == false) { + // TODO: implement cleanup for chatlobbies and distant chat + + ChatId chatId((*group).toStdString()); + // remove if not a chat id and pgp id was removed from friendslist + if(chatId.isNotSet() && rsPeers->isGPGAccepted(RsPgpId((*group).toStdString())) == false) { remove(*group); } } @@ -92,38 +91,42 @@ void RsharePeerSettings::cleanDeadIds() } } -bool RsharePeerSettings::getSettingsIdOfPeerId(const RsPeerId &peerId, std::string &settingsId) +bool RsharePeerSettings::getSettingsIdOfPeerId(const ChatId& chatId, std::string &settingsId) { - ChatLobbyId lid; - if (rsMsgs->isLobbyId(peerId, lid)) { - settingsId = peerId.toStdString(); + if(chatId.isPeerId()) + { + RsPeerId peerId = chatId.toPeerId(); + // for ssl id, get pgp id + // check if pgp id is cached + std::map::iterator it = m_SslToGpg.find(peerId); + if (it != m_SslToGpg.end()) { + settingsId = it->second; + return true; + } + // if not fetch and store it + RsPeerDetails details; + if (rsPeers->getPeerDetails(peerId, details) == false) { + return false; + } + settingsId = details.gpg_id.toStdString(); + m_SslToGpg[peerId] = settingsId ; return true; } - - std::map::iterator it = m_SslToGpg.find(peerId); - if (it != m_SslToGpg.end()) { - settingsId = it->second; + if(chatId.isGxsId() || chatId.isLobbyId() || chatId.isBroadcast()) + { + settingsId = chatId.toStdString(); return true; } - - RsPeerDetails details; - if (rsPeers->getPeerDetails(peerId, details) == false) { - return false; - } - - settingsId = details.gpg_id.toStdString(); - m_SslToGpg[peerId] = settingsId ; - - return true; + return false; } /* get value of peer */ -QVariant RsharePeerSettings::get(const RsPeerId &peerId, const QString &key, const QVariant &defaultValue) +QVariant RsharePeerSettings::get(const ChatId& chatId, const QString &key, const QVariant &defaultValue) { QVariant result; std::string settingsId; - if (getSettingsIdOfPeerId(peerId, settingsId) == false) { + if (getSettingsIdOfPeerId(chatId, settingsId) == false) { /* settings id not found */ return result; } @@ -136,10 +139,10 @@ QVariant RsharePeerSettings::get(const RsPeerId &peerId, const QString &key, con } /* set value of peer */ -void RsharePeerSettings::set(const RsPeerId &peerId, const QString &key, const QVariant &value) +void RsharePeerSettings::set(const ChatId& chatId, const QString &key, const QVariant &value) { std::string settingsId; - if (getSettingsIdOfPeerId(peerId, settingsId) == false) { + if (getSettingsIdOfPeerId(chatId, settingsId) == false) { /* settings id not found */ return; } @@ -153,44 +156,44 @@ void RsharePeerSettings::set(const RsPeerId &peerId, const QString &key, const Q endGroup(); } -QString RsharePeerSettings::getPrivateChatColor(const RsPeerId &peerId) +QString RsharePeerSettings::getPrivateChatColor(const ChatId& chatId) { - return get(peerId, "PrivateChatColor", QColor(Qt::black).name()).toString(); + return get(chatId, "PrivateChatColor", QColor(Qt::black).name()).toString(); } -void RsharePeerSettings::setPrivateChatColor(const RsPeerId &peerId, const QString &value) +void RsharePeerSettings::setPrivateChatColor(const ChatId& chatId, const QString &value) { - set(peerId, "PrivateChatColor", value); + set(chatId, "PrivateChatColor", value); } -QString RsharePeerSettings::getPrivateChatFont(const RsPeerId &peerId) +QString RsharePeerSettings::getPrivateChatFont(const ChatId& chatId) { - return get(peerId, "PrivateChatFont", Settings->getChatScreenFont()).toString(); + return get(chatId, "PrivateChatFont", Settings->getChatScreenFont()).toString(); } -void RsharePeerSettings::setPrivateChatFont(const RsPeerId &peerId, const QString &value) +void RsharePeerSettings::setPrivateChatFont(const ChatId& chatId, const QString &value) { if (Settings->getChatScreenFont() == value) { - set(peerId, "PrivateChatFont", QVariant()); + set(chatId, "PrivateChatFont", QVariant()); } else { - set(peerId, "PrivateChatFont", value); + set(chatId, "PrivateChatFont", value); } } -bool RsharePeerSettings::getPrivateChatOnTop(const RsPeerId &peerId) +bool RsharePeerSettings::getPrivateChatOnTop(const ChatId& chatId) { - return get(peerId, "PrivateChatOnTop", false).toBool(); + return get(chatId, "PrivateChatOnTop", false).toBool(); } -void RsharePeerSettings::setPrivateChatOnTop(const RsPeerId &peerId, bool value) +void RsharePeerSettings::setPrivateChatOnTop(const ChatId& chatId, bool value) { - set(peerId, "PrivateChatOnTop", value); + set(chatId, "PrivateChatOnTop", value); } -void RsharePeerSettings::saveWidgetInformation(const RsPeerId &peerId, QWidget *widget) +void RsharePeerSettings::saveWidgetInformation(const ChatId& chatId, QWidget *widget) { std::string settingsId; - if (getSettingsIdOfPeerId(peerId, settingsId) == false) { + if (getSettingsIdOfPeerId(chatId, settingsId) == false) { /* settings id not found */ return; } @@ -207,10 +210,10 @@ void RsharePeerSettings::saveWidgetInformation(const RsPeerId &peerId, QWidget * endGroup(); } -void RsharePeerSettings::loadWidgetInformation(const RsPeerId &peerId, QWidget *widget) +void RsharePeerSettings::loadWidgetInformation(const ChatId& chatId, QWidget *widget) { std::string settingsId; - if (getSettingsIdOfPeerId(peerId, settingsId) == false) { + if (getSettingsIdOfPeerId(chatId, settingsId) == false) { /* settings id not found */ return; } @@ -227,30 +230,30 @@ void RsharePeerSettings::loadWidgetInformation(const RsPeerId &peerId, QWidget * endGroup(); } -bool RsharePeerSettings::getShowAvatarFrame(const RsPeerId &peerId) +bool RsharePeerSettings::getShowAvatarFrame(const ChatId& chatId) { - return get(peerId, "ShowAvatarFrame", true).toBool(); + return get(chatId, "ShowAvatarFrame", true).toBool(); } -void RsharePeerSettings::setShowAvatarFrame(const RsPeerId &peerId, bool value) +void RsharePeerSettings::setShowAvatarFrame(const ChatId& chatId, bool value) { - return set(peerId, "ShowAvatarFrame", value); + return set(chatId, "ShowAvatarFrame", value); } -bool RsharePeerSettings::getShowParticipantsFrame(const RsPeerId &peerId) +bool RsharePeerSettings::getShowParticipantsFrame(const ChatId& chatId) { - return get(peerId, "ShowParticipantsFrame", true).toBool(); + return get(chatId, "ShowParticipantsFrame", true).toBool(); } -void RsharePeerSettings::setShowParticipantsFrame(const RsPeerId &peerId, bool value) +void RsharePeerSettings::setShowParticipantsFrame(const ChatId& chatId, bool value) { - return set(peerId, "ShowParticipantsFrame", value); + return set(chatId, "ShowParticipantsFrame", value); } -void RsharePeerSettings::getStyle(const RsPeerId &peerId, const QString &name, RSStyle &style) +void RsharePeerSettings::getStyle(const ChatId& chatId, const QString &name, RSStyle &style) { std::string settingsId; - if (getSettingsIdOfPeerId(peerId, settingsId) == false) { + if (getSettingsIdOfPeerId(chatId, settingsId) == false) { /* settings id not found */ return; } @@ -266,10 +269,10 @@ void RsharePeerSettings::getStyle(const RsPeerId &peerId, const QString &name, R endGroup(); } -void RsharePeerSettings::setStyle(const RsPeerId &peerId, const QString &name, RSStyle &style) +void RsharePeerSettings::setStyle(const ChatId& chatId, const QString &name, RSStyle &style) { std::string settingsId; - if (getSettingsIdOfPeerId(peerId, settingsId) == false) { + if (getSettingsIdOfPeerId(chatId, settingsId) == false) { /* settings id not found */ return; } diff --git a/retroshare-gui/src/gui/settings/RsharePeerSettings.h b/retroshare-gui/src/gui/settings/RsharePeerSettings.h index 4486c8c6f..94d841b03 100644 --- a/retroshare-gui/src/gui/settings/RsharePeerSettings.h +++ b/retroshare-gui/src/gui/settings/RsharePeerSettings.h @@ -23,6 +23,8 @@ #define _RSHAREPEERSETTINGS_H #include +#include +#include class RSStyle; @@ -33,38 +35,38 @@ public: /* create settings object */ static void Create (); - QString getPrivateChatColor(const RsPeerId &peerId); - void setPrivateChatColor(const RsPeerId &peerId, const QString &value); + QString getPrivateChatColor(const ChatId& chatId); + void setPrivateChatColor(const ChatId& chatId, const QString &value); - QString getPrivateChatFont(const RsPeerId &peerId); - void setPrivateChatFont(const RsPeerId &peerId, const QString &value); + QString getPrivateChatFont(const ChatId& chatId); + void setPrivateChatFont(const ChatId& chatId, const QString &value); - bool getPrivateChatOnTop(const RsPeerId &peerId); - void setPrivateChatOnTop(const RsPeerId &peerId, bool value); + bool getPrivateChatOnTop(const ChatId& chatId); + void setPrivateChatOnTop(const ChatId& chatId, bool value); - void saveWidgetInformation(const RsPeerId &peerId, QWidget *widget); - void loadWidgetInformation(const RsPeerId &peerId, QWidget *widget); + void saveWidgetInformation(const ChatId& chatId, QWidget *widget); + void loadWidgetInformation(const ChatId& chatId, QWidget *widget); - bool getShowAvatarFrame(const RsPeerId &peerId); - void setShowAvatarFrame(const RsPeerId &peerId, bool value); + bool getShowAvatarFrame(const ChatId& chatId); + void setShowAvatarFrame(const ChatId& chatId, bool value); - bool getShowParticipantsFrame(const RsPeerId &peerId); - void setShowParticipantsFrame(const RsPeerId &peerId, bool value); + bool getShowParticipantsFrame(const ChatId& chatId); + void setShowParticipantsFrame(const ChatId& chatId, bool value); - void getStyle(const RsPeerId &peerId, const QString &name, RSStyle &style); - void setStyle(const RsPeerId &peerId, const QString &name, RSStyle &style); + void getStyle(const ChatId& chatId, const QString &name, RSStyle &style); + void setStyle(const ChatId& chatId, const QString &name, RSStyle &style); protected: /** Default constructor. */ RsharePeerSettings(); - bool getSettingsIdOfPeerId(const RsPeerId &peerId, std::string &settingsId); + bool getSettingsIdOfPeerId(const ChatId& chatId, std::string &settingsId); void cleanDeadIds(); /* get value of peer */ - QVariant get(const RsPeerId &peerId, const QString &key, const QVariant &defaultValue = QVariant()); + QVariant get(const ChatId& chatId, const QString &key, const QVariant &defaultValue = QVariant()); /* set value of peer */ - void set(const RsPeerId &peerId, const QString &key, const QVariant &value); + void set(const ChatId& chatId, const QString &key, const QVariant &value); /* map for fast access of the gpg id to the ssl id */ std::map m_SslToGpg; diff --git a/retroshare-gui/src/gui/toaster/ChatLobbyToaster.cpp b/retroshare-gui/src/gui/toaster/ChatLobbyToaster.cpp index 1a7092ab5..9167f0b3b 100644 --- a/retroshare-gui/src/gui/toaster/ChatLobbyToaster.cpp +++ b/retroshare-gui/src/gui/toaster/ChatLobbyToaster.cpp @@ -25,13 +25,12 @@ #include -ChatLobbyToaster::ChatLobbyToaster(const RsPeerId &peerId, const QString &name, const QString &message) : QWidget(NULL) +ChatLobbyToaster::ChatLobbyToaster(const ChatLobbyId &lobby_id, const QString &name, const QString &message): + QWidget(NULL), mLobbyId(lobby_id) { /* Invoke the Qt Designer generated object setup routine */ ui.setupUi(this); - this->peerId = peerId; - connect(ui.toasterButton, SIGNAL(clicked()), SLOT(chatButtonSlot())); connect(ui.closeButton, SIGNAL(clicked()), SLOT(hide())); @@ -44,21 +43,17 @@ ChatLobbyToaster::ChatLobbyToaster(const RsPeerId &peerId, const QString &name, std::list linfos; rsMsgs->getChatLobbyList(linfos); - - ChatLobbyId lobbyId; - if (rsMsgs->isLobbyId(peerId, lobbyId)) { - for (std::list::const_iterator it(linfos.begin()); it != linfos.end(); ++it) { - if ((*it).lobby_id == lobbyId) { - lobbyName += "@" + RsHtml::plainText(it->lobby_name); - break; - } - } - } + for (std::list::const_iterator it(linfos.begin()); it != linfos.end(); ++it) { + if ((*it).lobby_id == mLobbyId) { + lobbyName += "@" + RsHtml::plainText(it->lobby_name); + break; + } + } ui.toasterLabel->setText(lobbyName); } void ChatLobbyToaster::chatButtonSlot() { - ChatDialog::chatFriend(peerId); + ChatDialog::chatFriend(ChatId(mLobbyId)); hide(); } diff --git a/retroshare-gui/src/gui/toaster/ChatLobbyToaster.h b/retroshare-gui/src/gui/toaster/ChatLobbyToaster.h index 37d774943..bc7c3d262 100644 --- a/retroshare-gui/src/gui/toaster/ChatLobbyToaster.h +++ b/retroshare-gui/src/gui/toaster/ChatLobbyToaster.h @@ -24,6 +24,8 @@ #include "ui_ChatLobbyToaster.h" +#include "retroshare/rsmsgs.h" + /** * Shows a toaster when a chat is incoming. * @@ -34,13 +36,13 @@ class ChatLobbyToaster : public QWidget Q_OBJECT public: - ChatLobbyToaster(const RsPeerId &peerId, const QString &name, const QString &message); + ChatLobbyToaster(const ChatLobbyId &lobby_id, const QString &name, const QString &message); private slots: void chatButtonSlot(); private: - RsPeerId peerId; + ChatLobbyId mLobbyId; /** Qt Designer generated object */ Ui::ChatLobbyToaster ui; diff --git a/retroshare-gui/src/gui/toaster/ChatToaster.cpp b/retroshare-gui/src/gui/toaster/ChatToaster.cpp index 74054e4d9..48e25e0ee 100644 --- a/retroshare-gui/src/gui/toaster/ChatToaster.cpp +++ b/retroshare-gui/src/gui/toaster/ChatToaster.cpp @@ -25,25 +25,23 @@ #include -ChatToaster::ChatToaster(const RsPeerId &peerId, const QString &message) : QWidget(NULL) +ChatToaster::ChatToaster(const RsPeerId &peer_id, const QString &message) : QWidget(NULL), mPeerId(peer_id) { /* Invoke the Qt Designer generated object setup routine */ ui.setupUi(this); - this->peerId = peerId; - connect(ui.toasterButton, SIGNAL(clicked()), SLOT(chatButtonSlot())); connect(ui.closeButton, SIGNAL(clicked()), SLOT(hide())); /* set informations */ ui.textLabel->setText(RsHtml().formatText(NULL, message, RSHTML_FORMATTEXT_EMBED_SMILEYS | RSHTML_FORMATTEXT_EMBED_LINKS | RSHTML_FORMATTEXT_CLEANSTYLE)); - ui.toasterLabel->setText(QString::fromUtf8(rsPeers->getPeerName(peerId).c_str())); + ui.toasterLabel->setText(QString::fromUtf8(rsPeers->getPeerName(mPeerId).c_str())); ui.avatarWidget->setFrameType(AvatarWidget::STATUS_FRAME); - ui.avatarWidget->setId(peerId); + ui.avatarWidget->setId(mPeerId); } void ChatToaster::chatButtonSlot() { - ChatDialog::chatFriend(peerId); + ChatDialog::chatFriend(ChatId(mPeerId)); hide(); } diff --git a/retroshare-gui/src/gui/toaster/ChatToaster.h b/retroshare-gui/src/gui/toaster/ChatToaster.h index dad389cd7..ff1cfce5f 100644 --- a/retroshare-gui/src/gui/toaster/ChatToaster.h +++ b/retroshare-gui/src/gui/toaster/ChatToaster.h @@ -34,13 +34,13 @@ class ChatToaster : public QWidget Q_OBJECT public: - ChatToaster(const RsPeerId &peerId, const QString &message); + ChatToaster(const RsPeerId &peer_id, const QString &message); private slots: void chatButtonSlot(); private: - RsPeerId peerId; + RsPeerId mPeerId; /** Qt Designer generated object */ Ui::ChatToaster ui; diff --git a/retroshare-gui/src/gui/toaster/OnlineToaster.cpp b/retroshare-gui/src/gui/toaster/OnlineToaster.cpp index bc02a9809..776c9518e 100644 --- a/retroshare-gui/src/gui/toaster/OnlineToaster.cpp +++ b/retroshare-gui/src/gui/toaster/OnlineToaster.cpp @@ -41,6 +41,6 @@ OnlineToaster::OnlineToaster(const RsPeerId &peerId) : QWidget(NULL) void OnlineToaster::chatButtonSlot() { - ChatDialog::chatFriend(peerId); + ChatDialog::chatFriend(ChatId(peerId)); hide(); } diff --git a/retroshare-gui/src/main.cpp b/retroshare-gui/src/main.cpp index 803d13994..abab0ed04 100644 --- a/retroshare-gui/src/main.cpp +++ b/retroshare-gui/src/main.cpp @@ -382,7 +382,6 @@ int main(int argc, char *argv[]) std::cerr << "connecting signals and slots" << std::endl ; QObject::connect(notify,SIGNAL(gotTurtleSearchResult(qulonglong,FileDetail)),w->transfersDialog->searchDialog ,SLOT(updateFiles(qulonglong,FileDetail))) ; QObject::connect(notify,SIGNAL(deferredSignatureHandlingRequested()),notify,SLOT(handleSignatureEvent()),Qt::QueuedConnection) ; - QObject::connect(notify,SIGNAL(raiseChatWindow(const RsPeerId&)),notify,SLOT(raiseChatWindow_slot(const RsPeerId&)),Qt::QueuedConnection) ; QObject::connect(notify,SIGNAL(chatLobbyTimeShift(int)),notify,SLOT(handleChatLobbyTimeShift(int)),Qt::QueuedConnection) ; QObject::connect(notify,SIGNAL(diskFull(int,int)) ,w ,SLOT(displayDiskSpaceWarning(int,int))) ; QObject::connect(notify,SIGNAL(filesPostModChanged(bool)) ,w ,SLOT(postModDirectories(bool) )) ;