simplification of the chat interface to libretroshare using a single unified class for chat IDs. Used a common chat widget for all chats including broadcast. Opens the way to having plugins send/recv chat messages. Patch from Electron.

git-svn-id: http://svn.code.sf.net/p/retroshare/code/trunk@7800 b45a01b8-16f6-495d-af2f-9b41ad6348cc
This commit is contained in:
csoler 2014-12-29 21:41:05 +00:00
parent 535fe875e4
commit 13d7866171
53 changed files with 1180 additions and 2280 deletions

View File

@ -1,5 +1,7 @@
TEMPLATE = subdirs
CONFIG += ordered
SUBDIRS += \
openpgpsdk/src/openpgpsdk.pro \
supportlibs/pegmarkdown/pegmarkdown.pro \

View File

@ -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) ;
}
}

View File

@ -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) ;

View File

@ -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:

View File

@ -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<RsPeerId,AvatarInfo*>::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<RsPeerId,AvatarInfo*>::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 <new> flag to packet." << std::endl;
std::cerr << "p3ChatService::sendChat: new avatar never sent to peer " << id << ". Setting <new> 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<RsPeerId,StateStringInfo>::iterator it = _state_strings.find(id) ;
std::map<RsPeerId,StateStringInfo>::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<RsChatLobbyMsgItem*>(ci)))
return true ;
if(!DistributedChatService::locked_checkAndRebuildPartialLobbyMessage(dynamic_cast<RsChatLobbyMsgItem*>(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<RsChatLobbyMsgItem*>(c) ;
if(lobbyItem != NULL)
{
m.lobby_peer_nickname = lobbyItem->nick;
m.chat_id = ChatId(lobbyItem->lobby_id);
return;
}
bool p3ChatService::getPublicChatQueue(std::list<ChatInfo> &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<RsChatMsgItem *>::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<RsPeerId> &ids)
{
ids.clear();
RsStackMutex stack(mChatMtx); /********** STACK LOCKED MTX ******/
std::list<RsChatMsgItem *> *list;
if (incoming) {
list = &privateIncomingList;
} else {
list = &privateOutgoingList;
}
// get the items from the private list.
if (list->size() == 0) {
return false;
}
std::list<RsChatMsgItem *>::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<ChatInfo> &chats)
{
RsStackMutex stack(mChatMtx); /********** STACK LOCKED MTX ******/
std::list<RsChatMsgItem *> *list;
if (incoming) {
list = &privateIncomingList;
} else {
list = &privateOutgoingList;
}
// get the items from the private list.
if (list->size() == 0) {
return false;
}
std::list<RsChatMsgItem *>::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<RsChatMsgItem *> *list;
if (incoming) {
list = &privateIncomingList;
} else {
list = &privateOutgoingList;
}
// get the items from the private list.
if (list->size() == 0) {
return false;
}
std::list<RsChatMsgItem *>::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<RsChatLobbyMsgItem*>(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<RsItem*>& list)
list.push_back(di) ;
/* save incoming private chat messages */
std::list<RsChatMsgItem *>::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<RsChatMsgItem *>::iterator it;
for (it = privateOutgoingList.begin(); it != privateOutgoingList.end(); it++) {
RsPrivateChatMsgConfigItem *ci = new RsPrivateChatMsgConfigItem;
@ -1418,7 +1270,7 @@ void p3ChatService::statusChange(const std::list<pqiServicePeer> &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<pqiServicePeer> &plist)
} /* UNLOCKED */
for(uint32_t i=0;i<to_send.size();++i)
{
ChatMessage message;
initChatMessage(to_send[i], message);
message.incoming = false;
message.online = true;
RsServer::notify()->notifyChatMessage(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<pqiServicePeer> &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<RsChatMsgItem *>::iterator cit = privateOutgoingList.begin();
while (cit != privateOutgoingList.end()) {
RsChatMsgItem *c = *cit;
if (c->PeerId() == it->id) {
cit = privateOutgoingList.erase(cit);
continue;
}
++cit;
}
IndicateConfigChanged();
}
}
}

View File

@ -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<pqiServicePeer> &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<ChatInfo> &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<RsPeerId> &ids);
/*!
* This retrieves all private chat msg items for peer
*/
bool getPrivateChatQueue(bool incoming, const RsPeerId &id, std::list<ChatInfo> &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<RsItem*>& 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<RsChatMsgItem *> publicList;
std::list<RsChatMsgItem *> privateIncomingList;
std::list<RsChatMsgItem *> privateOutgoingList;
std::list<RsChatMsgItem *> privateOutgoingList; // messages waiting to be send when peer comes online
AvatarInfo *_own_avatar ;
std::map<RsPeerId,AvatarInfo *> _avatars ;

View File

@ -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;

View File

@ -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<const RsChatLobbyMsgItem*>(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<RsPeerId, std::map<uint32_t, RsHistoryMsgItem*> >::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<RsItem*>& 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<HistoryMsg> &msgs, uint32_t loadCount)
bool p3HistoryMgr::getMessages(const ChatId &chatId, std::list<HistoryMsg> &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<RsPeerId, std::map<uint32_t, RsHistoryMsgItem*> >::iterator mit = mMessages.find(chatPeerId);
if (mit == mMessages.end()) {

View File

@ -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<HistoryMsg> &msgs, uint32_t loadCount);
bool getMessages(const ChatId &chatPeerId, std::list<HistoryMsg> &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<uint32_t> &msgIds);
virtual bool getEnable(uint32_t chat_type);
@ -72,6 +73,8 @@ public:
virtual bool loadList(std::list<RsItem*>& load);
private:
static bool chatIdToVirtualPeerId(ChatId chat_id, RsPeerId& peer_id);
uint32_t nextMsgId;
std::map<RsPeerId, std::map<uint32_t, RsHistoryMsgItem*> > mMessages;

View File

@ -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) ; }

View File

@ -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 */) ;

View File

@ -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<HistoryMsg> &msgs, uint32_t loadCount) = 0;
virtual bool getMessages(const ChatId &chatPeerId, std::list<HistoryMsg> &msgs, uint32_t loadCount) = 0;
virtual bool getMessage(uint32_t msgId, HistoryMsg &msg) = 0;
virtual void removeMessages(const std::list<uint32_t> &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;

View File

@ -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<ChatInfo> &chats) = 0;
virtual int getPrivateChatQueueCount(bool incoming) = 0;
virtual bool getPrivateChatQueueIds(bool incoming, std::list<RsPeerId> &ids) = 0;
virtual bool getPrivateChatQueue(bool incoming, const RsPeerId& id, std::list<ChatInfo> &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 ;

View File

@ -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 */) {}

