merged in new lobbies with GXS ids. Old peers and new peers cannot see each others lobby lists. Invitations still work and can be used to transfer a lobby ID between versions. Messages of old and new peers will not be visible to each other

git-svn-id: http://svn.code.sf.net/p/retroshare/code/trunk@7986 b45a01b8-16f6-495d-af2f-9b41ad6348cc
This commit is contained in:
csoler 2015-03-06 21:13:23 +00:00
parent 2044575067
commit f9c78ebd61
22 changed files with 1430 additions and 980 deletions

View File

@ -12,6 +12,7 @@ Level | What
E [ ] it's not possible to create a Posted thread without a Owner. E [ ] it's not possible to create a Posted thread without a Owner.
Bug? If not, then remove "No signature" from selection box Bug? If not, then remove "No signature" from selection box
E [ ] Show an info page for unsubscribed posted threads (same as forums) E [ ] Show an info page for unsubscribed posted threads (same as forums)
E [ ] Links in Posted cannot be clicked.
M [ ] Fix the counting of unread messages in Posted. Now it's wrong. M [ ] Fix the counting of unread messages in Posted. Now it's wrong.
E [X] Make the GUI of Posted more sexy: more compact items, remove unecessary text, use consistent icons,... E [X] Make the GUI of Posted more sexy: more compact items, remove unecessary text, use consistent icons,...
@ -28,13 +29,18 @@ E [ ] Recommendation messages do not show complete links. Links show up i
E [X] Recommendation messages should not be signed by the retroshare team!! E [X] Recommendation messages should not be signed by the retroshare team!!
E [ ] when adding a friend through clicking on cert links, the add friend wizard is shown twice! E [ ] when adding a friend through clicking on cert links, the add friend wizard is shown twice!
M [X] add a flag in friends option to allow auto-download of recommended files M [X] add a flag in friends option to allow auto-download of recommended files
M [ ] sound is not working for some users on linux. We also need a "test sound" button in config->sound
E [ ] some widgets in the GUI do not follow the system style => GUI looks bad on these systems
E [ ] display version ID in windows version
E [ ] recommended friends messages have embedded buttons of wrong size. Use RSLinks instead!
Messages Messages
H [ ] distant messages should be made async-ed H [ ] distant messages should be made async-ed
M [ ] distant messages are not re-sent when the peer is offline the first time M [ ] distant messages are not re-sent when the peer is offline the first time
M [ ] sent messages to direct peers in the Sent box have inconsistent To field. M [X] sent messages to direct peers in the Sent box have inconsistent To field.
Raises an error if you click on it. Raises an error if you click on it.
H [ ] Merge the new messaging format? (or keep this for > 0.6) H [ ] Merge the new messaging format? (or keep this for > 0.6)
M [ ] icons for GxsTreeWidgetItem are too small in distant messages list widget
Channels Channels
[X] Unsubscribed channels should show an info page when selected, like forums [X] Unsubscribed channels should show an info page when selected, like forums
@ -42,9 +48,10 @@ H [ ] marking all as read in channels takes time. The channel icon should
during the operation to avoid the user to re-click many times in the hope to get during the operation to avoid the user to re-click many times in the hope to get
the posts marked as read. the posts marked as read.
[X] channels items show a 0 left to the up/Dn buttons. What is it?? [X] channels items show a 0 left to the up/Dn buttons. What is it??
[ ] allow to post on channels when attachment is not in shared files. Just display a warning.
Chat lobbies Chat lobbies
H [ ] Chat lobbies should use Identities. That's a significant change, probably not backward compatible. H [X] Chat lobbies should use Identities. That's a significant change, probably not backward compatible.
[X] Remove deprecated code in rschatitems. [X] Remove deprecated code in rschatitems.
Chat Chat
@ -67,6 +74,7 @@ M [ ] allow to share identities between locations.
Network Network
E [ ] Friends => Friend nodes E [ ] Friends => Friend nodes
E [ ] remove TCP, TOR, UDP from the status column, and move it in front of IP
News feed News feed
[X] remove the Ghost news feed items [X] remove the Ghost news feed items

File diff suppressed because it is too large Load Diff

View File

@ -32,6 +32,7 @@ typedef RsPeerId ChatLobbyVirtualPeerId ;
class RsItem ; class RsItem ;
class p3HistoryMgr ; class p3HistoryMgr ;
class p3IdService ;
class p3ServiceControl; class p3ServiceControl;
class RsChatLobbyItem ; class RsChatLobbyItem ;
class RsChatLobbyListRequestItem ; class RsChatLobbyListRequestItem ;
@ -49,7 +50,7 @@ class RsChatMsgItem ;
class DistributedChatService class DistributedChatService
{ {
public: public:
DistributedChatService(uint32_t service_type,p3ServiceControl *sc,p3HistoryMgr *hm) ; DistributedChatService(uint32_t service_type,p3ServiceControl *sc,p3HistoryMgr *hm,p3IdService *is) ;
virtual ~DistributedChatService() {} virtual ~DistributedChatService() {}
@ -59,24 +60,25 @@ class DistributedChatService
// //
bool getVirtualPeerId(const ChatLobbyId& lobby_id, RsPeerId& virtual_peer_id) ; bool getVirtualPeerId(const ChatLobbyId& lobby_id, RsPeerId& virtual_peer_id) ;
bool isLobbyId(const RsPeerId& virtual_peer_id, ChatLobbyId& lobby_id) ; bool isLobbyId(const RsPeerId& virtual_peer_id, ChatLobbyId& lobby_id) ;
void getChatLobbyList(std::list<ChatLobbyInfo, std::allocator<ChatLobbyInfo> >& cl_infos) ; void getChatLobbyList(std::list<ChatLobbyId>& clids) ;
bool acceptLobbyInvite(const ChatLobbyId& id) ; bool getChatLobbyInfo(const ChatLobbyId& id,ChatLobbyInfo& clinfo) ;
bool acceptLobbyInvite(const ChatLobbyId& id,const RsGxsId& identity) ;
void denyLobbyInvite(const ChatLobbyId& id) ; void denyLobbyInvite(const ChatLobbyId& id) ;
void getPendingChatLobbyInvites(std::list<ChatLobbyInvite>& invites) ; void getPendingChatLobbyInvites(std::list<ChatLobbyInvite>& invites) ;
void invitePeerToLobby(const ChatLobbyId&, const RsPeerId& peer_id,bool connexion_challenge = false) ; void invitePeerToLobby(const ChatLobbyId&, const RsPeerId& peer_id,bool connexion_challenge = false) ;
void unsubscribeChatLobby(const ChatLobbyId& lobby_id) ; void unsubscribeChatLobby(const ChatLobbyId& lobby_id) ;
bool setNickNameForChatLobby(const ChatLobbyId& lobby_id,const std::string& nick) ; bool setIdentityForChatLobby(const ChatLobbyId& lobby_id,const RsGxsId& nick) ;
bool getNickNameForChatLobby(const ChatLobbyId& lobby_id,std::string& nick) ; bool getIdentityForChatLobby(const ChatLobbyId& lobby_id,RsGxsId& nick) ;
bool setDefaultNickNameForChatLobby(const std::string& nick) ; bool setDefaultIdentityForChatLobby(const RsGxsId& nick) ;
bool getDefaultNickNameForChatLobby(std::string& nick) ; bool getDefaultIdentityForChatLobby(RsGxsId& nick) ;
void setLobbyAutoSubscribe(const ChatLobbyId& lobby_id, const bool autoSubscribe); void setLobbyAutoSubscribe(const ChatLobbyId& lobby_id, const bool autoSubscribe);
bool getLobbyAutoSubscribe(const ChatLobbyId& lobby_id); bool getLobbyAutoSubscribe(const ChatLobbyId& lobby_id);
void sendLobbyStatusString(const ChatLobbyId& id,const std::string& status_string) ; void sendLobbyStatusString(const ChatLobbyId& id,const std::string& status_string) ;
ChatLobbyId createChatLobby(const std::string& lobby_name,const std::string& lobby_topic, const std::list<RsPeerId>& invited_friends,uint32_t privacy_type) ; ChatLobbyId createChatLobby(const std::string& lobby_name,const RsGxsId& lobby_identity,const std::string& lobby_topic, const std::list<RsPeerId>& invited_friends,ChatLobbyFlags flags) ;
void getListOfNearbyChatLobbies(std::vector<VisibleChatLobbyRecord>& public_lobbies) ; void getListOfNearbyChatLobbies(std::vector<VisibleChatLobbyRecord>& public_lobbies) ;
bool joinVisibleChatLobby(const ChatLobbyId& id) ; bool joinVisibleChatLobby(const ChatLobbyId& id, const RsGxsId &gxs_id) ;
protected: protected:
bool handleRecvItem(RsChatItem *) ; bool handleRecvItem(RsChatItem *) ;
@ -89,11 +91,13 @@ class DistributedChatService
bool processLoadListItem(const RsItem *item) ; bool processLoadListItem(const RsItem *item) ;
bool locked_checkAndRebuildPartialLobbyMessage(RsChatLobbyMsgItem *) ; bool locked_checkAndRebuildPartialLobbyMessage(RsChatLobbyMsgItem *) ;
void checkSizeAndSendLobbyMessage(RsChatLobbyMsgItem *) ; void checkSizeAndSendLobbyMessage(RsChatItem *) ;
bool sendLobbyChat(const ChatLobbyId &lobby_id, const std::string&) ; bool sendLobbyChat(const ChatLobbyId &lobby_id, const std::string&) ;
bool handleRecvChatLobbyMsgItem(RsChatMsgItem *item) ; bool handleRecvChatLobbyMsgItem(RsChatMsgItem *item) ;
bool checkSignature(RsChatLobbyBouncingObject *obj,const RsPeerId& peer_id) ;
private: private:
/// make some statistics about time shifts, to prevent various issues. /// make some statistics about time shifts, to prevent various issues.
void addTimeShiftStatistics(int shift) ; void addTimeShiftStatistics(int shift) ;
@ -138,7 +142,6 @@ class DistributedChatService
time_t last_connexion_challenge_time ; time_t last_connexion_challenge_time ;
time_t last_keep_alive_packet_time ; time_t last_keep_alive_packet_time ;
std::set<RsPeerId> previously_known_peers ; std::set<RsPeerId> previously_known_peers ;
uint32_t flags ;
}; };
std::map<ChatLobbyId,ChatLobbyEntry> _chat_lobbys ; std::map<ChatLobbyId,ChatLobbyEntry> _chat_lobbys ;
@ -154,11 +157,12 @@ class DistributedChatService
time_t last_lobby_challenge_time ; // prevents bruteforce attack time_t last_lobby_challenge_time ; // prevents bruteforce attack
time_t last_visible_lobby_info_request_time ; // allows to ask for updates time_t last_visible_lobby_info_request_time ; // allows to ask for updates
bool _should_reset_lobby_counts ; bool _should_reset_lobby_counts ;
std::string _default_nick_name ; RsGxsId _default_identity ;
uint32_t mServType ; uint32_t mServType ;
RsMutex mDistributedChatMtx ; RsMutex mDistributedChatMtx ;
p3ServiceControl *mServControl; p3ServiceControl *mServControl;
p3HistoryMgr *mHistMgr; p3HistoryMgr *mHistMgr;
p3IdService *mIdService ;
}; };

View File