View File

@ -44,7 +44,7 @@ uint32_t p3History::getMaxStorageDuration()
{
return mHistoryMgr->getMaxStorageDuration() ;
}
bool p3History::getMessages(const RsPeerId &chatPeerId, std::list<HistoryMsg> &msgs, const uint32_t loadCount)
bool p3History::getMessages(const ChatId &chatPeerId, std::list<HistoryMsg> &msgs, const uint32_t loadCount)
{
return mHistoryMgr->getMessages(chatPeerId, msgs, loadCount);
}
@ -59,7 +59,7 @@ void p3History::removeMessages(const std::list<uint32_t> &msgIds)
mHistoryMgr->removeMessages(msgIds);
}
void p3History::clear(const RsPeerId &chatPeerId)
void p3History::clear(const ChatId &chatPeerId)
{
mHistoryMgr->clear(chatPeerId);
}

View File

@ -41,10 +41,10 @@ public:
p3History(p3HistoryMgr* historyMgr);
virtual ~p3History();
virtual bool getMessages(const RsPeerId &chatPeerId, std::list<HistoryMsg> &msgs, uint32_t loadCount);
virtual bool getMessages(const ChatId &chatPeerId, std::list<HistoryMsg> &msgs, uint32_t loadCount);
virtual bool getMessage(uint32_t msgId, HistoryMsg &msg);
virtual void removeMessages(const std::list<uint32_t> &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);

View File

@ -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<MsgInfoSummary> &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<ChatInfo> &chats)
{
return mChatSrv->getPublicChatQueue(chats);
}
int p3Msgs::getPrivateChatQueueCount(bool incoming)
{
return mChatSrv->getPrivateChatQueueCount(incoming);
}
bool p3Msgs::getPrivateChatQueueIds(bool incoming, std::list<RsPeerId> &ids)
{
return mChatSrv->getPrivateChatQueueIds(incoming, ids);
}
bool p3Msgs::getPrivateChatQueue(bool incoming, const RsPeerId& id, std::list<ChatInfo> &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) ;

View File

@ -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<ChatInfo> &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<RsPeerId> &ids);
/*!
* @param chats ref to list of received private chats is stored here
*/
virtual bool getPrivateChatQueue(bool incoming, const RsPeerId& id, std::list<ChatInfo> &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) ;
/****************************************/

View File

@ -1,5 +1,5 @@
TEMPLATE = subdirs
SUBDIRS += \
VOIP \
FeedReader
#VOIP \
#FeedReader

View File

@ -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<ChatLobbyDialog*>(ChatDialog::getExistingChat(vpid))) {
cld->displayLobbyEvent(event_type, nickname, str);
}
}
if (ChatLobbyDialog *cld = dynamic_cast<ChatLobbyDialog*>(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;
}

View File

@ -21,26 +21,17 @@
#include <time.h>
#include <QColorDialog>
#include <QDropEvent>
#include <QFontDialog>
#include <QMenu>
#include <QScrollBar>
#include <QTextStream>
#include <QTextCodec>
#include <QTimer>
#include <QMessageBox>
#include <QTextDocumentFragment>
#include "retroshare/rspeers.h"
#include <retroshare/rspeers.h>
#include <retroshare/rshistory.h>
#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.");
// "<font color='grey'>" + DateTime::formatTime(QTime::currentTime()) + "</font> -
msg = QString("<font color='blue'><i>" + msg + "</i></font>");
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<HashedFile>)), this, SLOT(fileHashingFinished(QList<HashedFile>)));
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<HistoryMsg> historyMsgs;
rsHistory->getMessages(RsPeerId(), historyMsgs, messageCount);
std::list<HistoryMsg>::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<int> sizes;
/*remove
QList<int> 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<ChatInfo> 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<ChatInfo>::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<QKeyEvent*>(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<std::string> peers;
std::list<std::string>::iterator it;
if (!rsPeers)
{
/* not ready yet! */
return;
}
rsPeers->getOnlineList(peers);
/* get a link to the table */
//QTreeWidget *sendWidget = ui.msgSendList;
QList<QTreeWidgetItem *> 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("<font color='grey'>" + DateTime::formatTime(QTime::currentTime()) + "</font> - <font color='" + color.name() + "'><i>" + info + "</i></font>");
}
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<QPushButton*>(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<HashedFile> hashedFiles)
{
std::cerr << "FriendsDialog::fileHashingFinished() started." << std::endl;
QString mesgString;
QList<HashedFile>::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 += "<BR>";
}
}
#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<FriendsDialog*>(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();
}

View File

@ -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<HashedFile> 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;

View File