@ -54,7 +54,7 @@ static const uint32_t MAX_AVATAR_JPEG_SIZE = 32767; // Maximum size
// Images are 96x96, which makes approx. 27000 bytes uncompressed. // Images are 96x96, which makes approx. 27000 bytes uncompressed.
p3ChatService::p3ChatService(p3ServiceControl *sc,p3IdService *pids, p3LinkMgr *lm, p3HistoryMgr *historyMgr) p3ChatService::p3ChatService(p3ServiceControl *sc,p3IdService *pids, p3LinkMgr *lm, p3HistoryMgr *historyMgr)
:DistantChatService(pids),DistributedChatService(getServiceInfo().mServiceType,sc,historyMgr), mChatMtx("p3ChatService"),mServiceCtrl(sc), mLinkMgr(lm) , mHistoryMgr(historyMgr) :DistantChatService(pids),DistributedChatService(getServiceInfo().mServiceType,sc,historyMgr,pids), mChatMtx("p3ChatService"),mServiceCtrl(sc), mLinkMgr(lm) , mHistoryMgr(historyMgr)
{ {
_serializer = new RsChatSerialiser() ; _serializer = new RsChatSerialiser() ;
@ -811,7 +811,7 @@ void p3ChatService::initChatMessage(RsChatMsgItem *c, ChatMessage &m)
RsChatLobbyMsgItem *lobbyItem = dynamic_cast<RsChatLobbyMsgItem*>(c) ; RsChatLobbyMsgItem *lobbyItem = dynamic_cast<RsChatLobbyMsgItem*>(c) ;
if(lobbyItem != NULL) if(lobbyItem != NULL)
{ {
m.lobby_peer_nickname = lobbyItem->nick; m.lobby_peer_gxs_id = lobbyItem->signature.keyId ;
m.chat_id = ChatId(lobbyItem->lobby_id); m.chat_id = ChatId(lobbyItem->lobby_id);
return; return;
} }

View File

@ -68,10 +68,11 @@ std::ostream& RsChatLobbyListItem::print(std::ostream &out, uint16_t indent)
{ {
printRsItemBase(out, "RsChatLobbyListItem", indent); printRsItemBase(out, "RsChatLobbyListItem", indent);
for(uint32_t i=0;i<lobby_ids.size();++i) for(uint32_t i=0;i<lobbies.size();++i)
{ {
printIndent(out, indent+2); printIndent(out, indent+2);
out << "lobby 0x" << std::hex << lobby_ids[i] << std::dec << " (name=\"" << lobby_names[i] << "\", topic="<< lobby_topics[i] << "\", count=" << lobby_counts[i] << ", privacy_level = " << lobby_privacy_levels[i] << std::endl ; out << "lobby 0x" << std::hex << lobbies[i].id << std::dec << " (name=\"" << lobbies[i].name << "\", topic="<< lobbies[i].topic
<< "\", count=" << lobbies[i].count << ", flags = " << lobbies[i].flags << std::endl ;
} }
printRsItemEnd(out, "RsChatLobbyListItem", indent); printRsItemEnd(out, "RsChatLobbyListItem", indent);
@ -88,6 +89,7 @@ std::ostream& RsChatLobbyBouncingObject::print(std::ostream &out, uint16_t inden
printIndent(out, indent); out << "Lobby ID: " << std::hex << lobby_id << std::endl; printIndent(out, indent); out << "Lobby ID: " << std::hex << lobby_id << std::endl;
printIndent(out, indent); out << "Msg ID: " << std::hex << msg_id << std::dec << std::endl; printIndent(out, indent); out << "Msg ID: " << std::hex << msg_id << std::dec << std::endl;
printIndent(out, indent); out << "Nick: " << nick << std::dec << std::endl; printIndent(out, indent); out << "Nick: " << nick << std::dec << std::endl;
printIndent(out, indent); out << "Sign: " << signature.keyId << std::dec << std::endl;
return out; return out;
} }
@ -267,11 +269,11 @@ RsItem *RsChatSerialiser::deserialise(void *data, uint32_t *pktsize)
case RS_PKT_SUBTYPE_DISTANT_INVITE_CONFIG: return new RsPrivateChatDistantInviteConfigItem(data,*pktsize) ; case RS_PKT_SUBTYPE_DISTANT_INVITE_CONFIG: return new RsPrivateChatDistantInviteConfigItem(data,*pktsize) ;
case RS_PKT_SUBTYPE_CHAT_STATUS: return new RsChatStatusItem(data,*pktsize) ; case RS_PKT_SUBTYPE_CHAT_STATUS: return new RsChatStatusItem(data,*pktsize) ;
case RS_PKT_SUBTYPE_CHAT_AVATAR: return new RsChatAvatarItem(data,*pktsize) ; case RS_PKT_SUBTYPE_CHAT_AVATAR: return new RsChatAvatarItem(data,*pktsize) ;
case RS_PKT_SUBTYPE_CHAT_LOBBY_MSG: return new RsChatLobbyMsgItem(data,*pktsize) ; case RS_PKT_SUBTYPE_CHAT_LOBBY_SIGNED_MSG: return new RsChatLobbyMsgItem(data,*pktsize) ;
case RS_PKT_SUBTYPE_CHAT_LOBBY_INVITE: return new RsChatLobbyInviteItem(data,*pktsize) ; case RS_PKT_SUBTYPE_CHAT_LOBBY_INVITE: return new RsChatLobbyInviteItem(data,*pktsize) ;
case RS_PKT_SUBTYPE_CHAT_LOBBY_CHALLENGE: return new RsChatLobbyConnectChallengeItem(data,*pktsize) ; case RS_PKT_SUBTYPE_CHAT_LOBBY_CHALLENGE: return new RsChatLobbyConnectChallengeItem(data,*pktsize) ;
case RS_PKT_SUBTYPE_CHAT_LOBBY_UNSUBSCRIBE: return new RsChatLobbyUnsubscribeItem(data,*pktsize) ; case RS_PKT_SUBTYPE_CHAT_LOBBY_UNSUBSCRIBE: return new RsChatLobbyUnsubscribeItem(data,*pktsize) ;
case RS_PKT_SUBTYPE_CHAT_LOBBY_EVENT: return new RsChatLobbyEventItem(data,*pktsize) ; case RS_PKT_SUBTYPE_CHAT_LOBBY_SIGNED_EVENT: return new RsChatLobbyEventItem(data,*pktsize) ;
case RS_PKT_SUBTYPE_CHAT_LOBBY_LIST_REQUEST: return new RsChatLobbyListRequestItem(data,*pktsize) ; case RS_PKT_SUBTYPE_CHAT_LOBBY_LIST_REQUEST: return new RsChatLobbyListRequestItem(data,*pktsize) ;
case RS_PKT_SUBTYPE_CHAT_LOBBY_LIST: return new RsChatLobbyListItem(data,*pktsize) ; case RS_PKT_SUBTYPE_CHAT_LOBBY_LIST: return new RsChatLobbyListItem(data,*pktsize) ;
case RS_PKT_SUBTYPE_CHAT_LOBBY_CONFIG: return new RsChatLobbyConfigItem(data,*pktsize) ; case RS_PKT_SUBTYPE_CHAT_LOBBY_CONFIG: return new RsChatLobbyConfigItem(data,*pktsize) ;
@ -306,28 +308,38 @@ uint32_t RsChatLobbyConnectChallengeItem::serial_size()
s += 8; // challenge code s += 8; // challenge code
return s ; return s ;
} }
uint32_t RsChatLobbyBouncingObject::serialized_size(bool include_signature)
uint32_t RsChatLobbyBouncingObject::serial_size()
{ {
uint32_t s = 0 ; // no header! uint32_t s = 0 ; // no header!
s += 8 ; // lobby_id s += 8 ; // lobby_id
s += 8 ; // msg_id s += 8 ; // msg_id
s += GetTlvStringSize(nick) ; // nick s += GetTlvStringSize(nick) ; // nick
if(include_signature)
s += signature.TlvSize() ; // signature
return s ; return s ;
} }
uint32_t RsChatLobbyEventItem::signed_serial_size()
uint32_t RsChatLobbyEventItem::serial_size()
{ {
uint32_t s = 8 ; // header uint32_t s = 8 ; // header
s += RsChatLobbyBouncingObject::serial_size() ;
s += 1 ; // event_type s += 1 ; // event_type
s += GetTlvStringSize(string1) ; // string1 s += GetTlvStringSize(string1) ; // string1
s += 4 ; // send time s += 4 ; // send time
s += RsChatLobbyBouncingObject::serialized_size(false) ;
return s ; return s ;
} }
uint32_t RsChatLobbyEventItem::serial_size()
{
uint32_t s = 8 ; // header
s += 1 ; // event_type
s += GetTlvStringSize(string1) ; // string1
s += 4 ; // send time
s += RsChatLobbyBouncingObject::serialized_size(true) ;
return s ;
}
uint32_t RsChatLobbyListRequestItem::serial_size() uint32_t RsChatLobbyListRequestItem::serial_size()
{ {
uint32_t s = 8 ; // header uint32_t s = 8 ; // header
@ -337,24 +349,30 @@ uint32_t RsChatLobbyListItem::serial_size()
{ {
uint32_t s = 8 ; // header uint32_t s = 8 ; // header
s += 4 ; // number of elements in the vectors s += 4 ; // number of elements in the vectors
s += lobby_ids.size() * 8 ; // lobby_ids
for(uint32_t i=0;i<lobby_names.size();++i) for(uint32_t i=0;i<lobbies.size();++i)
s += GetTlvStringSize(lobby_names[i]) ; // lobby_names {
s += 8 ; // id
for(uint32_t i=0;i<lobby_topics.size();++i) s += GetTlvStringSize(lobbies[i].name) ; // lobby_names
s += GetTlvStringSize(lobby_topics[i]) ; // lobby_topics s += GetTlvStringSize(lobbies[i].topic) ; // lobby_topics
s += 4 ; // lobby_counts
s += lobby_counts.size() * 4 ; // lobby_counts s += 4 ; // lobby_flags
s += lobby_privacy_levels.size() * 4 ; // lobby_privacy_levels }
return s ; return s ;
} }
uint32_t RsChatLobbyMsgItem::serial_size() uint32_t RsChatLobbyMsgItem::serial_size()
{ {
uint32_t s = RsChatMsgItem::serial_size() ; // parent uint32_t s = RsChatMsgItem::serial_size() ; // parent
s += RsChatLobbyBouncingObject::serial_size() ;
s += 1; // subpacket id
s += 8; // parent_msg_id s += 8; // parent_msg_id
s += RsChatLobbyBouncingObject::serialized_size(true) ;
return s;
}
uint32_t RsChatLobbyMsgItem::signed_serial_size()
{
uint32_t s = RsChatMsgItem::serial_size() ; // parent
s += 8; // parent_msg_id
s += RsChatLobbyBouncingObject::serialized_size(false) ;
return s; return s;
} }
@ -523,7 +541,7 @@ bool RsChatMsgItem::serialise(void *data, uint32_t& pktsize)
return ok ; return ok ;
} }
bool RsChatLobbyBouncingObject::serialise(void *data,uint32_t tlvsize,uint32_t& offset) bool RsChatLobbyBouncingObject::serialise_to_memory(void *data,uint32_t tlvsize,uint32_t& offset,bool include_signature)
{ {
bool ok = true ; bool ok = true ;
@ -531,6 +549,9 @@ bool RsChatLobbyBouncingObject::serialise(void *data,uint32_t tlvsize,uint32_t&
ok &= setRawUInt64(data, tlvsize, &offset, msg_id); ok &= setRawUInt64(data, tlvsize, &offset, msg_id);
ok &= SetTlvString(data, tlvsize, &offset, TLV_TYPE_STR_NAME, nick); ok &= SetTlvString(data, tlvsize, &offset, TLV_TYPE_STR_NAME, nick);
if(include_signature)
ok &= signature.SetTlv(data, tlvsize, &offset);
return ok ; return ok ;
} }
@ -549,10 +570,12 @@ bool RsChatLobbyMsgItem::serialise(void *data, uint32_t& pktsize)
ok &= setRsItemHeader(data, tlvsize, PacketId(), tlvsize); // correct header! ok &= setRsItemHeader(data, tlvsize, PacketId(), tlvsize); // correct header!
pktsize = tlvsize; pktsize = tlvsize;
ok &= RsChatLobbyBouncingObject::serialise(data,tlvsize,offset) ;
ok &= setRawUInt8(data, tlvsize, &offset, subpacket_id);
ok &= setRawUInt64(data, tlvsize, &offset, parent_msg_id); ok &= setRawUInt64(data, tlvsize, &offset, parent_msg_id);
// The signature is at the end of the serialised data, so that the signed data is *before* the signature.
ok &= RsChatLobbyBouncingObject::serialise_to_memory(data,tlvsize,offset,true) ;
/* add mandatory parts first */ /* add mandatory parts first */
if (offset != tlvsize) if (offset != tlvsize)
{ {
@ -564,6 +587,40 @@ bool RsChatLobbyMsgItem::serialise(void *data, uint32_t& pktsize)
#endif #endif
return ok ; return ok ;
} }
/* serialise the data to the buffer */
bool RsChatLobbyMsgItem::serialise_signed_part(void *data, uint32_t& pktsize)
{
uint32_t tlvsize = signed_serial_size() ;
if (pktsize < tlvsize)
return false; /* not enough space */
bool ok = true;
ok &= RsChatMsgItem::serialise(data,pktsize) ; // first, serialize parent
uint32_t offset = pktsize;
ok &= setRsItemHeader(data, tlvsize, PacketId(), tlvsize); // correct header!
pktsize = tlvsize;
//ok &= setRawUInt8(data, tlvsize, &offset, subpacket_id); // don't serialise sub-part id.
ok &= setRawUInt64(data, tlvsize, &offset, parent_msg_id);
// The signature is at the end of the serialised data, so that the signed data is *before* the signature.
ok &= RsChatLobbyBouncingObject::serialise_to_memory(data,tlvsize,offset,false) ;
/* add mandatory parts first */
if (offset != tlvsize)
{
ok = false;
std::cerr << "RsChatSerialiser::serialiseItem() Size Error! " << std::endl;
}
#ifdef CHAT_DEBUG
std::cerr << "computed size: " << 256*((unsigned char*)data)[6]+((unsigned char*)data)[7] << std::endl ;
#endif
return ok ;
}
bool RsChatLobbyListRequestItem::serialise(void *data, uint32_t& pktsize) bool RsChatLobbyListRequestItem::serialise(void *data, uint32_t& pktsize)
{ {
@ -586,26 +643,18 @@ bool RsChatLobbyListItem::serialise(void *data, uint32_t& pktsize)
if (pktsize < tlvsize) if (pktsize < tlvsize)
return false; /* not enough space */ return false; /* not enough space */
if((lobby_ids.size() != lobby_names.size()) ||
(lobby_ids.size() != lobby_topics.size()) ||
(lobby_ids.size() != lobby_counts.size()) ||
(lobby_ids.size() != lobby_privacy_levels.size()))
{
std::cerr << "Consistency error in RsChatLobbyListItem!! Sizes don't match!" << std::endl;
return false ;
}
pktsize = tlvsize ; pktsize = tlvsize ;
uint32_t offset = 8 ; uint32_t offset = 8 ;
ok &= setRawUInt32(data, tlvsize, &offset, lobby_ids.size()); ok &= setRawUInt32(data, tlvsize, &offset, lobbies.size());
for(uint32_t i=0;i<lobby_ids.size();++i) for(uint32_t i=0;i<lobbies.size();++i)
{ {
ok &= setRawUInt64(data, tlvsize, &offset, lobby_ids[i]); ok &= setRawUInt64(data, tlvsize, &offset, lobbies[i].id);
ok &= SetTlvString(data, tlvsize, &offset, TLV_TYPE_STR_NAME, lobby_names[i]); ok &= SetTlvString(data, tlvsize, &offset, TLV_TYPE_STR_NAME, lobbies[i].name);
ok &= SetTlvString(data, tlvsize, &offset, TLV_TYPE_STR_NAME, lobby_topics[i]); ok &= SetTlvString(data, tlvsize, &offset, TLV_TYPE_STR_NAME, lobbies[i].topic);
ok &= setRawUInt32(data, tlvsize, &offset, lobby_counts[i]); ok &= setRawUInt32(data, tlvsize, &offset, lobbies[i].count);
ok &= setRawUInt32(data, tlvsize, &offset, lobby_privacy_levels[i]); ok &= setRawUInt32(data, tlvsize, &offset, lobbies[i].flags.toUInt32());
} }
if (offset != tlvsize) if (offset != tlvsize)
{ {
@ -625,11 +674,42 @@ bool RsChatLobbyEventItem::serialise(void *data, uint32_t& pktsize)
uint32_t offset = 8 ; uint32_t offset = 8 ;
ok &= RsChatLobbyBouncingObject::serialise(data,tlvsize,offset) ; // first, serialize parent
ok &= setRawUInt8(data, tlvsize, &offset, event_type); ok &= setRawUInt8(data, tlvsize, &offset, event_type);
ok &= SetTlvString(data, tlvsize, &offset, TLV_TYPE_STR_NAME, string1); ok &= SetTlvString(data, tlvsize, &offset, TLV_TYPE_STR_NAME, string1);
ok &= setRawUInt32(data, tlvsize, &offset, sendTime); ok &= setRawUInt32(data, tlvsize, &offset, sendTime);
ok &= RsChatLobbyBouncingObject::serialise_to_memory(data,tlvsize,offset,true) ; // at the end, serialize parent
pktsize = tlvsize ;
/* add mandatory parts first */
if (offset != tlvsize)
{
ok = false;
std::cerr << "RsChatSerialiser::serialiseItem() Size Error! " << std::endl;
}
#ifdef CHAT_DEBUG
std::cerr << "computed size: " << 256*((unsigned char*)data)[6]+((unsigned char*)data)[7] << std::endl ;
#endif
return ok ;
}
bool RsChatLobbyEventItem::serialise_signed_part(void *data, uint32_t& pktsize)
{
uint32_t tlvsize = signed_serial_size() ;
bool ok = true ;
ok &= setRsItemHeader(data, tlvsize, PacketId(), tlvsize); // correct header!
if (pktsize < tlvsize)
return false; /* not enough space */
uint32_t offset = 8 ;
ok &= setRawUInt8(data, tlvsize, &offset, event_type);
ok &= SetTlvString(data, tlvsize, &offset, TLV_TYPE_STR_NAME, string1);
ok &= setRawUInt32(data, tlvsize, &offset, sendTime);
ok &= RsChatLobbyBouncingObject::serialise_to_memory(data,tlvsize,offset,false) ; // at the end, serialize parent
pktsize = tlvsize ; pktsize = tlvsize ;
/* add mandatory parts first */ /* add mandatory parts first */
@ -706,7 +786,7 @@ bool RsChatLobbyInviteItem::serialise(void *data, uint32_t& pktsize)
ok &= setRawUInt64(data, tlvsize, &offset, lobby_id); ok &= setRawUInt64(data, tlvsize, &offset, lobby_id);
ok &= SetTlvString(data, tlvsize, &offset, TLV_TYPE_STR_NAME, lobby_name); ok &= SetTlvString(data, tlvsize, &offset, TLV_TYPE_STR_NAME, lobby_name);
ok &= setRawUInt32(data, tlvsize, &offset, lobby_privacy_level); ok &= setRawUInt32(data, tlvsize, &offset, lobby_flags.toUInt32());
if (offset != tlvsize) if (offset != tlvsize)
{ {
@ -966,17 +1046,17 @@ RsChatMsgItem::RsChatMsgItem(void *data,uint32_t /*size*/,uint8_t subtype)
} }
RsChatLobbyMsgItem::RsChatLobbyMsgItem(void *data,uint32_t /*size*/) RsChatLobbyMsgItem::RsChatLobbyMsgItem(void *data,uint32_t /*size*/)
: RsChatMsgItem(data,0,RS_PKT_SUBTYPE_CHAT_LOBBY_MSG) : RsChatMsgItem(data,0,RS_PKT_SUBTYPE_CHAT_LOBBY_SIGNED_MSG)
{ {
uint32_t rssize = getRsItemSize(data); uint32_t rssize = getRsItemSize(data);
bool ok = true ; bool ok = true ;
uint32_t offset = RsChatMsgItem::serial_size() ; uint32_t offset = RsChatMsgItem::serial_size() ;
ok &= RsChatLobbyBouncingObject::deserialise(data,rssize,offset) ;
ok &= getRawUInt8(data, rssize, &offset, &subpacket_id);
ok &= getRawUInt64(data, rssize, &offset, &parent_msg_id); ok &= getRawUInt64(data, rssize, &offset, &parent_msg_id);
ok &= RsChatLobbyBouncingObject::deserialise_from_memory(data,rssize,offset) ;
#ifdef CHAT_DEBUG #ifdef CHAT_DEBUG
std::cerr << "Building new chat lobby msg item." << std::endl ; std::cerr << "Building new chat lobby msg item." << std::endl ;
#endif #endif
@ -1007,19 +1087,19 @@ RsChatLobbyListItem::RsChatLobbyListItem(void *data,uint32_t)
uint32_t n=0 ; uint32_t n=0 ;
ok &= getRawUInt32(data, rssize, &offset, &n); ok &= getRawUInt32(data, rssize, &offset, &n);
lobby_ids.resize(n) ; lobbies.resize(n) ;
lobby_names.resize(n) ;
lobby_topics.resize(n) ;
lobby_counts.resize(n) ;
lobby_privacy_levels.resize(n) ;
for(uint32_t i=0;i<n;++i) for(uint32_t i=0;i<n;++i)
{ {
ok &= getRawUInt64(data, rssize, &offset, &lobby_ids[i]); ok &= getRawUInt64(data, rssize, &offset, &lobbies[i].id);
ok &= GetTlvString(data, rssize, &offset, TLV_TYPE_STR_NAME, lobby_names[i]); ok &= GetTlvString(data, rssize, &offset, TLV_TYPE_STR_NAME, lobbies[i].name);
ok &= GetTlvString(data, rssize, &offset, TLV_TYPE_STR_NAME, lobby_topics[i]); ok &= GetTlvString(data, rssize, &offset, TLV_TYPE_STR_NAME, lobbies[i].topic);
ok &= getRawUInt32(data, rssize, &offset, &lobby_counts[i]); ok &= getRawUInt32(data, rssize, &offset, &lobbies[i].count);
ok &= getRawUInt32(data, rssize, &offset, &lobby_privacy_levels[i]);
uint32_t fl=0 ;
ok &= getRawUInt32(data, rssize, &offset, &fl);
lobbies[i].flags = ChatLobbyFlags(fl) ;
} }
if (offset != rssize) if (offset != rssize)
@ -1028,7 +1108,7 @@ RsChatLobbyListItem::RsChatLobbyListItem(void *data,uint32_t)
std::cerr << "Unknown error while deserializing." << std::endl ; std::cerr << "Unknown error while deserializing." << std::endl ;
} }
bool RsChatLobbyBouncingObject::deserialise(void *data,uint32_t rssize,uint32_t& offset) bool RsChatLobbyBouncingObject::deserialise_from_memory(void *data,uint32_t rssize,uint32_t& offset)
{ {
bool ok = true ; bool ok = true ;
/* get mandatory parts first */ /* get mandatory parts first */
@ -1036,23 +1116,25 @@ bool RsChatLobbyBouncingObject::deserialise(void *data,uint32_t rssize,uint32_t&
ok &= getRawUInt64(data, rssize, &offset, &msg_id); ok &= getRawUInt64(data, rssize, &offset, &msg_id);
ok &= GetTlvString(data, rssize, &offset, TLV_TYPE_STR_NAME, nick); ok &= GetTlvString(data, rssize, &offset, TLV_TYPE_STR_NAME, nick);
ok &= signature.GetTlv(data, rssize, &offset);
return ok ; return ok ;
} }
RsChatLobbyEventItem::RsChatLobbyEventItem(void *data,uint32_t /*size*/) RsChatLobbyEventItem::RsChatLobbyEventItem(void *data,uint32_t /*size*/)
: RsChatItem(RS_PKT_SUBTYPE_CHAT_LOBBY_EVENT) : RsChatItem(RS_PKT_SUBTYPE_CHAT_LOBBY_SIGNED_EVENT)
{ {
uint32_t rssize = getRsItemSize(data); uint32_t rssize = getRsItemSize(data);
bool ok = true ; bool ok = true ;
uint32_t offset = 8 ; uint32_t offset = 8 ;
ok &= RsChatLobbyBouncingObject::deserialise(data,rssize,offset) ;
ok &= getRawUInt8(data, rssize, &offset, &event_type); ok &= getRawUInt8(data, rssize, &offset, &event_type);
ok &= GetTlvString(data, rssize, &offset, TLV_TYPE_STR_NAME, string1); ok &= GetTlvString(data, rssize, &offset, TLV_TYPE_STR_NAME, string1);
ok &= getRawUInt32(data, rssize, &offset, &sendTime); ok &= getRawUInt32(data, rssize, &offset, &sendTime);
ok &= RsChatLobbyBouncingObject::deserialise_from_memory(data,rssize,offset) ;
#ifdef CHAT_DEBUG #ifdef CHAT_DEBUG
std::cerr << "Building new chat lobby status item." << std::endl ; std::cerr << "Building new chat lobby status item." << std::endl ;
#endif #endif
@ -1113,7 +1195,11 @@ RsChatLobbyInviteItem::RsChatLobbyInviteItem(void *data,uint32_t /*size*/)
/* get mandatory parts first */ /* get mandatory parts first */
ok &= getRawUInt64(data, rssize, &offset, &lobby_id); ok &= getRawUInt64(data, rssize, &offset, &lobby_id);
ok &= GetTlvString(data, rssize, &offset, TLV_TYPE_STR_NAME, lobby_name); ok &= GetTlvString(data, rssize, &offset, TLV_TYPE_STR_NAME, lobby_name);
ok &= getRawUInt32(data, rssize, &offset, &lobby_privacy_level);
uint32_t fl ;
ok &= getRawUInt32(data, rssize, &offset, &fl) ;
lobby_flags = ChatLobbyFlags(fl) ;
#ifdef CHAT_DEBUG #ifdef CHAT_DEBUG
std::cerr << "Building new chat msg item." << std::endl ; std::cerr << "Building new chat msg item." << std::endl ;

View File

@ -60,16 +60,19 @@ const uint8_t RS_PKT_SUBTYPE_CHAT_LOBBY_ACCEPT = 0x08 ;
const uint8_t RS_PKT_SUBTYPE_CHAT_LOBBY_CHALLENGE = 0x09 ; const uint8_t RS_PKT_SUBTYPE_CHAT_LOBBY_CHALLENGE = 0x09 ;
const uint8_t RS_PKT_SUBTYPE_CHAT_LOBBY_UNSUBSCRIBE = 0x0A ; const uint8_t RS_PKT_SUBTYPE_CHAT_LOBBY_UNSUBSCRIBE = 0x0A ;
const uint8_t RS_PKT_SUBTYPE_CHAT_LOBBY_EVENT_DEPREC = 0x0B ; // don't use ! Deprecated const uint8_t RS_PKT_SUBTYPE_CHAT_LOBBY_EVENT_DEPREC = 0x0B ; // don't use ! Deprecated
const uint8_t RS_PKT_SUBTYPE_CHAT_LOBBY_MSG = 0x0C ; const uint8_t RS_PKT_SUBTYPE_CHAT_LOBBY_MSG = 0x0C ; // will be deprecated when only signed messages are accepted (02/2015)
const uint8_t RS_PKT_SUBTYPE_CHAT_LOBBY_LIST_REQUEST = 0x0D ; const uint8_t RS_PKT_SUBTYPE_CHAT_LOBBY_LIST_REQUEST = 0x0D ;
const uint8_t RS_PKT_SUBTYPE_CHAT_LOBBY_LIST_deprecated = 0x0E ; // to be removed const uint8_t RS_PKT_SUBTYPE_CHAT_LOBBY_LIST_deprecated = 0x0E ; // to be removed
const uint8_t RS_PKT_SUBTYPE_CHAT_LOBBY_INVITE = 0x0F ; const uint8_t RS_PKT_SUBTYPE_CHAT_LOBBY_INVITE = 0x0F ;
const uint8_t RS_PKT_SUBTYPE_CHAT_LOBBY_EVENT = 0x10 ; const uint8_t RS_PKT_SUBTYPE_CHAT_LOBBY_EVENT = 0x10 ;
const uint8_t RS_PKT_SUBTYPE_CHAT_LOBBY_LIST_deprecated2 = 0x11 ; // to be removed (deprecated since 02 Dec. 2012) const uint8_t RS_PKT_SUBTYPE_CHAT_LOBBY_LIST_deprecated2 = 0x11 ; // to be removed (deprecated since 02 Dec. 2012)
const uint8_t RS_PKT_SUBTYPE_CHAT_LOBBY_LIST = 0x12 ; const uint8_t RS_PKT_SUBTYPE_CHAT_LOBBY_LIST_deprecated3 = 0x12 ;
const uint8_t RS_PKT_SUBTYPE_DISTANT_INVITE_CONFIG = 0x13 ; const uint8_t RS_PKT_SUBTYPE_DISTANT_INVITE_CONFIG = 0x13 ;
const uint8_t RS_PKT_SUBTYPE_CHAT_LOBBY_CONFIG = 0x15 ; const uint8_t RS_PKT_SUBTYPE_CHAT_LOBBY_CONFIG = 0x15 ;
const uint8_t RS_PKT_SUBTYPE_DISTANT_CHAT_DH_PUBLIC_KEY = 0x16 ; const uint8_t RS_PKT_SUBTYPE_DISTANT_CHAT_DH_PUBLIC_KEY = 0x16 ;
const uint8_t RS_PKT_SUBTYPE_CHAT_LOBBY_SIGNED_MSG = 0x17 ;
const uint8_t RS_PKT_SUBTYPE_CHAT_LOBBY_SIGNED_EVENT = 0x18 ;
const uint8_t RS_PKT_SUBTYPE_CHAT_LOBBY_LIST = 0x19 ;
typedef uint64_t ChatLobbyId ; typedef uint64_t ChatLobbyId ;
typedef uint64_t ChatLobbyMsgId ; typedef uint64_t ChatLobbyMsgId ;
@ -114,6 +117,7 @@ class RsChatMsgItem: public RsChatItem
uint32_t chatFlags; uint32_t chatFlags;
uint32_t sendTime; uint32_t sendTime;
std::string message; std::string message;
/* not serialised */ /* not serialised */
uint32_t recvTime; uint32_t recvTime;
}; };
@ -128,18 +132,30 @@ class RsChatLobbyBouncingObject
ChatLobbyMsgId msg_id ; ChatLobbyMsgId msg_id ;
ChatLobbyNickName nick ; // Nickname of sender ChatLobbyNickName nick ; // Nickname of sender
RsTlvKeySignature signature ;
virtual RsChatLobbyBouncingObject *duplicate() const = 0 ; virtual RsChatLobbyBouncingObject *duplicate() const = 0 ;
virtual uint32_t serial_size() ;
virtual bool serialise(void *data,uint32_t tlvsize,uint32_t& offset) ;
virtual std::ostream& print(std::ostream &out, uint16_t indent = 0); virtual std::ostream& print(std::ostream &out, uint16_t indent = 0);
bool deserialise(void *data,uint32_t rssize,uint32_t& offset) ; // returns the size in bytes of the data chunk to sign.
virtual uint32_t signed_serial_size() =0;
virtual bool serialise_signed_part(void *data,uint32_t& size) = 0;
protected:
// The functions below handle the serialisation of data that is specific to the bouncing object level.
// They are called by serial_size() and serialise() from children, but should not overload the serial_size() and
// serialise() methods, otherwise the wrong method will be called when serialising from this top level class.
uint32_t serialized_size(bool include_signature) ;
bool serialise_to_memory(void *data,uint32_t tlvsize,uint32_t& offset,bool include_signature) ;
bool deserialise_from_memory(void *data,uint32_t rssize,uint32_t& offset) ;
}; };
class RsChatLobbyMsgItem: public RsChatMsgItem, public RsChatLobbyBouncingObject class RsChatLobbyMsgItem: public RsChatMsgItem, public RsChatLobbyBouncingObject
{ {
public: public:
RsChatLobbyMsgItem() :RsChatMsgItem(RS_PKT_SUBTYPE_CHAT_LOBBY_MSG) {} RsChatLobbyMsgItem() :RsChatMsgItem(RS_PKT_SUBTYPE_CHAT_LOBBY_SIGNED_MSG) {}
RsChatLobbyMsgItem(void *data,uint32_t size) ; // deserialization /// TODO!!! RsChatLobbyMsgItem(void *data,uint32_t size) ; // deserialization /// TODO!!!
@ -150,14 +166,16 @@ class RsChatLobbyMsgItem: public RsChatMsgItem, public RsChatLobbyBouncingObject
virtual bool serialise(void *data,uint32_t& size) ; // Isn't it better that items can serialize themselves ? virtual bool serialise(void *data,uint32_t& size) ; // Isn't it better that items can serialize themselves ?
virtual uint32_t serial_size() ; // deserialise is handled using a constructor virtual uint32_t serial_size() ; // deserialise is handled using a constructor
uint8_t subpacket_id ; // this is for proper handling of split packets. virtual uint32_t signed_serial_size() ;
virtual bool serialise_signed_part(void *data,uint32_t& size) ;// Isn't it better that items can serialize themselves ?
ChatLobbyMsgId parent_msg_id ; // Used for threaded chat. ChatLobbyMsgId parent_msg_id ; // Used for threaded chat.
}; };
class RsChatLobbyEventItem: public RsChatItem, public RsChatLobbyBouncingObject class RsChatLobbyEventItem: public RsChatItem, public RsChatLobbyBouncingObject
{ {
public: public:
RsChatLobbyEventItem() :RsChatItem(RS_PKT_SUBTYPE_CHAT_LOBBY_EVENT) {} RsChatLobbyEventItem() :RsChatItem(RS_PKT_SUBTYPE_CHAT_LOBBY_SIGNED_EVENT) {}
RsChatLobbyEventItem(void *data,uint32_t size) ; // deserialization /// TODO!!! RsChatLobbyEventItem(void *data,uint32_t size) ; // deserialization /// TODO!!!
virtual ~RsChatLobbyEventItem() {} virtual ~RsChatLobbyEventItem() {}
@ -167,6 +185,9 @@ class RsChatLobbyEventItem: public RsChatItem, public RsChatLobbyBouncingObject
virtual bool serialise(void *data,uint32_t& size) ; virtual bool serialise(void *data,uint32_t& size) ;
virtual uint32_t serial_size() ; virtual uint32_t serial_size() ;
virtual uint32_t signed_serial_size() ;
virtual bool serialise_signed_part(void *data,uint32_t& size) ;
// members. // members.
// //
uint8_t event_type ; // used for defining the type of event. uint8_t event_type ; // used for defining the type of event.
@ -186,6 +207,16 @@ class RsChatLobbyListRequestItem: public RsChatItem
virtual std::ostream& print(std::ostream &out, uint16_t indent = 0); virtual std::ostream& print(std::ostream &out, uint16_t indent = 0);
}; };
struct VisibleChatLobbyInfo
{
ChatLobbyId id ;
std::string name ;
std::string topic ;
uint32_t count ;
ChatLobbyFlags flags ;
};
class RsChatLobbyListItem: public RsChatItem class RsChatLobbyListItem: public RsChatItem
{ {
public: public:
@ -198,12 +229,9 @@ class RsChatLobbyListItem: public RsChatItem
virtual bool serialise(void *data,uint32_t& size) ; virtual bool serialise(void *data,uint32_t& size) ;
virtual uint32_t serial_size() ; virtual uint32_t serial_size() ;
std::vector<ChatLobbyId> lobby_ids ; std::vector<VisibleChatLobbyInfo> lobbies ;
std::vector<std::string> lobby_names ;
std::vector<std::string> lobby_topics ;
std::vector<uint32_t> lobby_counts ;
std::vector<uint32_t> lobby_privacy_levels ;
}; };
class RsChatLobbyUnsubscribeItem: public RsChatItem class RsChatLobbyUnsubscribeItem: public RsChatItem
{ {
public: public:
@ -219,7 +247,6 @@ class RsChatLobbyUnsubscribeItem: public RsChatItem
virtual uint32_t serial_size() ; // deserialise is handled using a constructor virtual uint32_t serial_size() ; // deserialise is handled using a constructor
}; };
class RsChatLobbyConnectChallengeItem: public RsChatItem class RsChatLobbyConnectChallengeItem: public RsChatItem
{ {
public: public:
@ -247,7 +274,7 @@ class RsChatLobbyInviteItem: public RsChatItem
ChatLobbyId lobby_id ; ChatLobbyId lobby_id ;
std::string lobby_name ; std::string lobby_name ;
std::string lobby_topic ; std::string lobby_topic ;
uint32_t lobby_privacy_level ; ChatLobbyFlags lobby_flags ;
virtual bool serialise(void *data,uint32_t& size) ; // Isn't it better that items can serialize themselves ? virtual bool serialise(void *data,uint32_t& size) ; // Isn't it better that items can serialize themselves ?
virtual uint32_t serial_size() ; // deserialise is handled using a constructor virtual uint32_t serial_size() ; // deserialise is handled using a constructor

View File

@ -95,7 +95,7 @@ void p3HistoryMgr::addMessage(const ChatMessage& cm)
enabled = true; enabled = true;
} }
if (cm.chat_id.isLobbyId() && mLobbyEnable == true) { if (cm.chat_id.isLobbyId() && mLobbyEnable == true) {
peerName = cm.lobby_peer_nickname; peerName = cm.lobby_peer_gxs_id.toStdString();
enabled = true; enabled = true;
} }

View File

@ -80,9 +80,9 @@
#define RS_MSGTAGTYPE_LATER 5 #define RS_MSGTAGTYPE_LATER 5
#define RS_MSGTAGTYPE_USER 100 #define RS_MSGTAGTYPE_USER 100
#define RS_CHAT_LOBBY_PRIVACY_LEVEL_CHALLENGE 0 /* Used to accept connection challenges only. */ //#define RS_CHAT_LOBBY_PRIVACY_LEVEL_CHALLENGE 0 /* Used to accept connection challenges only. */
#define RS_CHAT_LOBBY_PRIVACY_LEVEL_PUBLIC 1 /* lobby is visible by friends. Friends can connect.*/ //#define RS_CHAT_LOBBY_PRIVACY_LEVEL_PUBLIC 1 /* lobby is visible by friends. Friends can connect.*/
#define RS_CHAT_LOBBY_PRIVACY_LEVEL_PRIVATE 2 /* lobby invisible by friends. Peers on invitation only .*/ //#define RS_CHAT_LOBBY_PRIVACY_LEVEL_PRIVATE 2 /* lobby invisible by friends. Peers on invitation only .*/
#define RS_CHAT_TYPE_PUBLIC 1 #define RS_CHAT_TYPE_PUBLIC 1
#define RS_CHAT_TYPE_PRIVATE 2 #define RS_CHAT_TYPE_PRIVATE 2
@ -90,6 +90,9 @@
#define RS_CHAT_TYPE_DISTANT 4 #define RS_CHAT_TYPE_DISTANT 4
const ChatLobbyFlags RS_CHAT_LOBBY_FLAGS_AUTO_SUBSCRIBE( 0x00000001 ) ; const ChatLobbyFlags RS_CHAT_LOBBY_FLAGS_AUTO_SUBSCRIBE( 0x00000001 ) ;
const ChatLobbyFlags RS_CHAT_LOBBY_FLAGS_ANONYMOUS ( 0x00000002 ) ;
const ChatLobbyFlags RS_CHAT_LOBBY_FLAGS_PUBLIC ( 0x00000004 ) ;
const ChatLobbyFlags RS_CHAT_LOBBY_FLAGS_CHALLENGE ( 0x00000008 ) ;
typedef uint64_t ChatLobbyId ; typedef uint64_t ChatLobbyId ;
typedef uint64_t ChatLobbyMsgId ; typedef uint64_t ChatLobbyMsgId ;
@ -306,7 +309,8 @@ class ChatMessage
public: public:
ChatId chat_id; // id of chat endpoint ChatId chat_id; // id of chat endpoint
RsPeerId broadcast_peer_id; // only used for broadcast chat: source peer id 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 RsGxsId lobby_peer_gxs_id; // only used for lobbys: nickname of message author
std::string peer_alternate_nickname; // only used when key is unknown.
unsigned int chatflags; unsigned int chatflags;
uint32_t sendTime; uint32_t sendTime;
@ -324,7 +328,7 @@ class ChatLobbyInvite
RsPeerId peer_id ; RsPeerId peer_id ;
std::string lobby_name ; std::string lobby_name ;
std::string lobby_topic ; std::string lobby_topic ;
uint32_t lobby_privacy_level ; ChatLobbyFlags lobby_flags ;
}; };
class VisibleChatLobbyRecord class VisibleChatLobbyRecord
@ -339,7 +343,7 @@ class VisibleChatLobbyRecord
uint32_t total_number_of_peers ; // total number of particpating peers. Might not be uint32_t total_number_of_peers ; // total number of particpating peers. Might not be
time_t last_report_time ; // last time the lobby was reported. time_t last_report_time ; // last time the lobby was reported.
uint32_t lobby_privacy_level ; // see RS_CHAT_LOBBY_PRIVACY_LEVEL_PUBLIC / RS_CHAT_LOBBY_PRIVACY_LEVEL_PRIVATE ChatLobbyFlags lobby_flags ; // see RS_CHAT_LOBBY_PRIVACY_LEVEL_PUBLIC / RS_CHAT_LOBBY_PRIVACY_LEVEL_PRIVATE
}; };
@ -350,10 +354,10 @@ class ChatLobbyInfo
std::string lobby_name ; // name to use for this lobby std::string lobby_name ; // name to use for this lobby
std::string lobby_topic ; // topic to use for this lobby std::string lobby_topic ; // topic to use for this lobby
std::set<RsPeerId> participating_friends ; // list of direct friend who participate. Used to broadcast sent messages. std::set<RsPeerId> participating_friends ; // list of direct friend who participate. Used to broadcast sent messages.
std::string nick_name ; // nickname to use for this lobby RsGxsId gxs_id ; // ID to sign messages
uint32_t lobby_privacy_level ; // see RS_CHAT_LOBBY_PRIVACY_LEVEL_PUBLIC / RS_CHAT_LOBBY_PRIVACY_LEVEL_PRIVATE ChatLobbyFlags lobby_flags ; // see RS_CHAT_LOBBY_PRIVACY_LEVEL_PUBLIC / RS_CHAT_LOBBY_PRIVACY_LEVEL_PRIVATE
std::map<std::string,time_t> nick_names ; // list of non direct friend who participate. Used to display only. std::map<RsGxsId,time_t> gxs_ids ; // list of non direct friend who participate. Used to display only.
time_t last_activity ; // last recorded activity. Useful for removing dead lobbies. time_t last_activity ; // last recorded activity. Useful for removing dead lobbies.
}; };
@ -443,23 +447,24 @@ virtual void getOwnAvatarData(unsigned char *& data,int& size) = 0 ;
/* Chat lobbies */ /* Chat lobbies */
/****************************************/ /****************************************/
virtual bool joinVisibleChatLobby(const ChatLobbyId& lobby_id) = 0 ; virtual bool joinVisibleChatLobby(const ChatLobbyId& lobby_id,const RsGxsId& own_id) = 0 ;
virtual bool isLobbyId(const RsPeerId& virtual_peer_id,ChatLobbyId& lobby_id) = 0; virtual bool isLobbyId(const RsPeerId& virtual_peer_id,ChatLobbyId& lobby_id) = 0;
virtual bool getVirtualPeerId(const ChatLobbyId& lobby_id,RsPeerId& vpid) = 0; virtual bool getVirtualPeerId(const ChatLobbyId& lobby_id,RsPeerId& vpid) = 0;
virtual void getChatLobbyList(std::list<ChatLobbyInfo>& cl_info) = 0; virtual void getChatLobbyList(std::list<ChatLobbyId>& cl_list) = 0;
virtual bool getChatLobbyInfo(const ChatLobbyId& id,ChatLobbyInfo& info) = 0 ;
virtual void getListOfNearbyChatLobbies(std::vector<VisibleChatLobbyRecord>& public_lobbies) = 0 ; virtual void getListOfNearbyChatLobbies(std::vector<VisibleChatLobbyRecord>& public_lobbies) = 0 ;
virtual void invitePeerToLobby(const ChatLobbyId& lobby_id,const RsPeerId& peer_id) = 0; virtual void invitePeerToLobby(const ChatLobbyId& lobby_id,const RsPeerId& peer_id) = 0;
virtual bool acceptLobbyInvite(const ChatLobbyId& id) = 0 ; virtual bool acceptLobbyInvite(const ChatLobbyId& id,const RsGxsId& identity) = 0 ;
virtual void denyLobbyInvite(const ChatLobbyId& id) = 0 ; virtual void denyLobbyInvite(const ChatLobbyId& id) = 0 ;
virtual void getPendingChatLobbyInvites(std::list<ChatLobbyInvite>& invites) = 0; virtual void getPendingChatLobbyInvites(std::list<ChatLobbyInvite>& invites) = 0;
virtual void unsubscribeChatLobby(const ChatLobbyId& lobby_id) = 0; virtual void unsubscribeChatLobby(const ChatLobbyId& lobby_id) = 0;
virtual bool setNickNameForChatLobby(const ChatLobbyId& lobby_id,const std::string& nick) = 0; virtual bool setIdentityForChatLobby(const ChatLobbyId& lobby_id,const RsGxsId& nick) = 0;
virtual bool getNickNameForChatLobby(const ChatLobbyId& lobby_id,std::string& nick) = 0 ; virtual bool getIdentityForChatLobby(const ChatLobbyId& lobby_id,RsGxsId& nick) = 0 ;
virtual bool setDefaultNickNameForChatLobby(const std::string& nick) = 0; virtual bool setDefaultIdentityForChatLobby(const RsGxsId& nick) = 0;
virtual bool getDefaultNickNameForChatLobby(std::string& nick) = 0 ; virtual bool getDefaultIdentityForChatLobby(RsGxsId& id) = 0 ;
virtual void setLobbyAutoSubscribe(const ChatLobbyId& lobby_id, const bool autoSubscribe) = 0 ; virtual void setLobbyAutoSubscribe(const ChatLobbyId& lobby_id, const bool autoSubscribe) = 0 ;
virtual bool getLobbyAutoSubscribe(const ChatLobbyId& lobby_id) = 0 ; virtual bool getLobbyAutoSubscribe(const ChatLobbyId& lobby_id) = 0 ;
virtual ChatLobbyId createChatLobby(const std::string& lobby_name,const std::string& lobby_topic,const std::list<RsPeerId>& invited_friends,uint32_t lobby_privacy_type) = 0 ; virtual ChatLobbyId createChatLobby(const std::string& lobby_name,const RsGxsId& lobby_identity,const std::string& lobby_topic,const std::list<RsPeerId>& invited_friends,ChatLobbyFlags lobby_privacy_type) = 0 ;
/****************************************/ /****************************************/
/* Distant chat */ /* Distant chat */