@ -223,463 +223,8 @@
<string>Broadcast</string>
</attribute>
<layout class="QGridLayout" name="gridLayout_3">
<item row="1" column="0">
<widget class="QFrame" name="toolBarFrame">
<property name="maximumSize">
<size>
<width>16777215</width>
<height>38</height>
</size>
</property>
<property name="frameShape">
<enum>QFrame::Box</enum>
</property>
<property name="frameShadow">
<enum>QFrame::Sunken</enum>
</property>
<layout class="QHBoxLayout" name="horizontalLayout">
<property name="margin">
<number>6</number>
</property>
<item>
<widget class="QToolButton" name="emoticonBtn">
<property name="sizePolicy">
<sizepolicy hsizetype="Expanding" vsizetype="Expanding">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="minimumSize">
<size>
<width>24</width>
<height>24</height>
</size>
</property>
<property name="maximumSize">
<size>
<width>24</width>
<height>24</height>
</size>
</property>
<property name="focusPolicy">
<enum>Qt::NoFocus</enum>
</property>
<property name="icon">
<iconset resource="images.qrc">
<normaloff>:/images/emoticons/kopete/kopete020.png</normaloff>:/images/emoticons/kopete/kopete020.png</iconset>
</property>
<property name="iconSize">
<size>
<width>24</width>
<height>24</height>
</size>
</property>
<property name="autoRaise">
<bool>true</bool>
</property>
</widget>
</item>
<item>
<widget class="QToolButton" name="textboldChatButton">
<property name="sizePolicy">
<sizepolicy hsizetype="Expanding" vsizetype="Expanding">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="minimumSize">
<size>
<width>24</width>
<height>24</height>
</size>
</property>
<property name="maximumSize">
<size>
<width>24</width>
<height>24</height>
</size>
</property>
<property name="focusPolicy">
<enum>Qt::NoFocus</enum>
</property>
<property name="toolTip">
<string>Bold</string>
</property>
<property name="icon">
<iconset resource="images.qrc">
<normaloff>:/images/edit-bold.png</normaloff>:/images/edit-bold.png</iconset>
</property>
<property name="checkable">
<bool>true</bool>
</property>
<property name="autoRaise">
<bool>true</bool>
</property>
</widget>
</item>
<item>
<widget class="QToolButton" name="textunderlineChatButton">
<property name="sizePolicy">
<sizepolicy hsizetype="Expanding" vsizetype="Expanding">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="minimumSize">
<size>
<width>24</width>
<height>24</height>
</size>
</property>
<property name="maximumSize">
<size>
<width>24</width>
<height>24</height>
</size>
</property>
<property name="focusPolicy">
<enum>Qt::NoFocus</enum>
</property>
<property name="toolTip">
<string>Underline</string>
</property>
<property name="text">
<string/>
</property>
<property name="icon">
<iconset resource="images.qrc">
<normaloff>:/images/edit-underline.png</normaloff>:/images/edit-underline.png</iconset>
</property>
<property name="checkable">
<bool>true</bool>
</property>
<property name="autoRaise">
<bool>true</bool>
</property>
</widget>
</item>
<item>
<widget class="QToolButton" name="textitalicChatButton">
<property name="sizePolicy">
<sizepolicy hsizetype="Expanding" vsizetype="Expanding">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="minimumSize">
<size>
<width>24</width>
<height>24</height>
</size>
</property>
<property name="maximumSize">
<size>
<width>24</width>
<height>24</height>
</size>
</property>
<property name="focusPolicy">
<enum>Qt::NoFocus</enum>
</property>
<property name="toolTip">
<string>Italic</string>
</property>
<property name="icon">
<iconset resource="images.qrc">
<normaloff>:/images/edit-italic.png</normaloff>:/images/edit-italic.png</iconset>
</property>
<property name="checkable">
<bool>true</bool>
</property>
<property name="autoRaise">
<bool>true</bool>
</property>
</widget>
</item>
<item>
<widget class="QToolButton" name="fontsButton">
<property name="sizePolicy">
<sizepolicy hsizetype="Expanding" vsizetype="Expanding">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="minimumSize">
<size>
<width>24</width>
<height>24</height>
</size>
</property>
<property name="maximumSize">
<size>
<width>24</width>
<height>24</height>
</size>
</property>
<property name="focusPolicy">
<enum>Qt::NoFocus</enum>
</property>
<property name="toolTip">
<string>Font</string>
</property>
<property name="icon">
<iconset resource="images.qrc">
<normaloff>:/images/fonts.png</normaloff>:/images/fonts.png</iconset>
</property>
<property name="autoRaise">
<bool>true</bool>
</property>
</widget>
</item>
<item>
<widget class="QToolButton" name="colorChatButton">
<property name="sizePolicy">
<sizepolicy hsizetype="Expanding" vsizetype="Expanding">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="minimumSize">
<size>
<width>24</width>
<height>24</height>
</size>
</property>
<property name="maximumSize">
<size>
<width>24</width>
<height>24</height>
</size>
</property>
<property name="focusPolicy">
<enum>Qt::NoFocus</enum>
</property>
<property name="toolTip">
<string>Text Color</string>
</property>
<property name="autoRaise">
<bool>true</bool>
</property>
</widget>
</item>
<item>
<widget class="QToolButton" name="attachPictureButton">
<property name="minimumSize">
<size>
<width>28</width>
<height>28</height>
</size>
</property>
<property name="maximumSize">
<size>
<width>28</width>
<height>28</height>
</size>
</property>
<property name="focusPolicy">
<enum>Qt::NoFocus</enum>
</property>
<property name="toolTip">
<string>Attach a Picture</string>
</property>
<property name="icon">
<iconset resource="images.qrc">
<normaloff>:/images/add_image24.png</normaloff>:/images/add_image24.png</iconset>
</property>
<property name="iconSize">
<size>
<width>24</width>
<height>24</height>
</size>
</property>
<property name="autoRaise">
<bool>true</bool>
</property>
</widget>
</item>
<item>
<widget class="QToolButton" name="addfileButton">
<property name="sizePolicy">
<sizepolicy hsizetype="Expanding" vsizetype="Expanding">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="minimumSize">
<size>
<width>26</width>
<height>26</height>
</size>
</property>
<property name="maximumSize">
<size>
<width>26</width>
<height>26</height>
</size>
</property>
<property name="focusPolicy">
<enum>Qt::NoFocus</enum>
</property>
<property name="toolTip">
<string>Attach File</string>
</property>
<property name="icon">
<iconset resource="images.qrc">
<normaloff>:/images/add-share24.png</normaloff>:/images/add-share24.png</iconset>
</property>
<property name="iconSize">
<size>
<width>24</width>
<height>24</height>
</size>
</property>
<property name="autoRaise">
<bool>true</bool>
</property>
</widget>
</item>
<item>
<widget class="QToolButton" name="menuButton">
<property name="sizePolicy">
<sizepolicy hsizetype="Expanding" vsizetype="Expanding">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="minimumSize">
<size>
<width>24</width>
<height>24</height>
</size>
</property>
<property name="maximumSize">
<size>
<width>24</width>
<height>24</height>
</size>
</property>
<property name="focusPolicy">
<enum>Qt::NoFocus</enum>
</property>
<property name="icon">
<iconset resource="images.qrc">
<normaloff>:/images/configure.png</normaloff>:/images/configure.png</iconset>
</property>
<property name="iconSize">
<size>
<width>22</width>
<height>22</height>
</size>
</property>
<property name="popupMode">
<enum>QToolButton::InstantPopup</enum>
</property>
<property name="autoRaise">
<bool>true</bool>
</property>
</widget>
</item>
<item>
<spacer>
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeType">
<enum>QSizePolicy::Expanding</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>321</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
<item>
<widget class="QPushButton" name="Sendbtn">
<property name="text">
<string>Send</string>
</property>
</widget>
</item>
</layout>
</widget>
</item>
<item row="0" column="0">
<widget class="QSplitter" name="splitter_2">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<property name="handleWidth">
<number>5</number>
</property>
<property name="childrenCollapsible">
<bool>false</bool>
</property>
<widget class="RSTextBrowser" name="msgText">
<property name="sizePolicy">
<sizepolicy hsizetype="Expanding" vsizetype="Expanding">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="minimumSize">
<size>
<width>0</width>
<height>60</height>
</size>
</property>
<property name="contextMenuPolicy">
<enum>Qt::CustomContextMenu</enum>
</property>
<property name="readOnly">
<bool>true</bool>
</property>
</widget>
<widget class="QWidget" name="layoutWidget_2">
<layout class="QVBoxLayout" name="verticalLayoutEdit">
<property name="spacing">
<number>0</number>
</property>
<item>
<widget class="QLabel" name="statusStringLabel">
<property name="text">
<string/>
</property>
</widget>
</item>
<item>
<widget class="QTextEdit" name="lineEdit">
<property name="minimumSize">
<size>
<width>0</width>
<height>30</height>
</size>
</property>
<property name="contextMenuPolicy">
<enum>Qt::CustomContextMenu</enum>
</property>
<property name="toolTip">
<string>Messages entered here are sent to all connected friends</string>
</property>
</widget>
</item>
</layout>
</widget>
</widget>
</item>
<item row="2" column="0">
<widget class="HashBox" name="hashBox">
<property name="sizePolicy">
<sizepolicy hsizetype="Expanding" vsizetype="MinimumExpanding">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="widgetResizable">
<bool>true</bool>
</property>
</widget>
<widget class="ChatWidget" name="chatWidget" native="true"/>
</item>
</layout>
</widget>
@ -798,11 +343,6 @@
<extends>QLabel</extends>
<header>gui/common/StyledLabel.h</header>
</customwidget>
<customwidget>
<class>RSTextBrowser</class>
<extends>QTextBrowser</extends>
<header>gui/common/RSTextBrowser.h</header>
</customwidget>
<customwidget>
<class>AvatarWidget</class>
<extends>QLabel</extends>
@ -815,12 +355,6 @@
<header>gui/common/FriendList.h</header>
<container>1</container>
</customwidget>
<customwidget>
<class>HashBox</class>
<extends>QScrollArea</extends>
<header location="global">gui/common/HashBox.h</header>
<container>1</container>
</customwidget>
<customwidget>
<class>ChatTabWidget</class>
<extends>QTabWidget</extends>
@ -832,6 +366,12 @@
<extends>QLabel</extends>
<header>gui/common/StyledElidedLabel.h</header>
</customwidget>
<customwidget>
<class>ChatWidget</class>
<extends>QWidget</extends>
<header location="global">gui/chat/ChatWidget.h</header>
<container>1</container>
</customwidget>
</customwidgets>
<resources>
<include location="images.qrc"/>