View File

@ -449,9 +449,13 @@ bool p3Msgs::isLobbyId(const RsPeerId& peer_id,ChatLobbyId& id)
return mChatSrv->isLobbyId(peer_id,id) ; return mChatSrv->isLobbyId(peer_id,id) ;
} }
void p3Msgs::getChatLobbyList(std::list<ChatLobbyInfo>& linfos) bool p3Msgs::getChatLobbyInfo(const ChatLobbyId& id,ChatLobbyInfo& linfo)
{ {
mChatSrv->getChatLobbyList(linfos) ; return mChatSrv->getChatLobbyInfo(id,linfo) ;
}
void p3Msgs::getChatLobbyList(std::list<ChatLobbyId>& lids)
{
mChatSrv->getChatLobbyList(lids) ;
} }
void p3Msgs::invitePeerToLobby(const ChatLobbyId& lobby_id, const RsPeerId& peer_id) void p3Msgs::invitePeerToLobby(const ChatLobbyId& lobby_id, const RsPeerId& peer_id)
{ {
@ -461,27 +465,27 @@ void p3Msgs::unsubscribeChatLobby(const ChatLobbyId& lobby_id)
{ {
mChatSrv->unsubscribeChatLobby(lobby_id) ; mChatSrv->unsubscribeChatLobby(lobby_id) ;
} }
bool p3Msgs::setDefaultNickNameForChatLobby(const std::string& nick) bool p3Msgs::setDefaultIdentityForChatLobby(const RsGxsId& nick)
{ {
return mChatSrv->setDefaultNickNameForChatLobby(nick) ; return mChatSrv->setDefaultIdentityForChatLobby(nick) ;
} }
bool p3Msgs::getDefaultNickNameForChatLobby(std::string& nick_name) bool p3Msgs::getDefaultIdentityForChatLobby(RsGxsId& nick_name)
{ {
return mChatSrv->getDefaultNickNameForChatLobby(nick_name) ; return mChatSrv->getDefaultIdentityForChatLobby(nick_name) ;
} }
bool p3Msgs::setNickNameForChatLobby(const ChatLobbyId& lobby_id,const std::string& nick) bool p3Msgs::setIdentityForChatLobby(const ChatLobbyId& lobby_id,const RsGxsId& nick)
{ {
return mChatSrv->setNickNameForChatLobby(lobby_id,nick) ; return mChatSrv->setIdentityForChatLobby(lobby_id,nick) ;
} }
bool p3Msgs::getNickNameForChatLobby(const ChatLobbyId& lobby_id,std::string& nick_name) bool p3Msgs::getIdentityForChatLobby(const ChatLobbyId& lobby_id,RsGxsId& nick_name)
{ {
return mChatSrv->getNickNameForChatLobby(lobby_id,nick_name) ; return mChatSrv->getIdentityForChatLobby(lobby_id,nick_name) ;
} }
bool p3Msgs::joinVisibleChatLobby(const ChatLobbyId& lobby_id) bool p3Msgs::joinVisibleChatLobby(const ChatLobbyId& lobby_id,const RsGxsId& own_id)
{ {
return mChatSrv->joinVisibleChatLobby(lobby_id) ; return mChatSrv->joinVisibleChatLobby(lobby_id,own_id) ;
} }
void p3Msgs::getListOfNearbyChatLobbies(std::vector<VisibleChatLobbyRecord>& public_lobbies) void p3Msgs::getListOfNearbyChatLobbies(std::vector<VisibleChatLobbyRecord>& public_lobbies)
@ -489,9 +493,9 @@ void p3Msgs::getListOfNearbyChatLobbies(std::vector<VisibleChatLobbyRecord>& pub
mChatSrv->getListOfNearbyChatLobbies(public_lobbies) ; mChatSrv->getListOfNearbyChatLobbies(public_lobbies) ;
} }
ChatLobbyId p3Msgs::createChatLobby(const std::string& lobby_name,const std::string& lobby_topic,const std::list<RsPeerId>& invited_friends,uint32_t privacy_type) ChatLobbyId p3Msgs::createChatLobby(const std::string& lobby_name,const RsGxsId& lobby_identity,const std::string& lobby_topic,const std::list<RsPeerId>& invited_friends,ChatLobbyFlags privacy_type)
{ {
return mChatSrv->createChatLobby(lobby_name,lobby_topic,invited_friends,privacy_type) ; return mChatSrv->createChatLobby(lobby_name,lobby_identity,lobby_topic,invited_friends,privacy_type) ;
} }
void p3Msgs::setLobbyAutoSubscribe(const ChatLobbyId& lobby_id, const bool autoSubscribe) void p3Msgs::setLobbyAutoSubscribe(const ChatLobbyId& lobby_id, const bool autoSubscribe)
@ -505,9 +509,9 @@ bool p3Msgs::getLobbyAutoSubscribe(const ChatLobbyId& lobby_id)
} }
bool p3Msgs::acceptLobbyInvite(const ChatLobbyId& id) bool p3Msgs::acceptLobbyInvite(const ChatLobbyId& id,const RsGxsId& gxs_id)
{ {
return mChatSrv->acceptLobbyInvite(id) ; return mChatSrv->acceptLobbyInvite(id,gxs_id) ;
} }
void p3Msgs::denyLobbyInvite(const ChatLobbyId& id) void p3Msgs::denyLobbyInvite(const ChatLobbyId& id)
{ {

View File

@ -136,23 +136,24 @@ class p3Msgs: public RsMsgs
/****************************************/ /****************************************/
virtual bool joinVisibleChatLobby(const ChatLobbyId& id) ; virtual bool joinVisibleChatLobby(const ChatLobbyId& id, const RsGxsId &own_id) ;
virtual void getListOfNearbyChatLobbies(std::vector<VisibleChatLobbyRecord>& public_lobbies) ; virtual void getListOfNearbyChatLobbies(std::vector<VisibleChatLobbyRecord>& public_lobbies) ;
virtual bool getVirtualPeerId(const ChatLobbyId& id,RsPeerId& vpid) ; virtual bool getVirtualPeerId(const ChatLobbyId& id,RsPeerId& vpid) ;
virtual bool isLobbyId(const RsPeerId& virtual_peer_id,ChatLobbyId& lobby_id) ; virtual bool isLobbyId(const RsPeerId& virtual_peer_id,ChatLobbyId& lobby_id) ;
virtual void getChatLobbyList(std::list<ChatLobbyInfo, std::allocator<ChatLobbyInfo> >&) ; virtual void getChatLobbyList(std::list<ChatLobbyId>& cl_list) ;
virtual bool getChatLobbyInfo(const ChatLobbyId& id,ChatLobbyInfo& info) ;
virtual void invitePeerToLobby(const ChatLobbyId&, const RsPeerId&) ; virtual void invitePeerToLobby(const ChatLobbyId&, const RsPeerId&) ;
virtual bool acceptLobbyInvite(const ChatLobbyId& id) ; virtual bool acceptLobbyInvite(const ChatLobbyId& id, const RsGxsId &gxs_id) ;
virtual void denyLobbyInvite(const ChatLobbyId& id) ; virtual void denyLobbyInvite(const ChatLobbyId& id) ;
virtual void getPendingChatLobbyInvites(std::list<ChatLobbyInvite>& invites) ; virtual void getPendingChatLobbyInvites(std::list<ChatLobbyInvite>& invites) ;
virtual void unsubscribeChatLobby(const ChatLobbyId& lobby_id) ; virtual void unsubscribeChatLobby(const ChatLobbyId& lobby_id) ;
virtual bool setNickNameForChatLobby(const ChatLobbyId& lobby_id,const std::string&) ; virtual bool setIdentityForChatLobby(const ChatLobbyId& lobby_id,const RsGxsId&) ;
virtual bool getNickNameForChatLobby(const ChatLobbyId&,std::string& nick) ; virtual bool getIdentityForChatLobby(const ChatLobbyId&,RsGxsId& nick) ;
virtual bool setDefaultNickNameForChatLobby(const std::string&) ; virtual bool setDefaultIdentityForChatLobby(const RsGxsId&) ;
virtual bool getDefaultNickNameForChatLobby(std::string& nick) ; virtual bool getDefaultIdentityForChatLobby(RsGxsId& nick) ;
virtual void setLobbyAutoSubscribe(const ChatLobbyId& lobby_id, const bool autoSubscribe); virtual void setLobbyAutoSubscribe(const ChatLobbyId& lobby_id, const bool autoSubscribe);
virtual bool getLobbyAutoSubscribe(const ChatLobbyId& lobby_id); virtual bool getLobbyAutoSubscribe(const ChatLobbyId& lobby_id);
virtual ChatLobbyId createChatLobby(const std::string& lobby_name,const std::string& lobby_topic,const std::list<RsPeerId>& invited_friends,uint32_t privacy_type) ; virtual ChatLobbyId createChatLobby(const std::string& lobby_name,const RsGxsId& lobby_identity,const std::string& lobby_topic,const std::list<RsPeerId>& invited_friends,ChatLobbyFlags privacy_type) ;
virtual bool initiateDistantChatConnexion(const RsGxsId& to_gxs_id,const RsGxsId& from_gxs_id,uint32_t& error_code) ; virtual bool initiateDistantChatConnexion(const RsGxsId& to_gxs_id,const RsGxsId& from_gxs_id,uint32_t& error_code) ;
virtual bool getDistantChatStatus(const RsGxsId& gxs_id,uint32_t& status, RsGxsId *from_gxs_id=NULL) ; virtual bool getDistantChatStatus(const RsGxsId& gxs_id,uint32_t& status, RsGxsId *from_gxs_id=NULL) ;

View File

@ -13,11 +13,13 @@
#include "chat/ChatLobbyUserNotify.h" #include "chat/ChatLobbyUserNotify.h"
#include "util/HandleRichText.h" #include "util/HandleRichText.h"
#include "util/QtVersion.h" #include "util/QtVersion.h"
#include <gui/settings/rsharesettings.h> #include "gui/settings/rsharesettings.h"
#include "gui/gxs/GxsIdDetails.h"
#include "retroshare/rsmsgs.h" #include "retroshare/rsmsgs.h"
#include "retroshare/rspeers.h" #include "retroshare/rspeers.h"
#include "retroshare/rsnotify.h" #include "retroshare/rsnotify.h"
#include "retroshare/rsidentity.h"
#define COLUMN_NAME 0 #define COLUMN_NAME 0
#define COLUMN_USER_COUNT 1 #define COLUMN_USER_COUNT 1
@ -94,28 +96,28 @@ ChatLobbyWidget::ChatLobbyWidget(QWidget *parent, Qt::WindowFlags flags)
privateSubLobbyItem->setText(COLUMN_NAME, tr("Private Subscribed Lobbies")); privateSubLobbyItem->setText(COLUMN_NAME, tr("Private Subscribed Lobbies"));
privateSubLobbyItem->setData(COLUMN_NAME, ROLE_SORT, "1"); privateSubLobbyItem->setData(COLUMN_NAME, ROLE_SORT, "1");
// privateLobbyItem->setIcon(COLUMN_NAME, QIcon(IMAGE_PRIVATE)); // privateLobbyItem->setIcon(COLUMN_NAME, QIcon(IMAGE_PRIVATE));
privateSubLobbyItem->setData(COLUMN_DATA, ROLE_PRIVACYLEVEL, RS_CHAT_LOBBY_PRIVACY_LEVEL_PRIVATE); privateSubLobbyItem->setData(COLUMN_DATA, ROLE_PRIVACYLEVEL, CHAT_LOBBY_PRIVACY_LEVEL_PRIVATE);
ui.lobbyTreeWidget->insertTopLevelItem(0, privateSubLobbyItem); ui.lobbyTreeWidget->insertTopLevelItem(0, privateSubLobbyItem);
publicSubLobbyItem = new RSTreeWidgetItem(compareRole, TYPE_FOLDER); publicSubLobbyItem = new RSTreeWidgetItem(compareRole, TYPE_FOLDER);
publicSubLobbyItem->setText(COLUMN_NAME, tr("Public Subscribed Lobbies")); publicSubLobbyItem->setText(COLUMN_NAME, tr("Public Subscribed Lobbies"));
publicSubLobbyItem->setData(COLUMN_NAME, ROLE_SORT, "2"); publicSubLobbyItem->setData(COLUMN_NAME, ROLE_SORT, "2");
// publicLobbyItem->setIcon(COLUMN_NAME, QIcon(IMAGE_PUBLIC)); // publicLobbyItem->setIcon(COLUMN_NAME, QIcon(IMAGE_PUBLIC));
publicSubLobbyItem->setData(COLUMN_DATA, ROLE_PRIVACYLEVEL, RS_CHAT_LOBBY_PRIVACY_LEVEL_PUBLIC); publicSubLobbyItem->setData(COLUMN_DATA, ROLE_PRIVACYLEVEL, CHAT_LOBBY_PRIVACY_LEVEL_PUBLIC);
ui.lobbyTreeWidget->insertTopLevelItem(1, publicSubLobbyItem); ui.lobbyTreeWidget->insertTopLevelItem(1, publicSubLobbyItem);
privateLobbyItem = new RSTreeWidgetItem(compareRole, TYPE_FOLDER); privateLobbyItem = new RSTreeWidgetItem(compareRole, TYPE_FOLDER);
privateLobbyItem->setText(COLUMN_NAME, tr("Private Lobbies")); privateLobbyItem->setText(COLUMN_NAME, tr("Private Lobbies"));
privateLobbyItem->setData(COLUMN_NAME, ROLE_SORT, "3"); privateLobbyItem->setData(COLUMN_NAME, ROLE_SORT, "3");
// privateLobbyItem->setIcon(COLUMN_NAME, QIcon(IMAGE_PRIVATE)); // privateLobbyItem->setIcon(COLUMN_NAME, QIcon(IMAGE_PRIVATE));
privateLobbyItem->setData(COLUMN_DATA, ROLE_PRIVACYLEVEL, RS_CHAT_LOBBY_PRIVACY_LEVEL_PRIVATE); privateLobbyItem->setData(COLUMN_DATA, ROLE_PRIVACYLEVEL, CHAT_LOBBY_PRIVACY_LEVEL_PRIVATE);
ui.lobbyTreeWidget->insertTopLevelItem(2, privateLobbyItem); ui.lobbyTreeWidget->insertTopLevelItem(2, privateLobbyItem);
publicLobbyItem = new RSTreeWidgetItem(compareRole, TYPE_FOLDER); publicLobbyItem = new RSTreeWidgetItem(compareRole, TYPE_FOLDER);
publicLobbyItem->setText(COLUMN_NAME, tr("Public Lobbies")); publicLobbyItem->setText(COLUMN_NAME, tr("Public Lobbies"));
publicLobbyItem->setData(COLUMN_NAME, ROLE_SORT, "4"); publicLobbyItem->setData(COLUMN_NAME, ROLE_SORT, "4");
// publicLobbyItem->setIcon(COLUMN_NAME, QIcon(IMAGE_PUBLIC)); // publicLobbyItem->setIcon(COLUMN_NAME, QIcon(IMAGE_PUBLIC));
publicLobbyItem->setData(COLUMN_DATA, ROLE_PRIVACYLEVEL, RS_CHAT_LOBBY_PRIVACY_LEVEL_PUBLIC); publicLobbyItem->setData(COLUMN_DATA, ROLE_PRIVACYLEVEL, CHAT_LOBBY_PRIVACY_LEVEL_PUBLIC);
ui.lobbyTreeWidget->insertTopLevelItem(3, publicLobbyItem); ui.lobbyTreeWidget->insertTopLevelItem(3, publicLobbyItem);
ui.lobbyTreeWidget->expandAll(); ui.lobbyTreeWidget->expandAll();
@ -212,16 +214,51 @@ void ChatLobbyWidget::lobbyTreeWidgetCustomPopupMenu(QPoint)
action->setData(item->data(COLUMN_DATA, ROLE_PRIVACYLEVEL).toInt()); action->setData(item->data(COLUMN_DATA, ROLE_PRIVACYLEVEL).toInt());
} }
if (item && item->type() == TYPE_LOBBY) { if (item && item->type() == TYPE_LOBBY)
if (item->data(COLUMN_DATA, ROLE_SUBSCRIBED).toBool()) { {
contextMnu.addAction(QIcon(IMAGE_UNSUBSCRIBE), tr("Unsubscribe"), this, SLOT(unsubscribeItem())); if (item->data(COLUMN_DATA, ROLE_SUBSCRIBED).toBool())
} else { contextMnu.addAction(QIcon(IMAGE_UNSUBSCRIBE), tr("Leave this lobby"), this, SLOT(unsubscribeItem()));
contextMnu.addAction(QIcon(IMAGE_SUBSCRIBE), tr("Subscribe"), this, SLOT(subscribeItem())); else
{
std::list<RsGxsId> own_identities ;
rsIdentity->getOwnIds(own_identities) ;
QTreeWidgetItem *item = ui.lobbyTreeWidget->currentItem();
uint32_t item_flags = item->data(COLUMN_DATA,ROLE_ID).toUInt() ;
if(own_identities.size() <= 1)
{
QAction *action = contextMnu.addAction(QIcon(IMAGE_SUBSCRIBE), tr("Enter this lobby"), this, SLOT(subscribeChatLobbyAs()));
if(own_identities.empty())
action->setEnabled(false) ;
else
action->setData(QString::fromStdString((own_identities.front()).toStdString())) ;
} }
if (item->data(COLUMN_DATA, ROLE_AUTOSUBSCRIBE).toBool()) { else
{
QMenu *mnu = contextMnu.addMenu(QIcon(IMAGE_SUBSCRIBE),tr("Enter this lobby as...")) ;
for(std::list<RsGxsId>::const_iterator it=own_identities.begin();it!=own_identities.end();++it)
{
RsIdentityDetails idd ;
rsIdentity->getIdDetails(*it,idd) ;
QPixmap pixmap ;
if(idd.mAvatar.mSize == 0 || !pixmap.loadFromData(idd.mAvatar.mData, idd.mAvatar.mSize, "PNG"))
pixmap = QPixmap::fromImage(GxsIdDetails::makeDefaultIcon(*it)) ;
QAction *action = mnu->addAction(QIcon(pixmap), QString("%1 (%2)").arg(QString::fromUtf8(idd.mNickname.c_str()), QString::fromStdString((*it).toStdString())), this, SLOT(subscribeChatLobbyAs()));
action->setData(QString::fromStdString((*it).toStdString())) ;
}
}
if (item->data(COLUMN_DATA, ROLE_AUTOSUBSCRIBE).toBool())
contextMnu.addAction(QIcon(IMAGE_AUTOSUBSCRIBE), tr("Remove Auto Subscribe"), this, SLOT(autoSubscribeItem())); contextMnu.addAction(QIcon(IMAGE_AUTOSUBSCRIBE), tr("Remove Auto Subscribe"), this, SLOT(autoSubscribeItem()));
} else { else
contextMnu.addAction(QIcon(IMAGE_SUBSCRIBE), tr("Add Auto Subscribe"), this, SLOT(autoSubscribeItem())); contextMnu.addAction(QIcon(IMAGE_SUBSCRIBE), tr("Add Auto Subscribe"), this, SLOT(autoSubscribeItem()));
} }
} }
@ -302,14 +339,11 @@ void ChatLobbyWidget::addChatPage(ChatLobbyDialog *d)
_lobby_infos[id].last_typing_event = time(NULL) ; _lobby_infos[id].last_typing_event = time(NULL) ;
_lobby_infos[id].unread_count = 0; _lobby_infos[id].unread_count = 0;
std::list<ChatLobbyInfo> lobbies; ChatLobbyInfo linfo ;
rsMsgs->getChatLobbyList(lobbies); if(rsMsgs->getChatLobbyInfo(id,linfo))
_lobby_infos[id].default_icon = (linfo.lobby_flags & RS_CHAT_LOBBY_FLAGS_PUBLIC) ? QIcon(IMAGE_PUBLIC):QIcon(IMAGE_PRIVATE) ;
for (std::list<ChatLobbyInfo>::const_iterator it = lobbies.begin(); it != lobbies.end();++it) { else
if (it->lobby_id == id) { std::cerr << "(EE) cannot find info for lobby " << std::hex << id << std::dec << std::endl;
_lobby_infos[id].default_icon = (it->lobby_privacy_level == RS_CHAT_LOBBY_PRIVACY_LEVEL_PRIVATE) ? QIcon(IMAGE_PRIVATE) : QIcon(IMAGE_PUBLIC);
}
}
} }
} }
@ -334,7 +368,7 @@ void ChatLobbyWidget::updateDisplay()
std::vector<VisibleChatLobbyRecord> visibleLobbies; std::vector<VisibleChatLobbyRecord> visibleLobbies;
rsMsgs->getListOfNearbyChatLobbies(visibleLobbies); rsMsgs->getListOfNearbyChatLobbies(visibleLobbies);
std::list<ChatLobbyInfo> lobbies; std::list<ChatLobbyId> lobbies;
rsMsgs->getChatLobbyList(lobbies); rsMsgs->getChatLobbyList(lobbies);
#ifdef CHAT_LOBBY_GUI_DEBUG #ifdef CHAT_LOBBY_GUI_DEBUG
@ -344,7 +378,7 @@ void ChatLobbyWidget::updateDisplay()
// now, do a nice display of lobbies // now, do a nice display of lobbies
RsPeerId vpid; RsPeerId vpid;
std::list<ChatLobbyInfo>::const_iterator lobbyIt; std::list<ChatLobbyId>::const_iterator lobbyIt;
// remove not existing public lobbies // remove not existing public lobbies
@ -381,7 +415,7 @@ void ChatLobbyWidget::updateDisplay()
// Check for participating lobby with public level // Check for participating lobby with public level
// //
for (lobbyIt = lobbies.begin(); lobbyIt != lobbies.end(); ++lobbyIt) for (lobbyIt = lobbies.begin(); lobbyIt != lobbies.end(); ++lobbyIt)
if(itemLoop->data(COLUMN_DATA, ROLE_ID).toULongLong() == lobbyIt->lobby_id) if(itemLoop->data(COLUMN_DATA, ROLE_ID).toULongLong() == *lobbyIt)
break; break;
if (lobbyIt == lobbies.end()) if (lobbyIt == lobbies.end())
@ -415,7 +449,8 @@ void ChatLobbyWidget::updateDisplay()
QTreeWidgetItem *item = NULL; QTreeWidgetItem *item = NULL;
QTreeWidgetItem *lobby_item =NULL; QTreeWidgetItem *lobby_item =NULL;
QTreeWidgetItem *lobby_other_item =NULL; QTreeWidgetItem *lobby_other_item =NULL;
if (lobby.lobby_privacy_level == RS_CHAT_LOBBY_PRIVACY_LEVEL_PUBLIC)
if (lobby.lobby_flags & RS_CHAT_LOBBY_FLAGS_PUBLIC)
{ {
if (subscribed) if (subscribed)
{ {
@ -469,14 +504,14 @@ void ChatLobbyWidget::updateDisplay()
if (item == NULL) if (item == NULL)
{ {
item = new RSTreeWidgetItem(compareRole, TYPE_LOBBY); item = new RSTreeWidgetItem(compareRole, TYPE_LOBBY);
icon = (lobby.lobby_privacy_level == RS_CHAT_LOBBY_PRIVACY_LEVEL_PUBLIC) ? QIcon(IMAGE_PUBLIC) : QIcon(IMAGE_PRIVATE); icon = (lobby.lobby_flags & RS_CHAT_LOBBY_FLAGS_PUBLIC) ? QIcon(IMAGE_PUBLIC) : QIcon(IMAGE_PRIVATE);
lobby_item->addChild(item); lobby_item->addChild(item);
} }
else else
{ {
if (item->data(COLUMN_DATA, ROLE_SUBSCRIBED).toBool() != subscribed) { if (item->data(COLUMN_DATA, ROLE_SUBSCRIBED).toBool() != subscribed) {
// Replace icon // Replace icon
icon = (lobby.lobby_privacy_level == RS_CHAT_LOBBY_PRIVACY_LEVEL_PUBLIC) ? QIcon(IMAGE_PUBLIC) : QIcon(IMAGE_PRIVATE); icon = (lobby.lobby_flags & RS_CHAT_LOBBY_FLAGS_PUBLIC) ? QIcon(IMAGE_PUBLIC) : QIcon(IMAGE_PRIVATE);
} }
} }
if (!icon.isNull()) { if (!icon.isNull()) {
@ -507,18 +542,18 @@ void ChatLobbyWidget::updateDisplay()
// //
for (lobbyIt = lobbies.begin(); lobbyIt != lobbies.end(); ++lobbyIt) for (lobbyIt = lobbies.begin(); lobbyIt != lobbies.end(); ++lobbyIt)
{ {
const ChatLobbyInfo &lobby = *lobbyIt; ChatLobbyInfo lobby ;
rsMsgs->getChatLobbyInfo(*lobbyIt,lobby) ;
#ifdef CHAT_LOBBY_GUI_DEBUG #ifdef CHAT_LOBBY_GUI_DEBUG
std::cerr << "adding " << lobby.lobby_name << "topic " << lobby.lobby_topic << " #" << std::hex << lobby.lobby_id << std::dec << " private " << lobby.nick_names.size() << " peers." << std::endl; std::cerr << "adding " << lobby.lobby_name << "topic " << lobby.lobby_topic << " #" << std::hex << lobby.lobby_id << std::dec << " private " << lobby.nick_names.size() << " peers." << std::endl;
#endif #endif
QTreeWidgetItem *itemParent; QTreeWidgetItem *itemParent;
if (lobby.lobby_privacy_level == RS_CHAT_LOBBY_PRIVACY_LEVEL_PUBLIC) { if (lobby.lobby_flags & RS_CHAT_LOBBY_FLAGS_PUBLIC)
itemParent = publicSubLobbyItem; itemParent = publicSubLobbyItem;
} else { else
itemParent = privateSubLobbyItem; itemParent = privateSubLobbyItem;
}
QTreeWidgetItem *item = NULL; QTreeWidgetItem *item = NULL;
@ -535,12 +570,12 @@ void ChatLobbyWidget::updateDisplay()
QIcon icon; QIcon icon;
if (item == NULL) { if (item == NULL) {
item = new RSTreeWidgetItem(compareRole, TYPE_LOBBY); item = new RSTreeWidgetItem(compareRole, TYPE_LOBBY);
icon = (lobby.lobby_privacy_level == RS_CHAT_LOBBY_PRIVACY_LEVEL_PUBLIC) ? QIcon(IMAGE_PUBLIC) : QIcon(IMAGE_PRIVATE); icon = (lobby.lobby_flags & RS_CHAT_LOBBY_FLAGS_PUBLIC) ? QIcon(IMAGE_PUBLIC) : QIcon(IMAGE_PRIVATE);
itemParent->addChild(item); itemParent->addChild(item);
} else { } else {
if (!item->data(COLUMN_DATA, ROLE_SUBSCRIBED).toBool()) { if (!item->data(COLUMN_DATA, ROLE_SUBSCRIBED).toBool()) {
// Replace icon // Replace icon
icon = (lobby.lobby_privacy_level == RS_CHAT_LOBBY_PRIVACY_LEVEL_PUBLIC) ? QIcon(IMAGE_PUBLIC) : QIcon(IMAGE_PRIVATE); icon = (lobby.lobby_flags & RS_CHAT_LOBBY_FLAGS_PUBLIC) ? QIcon(IMAGE_PUBLIC) : QIcon(IMAGE_PRIVATE);
} }
} }
if (!icon.isNull()) { if (!icon.isNull()) {
@ -549,7 +584,7 @@ void ChatLobbyWidget::updateDisplay()
bool autoSubscribe = rsMsgs->getLobbyAutoSubscribe(lobby.lobby_id); bool autoSubscribe = rsMsgs->getLobbyAutoSubscribe(lobby.lobby_id);
updateItem(ui.lobbyTreeWidget, item, lobby.lobby_id, lobby.lobby_name,lobby.lobby_topic, lobby.nick_names.size(), true, autoSubscribe); updateItem(ui.lobbyTreeWidget, item, lobby.lobby_id, lobby.lobby_name,lobby.lobby_topic, lobby.gxs_ids.size(), true, autoSubscribe);
} }
publicSubLobbyItem->setHidden(publicSubLobbyItem->childCount()==0); publicSubLobbyItem->setHidden(publicSubLobbyItem->childCount()==0);
privateSubLobbyItem->setHidden(privateSubLobbyItem->childCount()==0); privateSubLobbyItem->setHidden(privateSubLobbyItem->childCount()==0);
@ -581,18 +616,37 @@ void ChatLobbyWidget::showLobby(QTreeWidgetItem *item)
else else
ui.stackedWidget->setCurrentWidget(_lobby_infos[id].dialog) ; ui.stackedWidget->setCurrentWidget(_lobby_infos[id].dialog) ;
} }
void ChatLobbyWidget::subscribeChatLobbyAs()
{
QTreeWidgetItem *item = ui.lobbyTreeWidget->currentItem();
static void subscribeLobby(QTreeWidgetItem *item) if(!item)
return ;
ChatLobbyId id = item->data(COLUMN_DATA, ROLE_ID).toULongLong();
QAction *action = qobject_cast<QAction *>(QObject::sender());
if (!action)
return ;
RsGxsId gxs_id(action->data().toString().toStdString());
uint32_t error_code ;
if(rsMsgs->joinVisibleChatLobby(id,gxs_id))
ChatDialog::chatFriend(ChatId(id),true) ;
}
void ChatLobbyWidget::subscribeChatLobbyAtItem(QTreeWidgetItem *item)
{ {
if (item == NULL || item->type() != TYPE_LOBBY) { if (item == NULL || item->type() != TYPE_LOBBY) {
return; return;
} }
ChatLobbyId id = item->data(COLUMN_DATA, ROLE_ID).toULongLong(); ChatLobbyId id = item->data(COLUMN_DATA, ROLE_ID).toULongLong();
if (rsMsgs->joinVisibleChatLobby(id)) { RsGxsId gxs_id ;
if(rsMsgs->getDefaultIdentityForChatLobby(gxs_id) && !gxs_id.isNull() && rsMsgs->joinVisibleChatLobby(id,gxs_id))
ChatDialog::chatFriend(ChatId(id),true) ; ChatDialog::chatFriend(ChatId(id),true) ;
} }
}
void ChatLobbyWidget::autoSubscribeLobby(QTreeWidgetItem *item) void ChatLobbyWidget::autoSubscribeLobby(QTreeWidgetItem *item)
{ {
@ -603,7 +657,7 @@ void ChatLobbyWidget::autoSubscribeLobby(QTreeWidgetItem *item)
ChatLobbyId id = item->data(COLUMN_DATA, ROLE_ID).toULongLong(); ChatLobbyId id = item->data(COLUMN_DATA, ROLE_ID).toULongLong();
bool isAutoSubscribe = rsMsgs->getLobbyAutoSubscribe(id); bool isAutoSubscribe = rsMsgs->getLobbyAutoSubscribe(id);
rsMsgs->setLobbyAutoSubscribe(id, !isAutoSubscribe); rsMsgs->setLobbyAutoSubscribe(id, !isAutoSubscribe);
if (!isAutoSubscribe) subscribeLobby(item); if (!isAutoSubscribe) subscribeChatLobbyAtItem(item);
} }
void ChatLobbyWidget::showBlankPage(ChatLobbyId id) void ChatLobbyWidget::showBlankPage(ChatLobbyId id)
@ -621,7 +675,7 @@ void ChatLobbyWidget::showBlankPage(ChatLobbyId id)
ui.lobbyname_lineEdit->setText( RsHtml::plainText(it->lobby_name) ); ui.lobbyname_lineEdit->setText( RsHtml::plainText(it->lobby_name) );
ui.lobbyid_lineEdit->setText( QString::number((*it).lobby_id,16) ); ui.lobbyid_lineEdit->setText( QString::number((*it).lobby_id,16) );
ui.lobbytopic_lineEdit->setText( RsHtml::plainText(it->lobby_topic) ); ui.lobbytopic_lineEdit->setText( RsHtml::plainText(it->lobby_topic) );
ui.lobbytype_lineEdit->setText( (( (*it).lobby_privacy_level == RS_CHAT_LOBBY_PRIVACY_LEVEL_PRIVATE)?tr("Private"):tr("Public")) ); ui.lobbytype_lineEdit->setText( (( (*it).lobby_flags & RS_CHAT_LOBBY_FLAGS_PUBLIC)?tr("Public"):tr("Private")) );
ui.lobbypeers_lineEdit->setText( QString::number((*it).total_number_of_peers) ); ui.lobbypeers_lineEdit->setText( QString::number((*it).total_number_of_peers) );
ui.lobbyInfoLabel->setText(tr("You're not subscribed to this lobby; Double click-it to enter and chat.") ); ui.lobbyInfoLabel->setText(tr("You're not subscribed to this lobby; Double click-it to enter and chat.") );
@ -640,7 +694,7 @@ void ChatLobbyWidget::showBlankPage(ChatLobbyId id)
void ChatLobbyWidget::subscribeItem() void ChatLobbyWidget::subscribeItem()
{ {
subscribeLobby(ui.lobbyTreeWidget->currentItem()); subscribeChatLobbyAtItem(ui.lobbyTreeWidget->currentItem());
} }
void ChatLobbyWidget::autoSubscribeItem() void ChatLobbyWidget::autoSubscribeItem()
@ -786,7 +840,7 @@ void ChatLobbyWidget::updateCurrentLobby()
if(_lobby_infos.find(id) != _lobby_infos.end()) { if(_lobby_infos.find(id) != _lobby_infos.end()) {
int iPrivacyLevel= item->parent()->data(COLUMN_DATA, ROLE_PRIVACYLEVEL).toInt(); int iPrivacyLevel= item->parent()->data(COLUMN_DATA, ROLE_PRIVACYLEVEL).toInt();
QIcon icon = (iPrivacyLevel==RS_CHAT_LOBBY_PRIVACY_LEVEL_PUBLIC) ? QIcon(IMAGE_PUBLIC) : QIcon(IMAGE_PRIVATE); QIcon icon = (iPrivacyLevel==CHAT_LOBBY_PRIVACY_LEVEL_PUBLIC) ? QIcon(IMAGE_PUBLIC) : QIcon(IMAGE_PRIVATE);
_lobby_infos[id].default_icon = icon ; _lobby_infos[id].default_icon = icon ;
_lobby_infos[id].unread_count = 0; _lobby_infos[id].unread_count = 0;
item->setIcon(COLUMN_NAME, icon) ; item->setIcon(COLUMN_NAME, icon) ;
@ -823,13 +877,13 @@ void ChatLobbyWidget::updateMessageChanged(ChatLobbyId id)
void ChatLobbyWidget::itemDoubleClicked(QTreeWidgetItem *item, int /*column*/) void ChatLobbyWidget::itemDoubleClicked(QTreeWidgetItem *item, int /*column*/)
{ {
subscribeLobby(item); subscribeChatLobbyAtItem(item);
} }
void ChatLobbyWidget::displayChatLobbyEvent(qulonglong lobby_id, int event_type, const QString& nickname, const QString& str) void ChatLobbyWidget::displayChatLobbyEvent(qulonglong lobby_id, int event_type, const QString& gxs_id, const QString& str)
{ {
if (ChatLobbyDialog *cld = dynamic_cast<ChatLobbyDialog*>(ChatDialog::getExistingChat(ChatId(lobby_id)))) { if (ChatLobbyDialog *cld = dynamic_cast<ChatLobbyDialog*>(ChatDialog::getExistingChat(ChatId(lobby_id)))) {
cld->displayLobbyEvent(event_type, nickname, str); cld->displayLobbyEvent(event_type, RsGxsId(gxs_id.toStdString()), str);
} }
} }
@ -838,21 +892,46 @@ void ChatLobbyWidget::readChatLobbyInvites()
std::list<ChatLobbyInvite> invites; std::list<ChatLobbyInvite> invites;
rsMsgs->getPendingChatLobbyInvites(invites); rsMsgs->getPendingChatLobbyInvites(invites);
for(std::list<ChatLobbyInvite>::const_iterator it(invites.begin());it!=invites.end();++it) { RsGxsId default_id ;
if (QMessageBox::Ok == QMessageBox::question(this, tr("Invitation to chat lobby"), tr("%1 invites you to chat lobby named %2").arg(QString::fromUtf8(rsPeers->getPeerName((*it).peer_id).c_str())).arg(RsHtml::plainText(it->lobby_name)), QMessageBox::Ok, QMessageBox::Ignore)) { rsMsgs->getDefaultIdentityForChatLobby(default_id) ;
std::cerr << "Accepting invite to lobby " << (*it).lobby_name << std::endl;
rsMsgs->acceptLobbyInvite((*it).lobby_id); for(std::list<ChatLobbyInvite>::const_iterator it(invites.begin());it!=invites.end();++it)
{
QMessageBox mb(QObject::tr("Join chat lobby"),
tr("%1 invites you to chat lobby named %2").arg(QString::fromUtf8(rsPeers->getPeerName((*it).peer_id).c_str())).arg(RsHtml::plainText(it->lobby_name)),
QMessageBox::Question, QMessageBox::Yes,QMessageBox::No, 0);
GxsIdChooser *idchooser = new GxsIdChooser ;
idchooser->loadIds(IDCHOOSER_ID_REQUIRED,default_id) ;
mb.layout()->addWidget(new QLabel(tr("Choose an identity for this lobby:"))) ;
mb.layout()->addWidget(idchooser) ;
int res = mb.exec() ;
if (res == QMessageBox::No)
{
rsMsgs->denyLobbyInvite((*it).lobby_id);
continue ;
}
RsGxsId chosen_id ;
idchooser->getChosenId(chosen_id) ;
if(chosen_id.isNull())
{
rsMsgs->denyLobbyInvite((*it).lobby_id);
continue ;
}
rsMsgs->acceptLobbyInvite((*it).lobby_id,chosen_id);
RsPeerId vpid; RsPeerId vpid;
if(rsMsgs->getVirtualPeerId((*it).lobby_id,vpid )) { if(rsMsgs->getVirtualPeerId((*it).lobby_id,vpid ))
ChatDialog::chatFriend(ChatId((*it).lobby_id),true); ChatDialog::chatFriend(ChatId((*it).lobby_id),true);
} else { else
std::cerr << "No lobby known with id 0x" << std::hex << (*it).lobby_id << std::dec << std::endl; std::cerr << "No lobby known with id 0x" << std::hex << (*it).lobby_id << std::dec << std::endl;
}
} else {
rsMsgs->denyLobbyInvite((*it).lobby_id);
}
} }
} }

View File

@ -7,6 +7,9 @@
#define IMAGE_CHATLOBBY ":/images/chat_32.png" #define IMAGE_CHATLOBBY ":/images/chat_32.png"
#define CHAT_LOBBY_PRIVACY_LEVEL_PUBLIC 1
#define CHAT_LOBBY_PRIVACY_LEVEL_PRIVATE 2
class RSTreeWidgetItemCompareRole; class RSTreeWidgetItemCompareRole;
class ChatTabWidget ; class ChatTabWidget ;
class ChatLobbyDialog ; class ChatLobbyDialog ;
@ -55,11 +58,12 @@ protected slots:
void unsubscribeItem(); void unsubscribeItem();
void itemDoubleClicked(QTreeWidgetItem *item, int column); void itemDoubleClicked(QTreeWidgetItem *item, int column);
void updateCurrentLobby() ; void updateCurrentLobby() ;
void displayChatLobbyEvent(qulonglong lobby_id, int event_type, const QString& nickname, const QString& str); void displayChatLobbyEvent(qulonglong lobby_id, int event_type, const QString& gxs_id, const QString& str);
void readChatLobbyInvites(); void readChatLobbyInvites();
void showLobby(QTreeWidgetItem *lobby_item) ; void showLobby(QTreeWidgetItem *lobby_item) ;
void showBlankPage(ChatLobbyId id) ; void showBlankPage(ChatLobbyId id) ;
void unsubscribeChatLobby(ChatLobbyId id) ; void unsubscribeChatLobby(ChatLobbyId id) ;
void subscribeChatLobbyAs() ;
void updateTypingStatus(ChatLobbyId id) ; void updateTypingStatus(ChatLobbyId id) ;
void resetLobbyTreeIcons() ; void resetLobbyTreeIcons() ;
void updateMessageChanged(ChatLobbyId); void updateMessageChanged(ChatLobbyId);
@ -78,6 +82,8 @@ private slots:
private: private:
void autoSubscribeLobby(QTreeWidgetItem *item); void autoSubscribeLobby(QTreeWidgetItem *item);
void subscribeChatLobby(ChatLobbyId id) ;
void subscribeChatLobbyAtItem(QTreeWidgetItem *item) ;
bool filterItem(QTreeWidgetItem *item, const QString &text, int filterColumn); bool filterItem(QTreeWidgetItem *item, const QString &text, int filterColumn);

View File

@ -34,6 +34,8 @@
#include <gui/common/html.h> #include <gui/common/html.h>
#include "gui/common/RSTreeWidgetItem.h" #include "gui/common/RSTreeWidgetItem.h"
#include "gui/common/FriendSelectionDialog.h" #include "gui/common/FriendSelectionDialog.h"
#include "gui/gxs/GxsIdTreeWidgetItem.h"
#include "gui/gxs/GxsIdChooser.h"
#include "util/HandleRichText.h" #include "util/HandleRichText.h"
#include <retroshare/rsnotify.h> #include <retroshare/rsnotify.h>
@ -43,7 +45,8 @@
#define COLUMN_ICON 0 #define COLUMN_ICON 0
#define COLUMN_NAME 1 #define COLUMN_NAME 1
#define COLUMN_ACTIVITY 2 #define COLUMN_ACTIVITY 2
#define COLUMN_COUNT 3 #define COLUMN_ID 3
#define COLUMN_COUNT 4
/** Default constructor */ /** Default constructor */
ChatLobbyDialog::ChatLobbyDialog(const ChatLobbyId& lid, QWidget *parent, Qt::WindowFlags flags) ChatLobbyDialog::ChatLobbyDialog(const ChatLobbyId& lid, QWidget *parent, Qt::WindowFlags flags)
@ -53,16 +56,20 @@ ChatLobbyDialog::ChatLobbyDialog(const ChatLobbyId& lid, QWidget *parent, Qt::Wi
ui.setupUi(this); ui.setupUi(this);
connect(ui.participantsFrameButton, SIGNAL(toggled(bool)), this, SLOT(showParticipantsFrame(bool))); connect(ui.participantsFrameButton, SIGNAL(toggled(bool)), this, SLOT(showParticipantsFrame(bool)));
connect(ui.actionChangeNickname, SIGNAL(triggered()), this, SLOT(changeNickname())); //connect(ui.actionChangeNickname, SIGNAL(triggered()), this, SLOT(changeNickname()));
connect(ui.participantsList, SIGNAL(customContextMenuRequested(QPoint)), this, SLOT(participantsTreeWidgetCustomPopupMenu(QPoint))); connect(ui.participantsList, SIGNAL(customContextMenuRequested(QPoint)), this, SLOT(participantsTreeWidgetCustomPopupMenu(QPoint)));
connect(ui.participantsList, SIGNAL(itemDoubleClicked(QTreeWidgetItem*,int)), this, SLOT(participantsTreeWidgetDoubleClicked(QTreeWidgetItem*,int))); connect(ui.participantsList, SIGNAL(itemDoubleClicked(QTreeWidgetItem*,int)), this, SLOT(participantsTreeWidgetDoubleClicked(QTreeWidgetItem*,int)));
ui.participantsList->setColumnCount(COLUMN_COUNT); ui.participantsList->setColumnCount(COLUMN_COUNT);
ui.participantsList->setColumnWidth(COLUMN_ICON, 20); ui.participantsList->setColumnWidth(COLUMN_ICON, 20);
ui.participantsList->setColumnHidden(COLUMN_ACTIVITY,true); ui.participantsList->setColumnHidden(COLUMN_ACTIVITY,true);
ui.participantsList->setColumnHidden(COLUMN_ID,true);
muteAct = new QAction(QIcon(), tr("Mute participant"), this); muteAct = new QAction(QIcon(), tr("Mute participant"), this);
distantChatAct = new QAction(QIcon(), tr("Start private chat"), this);
connect(muteAct, SIGNAL(triggered()), this, SLOT(changePartipationState())); connect(muteAct, SIGNAL(triggered()), this, SLOT(changePartipationState()));
connect(distantChatAct, SIGNAL(triggered()), this, SLOT(distantChatParticipant()));
// Add a button to invite friends. // Add a button to invite friends.
// //
@ -73,6 +80,9 @@ ChatLobbyDialog::ChatLobbyDialog(const ChatLobbyId& lid, QWidget *parent, Qt::Wi
inviteFriendsButton->setAutoRaise(true) ; inviteFriendsButton->setAutoRaise(true) ;
inviteFriendsButton->setToolTip(tr("Invite friends to this lobby")); inviteFriendsButton->setToolTip(tr("Invite friends to this lobby"));
mParticipantCompareRole = new RSTreeWidgetItemCompareRole;
mParticipantCompareRole->setRole(0, Qt::UserRole);
{ {
QIcon icon ; QIcon icon ;
icon.addPixmap(QPixmap(":/images/edit_add24.png")) ; icon.addPixmap(QPixmap(":/images/edit_add24.png")) ;
@ -84,6 +94,16 @@ ChatLobbyDialog::ChatLobbyDialog(const ChatLobbyId& lid, QWidget *parent, Qt::Wi
getChatWidget()->addChatBarWidget(inviteFriendsButton) ; getChatWidget()->addChatBarWidget(inviteFriendsButton) ;
RsGxsId current_id;
rsMsgs->getIdentityForChatLobby(lobbyId, current_id);
ownIdChooser = new GxsIdChooser() ;
ownIdChooser->loadIds(IDCHOOSER_ID_REQUIRED,current_id) ;
getChatWidget()->addChatBarWidget(ownIdChooser) ;
connect(ownIdChooser,SIGNAL(currentIndexChanged(int)),this,SLOT(changeNickname())) ;
unsubscribeButton = new QToolButton ; unsubscribeButton = new QToolButton ;
unsubscribeButton->setMinimumSize(QSize(28,28)) ; unsubscribeButton->setMinimumSize(QSize(28,28)) ;
unsubscribeButton->setMaximumSize(QSize(28,28)) ; unsubscribeButton->setMaximumSize(QSize(28,28)) ;
@ -137,25 +157,33 @@ void ChatLobbyDialog::participantsTreeWidgetCustomPopupMenu(QPoint)
QMenu contextMnu(this); QMenu contextMnu(this);
contextMnu.addAction(muteAct); contextMnu.addAction(muteAct);
contextMnu.addAction(distantChatAct);
muteAct->setCheckable(true); muteAct->setCheckable(true);
muteAct->setEnabled(false); muteAct->setEnabled(false);
muteAct->setChecked(false); muteAct->setChecked(false);
if (selectedItems.size()) {
std::string nickName; if (selectedItems.size())
rsMsgs->getNickNameForChatLobby(lobbyId, nickName); {
if(selectedItems.count()>1 || (selectedItems.at(0)->text(COLUMN_NAME).toStdString()!=nickName)) RsGxsId nickName;
rsMsgs->getIdentityForChatLobby(lobbyId, nickName);
if(selectedItems.count()>1 || (RsGxsId(selectedItems.at(0)->text(COLUMN_ID).toStdString())!=nickName))
{ {
muteAct->setEnabled(true); muteAct->setEnabled(true);
QList<QTreeWidgetItem*>::iterator item; QList<QTreeWidgetItem*>::iterator item;
for (item = selectedItems.begin(); item != selectedItems.end(); ++item) { for (item = selectedItems.begin(); item != selectedItems.end(); ++item) {
if (isParticipantMuted((*item)->text(COLUMN_NAME))) {
RsGxsId gxsid ;
if ( dynamic_cast<GxsIdRSTreeWidgetItem*>(*item)->getId(gxsid) && isParticipantMuted(gxsid))
{
muteAct->setChecked(true); muteAct->setChecked(true);
break; break;
} }
} }
} }
distantChatAct->setEnabled(selectedItems.count()==1 && RsGxsId(selectedItems.front()->text(COLUMN_ID).toStdString())!=nickName) ;
} }
contextMnu.exec(QCursor::pos()); contextMnu.exec(QCursor::pos());
@ -163,31 +191,33 @@ void ChatLobbyDialog::participantsTreeWidgetCustomPopupMenu(QPoint)
void ChatLobbyDialog::init() void ChatLobbyDialog::init()
{ {
std::list<ChatLobbyInfo> lobbies; ChatLobbyInfo linfo ;
rsMsgs->getChatLobbyList(lobbies);
QString title; QString title;
std::list<ChatLobbyInfo>::const_iterator lobbyIt; std::list<ChatLobbyInfo>::const_iterator lobbyIt;
for (lobbyIt = lobbies.begin(); lobbyIt != lobbies.end(); ++lobbyIt) {
if (lobbyIt->lobby_id == lobbyId) { if(rsMsgs->getChatLobbyInfo(lobbyId,linfo))
title = QString::fromUtf8((*lobbyIt).lobby_name.c_str()); {
QString msg = tr("Welcome to lobby %1").arg(RsHtml::plainText(lobbyIt->lobby_name)); title = QString::fromUtf8(linfo.lobby_name.c_str());
_lobby_name = QString::fromUtf8(lobbyIt->lobby_name.c_str()) ;
if (!lobbyIt->lobby_topic.empty()) { QString msg = tr("Welcome to lobby %1").arg(RsHtml::plainText(linfo.lobby_name));
msg += "\n" + tr("Topic: %1").arg(RsHtml::plainText(lobbyIt->lobby_topic)); _lobby_name = QString::fromUtf8(linfo.lobby_name.c_str()) ;
if (!linfo.lobby_topic.empty()) {
msg += "\n" + tr("Topic: %1").arg(RsHtml::plainText(linfo.lobby_topic));
} }
ui.chatWidget->setWelcomeMessage(msg); ui.chatWidget->setWelcomeMessage(msg);
break;
}
} }
ChatDialog::init(ChatId(lobbyId), title); ChatDialog::init(ChatId(lobbyId), title);
std::string nickName; RsGxsId gxs_id;
rsMsgs->getNickNameForChatLobby(lobbyId, nickName); rsMsgs->getIdentityForChatLobby(lobbyId, gxs_id);
ui.chatWidget->setName(QString::fromUtf8(nickName.c_str()));
RsIdentityDetails details ;
rsIdentity->getIdDetails(gxs_id,details) ;
ui.chatWidget->setName(QString::fromUtf8(details.mNickname.c_str()));
ui.chatWidget->addToolsAction(ui.actionChangeNickname); ui.chatWidget->addToolsAction(ui.actionChangeNickname);
ui.chatWidget->setDefaultExtraFileFlags(RS_FILE_REQ_ANONYMOUS_ROUTING); ui.chatWidget->setDefaultExtraFileFlags(RS_FILE_REQ_ANONYMOUS_ROUTING);
@ -201,7 +231,7 @@ void ChatLobbyDialog::init()
dynamic_cast<ChatLobbyWidget*>(MainWindow::getPage(MainWindow::ChatLobby))->addChatPage(this) ; dynamic_cast<ChatLobbyWidget*>(MainWindow::getPage(MainWindow::ChatLobby))->addChatPage(this) ;
/** List of muted Participants */ /** List of muted Participants */
mutedParticipants = new QStringList; mutedParticipants.clear() ;
// load settings // load settings
processSettings(true); processSettings(true);
@ -249,14 +279,19 @@ void ChatLobbyDialog::processSettings(bool load)
* *
* - send a Message to all Members => later: send hidden message to clients, so they can actualize there mutedParticipants list * - send a Message to all Members => later: send hidden message to clients, so they can actualize there mutedParticipants list
*/ */
void ChatLobbyDialog::setNickname(const QString &nickname) void ChatLobbyDialog::setIdentity(const RsGxsId& gxs_id)
{ {
rsMsgs->setNickNameForChatLobby(lobbyId, nickname.toUtf8().constData()); rsMsgs->setIdentityForChatLobby(lobbyId, gxs_id) ;
// get new nick name // get new nick name
std::string newNickname; RsGxsId newid;
if (rsMsgs->getNickNameForChatLobby(lobbyId, newNickname)) {
ui.chatWidget->setName(QString::fromUtf8(newNickname.c_str())); if (rsMsgs->getIdentityForChatLobby(lobbyId, newid))
{
RsIdentityDetails details ;
rsIdentity->getIdDetails(gxs_id,details) ;
ui.chatWidget->setName(QString::fromUtf8(details.mNickname.c_str()));
} }
} }
@ -265,17 +300,14 @@ void ChatLobbyDialog::setNickname(const QString &nickname)
*/ */
void ChatLobbyDialog::changeNickname() void ChatLobbyDialog::changeNickname()
{ {
QInputDialog dialog; RsGxsId current_id;
dialog.setWindowTitle(tr("Change nick name")); rsMsgs->getIdentityForChatLobby(lobbyId, current_id);
dialog.setLabelText(tr("Please enter your new nick name"));
std::string nickName; RsGxsId new_id ;
rsMsgs->getNickNameForChatLobby(lobbyId, nickName); ownIdChooser->getChosenId(new_id) ;
dialog.setTextValue(QString::fromUtf8(nickName.c_str()));
if (dialog.exec() == QDialog::Accepted && !dialog.textValue().isEmpty()) { if(!new_id.isNull() && new_id != current_id)
setNickname(dialog.textValue()); setIdentity(new_id);
}
} }
/** /**
@ -288,9 +320,17 @@ void ChatLobbyDialog::addChatMsg(const ChatMessage& msg)
QDateTime sendTime = QDateTime::fromTime_t(msg.sendTime); QDateTime sendTime = QDateTime::fromTime_t(msg.sendTime);
QDateTime recvTime = QDateTime::fromTime_t(msg.recvTime); QDateTime recvTime = QDateTime::fromTime_t(msg.recvTime);
QString message = QString::fromUtf8(msg.msg.c_str()); QString message = QString::fromUtf8(msg.msg.c_str());
QString name = QString::fromUtf8(msg.lobby_peer_nickname.c_str()); RsGxsId gxs_id = msg.lobby_peer_gxs_id ;
if(!isParticipantMuted(gxs_id)) { // We could change addChatMsg to display the peers icon, passing a ChatId
RsIdentityDetails details ;
QString name ;
if(rsIdentity->getIdDetails(gxs_id,details))
name = QString::fromUtf8(details.mNickname.c_str()) ;
else
name = QString::fromUtf8(msg.peer_alternate_nickname.c_str()) + " (" + QString::fromStdString(gxs_id.toStdString()) + ")" ;
if(!isParticipantMuted(name)) {
ui.chatWidget->addChatMsg(msg.incoming, name, sendTime, recvTime, message, ChatWidget::MSGTYPE_NORMAL); ui.chatWidget->addChatMsg(msg.incoming, name, sendTime, recvTime, message, ChatWidget::MSGTYPE_NORMAL);
emit messageReceived(id()) ; emit messageReceived(id()) ;
} }
@ -298,7 +338,7 @@ void ChatLobbyDialog::addChatMsg(const ChatMessage& msg)
// This is a trick to translate HTML into text. // This is a trick to translate HTML into text.
QTextEdit editor; QTextEdit editor;
editor.setHtml(message); editor.setHtml(message);
QString notifyMsg = name + ": " + editor.toPlainText(); QString notifyMsg = QString::fromStdString(gxs_id.toStdString()) + ": " + editor.toPlainText();
if(notifyMsg.length() > 30) if(notifyMsg.length() > 30)
MainWindow::displayLobbySystrayMsg(tr("Lobby chat") + ": " + _lobby_name, notifyMsg.left(30) + QString("...")); MainWindow::displayLobbySystrayMsg(tr("Lobby chat") + ": " + _lobby_name, notifyMsg.left(30) + QString("..."));
@ -309,7 +349,7 @@ void ChatLobbyDialog::addChatMsg(const ChatMessage& msg)
time_t now = time(NULL); time_t now = time(NULL);
QList<QTreeWidgetItem*> qlFoundParticipants=ui.participantsList->findItems(name,Qt::MatchExactly,COLUMN_NAME); QList<QTreeWidgetItem*> qlFoundParticipants=ui.participantsList->findItems(QString::fromStdString(gxs_id.toStdString()),Qt::MatchExactly,COLUMN_ID);
if (qlFoundParticipants.count()!=0) qlFoundParticipants.at(0)->setText(COLUMN_ACTIVITY,QString::number(now)); if (qlFoundParticipants.count()!=0) qlFoundParticipants.at(0)->setText(COLUMN_ACTIVITY,QString::number(now));
if (now > lastUpdateListTime) { if (now > lastUpdateListTime) {
@ -325,68 +365,66 @@ void ChatLobbyDialog::addChatMsg(const ChatMessage& msg)
*/ */
void ChatLobbyDialog::updateParticipantsList() void ChatLobbyDialog::updateParticipantsList()
{ {
std::list<ChatLobbyInfo> lInfos; ChatLobbyInfo linfo;
rsMsgs->getChatLobbyList(lInfos);
std::list<ChatLobbyInfo>::const_iterator it(lInfos.begin()); if(rsMsgs->getChatLobbyInfo(lobbyId,linfo))
{
ChatLobbyInfo cliInfo=linfo;
QList<QTreeWidgetItem*> qlOldParticipants=ui.participantsList->findItems("*",Qt::MatchWildcard,COLUMN_ID);
// Set it to the current ChatLobby foreach(QTreeWidgetItem *qtwiCur,qlOldParticipants)
for (; it!=lInfos.end() && (*it).lobby_id != lobbyId; ++it) ; if(cliInfo.gxs_ids.find(RsGxsId((*qtwiCur).text(COLUMN_ID).toStdString())) == cliInfo.gxs_ids.end())
if (it != lInfos.end()) {
ChatLobbyInfo cliInfo=(*it);
QList<QTreeWidgetItem*> qlOldParticipants=ui.participantsList->findItems("*",Qt::MatchWildcard,COLUMN_NAME);
foreach(QTreeWidgetItem *qtwiCur,qlOldParticipants){
QString qsOldParticipant = qtwiCur->text(COLUMN_NAME);
QByteArray qbaPart=qsOldParticipant.toUtf8();
std::string strTemp=std::string(qbaPart.begin(),qbaPart.end());
std::map<std::string,time_t>::iterator itFound(cliInfo.nick_names.find(strTemp)) ;
if(itFound == cliInfo.nick_names.end())
{ {
//Old Participant go out, remove it //Old Participant go out, remove it
int index = ui.participantsList->indexOfTopLevelItem(qtwiCur); int index = ui.participantsList->indexOfTopLevelItem(qtwiCur);
delete ui.participantsList->takeTopLevelItem(index); delete ui.participantsList->takeTopLevelItem(index);
} }
}
for (std::map<RsGxsId,time_t>::const_iterator it2(linfo.gxs_ids.begin()); it2 != linfo.gxs_ids.end(); ++it2)
{
QString participant = QString::fromUtf8( (it2->first).toStdString().c_str() );
QList<QTreeWidgetItem*> qlFoundParticipants=ui.participantsList->findItems(participant,Qt::MatchExactly,COLUMN_ID);
for (std::map<std::string,time_t>::const_iterator it2((*it).nick_names.begin()); it2 != (*it).nick_names.end(); ++it2) { GxsIdRSTreeWidgetItem *widgetitem;
QString participant = QString::fromUtf8( (it2->first).c_str() );
QList<QTreeWidgetItem*> qlFoundParticipants=ui.participantsList->findItems(participant,Qt::MatchExactly,COLUMN_NAME);
QTreeWidgetItem *widgetitem;
if (qlFoundParticipants.count()==0) if (qlFoundParticipants.count()==0)
{ {
// TE: Add Wigdet to participantsList with Checkbox, to mute Participant // TE: Add Wigdet to participantsList with Checkbox, to mute Participant
widgetitem = new RSTreeWidgetItem;
widgetitem->setText(COLUMN_NAME, participant);
widgetitem->setText(COLUMN_ACTIVITY,QString::number(time(NULL)));
ui.participantsList->addTopLevelItem(widgetitem);
} else { widgetitem = qlFoundParticipants.at(0);}
if (isParticipantMuted(participant)) { widgetitem = new GxsIdRSTreeWidgetItem(mParticipantCompareRole);
widgetitem->setIcon(COLUMN_ICON, QIcon(":/images/redled.png")); widgetitem->setId(it2->first,COLUMN_NAME) ;
//widgetitem->setText(COLUMN_NAME, participant);
widgetitem->setText(COLUMN_ACTIVITY,QString::number(time(NULL)));
widgetitem->setText(COLUMN_ID,QString::fromStdString(it2->first.toStdString()));
ui.participantsList->addTopLevelItem(widgetitem);
}
else
widgetitem = dynamic_cast<GxsIdRSTreeWidgetItem*>(qlFoundParticipants.at(0));
if (isParticipantMuted(it2->first)) {
widgetitem->setTextColor(COLUMN_NAME,QColor(255,0,0)); widgetitem->setTextColor(COLUMN_NAME,QColor(255,0,0));
} else { } else {
widgetitem->setIcon(COLUMN_ICON, QIcon(":/images/greenled.png"));
widgetitem->setTextColor(COLUMN_NAME,ui.participantsList->palette().color(QPalette::Active, QPalette::Text)); widgetitem->setTextColor(COLUMN_NAME,ui.participantsList->palette().color(QPalette::Active, QPalette::Text));
} }
time_t tLastAct=widgetitem->text(COLUMN_ACTIVITY).toInt(); time_t tLastAct=widgetitem->text(COLUMN_ACTIVITY).toInt();
time_t now = time(NULL); time_t now = time(NULL);
if (tLastAct<now-60*30)
widgetitem->setIcon(COLUMN_ICON, QIcon(isParticipantMuted(participant)?":/images/ledoff1.png":":/images/grayled.png"));
std::string nickName; if(isParticipantMuted(it2->first))
rsMsgs->getNickNameForChatLobby(lobbyId, nickName); widgetitem->setIcon(COLUMN_ICON, QIcon(":/images/ledoff1.png")) ;
if (participant.toStdString()==nickName) widgetitem->setIcon(COLUMN_ICON, QIcon(":/images/yellowled.png")); else if (tLastAct<now-60*30)
widgetitem->setIcon(COLUMN_ICON, QIcon(":/images/grayled.png"));
else
widgetitem->setIcon(COLUMN_ICON, QIcon(":/images/ledon1.png"));
RsGxsId gxs_id;
rsMsgs->getIdentityForChatLobby(lobbyId, gxs_id);
if (RsGxsId(participant.toStdString()) == gxs_id) widgetitem->setIcon(COLUMN_ICON, QIcon(":/images/yellowled.png"));
QTime qtLastAct=QTime(0,0,0).addSecs(now-tLastAct); QTime qtLastAct=QTime(0,0,0).addSecs(now-tLastAct);
widgetitem->setToolTip(COLUMN_NAME,tr("Right click to mute/unmute participants<br/>Double click to address this person<br/>") widgetitem->setToolTip(COLUMN_ICON,tr("Right click to mute/unmute participants<br/>Double click to address this person<br/>")
+tr("This participant is not active since:") +tr("This participant is not active since:")
+qtLastAct.toString() +qtLastAct.toString()
+tr(" seconds") +tr(" seconds")
@ -409,25 +447,26 @@ void ChatLobbyDialog::updateParticipantsList()
void ChatLobbyDialog::changePartipationState() void ChatLobbyDialog::changePartipationState()
{ {
QList<QTreeWidgetItem*> selectedItems = ui.participantsList->selectedItems(); QList<QTreeWidgetItem*> selectedItems = ui.participantsList->selectedItems();
if (selectedItems.isEmpty()) { if (selectedItems.isEmpty()) {
return; return;
} }
QList<QTreeWidgetItem*>::iterator item; QList<QTreeWidgetItem*>::iterator item;
for (item = selectedItems.begin(); item != selectedItems.end(); ++item) { for (item = selectedItems.begin(); item != selectedItems.end(); ++item) {
QString nickname = (*item)->text(COLUMN_NAME);
std::cerr << "check Partipation status for '" << nickname.toUtf8().constData() << std::endl; RsGxsId gxs_id ;
dynamic_cast<GxsIdRSTreeWidgetItem*>(*item)->getId(gxs_id) ;
std::cerr << "check Partipation status for '" << gxs_id << std::endl;
if (muteAct->isChecked()) { if (muteAct->isChecked()) {
muteParticipant(nickname); muteParticipant(gxs_id);
} else { } else {
unMuteParticipant(nickname); unMuteParticipant(gxs_id);
} }
} }
mutedParticipants->removeDuplicates();
updateParticipantsList(); updateParticipantsList();
} }
@ -459,41 +498,77 @@ void ChatLobbyDialog::participantsTreeWidgetDoubleClicked(QTreeWidgetItem *item,
// updateParticipantsList(); // updateParticipantsList();
} }
void ChatLobbyDialog::muteParticipant(const QString &nickname) { void ChatLobbyDialog::distantChatParticipant()
std::cerr << " Mute " << std::endl; {
std::string myNickName; std::cerr << " initiating distant chat" << std::endl;
rsMsgs->getNickNameForChatLobby(lobbyId, myNickName);
if (nickname.toStdString()!=myNickName) QList<QTreeWidgetItem*> selectedItems = ui.participantsList->selectedItems();
mutedParticipants->append(nickname);
if (selectedItems.isEmpty())
return;
if(selectedItems.size() != 1)
return ;
GxsIdRSTreeWidgetItem *item = dynamic_cast<GxsIdRSTreeWidgetItem*>(selectedItems.front());
if(!item)
return ;
RsGxsId gxs_id ;
item->getId(gxs_id) ;
RsGxsId own_id;
rsMsgs->getIdentityForChatLobby(lobbyId, own_id);
uint32_t error_code ;
if(! rsMsgs->initiateDistantChatConnexion(gxs_id,own_id,error_code))
{
QString error_str ;
switch(error_code)
{
case RS_DISTANT_CHAT_ERROR_DECRYPTION_FAILED : error_str = tr("Decryption failed.") ; break ;
case RS_DISTANT_CHAT_ERROR_SIGNATURE_MISMATCH : error_str = tr("Signature mismatch") ; break ;
case RS_DISTANT_CHAT_ERROR_UNKNOWN_KEY : error_str = tr("Unknown key") ; break ;
case RS_DISTANT_CHAT_ERROR_UNKNOWN_HASH : error_str = tr("Unknown hash") ; break ;
default:
error_str = tr("Unknown error.") ;
}
QMessageBox::warning(NULL,tr("Cannot start distant chat"),tr("Distant cannot be initiated: ")+error_str
+QString::number(error_code)) ;
}
} }
void ChatLobbyDialog::unMuteParticipant(const QString &nickname) {
void ChatLobbyDialog::muteParticipant(const RsGxsId& nickname)
{
std::cerr << " Mute " << std::endl;
RsGxsId gxs_id;
rsMsgs->getIdentityForChatLobby(lobbyId, gxs_id);
if (gxs_id!=nickname)
mutedParticipants.insert(nickname);
}
void ChatLobbyDialog::unMuteParticipant(const RsGxsId& id)
{
std::cerr << " UnMute " << std::endl; std::cerr << " UnMute " << std::endl;
mutedParticipants->removeAll(nickname); mutedParticipants.erase(id);
} }
/** /**
* Is this nickName already known in the lobby * Is this nickName already known in the lobby
*/ */
bool ChatLobbyDialog::isNicknameInLobby(const QString &nickname) { bool ChatLobbyDialog::isNicknameInLobby(const RsGxsId& nickname)
{
ChatLobbyInfo clinfo;
std::list<ChatLobbyInfo> linfos; if(! rsMsgs->getChatLobbyInfo(lobbyId,clinfo))
rsMsgs->getChatLobbyList(linfos);
std::list<ChatLobbyInfo>::const_iterator it(linfos.begin());
// Set it to the current ChatLobby
for (; it!=linfos.end() && (*it).lobby_id != lobbyId; ++it) ;
if (it != linfos.end()) {
for (std::map<std::string,time_t>::const_iterator it2((*it).nick_names.begin()); it2 != (*it).nick_names.end(); ++it2) {
QString participant = QString::fromUtf8( (it2->first).c_str() );
if (participant==nickname) {
return true;
}
}
}
return false ; return false ;
return clinfo.gxs_ids.find(nickname) != clinfo.gxs_ids.end() ;
} }
/** /**
@ -507,42 +582,71 @@ bool ChatLobbyDialog::isNicknameInLobby(const QString &nickname) {
* *
* @param QString nickname to check * @param QString nickname to check
*/ */
bool ChatLobbyDialog::isParticipantMuted(const QString &participant) bool ChatLobbyDialog::isParticipantMuted(const RsGxsId& participant)
{ {
// nickname in Mute list // nickname in Mute list
return mutedParticipants->contains(participant); return mutedParticipants.find(participant) != mutedParticipants.end();
} }
void ChatLobbyDialog::displayLobbyEvent(int event_type, const QString& nickname, const QString& str) QString ChatLobbyDialog::getParticipantName(const RsGxsId& gxs_id) const
{
RsIdentityDetails details ;
QString name ;
if(rsIdentity->getIdDetails(gxs_id,details))
name = QString::fromUtf8(details.mNickname.c_str()) ;
else
name = QString::fromUtf8("[Unknown] (") + QString::fromStdString(gxs_id.toStdString()) + ")" ;
return name ;
}
void ChatLobbyDialog::displayLobbyEvent(int event_type, const RsGxsId& gxs_id, const QString& str)
{
RsGxsId qsParticipant;
QString name= getParticipantName(gxs_id) ;
switch (event_type)
{ {
QString qsParticipant="";
switch (event_type) {
case RS_CHAT_LOBBY_EVENT_PEER_LEFT: case RS_CHAT_LOBBY_EVENT_PEER_LEFT:
qsParticipant=str; qsParticipant=gxs_id;
ui.chatWidget->addChatMsg(true, tr("Lobby management"), QDateTime::currentDateTime(), QDateTime::currentDateTime(), tr("%1 has left the lobby.").arg(RsHtml::plainText(str)), ChatWidget::MSGTYPE_SYSTEM); ui.chatWidget->addChatMsg(true, tr("Lobby management"), QDateTime::currentDateTime(), QDateTime::currentDateTime(), tr("%1 has left the lobby.").arg(RsHtml::plainText(name)), ChatWidget::MSGTYPE_SYSTEM);
emit peerLeft(id()) ; emit peerLeft(id()) ;
break; break;
case RS_CHAT_LOBBY_EVENT_PEER_JOINED: case RS_CHAT_LOBBY_EVENT_PEER_JOINED:
qsParticipant=str; qsParticipant=gxs_id;
ui.chatWidget->addChatMsg(true, tr("Lobby management"), QDateTime::currentDateTime(), QDateTime::currentDateTime(), tr("%1 joined the lobby.").arg(RsHtml::plainText(str)), ChatWidget::MSGTYPE_SYSTEM); ui.chatWidget->addChatMsg(true, tr("Lobby management"), QDateTime::currentDateTime(), QDateTime::currentDateTime(), tr("%1 joined the lobby.").arg(RsHtml::plainText(name)), ChatWidget::MSGTYPE_SYSTEM);
emit peerJoined(id()) ; emit peerJoined(id()) ;
break; break;
case RS_CHAT_LOBBY_EVENT_PEER_STATUS: case RS_CHAT_LOBBY_EVENT_PEER_STATUS:
qsParticipant=nickname; {
ui.chatWidget->updateStatusString(RsHtml::plainText(nickname) + " %1", RsHtml::plainText(str));
if (!isParticipantMuted(nickname)) { qsParticipant=gxs_id;
ui.chatWidget->updateStatusString(RsHtml::plainText(name) + " %1", RsHtml::plainText(str));
if (!isParticipantMuted(gxs_id))
emit typingEventReceived(id()) ; emit typingEventReceived(id()) ;
} }
break; break;
case RS_CHAT_LOBBY_EVENT_PEER_CHANGE_NICKNAME: case RS_CHAT_LOBBY_EVENT_PEER_CHANGE_NICKNAME:
qsParticipant=str; {
ui.chatWidget->addChatMsg(true, tr("Lobby management"), QDateTime::currentDateTime(), QDateTime::currentDateTime(), tr("%1 changed his name to: %2").arg(RsHtml::plainText(nickname), RsHtml::plainText(str)), ChatWidget::MSGTYPE_SYSTEM); qsParticipant=gxs_id;
QString newname= getParticipantName(RsGxsId(str.toStdString())) ;
ui.chatWidget->addChatMsg(true, tr("Lobby management"), QDateTime::currentDateTime(),
QDateTime::currentDateTime(),
tr("%1 changed his name to: %2").arg(name).arg(newname),
ChatWidget::MSGTYPE_SYSTEM);
// TODO if a user was muted and changed his name, update mute list, but only, when the muted peer, dont change his name to a other peer in your chat lobby // TODO if a user was muted and changed his name, update mute list, but only, when the muted peer, dont change his name to a other peer in your chat lobby
if (isParticipantMuted(nickname) && !isNicknameInLobby(str)) { if (isParticipantMuted(gxs_id))
muteParticipant(str); muteParticipant(RsGxsId(str.toStdString())) ;
} }
break; break;
case RS_CHAT_LOBBY_EVENT_KEEP_ALIVE: case RS_CHAT_LOBBY_EVENT_KEEP_ALIVE:
//std::cerr << "Received keep alive packet from " << nickname.toStdString() << " in lobby " << getPeerId() << std::endl; //std::cerr << "Received keep alive packet from " << nickname.toStdString() << " in lobby " << getPeerId() << std::endl;
@ -551,9 +655,12 @@ void ChatLobbyDialog::displayLobbyEvent(int event_type, const QString& nickname,
std::cerr << "ChatLobbyDialog::displayLobbyEvent() Unhandled lobby event type " << event_type << std::endl; std::cerr << "ChatLobbyDialog::displayLobbyEvent() Unhandled lobby event type " << event_type << std::endl;
} }
if (qsParticipant!=""){ if (!qsParticipant.isNull())
QList<QTreeWidgetItem*> qlFoundParticipants=ui.participantsList->findItems(str,Qt::MatchExactly,COLUMN_NAME); {
if (qlFoundParticipants.count()!=0) qlFoundParticipants.at(0)->setText(COLUMN_ACTIVITY,QString::number(time(NULL))); QList<QTreeWidgetItem*> qlFoundParticipants=ui.participantsList->findItems(QString::fromStdString(qsParticipant.toStdString()),Qt::MatchExactly,COLUMN_ID);
if (qlFoundParticipants.count()!=0)
qlFoundParticipants.at(0)->setText(COLUMN_ACTIVITY,QString::number(time(NULL)));
} }
updateParticipantsList() ; updateParticipantsList() ;

View File

@ -24,8 +24,10 @@
#define _CHATLOBBYDIALOG_H #define _CHATLOBBYDIALOG_H
#include "ui_ChatLobbyDialog.h" #include "ui_ChatLobbyDialog.h"
#include "gui/common/RSTreeWidgetItem.h"
#include "ChatDialog.h" #include "ChatDialog.h"
class GxsIdChooser ;
class QToolButton; class QToolButton;
class ChatLobbyDialog: public ChatDialog class ChatLobbyDialog: public ChatDialog
@ -35,14 +37,14 @@ class ChatLobbyDialog: public ChatDialog
friend class ChatDialog; friend class ChatDialog;
public: public:
void displayLobbyEvent(int event_type, const QString& nickname, const QString& str); void displayLobbyEvent(int event_type, const RsGxsId &gxs_id, const QString& str);
virtual void showDialog(uint chatflags); virtual void showDialog(uint chatflags);
virtual ChatWidget *getChatWidget(); virtual ChatWidget *getChatWidget();
virtual bool hasPeerStatus() { return false; } virtual bool hasPeerStatus() { return false; }
virtual bool notifyBlink(); virtual bool notifyBlink();
void setNickname(const QString &nickname); void setIdentity(const RsGxsId& gxs_id);
bool isParticipantMuted(const QString &participant); bool isParticipantMuted(const RsGxsId &participant);
ChatLobbyId id() const { return lobbyId ;} ChatLobbyId id() const { return lobbyId ;}
private slots: private slots:
@ -73,19 +75,23 @@ protected:
protected slots: protected slots:
void changeNickname(); void changeNickname();
void changePartipationState(); void changePartipationState();
void distantChatParticipant();
void participantsTreeWidgetDoubleClicked(QTreeWidgetItem *item, int column); void participantsTreeWidgetDoubleClicked(QTreeWidgetItem *item, int column);
private: private:
void updateParticipantsList(); void updateParticipantsList();
void muteParticipant(const QString &nickname); QString getParticipantName(const RsGxsId& id) const;
void unMuteParticipant(const QString &nickname); void muteParticipant(const RsGxsId& id);
bool isNicknameInLobby(const QString &nickname); void unMuteParticipant(const RsGxsId& id);
bool isNicknameInLobby(const RsGxsId& id);
ChatLobbyId lobbyId; ChatLobbyId lobbyId;
QString _lobby_name ; QString _lobby_name ;
time_t lastUpdateListTime; time_t lastUpdateListTime;
RSTreeWidgetItemCompareRole *mParticipantCompareRole ;
QToolButton *inviteFriendsButton ; QToolButton *inviteFriendsButton ;
QToolButton *unsubscribeButton ; QToolButton *unsubscribeButton ;
@ -93,9 +99,12 @@ private:
Ui::ChatLobbyDialog ui; Ui::ChatLobbyDialog ui;
/** Ignored Users in Chatlobby by nickname until we had implemented Peer Ids in ver 0.6 */ /** Ignored Users in Chatlobby by nickname until we had implemented Peer Ids in ver 0.6 */
QStringList *mutedParticipants; std::set<RsGxsId> mutedParticipants;
QAction *muteAct; QAction *muteAct;
QAction *distantChatAct;
GxsIdChooser *ownIdChooser ;
}; };
#endif #endif

View File

@ -523,19 +523,9 @@ static bool caseInsensitiveCompare(QString a, QString b)
void ChatWidget::completeNickname(bool reverse) void ChatWidget::completeNickname(bool reverse)
{ {
// Find lobby we belong to // Find lobby we belong to
const ChatLobbyInfo *lobby = NULL; ChatLobbyInfo lobby ;
std::list<ChatLobbyInfo> lobbies;
rsMsgs->getChatLobbyList(lobbies);
std::list<ChatLobbyInfo>::const_iterator lobbyIt; if(! rsMsgs->getChatLobbyInfo(chatId.toLobbyId(),lobby))
for (lobbyIt = lobbies.begin(); lobbyIt != lobbies.end(); ++lobbyIt) {
if (chatId.toLobbyId() == lobbyIt->lobby_id) {
lobby = &*lobbyIt;
break;
}
}
if (!lobby)
return ; return ;
QTextCursor cursor = ui->chatTextEdit->textCursor(); QTextCursor cursor = ui->chatTextEdit->textCursor();
@ -567,13 +557,12 @@ void ChatWidget::completeNickname(bool reverse)
word.chop(2); word.chop(2);
} }
#warning still need to use real nicknames for nickname completion.
if (word.length() > 0) { if (word.length() > 0) {
// Sort participants list // Sort participants list
std::list<QString> participants; std::list<QString> participants;
for ( std::map<std::string,time_t>::const_iterator it = lobby->nick_names.begin(); for ( std::map<RsGxsId,time_t>::const_iterator it = lobby.gxs_ids.begin(); it != lobby.gxs_ids.end(); ++it) {
it != lobby->nick_names.end(); participants.push_front(QString::fromUtf8(it->first.toStdString().c_str()));
++it) {
participants.push_front(QString::fromUtf8(it->first.c_str()));
} }
participants.sort(caseInsensitiveCompare); participants.sort(caseInsensitiveCompare);
@ -626,31 +615,19 @@ void ChatWidget::completeNickname(bool reverse)
QAbstractItemModel *ChatWidget::modelFromPeers() QAbstractItemModel *ChatWidget::modelFromPeers()
{ {
// Find lobby we belong to // Find lobby we belong to
const ChatLobbyInfo *lobby = NULL; ChatLobbyInfo lobby ;
std::list<ChatLobbyInfo> lobbies;
rsMsgs->getChatLobbyList(lobbies);
std::list<ChatLobbyInfo>::const_iterator lobbyIt; if(! rsMsgs->getChatLobbyInfo(chatId.toLobbyId(),lobby))
for (lobbyIt = lobbies.begin(); lobbyIt != lobbies.end(); ++lobbyIt) {
if (chatId.toLobbyId() == lobbyIt->lobby_id) {
lobby = &*lobbyIt;
break;
}
}
if (!lobby)
return new QStringListModel(completer); return new QStringListModel(completer);
#ifndef QT_NO_CURSOR #ifndef QT_NO_CURSOR
QApplication::setOverrideCursor(QCursor(Qt::WaitCursor)); QApplication::setOverrideCursor(QCursor(Qt::WaitCursor));
#endif #endif
#warning still need to use real nicknames for nickname completion.
// Get participants list // Get participants list
QStringList participants; QStringList participants;
for ( std::map<std::string,time_t>::const_iterator it = lobby->nick_names.begin(); for ( std::map<RsGxsId,time_t>::const_iterator it = lobby.gxs_ids.begin(); it != lobby.gxs_ids.end(); ++it)
it != lobby->nick_names.end(); participants.push_front(QString::fromUtf8(it->first.toStdString().c_str()));
++it) {
participants.push_front(QString::fromUtf8(it->first.c_str()));
}
#ifndef QT_NO_CURSOR #ifndef QT_NO_CURSOR
QApplication::restoreOverrideCursor(); QApplication::restoreOverrideCursor();

View File

@ -31,6 +31,7 @@
#include "gui/common/PeerDefs.h" #include "gui/common/PeerDefs.h"
#include "ChatDialog.h" #include "ChatDialog.h"
#include "gui/ChatLobbyWidget.h"
CreateLobbyDialog::CreateLobbyDialog(const std::list<RsPeerId>& peer_list, int privacyLevel, QWidget *parent) : CreateLobbyDialog::CreateLobbyDialog(const std::list<RsPeerId>& peer_list, int privacyLevel, QWidget *parent) :
QDialog(parent, Qt::WindowSystemMenuHint | Qt::WindowTitleHint | Qt::WindowCloseButtonHint) QDialog(parent, Qt::WindowSystemMenuHint | Qt::WindowTitleHint | Qt::WindowCloseButtonHint)
@ -41,20 +42,22 @@ CreateLobbyDialog::CreateLobbyDialog(const std::list<RsPeerId>& peer_list, int p
ui->headerFrame->setHeaderImage(QPixmap(":/images/chat_64.png")); ui->headerFrame->setHeaderImage(QPixmap(":/images/chat_64.png"));
ui->headerFrame->setHeaderText(tr("Create Chat Lobby")); ui->headerFrame->setHeaderText(tr("Create Chat Lobby"));
std::string default_nick ; RsGxsId default_identity ;
rsMsgs->getDefaultNickNameForChatLobby(default_nick) ; rsMsgs->getDefaultIdentityForChatLobby(default_identity) ;
#if QT_VERSION >= 0x040700 ui->idChooser_CB->loadIds(IDCHOOSER_ID_REQUIRED, default_identity);
ui->lobbyName_LE->setPlaceholderText(tr("Put a sensible lobby name here")) ;
ui->nickName_LE->setPlaceholderText(tr("Your nickname for this lobby (Change default name in options->chat)")) ; //#if QT_VERSION >= 0x040700
#endif // ui->lobbyName_LE->setPlaceholderText(tr("Put a sensible lobby name here")) ;
ui->nickName_LE->setText(QString::fromUtf8(default_nick.c_str())) ; // ui->nickName_LE->setPlaceholderText(tr("Your nickname for this lobby (Change default name in options->chat)")) ;
//#endif
// ui->nickName_LE->setText(QString::fromUtf8(default_nick.c_str())) ;
connect( ui->buttonBox, SIGNAL(accepted()), this, SLOT(createLobby())); connect( ui->buttonBox, SIGNAL(accepted()), this, SLOT(createLobby()));
connect( ui->buttonBox, SIGNAL(rejected()), this, SLOT(close())); connect( ui->buttonBox, SIGNAL(rejected()), this, SLOT(close()));
connect( ui->lobbyName_LE, SIGNAL( textChanged ( QString ) ), this, SLOT( checkTextFields( ) ) ); connect( ui->lobbyName_LE, SIGNAL( textChanged ( QString ) ), this, SLOT( checkTextFields( ) ) );
connect( ui->lobbyTopic_LE, SIGNAL( textChanged ( QString ) ), this, SLOT( checkTextFields( ) ) ); connect( ui->lobbyTopic_LE, SIGNAL( textChanged ( QString ) ), this, SLOT( checkTextFields( ) ) );
connect( ui->nickName_LE, SIGNAL( textChanged ( QString ) ), this, SLOT( checkTextFields( ) ) ); connect( ui->idChooser_CB, SIGNAL( currentChanged ( int ) ), this, SLOT( checkTextFields( ) ) );
/* initialize key share list */ /* initialize key share list */
ui->keyShareList->setHeaderText(tr("Contacts:")); ui->keyShareList->setHeaderText(tr("Contacts:"));
@ -64,7 +67,7 @@ CreateLobbyDialog::CreateLobbyDialog(const std::list<RsPeerId>& peer_list, int p
ui->keyShareList->setSelectedIds<RsPeerId,FriendSelectionWidget::IDTYPE_SSL>(peer_list, false); ui->keyShareList->setSelectedIds<RsPeerId,FriendSelectionWidget::IDTYPE_SSL>(peer_list, false);
if (privacyLevel) { if (privacyLevel) {
ui->security_CB->setCurrentIndex((privacyLevel == RS_CHAT_LOBBY_PRIVACY_LEVEL_PUBLIC) ? 0 : 1); ui->security_CB->setCurrentIndex((privacyLevel == CHAT_LOBBY_PRIVACY_LEVEL_PUBLIC) ? 0 : 1);
} }
checkTextFields(); checkTextFields();
@ -91,10 +94,17 @@ void CreateLobbyDialog::changeEvent(QEvent *e)
void CreateLobbyDialog::checkTextFields() void CreateLobbyDialog::checkTextFields()
{ {
if(ui->lobbyName_LE->text() == "" || ui->nickName_LE->text() == "") RsGxsId id ;
ui->buttonBox->button(QDialogButtonBox::Ok)->setEnabled(false) ;
else switch(ui->idChooser_CB->getChosenId(id))
{
case GxsIdChooser::NoId:
case GxsIdChooser::None: ui->buttonBox->button(QDialogButtonBox::Ok)->setEnabled(false) ;
break ;
default:
ui->buttonBox->button(QDialogButtonBox::Ok)->setEnabled(true) ; ui->buttonBox->button(QDialogButtonBox::Ok)->setEnabled(true) ;
break ;
}
} }
void CreateLobbyDialog::createLobby() void CreateLobbyDialog::createLobby()
@ -111,18 +121,25 @@ void CreateLobbyDialog::createLobby()
std::string lobby_name = ui->lobbyName_LE->text().toUtf8().constData() ; std::string lobby_name = ui->lobbyName_LE->text().toUtf8().constData() ;
std::string lobby_topic = ui->lobbyTopic_LE->text().toUtf8().constData() ; std::string lobby_topic = ui->lobbyTopic_LE->text().toUtf8().constData() ;
// set nick name !
RsGxsId gxs_id ;
switch(ui->idChooser_CB->getChosenId(gxs_id))
{
case GxsIdChooser::NoId:
case GxsIdChooser::None:
return ;
}
// add to group // add to group
int lobby_privacy_type = (ui->security_CB->currentIndex() == 0)?RS_CHAT_LOBBY_PRIVACY_LEVEL_PUBLIC:RS_CHAT_LOBBY_PRIVACY_LEVEL_PRIVATE ; ChatLobbyFlags lobby_flags ;
ChatLobbyId id = rsMsgs->createChatLobby(lobby_name, lobby_topic, shareList, lobby_privacy_type); if(ui->security_CB->currentIndex() == 0)
lobby_flags |= RS_CHAT_LOBBY_FLAGS_PUBLIC ;
ChatLobbyId id = rsMsgs->createChatLobby(lobby_name,gxs_id, lobby_topic, shareList, lobby_flags);
std::cerr << "gui: Created chat lobby " << std::hex << id << std::endl ; std::cerr << "gui: Created chat lobby " << std::hex << id << std::endl ;
// set nick name !
rsMsgs->setNickNameForChatLobby(id,ui->nickName_LE->text().toUtf8().constData()) ;
// open chat window !! // open chat window !!
ChatDialog::chatFriend(ChatId(id)) ; ChatDialog::chatFriend(ChatId(id)) ;

View File

@ -6,7 +6,7 @@
<rect> <rect>
<x>0</x> <x>0</x>
<y>0</y> <y>0</y>
<width>643</width> <width>787</width>
<height>486</height> <height>486</height>
</rect> </rect>
</property> </property>
@ -76,16 +76,13 @@
<item row="2" column="0"> <item row="2" column="0">
<widget class="QLabel" name="label_4"> <widget class="QLabel" name="label_4">
<property name="text"> <property name="text">
<string>Your nick name:</string> <string>Identity to use:</string>
</property> </property>
<property name="alignment"> <property name="alignment">
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set> <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
</property> </property>
</widget> </widget>
</item> </item>
<item row="2" column="2">
<widget class="QLineEdit" name="nickName_LE"/>
</item>
<item row="3" column="0"> <item row="3" column="0">
<widget class="QLabel" name="label_6"> <widget class="QLabel" name="label_6">
<property name="text"> <property name="text">
@ -110,6 +107,9 @@
</item> </item>
</widget> </widget>
</item> </item>
<item row="2" column="2">
<widget class="GxsIdChooser" name="idChooser_CB"/>
</item>
</layout> </layout>
</item> </item>
<item> <item>
@ -265,6 +265,11 @@
<header>gui/common/FriendSelectionWidget.h</header> <header>gui/common/FriendSelectionWidget.h</header>
<container>1</container> <container>1</container>
</customwidget> </customwidget>
<customwidget>
<class>GxsIdChooser</class>
<extends>QComboBox</extends>
<header>gui/gxs/GxsIdChooser.h</header>
</customwidget>
</customwidgets> </customwidgets>
<resources> <resources>
<include location="../images.qrc"/> <include location="../images.qrc"/>

View File

@ -122,6 +122,10 @@ static void loadPrivateIdsCallback(GxsIdDetailsType type, const RsIdentityDetail
return; return;
} }
// this prevents the objects that depend on what's in the combo-box to activate and
// perform any change.Only user-changes should cause this.
chooser->blockSignals(true) ;
QString text = GxsIdDetails::getNameForType(type, details); QString text = GxsIdDetails::getNameForType(type, details);
QString id = QString::fromStdString(details.mId.toStdString()); QString id = QString::fromStdString(details.mId.toStdString());
@ -157,6 +161,8 @@ static void loadPrivateIdsCallback(GxsIdDetailsType type, const RsIdentityDetail
chooser->setItemIcon(index, icons.empty() ? QIcon() : icons[0]); chooser->setItemIcon(index, icons.empty() ? QIcon() : icons[0]);
chooser->model()->sort(0); chooser->model()->sort(0);
chooser->blockSignals(false) ;
} }
void GxsIdChooser::loadPrivateIds(uint32_t token) void GxsIdChooser::loadPrivateIds(uint32_t token)

View File

@ -892,10 +892,10 @@ void NotifyQt::UpdateGUI()
break; break;
} }
ChatLobbyDialog *chatLobbyDialog = dynamic_cast<ChatLobbyDialog*>(chatDialog); ChatLobbyDialog *chatLobbyDialog = dynamic_cast<ChatLobbyDialog*>(chatDialog);
if (!chatLobbyDialog || chatLobbyDialog->isParticipantMuted(QString::fromUtf8(title.c_str()))) {
// participant is muted if (!chatLobbyDialog || chatLobbyDialog->isParticipantMuted(RsGxsId(title)))
break; break; // participant is muted
}
toaster = new Toaster(new ChatLobbyToaster(lobby_id, QString::fromUtf8(title.c_str()), QString::fromUtf8(msg.c_str()))); toaster = new Toaster(new ChatLobbyToaster(lobby_id, QString::fromUtf8(title.c_str()), QString::fromUtf8(msg.c_str())));
} }
break; break;

View File

@ -151,7 +151,16 @@ ChatPage::save(QString &/*errmsg*/)
rsHistory->setSaveCount(RS_HISTORY_TYPE_PRIVATE, ui.privateChatSaveCount->value()); rsHistory->setSaveCount(RS_HISTORY_TYPE_PRIVATE, ui.privateChatSaveCount->value());
rsHistory->setSaveCount(RS_HISTORY_TYPE_LOBBY , ui.lobbyChatSaveCount->value()); rsHistory->setSaveCount(RS_HISTORY_TYPE_LOBBY , ui.lobbyChatSaveCount->value());
rsMsgs->setDefaultNickNameForChatLobby(ui.chatLobbyNick_LE->text().toUtf8().constData()) ; RsGxsId chosen_id ;
switch(ui.chatLobbyIdentity_IC->getChosenId(chosen_id))
{
case GxsIdChooser::KnowId:
case GxsIdChooser::UnKnowId:
rsMsgs->setDefaultIdentityForChatLobby(chosen_id) ;
break ;
default:;
}
ChatStyleInfo info; ChatStyleInfo info;
QListWidgetItem *item = ui.publicList->currentItem(); QListWidgetItem *item = ui.publicList->currentItem();
@ -260,9 +269,11 @@ ChatPage::load()
privateStylePath = loadStyleInfo(ChatStyle::TYPE_PRIVATE, ui.privateList, ui.privateComboBoxVariant, privateStyleVariant); privateStylePath = loadStyleInfo(ChatStyle::TYPE_PRIVATE, ui.privateList, ui.privateComboBoxVariant, privateStyleVariant);
historyStylePath = loadStyleInfo(ChatStyle::TYPE_HISTORY, ui.historyList, ui.historyComboBoxVariant, historyStyleVariant); historyStylePath = loadStyleInfo(ChatStyle::TYPE_HISTORY, ui.historyList, ui.historyComboBoxVariant, historyStyleVariant);
std::string nick ; RsGxsId gxs_id ;
rsMsgs->getDefaultNickNameForChatLobby(nick) ; rsMsgs->getDefaultIdentityForChatLobby(gxs_id) ;
ui.chatLobbyNick_LE->setText(QString::fromUtf8(nick.c_str())) ;
ui.chatLobbyIdentity_IC->loadIds(IDCHOOSER_ID_REQUIRED, gxs_id);
ui.chatLobbyIdentity_IC->setChosenId(gxs_id);
uint chatflags = Settings->getChatFlags(); uint chatflags = Settings->getChatFlags();

View File

@ -6,8 +6,8 @@
<rect> <rect>
<x>0</x> <x>0</x>
<y>0</y> <y>0</y>
<width>606</width> <width>705</width>
<height>477</height> <height>517</height>
</rect> </rect>
</property> </property>
<layout class="QGridLayout" name="gridLayout_2"> <layout class="QGridLayout" name="gridLayout_2">
@ -158,7 +158,7 @@
<item> <item>
<widget class="QLabel" name="label"> <widget class="QLabel" name="label">
<property name="text"> <property name="text">
<string>Default nickname for chat lobbies:</string> <string>Default identity for chat lobbies:</string>
</property> </property>
</widget> </widget>
</item> </item>
@ -181,14 +181,7 @@
</spacer> </spacer>
</item> </item>
<item> <item>
<widget class="QLineEdit" name="chatLobbyNick_LE"> <widget class="GxsIdChooser" name="chatLobbyIdentity_IC"/>
<property name="sizePolicy">
<sizepolicy hsizetype="Expanding" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
</widget>
</item> </item>
</layout> </layout>
</item> </item>
@ -1188,6 +1181,13 @@
</item> </item>
</layout> </layout>
</widget> </widget>
<customwidgets>
<customwidget>
<class>GxsIdChooser</class>
<extends>QComboBox</extends>
<header>gui/gxs/GxsIdChooser.h</header>
</customwidget>
</customwidgets>
<resources/> <resources/>
<connections/> <connections/>
</ui> </ui>

View File

@ -41,14 +41,10 @@ ChatLobbyToaster::ChatLobbyToaster(const ChatLobbyId &lobby_id, const QString &n
QString lobbyName = RsHtml::plainText(name); QString lobbyName = RsHtml::plainText(name);
std::list<ChatLobbyInfo> linfos; ChatLobbyInfo clinfo ;
rsMsgs->getChatLobbyList(linfos); if(rsMsgs->getChatLobbyInfo(mLobbyId,clinfo))
for (std::list<ChatLobbyInfo>::const_iterator it(linfos.begin()); it != linfos.end(); ++it) { lobbyName += "@" + RsHtml::plainText(clinfo.lobby_name);
if ((*it).lobby_id == mLobbyId) {
lobbyName += "@" + RsHtml::plainText(it->lobby_name);
break;
}
}
ui.toasterLabel->setText(lobbyName); ui.toasterLabel->setText(lobbyName);
} }