View File

@ -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*/)

View File

@ -36,7 +36,7 @@
#include <retroshare/rsnotify.h>
#include <retroshare/rspeers.h>
static std::map<RsPeerId, ChatDialog*> chatDialogs;
static std::map<ChatId, ChatDialog*> 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<RsPeerId, ChatDialog *>::iterator it;
if (chatDialogs.end() != (it = chatDialogs.find(getPeerId()))) {
chatDialogs.erase(it);
std::map<ChatId, ChatDialog *>::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<RsPeerId, ChatDialog*>::iterator it;
if (chatDialogs.end() != (it = chatDialogs.find(peerId))) {
/* exists already */
return it->second;
}
std::map<ChatId, ChatDialog*>::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<ChatLobbyInfo> linfos;
rsMsgs->getChatLobbyList(linfos);
if (cd == NULL) {
return NULL;
}
for (std::list<ChatLobbyInfo>::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<ChatDialog*> list;
std::map<RsPeerId, ChatDialog*>::iterator it;
for (it = chatDialogs.begin(); it != chatDialogs.end(); ++it) {
std::map<ChatId, ChatDialog*>::iterator it;
for (it = chatDialogs2.begin(); it != chatDialogs2.end(); ++it) {
if (it->second) {
list.push_back(it->second);
}
}
chatDialogs.clear();
chatDialogs2.clear();
std::list<ChatDialog*>::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<RsPeerId> ids;
if (rsMsgs->getPrivateChatQueueIds(true, ids)) {
uint chatflags = Settings->getChatFlags();
std::list<RsPeerId>::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<RsPeerId, ChatDialog *>::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<ChatInfo> newchat;
if (!rsMsgs->getPrivateChatQueue(true, peerId, newchat)) {
return;
}
std::list<ChatInfo>::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);
}

View File

@ -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

View File

@ -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<RsPeerId>::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<ChatLobbyInfo> lobbies;
rsMsgs->getChatLobbyList(lobbies);
QString title;
std::list<ChatLobbyInfo>::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);
}

View File

@ -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();

View File

@ -23,14 +23,15 @@
#include "gui/notifyqt.h"
#include "gui/MainWindow.h"
#include "gui/chat/ChatDialog.h"
#include "gui/settings/rsharesettings.h"
#include <retroshare/rsnotify.h>
#include <retroshare/rsmsgs.h>
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<ChatId, int>::iterator mit = mWaitingChats.begin(); mit != mWaitingChats.end(); ++mit)
{
sum += mit->second;
}
return sum;
}
void ChatUserNotify::iconClicked()
{
ChatDialog *chatDialog = NULL;
std::list<RsPeerId> 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<ChatId, int>::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();
}
}

View File

@ -22,6 +22,7 @@
#ifndef CHATUSERNOTIFY_H
#define CHATUSERNOTIFY_H
#include <retroshare/rsmsgs.h>
#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<ChatId, int> mWaitingChats;
};
#endif // CHATUSERNOTIFY_H

View File

@ -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<HistoryMsg>::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<ChatLobbyInfo>::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<ChatLobbyInfo>::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;
}

View File

@ -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;

View File

@ -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();
}

View File

@ -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<ChatInfo> savedOfflineChatNew;
QString name = getPeerName(rsPeers->getOwnId()) ;
std::list<ChatInfo> offlineChat;
if (rsMsgs->getPrivateChatQueueCount(false) && rsMsgs->getPrivateChatQueue(false, peerId, offlineChat)) {
ui.actionClearOfflineMessages->setEnabled(true);
std::list<ChatInfo>::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<ChatInfo>::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;
}

View File

@ -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<ChatInfo> savedOfflineChat;
/** Qt Designer generated object */
Ui::PopupChatDialog ui;

View File

@ -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();
}
}

View File

@ -26,6 +26,7 @@
#include <QTimer>
#include "ui_PopupChatWindow.h"
#include <retroshare/rstypes.h>
#include <retroshare/rsmsgs.h>
class ChatDialog;
@ -69,7 +70,7 @@ private slots:
private:
bool tabbedWindow;
bool firstShow;
RsPeerId peerId;
ChatId chatId;
ChatDialog *chatDialog;
QIcon mBlinkIcon;
QIcon *mEmptyIcon;

View File

@ -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)");
}

View File

@ -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

View File

@ -600,7 +600,8 @@ void FriendList::insertPeers()
// get ids of existing private chat messages
std::list<RsPeerId> privateChatIds;
rsMsgs->getPrivateChatQueueIds(true, privateChatIds);
// TODO
//rsMsgs->getPrivateChatQueueIds(true, privateChatIds);
// get existing groups
std::list<RsGroupInfo> 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;
}
}

View File

@ -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();

View File

@ -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<HistoryMsg> 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()

View File

@ -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;
};

View File

@ -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>("ChatId");
qRegisterMetaType<ChatMessage>("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<TurtleFileInfo>& 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<ChatLobbyDialog*>(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<ChatLobbyDialog*>(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));

View File

@ -4,6 +4,7 @@
#include <retroshare/rsiface.h>
#include <retroshare/rsturtle.h>
#include <retroshare/rsnotify.h>
#include <retroshare/rsmsgs.h>
#include <QObject>
#include <QMutex>
#include <QPoint>
@ -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<TurtleFileInfo>& 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();

View File

@ -29,7 +29,6 @@
#include <retroshare/rsinit.h>
#include <retroshare/rspeers.h>
#include <retroshare/rsmsgs.h>
#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<RsPeerId, std::string>::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<RsPeerId, std::string>::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;
}

View File

@ -23,6 +23,8 @@
#define _RSHAREPEERSETTINGS_H
#include <QSettings>
#include <retroshare/rstypes.h>
#include <retroshare/rsmsgs.h>
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<RsPeerId, std::string> m_SslToGpg;

View File

@ -25,13 +25,12 @@
#include <retroshare/rsmsgs.h>
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<ChatLobbyInfo> linfos;
rsMsgs->getChatLobbyList(linfos);
ChatLobbyId lobbyId;
if (rsMsgs->isLobbyId(peerId, lobbyId)) {
for (std::list<ChatLobbyInfo>::const_iterator it(linfos.begin()); it != linfos.end(); ++it) {
if ((*it).lobby_id == lobbyId) {
lobbyName += "@" + RsHtml::plainText(it->lobby_name);
break;
}
}
}
for (std::list<ChatLobbyInfo>::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();
}

View File

@ -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;

View File

@ -25,25 +25,23 @@
#include <retroshare/rspeers.h>
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();
}

View File

@ -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;

View File

@ -41,6 +41,6 @@ OnlineToaster::OnlineToaster(const RsPeerId &peerId) : QWidget(NULL)
void OnlineToaster::chatButtonSlot()
{
ChatDialog::chatFriend(peerId);
ChatDialog::chatFriend(ChatId(peerId));
hide();
}

View File

@ -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) )) ;