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.
Bug? If not, then remove "No signature" from selection box
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.
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 [ ] 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 [ ] 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
H [ ] distant messages should be made async-ed
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.
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
[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
the posts marked as read.
[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
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.
Chat
@ -67,6 +74,7 @@ M [ ] allow to share identities between locations.
Network
E [ ] Friends => Friend nodes
E [ ] remove TCP, TOR, UDP from the status column, and move it in front of IP
News feed
[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 p3HistoryMgr ;
class p3IdService ;
class p3ServiceControl;
class RsChatLobbyItem ;
class RsChatLobbyListRequestItem ;
@ -49,7 +50,7 @@ class RsChatMsgItem ;
class DistributedChatService
{
public:
DistributedChatService(uint32_t service_type,p3ServiceControl *sc,p3HistoryMgr *hm) ;
DistributedChatService(uint32_t service_type,p3ServiceControl *sc,p3HistoryMgr *hm,p3IdService *is) ;
virtual ~DistributedChatService() {}
@ -59,24 +60,25 @@ class DistributedChatService
//
bool getVirtualPeerId(const ChatLobbyId& lobby_id, RsPeerId& virtual_peer_id) ;
bool isLobbyId(const RsPeerId& virtual_peer_id, ChatLobbyId& lobby_id) ;
void getChatLobbyList(std::list<ChatLobbyInfo, std::allocator<ChatLobbyInfo> >& cl_infos) ;
bool acceptLobbyInvite(const ChatLobbyId& id) ;
void getChatLobbyList(std::list<ChatLobbyId>& clids) ;
bool getChatLobbyInfo(const ChatLobbyId& id,ChatLobbyInfo& clinfo) ;
bool acceptLobbyInvite(const ChatLobbyId& id,const RsGxsId& identity) ;
void denyLobbyInvite(const ChatLobbyId& id) ;
void getPendingChatLobbyInvites(std::list<ChatLobbyInvite>& invites) ;
void invitePeerToLobby(const ChatLobbyId&, const RsPeerId& peer_id,bool connexion_challenge = false) ;
void unsubscribeChatLobby(const ChatLobbyId& lobby_id) ;
bool setNickNameForChatLobby(const ChatLobbyId& lobby_id,const std::string& nick) ;
bool getNickNameForChatLobby(const ChatLobbyId& lobby_id,std::string& nick) ;
bool setDefaultNickNameForChatLobby(const std::string& nick) ;
bool getDefaultNickNameForChatLobby(std::string& nick) ;
bool setIdentityForChatLobby(const ChatLobbyId& lobby_id,const RsGxsId& nick) ;
bool getIdentityForChatLobby(const ChatLobbyId& lobby_id,RsGxsId& nick) ;
bool setDefaultIdentityForChatLobby(const RsGxsId& nick) ;
bool getDefaultIdentityForChatLobby(RsGxsId& nick) ;
void setLobbyAutoSubscribe(const ChatLobbyId& lobby_id, const bool autoSubscribe);
bool getLobbyAutoSubscribe(const ChatLobbyId& lobby_id);
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) ;
bool joinVisibleChatLobby(const ChatLobbyId& id) ;
bool joinVisibleChatLobby(const ChatLobbyId& id, const RsGxsId &gxs_id) ;
protected:
bool handleRecvItem(RsChatItem *) ;
@ -89,11 +91,13 @@ class DistributedChatService
bool processLoadListItem(const RsItem *item) ;
bool locked_checkAndRebuildPartialLobbyMessage(RsChatLobbyMsgItem *) ;
void checkSizeAndSendLobbyMessage(RsChatLobbyMsgItem *) ;
void checkSizeAndSendLobbyMessage(RsChatItem *) ;
bool sendLobbyChat(const ChatLobbyId &lobby_id, const std::string&) ;
bool handleRecvChatLobbyMsgItem(RsChatMsgItem *item) ;
bool checkSignature(RsChatLobbyBouncingObject *obj,const RsPeerId& peer_id) ;
private:
/// make some statistics about time shifts, to prevent various issues.
void addTimeShiftStatistics(int shift) ;
@ -138,7 +142,6 @@ class DistributedChatService
time_t last_connexion_challenge_time ;
time_t last_keep_alive_packet_time ;
std::set<RsPeerId> previously_known_peers ;
uint32_t flags ;
};
std::map<ChatLobbyId,ChatLobbyEntry> _chat_lobbys ;
@ -154,11 +157,12 @@ class DistributedChatService
time_t last_lobby_challenge_time ; // prevents bruteforce attack
time_t last_visible_lobby_info_request_time ; // allows to ask for updates
bool _should_reset_lobby_counts ;
std::string _default_nick_name ;
RsGxsId _default_identity ;
uint32_t mServType ;
RsMutex mDistributedChatMtx ;
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.
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() ;
@ -811,7 +811,7 @@ void p3ChatService::initChatMessage(RsChatMsgItem *c, ChatMessage &m)
RsChatLobbyMsgItem *lobbyItem = dynamic_cast<RsChatLobbyMsgItem*>(c) ;
if(lobbyItem != NULL)
{
m.lobby_peer_nickname = lobbyItem->nick;
m.lobby_peer_gxs_id = lobbyItem->signature.keyId ;
m.chat_id = ChatId(lobbyItem->lobby_id);
return;
}

View File

@ -68,10 +68,11 @@ std::ostream& RsChatLobbyListItem::print(std::ostream &out, uint16_t 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);
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);
@ -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 << "Msg ID: " << std::hex << msg_id << 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;
}
@ -262,20 +264,20 @@ RsItem *RsChatSerialiser::deserialise(void *data, uint32_t *pktsize)
switch(getRsItemSubType(rstype))
{
case RS_PKT_SUBTYPE_DEFAULT: return new RsChatMsgItem(data,*pktsize) ;
case RS_PKT_SUBTYPE_DEFAULT: return new RsChatMsgItem(data,*pktsize) ;
case RS_PKT_SUBTYPE_PRIVATECHATMSG_CONFIG: return new RsPrivateChatMsgConfigItem(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_AVATAR: return new RsChatAvatarItem(data,*pktsize) ;
case RS_PKT_SUBTYPE_CHAT_LOBBY_MSG: return new RsChatLobbyMsgItem(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_STATUS: return new RsChatStatusItem(data,*pktsize) ;
case RS_PKT_SUBTYPE_CHAT_AVATAR: return new RsChatAvatarItem(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_CHALLENGE: return new RsChatLobbyConnectChallengeItem(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: return new RsChatLobbyListItem(data,*pktsize) ;
case RS_PKT_SUBTYPE_CHAT_LOBBY_CONFIG: return new RsChatLobbyConfigItem(data,*pktsize) ;
case RS_PKT_SUBTYPE_DISTANT_CHAT_DH_PUBLIC_KEY: return new RsChatDHPublicKeyItem(data,*pktsize) ;
case RS_PKT_SUBTYPE_CHAT_LOBBY_CONFIG: return new RsChatLobbyConfigItem(data,*pktsize) ;
case RS_PKT_SUBTYPE_DISTANT_CHAT_DH_PUBLIC_KEY: return new RsChatDHPublicKeyItem(data,*pktsize) ;
default:
std::cerr << "Unknown packet type in chat!" << std::endl ;
return NULL ;
@ -306,28 +308,38 @@ uint32_t RsChatLobbyConnectChallengeItem::serial_size()
s += 8; // challenge code
return s ;
}
uint32_t RsChatLobbyBouncingObject::serial_size()
uint32_t RsChatLobbyBouncingObject::serialized_size(bool include_signature)
{
uint32_t s = 0 ; // no header!
s += 8 ; // lobby_id
s += 8 ; // msg_id
s += GetTlvStringSize(nick) ; // nick
uint32_t s = 0 ; // no header!
s += 8 ; // lobby_id
s += 8 ; // msg_id
s += GetTlvStringSize(nick) ; // nick
if(include_signature)
s += signature.TlvSize() ; // signature
return s ;
}
uint32_t RsChatLobbyEventItem::signed_serial_size()
{
uint32_t s = 8 ; // header
s += 1 ; // event_type
s += GetTlvStringSize(string1) ; // string1
s += 4 ; // send time
s += RsChatLobbyBouncingObject::serialized_size(false) ;
return s ;
}
uint32_t RsChatLobbyEventItem::serial_size()
{
uint32_t s = 8 ; // header
s += RsChatLobbyBouncingObject::serial_size() ;
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 s = 8 ; // header
@ -335,29 +347,35 @@ uint32_t RsChatLobbyListRequestItem::serial_size()
}
uint32_t RsChatLobbyListItem::serial_size()
{
uint32_t s = 8 ; // header
s += 4 ; // number of elements in the vectors
s += lobby_ids.size() * 8 ; // lobby_ids
uint32_t s = 8 ; // header
s += 4 ; // number of elements in the vectors
for(uint32_t i=0;i<lobby_names.size();++i)
s += GetTlvStringSize(lobby_names[i]) ; // lobby_names
for(uint32_t i=0;i<lobby_topics.size();++i)
s += GetTlvStringSize(lobby_topics[i]) ; // lobby_topics
s += lobby_counts.size() * 4 ; // lobby_counts
s += lobby_privacy_levels.size() * 4 ; // lobby_privacy_levels
return s ;
for(uint32_t i=0;i<lobbies.size();++i)
{
s += 8 ; // id
s += GetTlvStringSize(lobbies[i].name) ; // lobby_names
s += GetTlvStringSize(lobbies[i].topic) ; // lobby_topics
s += 4 ; // lobby_counts
s += 4 ; // lobby_flags
}
return s ;
}
uint32_t RsChatLobbyMsgItem::serial_size()
{
uint32_t s = RsChatMsgItem::serial_size() ; // parent
s += RsChatLobbyBouncingObject::serial_size() ;
s += 1; // subpacket id
s += 8; // parent_msg_id
uint32_t s = RsChatMsgItem::serial_size() ; // parent
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;
}
uint32_t RsChatLobbyInviteItem::serial_size()
{
uint32_t s = 8; /* header */
@ -523,15 +541,18 @@ bool RsChatMsgItem::serialise(void *data, uint32_t& pktsize)
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 ;
ok &= setRawUInt64(data, tlvsize, &offset, lobby_id);
ok &= setRawUInt64(data, tlvsize, &offset, msg_id);
ok &= SetTlvString(data, tlvsize, &offset, TLV_TYPE_STR_NAME, nick);
ok &= setRawUInt64(data, tlvsize, &offset, lobby_id);
ok &= setRawUInt64(data, tlvsize, &offset, msg_id);
ok &= SetTlvString(data, tlvsize, &offset, TLV_TYPE_STR_NAME, nick);
return ok ;
if(include_signature)
ok &= signature.SetTlv(data, tlvsize, &offset);
return ok ;
}
/* serialise the data to the buffer */
@ -549,11 +570,13 @@ bool RsChatLobbyMsgItem::serialise(void *data, uint32_t& pktsize)
ok &= setRsItemHeader(data, tlvsize, PacketId(), tlvsize); // correct header!
pktsize = tlvsize;
ok &= RsChatLobbyBouncingObject::serialise(data,tlvsize,offset) ;
ok &= setRawUInt8(data, tlvsize, &offset, subpacket_id);
ok &= setRawUInt64(data, tlvsize, &offset, parent_msg_id);
/* add mandatory parts first */
// 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 */
if (offset != tlvsize)
{
ok = false;
@ -564,6 +587,40 @@ bool RsChatLobbyMsgItem::serialise(void *data, uint32_t& pktsize)
#endif
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)
{
@ -586,26 +643,18 @@ bool RsChatLobbyListItem::serialise(void *data, uint32_t& pktsize)
if (pktsize < tlvsize)
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 ;
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 &= SetTlvString(data, tlvsize, &offset, TLV_TYPE_STR_NAME, lobby_names[i]);
ok &= SetTlvString(data, tlvsize, &offset, TLV_TYPE_STR_NAME, lobby_topics[i]);
ok &= setRawUInt32(data, tlvsize, &offset, lobby_counts[i]);
ok &= setRawUInt32(data, tlvsize, &offset, lobby_privacy_levels[i]);
ok &= setRawUInt64(data, tlvsize, &offset, lobbies[i].id);
ok &= SetTlvString(data, tlvsize, &offset, TLV_TYPE_STR_NAME, lobbies[i].name);
ok &= SetTlvString(data, tlvsize, &offset, TLV_TYPE_STR_NAME, lobbies[i].topic);
ok &= setRawUInt32(data, tlvsize, &offset, lobbies[i].count);
ok &= setRawUInt32(data, tlvsize, &offset, lobbies[i].flags.toUInt32());
}
if (offset != tlvsize)
{
@ -616,7 +665,37 @@ bool RsChatLobbyListItem::serialise(void *data, uint32_t& pktsize)
}
bool RsChatLobbyEventItem::serialise(void *data, uint32_t& pktsize)
{
uint32_t tlvsize = serial_size() ;
uint32_t tlvsize = 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,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!
@ -625,12 +704,13 @@ bool RsChatLobbyEventItem::serialise(void *data, uint32_t& pktsize)
uint32_t offset = 8 ;
ok &= RsChatLobbyBouncingObject::serialise(data,tlvsize,offset) ; // first, serialize parent
ok &= setRawUInt8(data, tlvsize, &offset, event_type);
ok &= SetTlvString(data, tlvsize, &offset, TLV_TYPE_STR_NAME, string1);
ok &= setRawUInt32(data, tlvsize, &offset, sendTime);
pktsize = tlvsize ;
ok &= RsChatLobbyBouncingObject::serialise_to_memory(data,tlvsize,offset,false) ; // at the end, serialize parent
pktsize = tlvsize ;
/* add mandatory parts first */
if (offset != tlvsize)
@ -706,7 +786,7 @@ bool RsChatLobbyInviteItem::serialise(void *data, uint32_t& pktsize)
ok &= setRawUInt64(data, tlvsize, &offset, lobby_id);
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)
{
@ -966,17 +1046,17 @@ RsChatMsgItem::RsChatMsgItem(void *data,uint32_t /*size*/,uint8_t subtype)
}
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);
bool ok = true ;
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 &= RsChatLobbyBouncingObject::deserialise_from_memory(data,rssize,offset) ;
#ifdef CHAT_DEBUG
std::cerr << "Building new chat lobby msg item." << std::endl ;
#endif
@ -1007,20 +1087,20 @@ RsChatLobbyListItem::RsChatLobbyListItem(void *data,uint32_t)
uint32_t n=0 ;
ok &= getRawUInt32(data, rssize, &offset, &n);
lobby_ids.resize(n) ;
lobby_names.resize(n) ;
lobby_topics.resize(n) ;
lobby_counts.resize(n) ;
lobby_privacy_levels.resize(n) ;
lobbies.resize(n) ;
for(uint32_t i=0;i<n;++i)
{
ok &= getRawUInt64(data, rssize, &offset, &lobby_ids[i]);
ok &= GetTlvString(data, rssize, &offset, TLV_TYPE_STR_NAME, lobby_names[i]);
ok &= GetTlvString(data, rssize, &offset, TLV_TYPE_STR_NAME, lobby_topics[i]);
ok &= getRawUInt32(data, rssize, &offset, &lobby_counts[i]);
ok &= getRawUInt32(data, rssize, &offset, &lobby_privacy_levels[i]);
}
{
ok &= getRawUInt64(data, rssize, &offset, &lobbies[i].id);
ok &= GetTlvString(data, rssize, &offset, TLV_TYPE_STR_NAME, lobbies[i].name);
ok &= GetTlvString(data, rssize, &offset, TLV_TYPE_STR_NAME, lobbies[i].topic);
ok &= getRawUInt32(data, rssize, &offset, &lobbies[i].count);
uint32_t fl=0 ;
ok &= getRawUInt32(data, rssize, &offset, &fl);
lobbies[i].flags = ChatLobbyFlags(fl) ;
}
if (offset != rssize)
std::cerr << "Size error while deserializing." << std::endl ;
@ -1028,7 +1108,7 @@ RsChatLobbyListItem::RsChatLobbyListItem(void *data,uint32_t)
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 ;
/* 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 &= GetTlvString(data, rssize, &offset, TLV_TYPE_STR_NAME, nick);
return ok ;
ok &= signature.GetTlv(data, rssize, &offset);
return ok ;
}
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);
bool ok = true ;
uint32_t offset = 8 ;
ok &= RsChatLobbyBouncingObject::deserialise(data,rssize,offset) ;
ok &= getRawUInt8(data, rssize, &offset, &event_type);
ok &= GetTlvString(data, rssize, &offset, TLV_TYPE_STR_NAME, string1);
ok &= getRawUInt32(data, rssize, &offset, &sendTime);
ok &= RsChatLobbyBouncingObject::deserialise_from_memory(data,rssize,offset) ;
#ifdef CHAT_DEBUG
std::cerr << "Building new chat lobby status item." << std::endl ;
#endif
@ -1112,8 +1194,12 @@ RsChatLobbyInviteItem::RsChatLobbyInviteItem(void *data,uint32_t /*size*/)
/* get mandatory parts first */
ok &= getRawUInt64(data, rssize, &offset, &lobby_id);
ok &= GetTlvString(data, rssize, &offset, TLV_TYPE_STR_NAME, lobby_name);
ok &= getRawUInt32(data, rssize, &offset, &lobby_privacy_level);
ok &= GetTlvString(data, rssize, &offset, TLV_TYPE_STR_NAME, lobby_name);
uint32_t fl ;
ok &= getRawUInt32(data, rssize, &offset, &fl) ;
lobby_flags = ChatLobbyFlags(fl) ;
#ifdef CHAT_DEBUG
std::cerr << "Building new chat msg item." << std::endl ;

View File

@ -54,26 +54,29 @@ const uint32_t RS_CHATMSG_CONFIGFLAG_INCOMING = 0x0001;
const uint8_t RS_PKT_SUBTYPE_CHAT_AVATAR = 0x03 ;
const uint8_t RS_PKT_SUBTYPE_CHAT_STATUS = 0x04 ;
const uint8_t RS_PKT_SUBTYPE_PRIVATECHATMSG_CONFIG = 0x05 ;
const uint8_t RS_PKT_SUBTYPE_CHAT_LOBBY_MSG_DEPRECATED = 0x06 ; // don't use ! Deprecated
const uint8_t RS_PKT_SUBTYPE_CHAT_LOBBY_INVITE_DEPREC = 0x07 ; // don't use ! Deprecated
const uint8_t RS_PKT_SUBTYPE_CHAT_LOBBY_MSG_DEPRECATED = 0x06 ; // don't use ! Deprecated
const uint8_t RS_PKT_SUBTYPE_CHAT_LOBBY_INVITE_DEPREC = 0x07 ; // don't use ! Deprecated
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_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_MSG = 0x0C ;
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 ; // 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_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_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 = 0x12 ;
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_deprecated3 = 0x12 ;
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_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 ChatLobbyMsgId ;
typedef std::string ChatLobbyNickName ;
typedef std::string ChatLobbyNickName ;
typedef uint64_t DistantChatDHSessionId ;
class RsChatItem: public RsItem
@ -98,24 +101,25 @@ class RsChatItem: public RsItem
*/
class RsChatMsgItem: public RsChatItem
{
public:
RsChatMsgItem() :RsChatItem(RS_PKT_SUBTYPE_DEFAULT) {}
RsChatMsgItem(uint8_t subtype) :RsChatItem(subtype) {}
public:
RsChatMsgItem() :RsChatItem(RS_PKT_SUBTYPE_DEFAULT) {}
RsChatMsgItem(uint8_t subtype) :RsChatItem(subtype) {}
RsChatMsgItem(void *data,uint32_t size,uint8_t subtype = RS_PKT_SUBTYPE_DEFAULT) ; // deserialization
RsChatMsgItem(void *data,uint32_t size,uint8_t subtype = RS_PKT_SUBTYPE_DEFAULT) ; // deserialization
virtual ~RsChatMsgItem() {}
virtual void clear() {}
virtual std::ostream& print(std::ostream &out, uint16_t indent = 0);
virtual ~RsChatMsgItem() {}
virtual void clear() {}
virtual std::ostream& print(std::ostream &out, uint16_t indent = 0);
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 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
uint32_t chatFlags;
uint32_t sendTime;
std::string message;
/* not serialised */
uint32_t recvTime;
uint32_t chatFlags;
uint32_t sendTime;
std::string message;
/* not serialised */
uint32_t recvTime;
};
// This class contains the info to bounce an object throughout a lobby, while
@ -123,55 +127,72 @@ class RsChatMsgItem: public RsChatItem
//
class RsChatLobbyBouncingObject
{
public:
ChatLobbyId lobby_id ;
ChatLobbyMsgId msg_id ;
ChatLobbyNickName nick ; // Nickname of sender
public:
ChatLobbyId lobby_id ;
ChatLobbyMsgId msg_id ;
ChatLobbyNickName nick ; // Nickname of sender
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);
RsTlvKeySignature signature ;
bool deserialise(void *data,uint32_t rssize,uint32_t& offset) ;
virtual RsChatLobbyBouncingObject *duplicate() const = 0 ;
virtual std::ostream& print(std::ostream &out, uint16_t indent = 0);
// 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
{
public:
RsChatLobbyMsgItem() :RsChatMsgItem(RS_PKT_SUBTYPE_CHAT_LOBBY_MSG) {}
public:
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!!!
virtual ~RsChatLobbyMsgItem() {}
virtual std::ostream& print(std::ostream &out, uint16_t indent = 0);
virtual RsChatLobbyBouncingObject *duplicate() const { return new RsChatLobbyMsgItem(*this) ; }
virtual ~RsChatLobbyMsgItem() {}
virtual std::ostream& print(std::ostream &out, uint16_t indent = 0);
virtual RsChatLobbyBouncingObject *duplicate() const { return new RsChatLobbyMsgItem(*this) ; }
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 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
uint8_t subpacket_id ; // this is for proper handling of split packets.
ChatLobbyMsgId parent_msg_id ; // Used for threaded chat.
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.
};
class RsChatLobbyEventItem: public RsChatItem, public RsChatLobbyBouncingObject
{
public:
RsChatLobbyEventItem() :RsChatItem(RS_PKT_SUBTYPE_CHAT_LOBBY_EVENT) {}
RsChatLobbyEventItem(void *data,uint32_t size) ; // deserialization /// TODO!!!
public:
RsChatLobbyEventItem() :RsChatItem(RS_PKT_SUBTYPE_CHAT_LOBBY_SIGNED_EVENT) {}
RsChatLobbyEventItem(void *data,uint32_t size) ; // deserialization /// TODO!!!
virtual ~RsChatLobbyEventItem() {}
virtual std::ostream& print(std::ostream &out, uint16_t indent = 0);
virtual RsChatLobbyBouncingObject *duplicate() const { return new RsChatLobbyEventItem(*this) ; }
//
virtual bool serialise(void *data,uint32_t& size) ;
virtual uint32_t serial_size() ;
virtual ~RsChatLobbyEventItem() {}
virtual std::ostream& print(std::ostream &out, uint16_t indent = 0);
virtual RsChatLobbyBouncingObject *duplicate() const { return new RsChatLobbyEventItem(*this) ; }
//
virtual bool serialise(void *data,uint32_t& size) ;
virtual uint32_t serial_size() ;
// members.
//
uint8_t event_type ; // used for defining the type of event.
std::string string1; // used for any string
uint32_t sendTime; // used to check for old looping messages
virtual uint32_t signed_serial_size() ;
virtual bool serialise_signed_part(void *data,uint32_t& size) ;
// members.
//
uint8_t event_type ; // used for defining the type of event.
std::string string1; // used for any string
uint32_t sendTime; // used to check for old looping messages
};
class RsChatLobbyListRequestItem: public RsChatItem
@ -184,8 +205,18 @@ class RsChatLobbyListRequestItem: public RsChatItem
virtual bool serialise(void *data,uint32_t& size) ;
virtual uint32_t serial_size() ;
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
{
public:
@ -198,12 +229,9 @@ class RsChatLobbyListItem: public RsChatItem
virtual bool serialise(void *data,uint32_t& size) ;
virtual uint32_t serial_size() ;
std::vector<ChatLobbyId> lobby_ids ;
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 ;
std::vector<VisibleChatLobbyInfo> lobbies ;
};
class RsChatLobbyUnsubscribeItem: public RsChatItem
{
public:
@ -219,7 +247,6 @@ class RsChatLobbyUnsubscribeItem: public RsChatItem
virtual uint32_t serial_size() ; // deserialise is handled using a constructor
};
class RsChatLobbyConnectChallengeItem: public RsChatItem
{
public:
@ -247,7 +274,7 @@ class RsChatLobbyInviteItem: public RsChatItem
ChatLobbyId lobby_id ;
std::string lobby_name ;
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 uint32_t serial_size() ; // deserialise is handled using a constructor

View File

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

View File

@ -80,9 +80,9 @@
#define RS_MSGTAGTYPE_LATER 5
#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_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_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_PRIVATE 2 /* lobby invisible by friends. Peers on invitation only .*/
#define RS_CHAT_TYPE_PUBLIC 1
#define RS_CHAT_TYPE_PRIVATE 2
@ -90,6 +90,9 @@
#define RS_CHAT_TYPE_DISTANT 4
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 ChatLobbyMsgId ;
@ -235,16 +238,16 @@ public:
};
#define RS_CHAT_PUBLIC 0x0001
#define RS_CHAT_PRIVATE 0x0002
#define RS_CHAT_PUBLIC 0x0001
#define RS_CHAT_PRIVATE 0x0002
#define RS_CHAT_AVATAR_AVAILABLE 0x0004
#define RS_DISTANT_CHAT_STATUS_UNKNOWN 0x0000
#define RS_DISTANT_CHAT_STATUS_TUNNEL_DN 0x0001
#define RS_DISTANT_CHAT_STATUS_TUNNEL_OK 0x0002
#define RS_DISTANT_CHAT_STATUS_CAN_TALK 0x0003
#define RS_DISTANT_CHAT_STATUS_UNKNOWN 0x0000
#define RS_DISTANT_CHAT_STATUS_TUNNEL_DN 0x0001
#define RS_DISTANT_CHAT_STATUS_TUNNEL_OK 0x0002
#define RS_DISTANT_CHAT_STATUS_CAN_TALK 0x0003
#define RS_DISTANT_CHAT_STATUS_REMOTELY_CLOSED 0x0004
#define RS_DISTANT_CHAT_STATUS_WAITING_DH 0x0005
#define RS_DISTANT_CHAT_STATUS_WAITING_DH 0x0005
#define RS_DISTANT_CHAT_ERROR_NO_ERROR 0x0000
#define RS_DISTANT_CHAT_ERROR_DECRYPTION_FAILED 0x0001
@ -306,7 +309,8 @@ class ChatMessage
public:
ChatId chat_id; // id of chat endpoint
RsPeerId broadcast_peer_id; // only used for broadcast chat: source peer id
std::string lobby_peer_nickname; // only used for lobbys: nickname of message author
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;
uint32_t sendTime;
@ -324,37 +328,37 @@ class ChatLobbyInvite
RsPeerId peer_id ;
std::string lobby_name ;
std::string lobby_topic ;
uint32_t lobby_privacy_level ;
ChatLobbyFlags lobby_flags ;
};
class VisibleChatLobbyRecord
{
public:
public:
VisibleChatLobbyRecord() { total_number_of_peers = 0 ; }
ChatLobbyId lobby_id ; // unique id of the lobby
std::string lobby_name ; // name 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.
ChatLobbyId lobby_id ; // unique id of the lobby
std::string lobby_name ; // name 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.
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.
uint32_t lobby_privacy_level ; // see RS_CHAT_LOBBY_PRIVACY_LEVEL_PUBLIC / RS_CHAT_LOBBY_PRIVACY_LEVEL_PRIVATE
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.
ChatLobbyFlags lobby_flags ; // see RS_CHAT_LOBBY_PRIVACY_LEVEL_PUBLIC / RS_CHAT_LOBBY_PRIVACY_LEVEL_PRIVATE
};
class ChatLobbyInfo
{
public:
ChatLobbyId lobby_id ; // unique id of the lobby
std::string lobby_name ; // name 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::string nick_name ; // nickname to use for this lobby
ChatLobbyId lobby_id ; // unique id of the lobby
std::string lobby_name ; // name 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.
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
std::map<std::string,time_t> nick_names ; // list of non direct friend who participate. Used to display only.
time_t last_activity ; // last recorded activity. Useful for removing dead lobbies.
ChatLobbyFlags lobby_flags ; // see RS_CHAT_LOBBY_PRIVACY_LEVEL_PUBLIC / RS_CHAT_LOBBY_PRIVACY_LEVEL_PRIVATE
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.
};
struct DistantChatInviteInfo
@ -443,23 +447,24 @@ virtual void getOwnAvatarData(unsigned char *& data,int& size) = 0 ;
/* 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 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 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 getPendingChatLobbyInvites(std::list<ChatLobbyInvite>& invites) = 0;
virtual void unsubscribeChatLobby(const ChatLobbyId& lobby_id) = 0;
virtual bool setNickNameForChatLobby(const ChatLobbyId& lobby_id,const std::string& nick) = 0;
virtual bool getNickNameForChatLobby(const ChatLobbyId& lobby_id,std::string& nick) = 0 ;
virtual bool setDefaultNickNameForChatLobby(const std::string& nick) = 0;
virtual bool getDefaultNickNameForChatLobby(std::string& nick) = 0 ;
virtual bool setIdentityForChatLobby(const ChatLobbyId& lobby_id,const RsGxsId& nick) = 0;
virtual bool getIdentityForChatLobby(const ChatLobbyId& lobby_id,RsGxsId& nick) = 0 ;
virtual bool setDefaultIdentityForChatLobby(const RsGxsId& nick) = 0;
virtual bool getDefaultIdentityForChatLobby(RsGxsId& id) = 0 ;
virtual void setLobbyAutoSubscribe(const ChatLobbyId& lobby_id, const bool autoSubscribe) = 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 */

View File

@ -449,9 +449,13 @@ bool p3Msgs::isLobbyId(const RsPeerId& peer_id,ChatLobbyId& 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)
{
@ -461,27 +465,27 @@ void p3Msgs::unsubscribeChatLobby(const ChatLobbyId& 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)
@ -489,9 +493,9 @@ void p3Msgs::getListOfNearbyChatLobbies(std::vector<VisibleChatLobbyRecord>& pub
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)
@ -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)
{

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 bool getVirtualPeerId(const ChatLobbyId& id,RsPeerId& vpid) ;
virtual bool isLobbyId(const RsPeerId& virtual_peer_id,ChatLobbyId& lobby_id) ;
virtual void getChatLobbyList(std::list<ChatLobbyInfo, std::allocator<ChatLobbyInfo> >&) ;
virtual void invitePeerToLobby(const ChatLobbyId&, const RsPeerId&) ;
virtual bool acceptLobbyInvite(const ChatLobbyId& id) ;
virtual void getChatLobbyList(std::list<ChatLobbyId>& cl_list) ;
virtual bool getChatLobbyInfo(const ChatLobbyId& id,ChatLobbyInfo& info) ;
virtual void invitePeerToLobby(const ChatLobbyId&, const RsPeerId&) ;
virtual bool acceptLobbyInvite(const ChatLobbyId& id, const RsGxsId &gxs_id) ;
virtual void denyLobbyInvite(const ChatLobbyId& id) ;
virtual void getPendingChatLobbyInvites(std::list<ChatLobbyInvite>& invites) ;
virtual void unsubscribeChatLobby(const ChatLobbyId& lobby_id) ;
virtual bool setNickNameForChatLobby(const ChatLobbyId& lobby_id,const std::string&) ;
virtual bool getNickNameForChatLobby(const ChatLobbyId&,std::string& nick) ;
virtual bool setDefaultNickNameForChatLobby(const std::string&) ;
virtual bool getDefaultNickNameForChatLobby(std::string& nick) ;
virtual bool setIdentityForChatLobby(const ChatLobbyId& lobby_id,const RsGxsId&) ;
virtual bool getIdentityForChatLobby(const ChatLobbyId&,RsGxsId& nick) ;
virtual bool setDefaultIdentityForChatLobby(const RsGxsId&) ;
virtual bool getDefaultIdentityForChatLobby(RsGxsId& nick) ;
virtual void setLobbyAutoSubscribe(const ChatLobbyId& lobby_id, const bool autoSubscribe);
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 getDistantChatStatus(const RsGxsId& gxs_id,uint32_t& status, RsGxsId *from_gxs_id=NULL) ;

View File

@ -13,11 +13,13 @@
#include "chat/ChatLobbyUserNotify.h"
#include "util/HandleRichText.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/rspeers.h"
#include "retroshare/rsnotify.h"
#include "retroshare/rsidentity.h"
#define COLUMN_NAME 0
#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->setData(COLUMN_NAME, ROLE_SORT, "1");
// 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);
publicSubLobbyItem = new RSTreeWidgetItem(compareRole, TYPE_FOLDER);
publicSubLobbyItem->setText(COLUMN_NAME, tr("Public Subscribed Lobbies"));
publicSubLobbyItem->setData(COLUMN_NAME, ROLE_SORT, "2");
// 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);
privateLobbyItem = new RSTreeWidgetItem(compareRole, TYPE_FOLDER);
privateLobbyItem->setText(COLUMN_NAME, tr("Private Lobbies"));
privateLobbyItem->setData(COLUMN_NAME, ROLE_SORT, "3");
// 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);
publicLobbyItem = new RSTreeWidgetItem(compareRole, TYPE_FOLDER);
publicLobbyItem->setText(COLUMN_NAME, tr("Public Lobbies"));
publicLobbyItem->setData(COLUMN_NAME, ROLE_SORT, "4");
// 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->expandAll();
@ -212,31 +214,66 @@ void ChatLobbyWidget::lobbyTreeWidgetCustomPopupMenu(QPoint)
action->setData(item->data(COLUMN_DATA, ROLE_PRIVACYLEVEL).toInt());
}
if (item && item->type() == TYPE_LOBBY) {
if (item->data(COLUMN_DATA, ROLE_SUBSCRIBED).toBool()) {
contextMnu.addAction(QIcon(IMAGE_UNSUBSCRIBE), tr("Unsubscribe"), this, SLOT(unsubscribeItem()));
} else {
contextMnu.addAction(QIcon(IMAGE_SUBSCRIBE), tr("Subscribe"), this, SLOT(subscribeItem()));
}
if (item->data(COLUMN_DATA, ROLE_AUTOSUBSCRIBE).toBool()) {
contextMnu.addAction(QIcon(IMAGE_AUTOSUBSCRIBE), tr("Remove Auto Subscribe"), this, SLOT(autoSubscribeItem()));
} else {
contextMnu.addAction(QIcon(IMAGE_SUBSCRIBE), tr("Add Auto Subscribe"), this, SLOT(autoSubscribeItem()));
if (item && item->type() == TYPE_LOBBY)
{
if (item->data(COLUMN_DATA, ROLE_SUBSCRIBED).toBool())
contextMnu.addAction(QIcon(IMAGE_UNSUBSCRIBE), tr("Leave this lobby"), this, SLOT(unsubscribeItem()));
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())) ;
}
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()));
else
contextMnu.addAction(QIcon(IMAGE_SUBSCRIBE), tr("Add Auto Subscribe"), this, SLOT(autoSubscribeItem()));
}
}
}
contextMnu.addSeparator();//-------------------------------------------------------------------
contextMnu.addSeparator();//-------------------------------------------------------------------
showUserCountAct->setChecked(!ui.lobbyTreeWidget->isColumnHidden(COLUMN_USER_COUNT));
showTopicAct->setChecked(!ui.lobbyTreeWidget->isColumnHidden(COLUMN_TOPIC));
showSubscribeAct->setChecked(!ui.lobbyTreeWidget->isColumnHidden(COLUMN_SUBSCRIBED));
showUserCountAct->setChecked(!ui.lobbyTreeWidget->isColumnHidden(COLUMN_USER_COUNT));
showTopicAct->setChecked(!ui.lobbyTreeWidget->isColumnHidden(COLUMN_TOPIC));
showSubscribeAct->setChecked(!ui.lobbyTreeWidget->isColumnHidden(COLUMN_SUBSCRIBED));
QMenu *menu = contextMnu.addMenu(tr("Columns"));
menu->addAction(showUserCountAct);
menu->addAction(showTopicAct);
menu->addAction(showSubscribeAct);
QMenu *menu = contextMnu.addMenu(tr("Columns"));
menu->addAction(showUserCountAct);
menu->addAction(showTopicAct);
menu->addAction(showSubscribeAct);
contextMnu.exec(QCursor::pos());
contextMnu.exec(QCursor::pos());
}
void ChatLobbyWidget::lobbyChanged()
@ -302,14 +339,11 @@ void ChatLobbyWidget::addChatPage(ChatLobbyDialog *d)
_lobby_infos[id].last_typing_event = time(NULL) ;
_lobby_infos[id].unread_count = 0;
std::list<ChatLobbyInfo> lobbies;
rsMsgs->getChatLobbyList(lobbies);
for (std::list<ChatLobbyInfo>::const_iterator it = lobbies.begin(); it != lobbies.end();++it) {
if (it->lobby_id == id) {
_lobby_infos[id].default_icon = (it->lobby_privacy_level == RS_CHAT_LOBBY_PRIVACY_LEVEL_PRIVATE) ? QIcon(IMAGE_PRIVATE) : QIcon(IMAGE_PUBLIC);
}
}
ChatLobbyInfo linfo ;
if(rsMsgs->getChatLobbyInfo(id,linfo))
_lobby_infos[id].default_icon = (linfo.lobby_flags & RS_CHAT_LOBBY_FLAGS_PUBLIC) ? QIcon(IMAGE_PUBLIC):QIcon(IMAGE_PRIVATE) ;
else
std::cerr << "(EE) cannot find info for lobby " << std::hex << id << std::dec << std::endl;
}
}
@ -334,7 +368,7 @@ void ChatLobbyWidget::updateDisplay()
std::vector<VisibleChatLobbyRecord> visibleLobbies;
rsMsgs->getListOfNearbyChatLobbies(visibleLobbies);
std::list<ChatLobbyInfo> lobbies;
std::list<ChatLobbyId> lobbies;
rsMsgs->getChatLobbyList(lobbies);
#ifdef CHAT_LOBBY_GUI_DEBUG
@ -344,7 +378,7 @@ void ChatLobbyWidget::updateDisplay()
// now, do a nice display of lobbies
RsPeerId vpid;
std::list<ChatLobbyInfo>::const_iterator lobbyIt;
std::list<ChatLobbyId>::const_iterator lobbyIt;
// remove not existing public lobbies
@ -381,7 +415,7 @@ void ChatLobbyWidget::updateDisplay()
// Check for participating lobby with public level
//
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;
if (lobbyIt == lobbies.end())
@ -414,33 +448,34 @@ void ChatLobbyWidget::updateDisplay()
QTreeWidgetItem *item = NULL;
QTreeWidgetItem *lobby_item =NULL;
QTreeWidgetItem *lobby_other_item =NULL;
if (lobby.lobby_privacy_level == RS_CHAT_LOBBY_PRIVACY_LEVEL_PUBLIC)
{
if (subscribed)
{
lobby_item = publicSubLobbyItem;
lobby_other_item = publicLobbyItem;
}
else
{
lobby_item = publicLobbyItem;
lobby_other_item = publicSubLobbyItem;
}
}
else
{
if (subscribed)
{
lobby_item = privateSubLobbyItem;
lobby_other_item = privateLobbyItem;
}
else
{
lobby_item = privateLobbyItem;
lobby_other_item = privateSubLobbyItem;
}
}
QTreeWidgetItem *lobby_other_item =NULL;
if (lobby.lobby_flags & RS_CHAT_LOBBY_FLAGS_PUBLIC)
{
if (subscribed)
{
lobby_item = publicSubLobbyItem;
lobby_other_item = publicLobbyItem;
}
else
{
lobby_item = publicLobbyItem;
lobby_other_item = publicSubLobbyItem;
}
}
else
{
if (subscribed)
{
lobby_item = privateSubLobbyItem;
lobby_other_item = privateLobbyItem;
}
else
{
lobby_item = privateLobbyItem;
lobby_other_item = privateSubLobbyItem;
}
}
//QTreeWidgetItem *lobby_item = (lobby.lobby_privacy_level == RS_CHAT_LOBBY_PRIVACY_LEVEL_PUBLIC)?publicLobbyItem:privateLobbyItem ;
// Search existing item
@ -469,14 +504,14 @@ void ChatLobbyWidget::updateDisplay()
if (item == NULL)
{
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);
}
else
{
if (item->data(COLUMN_DATA, ROLE_SUBSCRIBED).toBool() != subscribed) {
// 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()) {
@ -506,19 +541,19 @@ void ChatLobbyWidget::updateDisplay()
// Now add participating lobbies.
//
for (lobbyIt = lobbies.begin(); lobbyIt != lobbies.end(); ++lobbyIt)
{
const ChatLobbyInfo &lobby = *lobbyIt;
{
ChatLobbyInfo lobby ;
rsMsgs->getChatLobbyInfo(*lobbyIt,lobby) ;
#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;
#endif
QTreeWidgetItem *itemParent;
if (lobby.lobby_privacy_level == RS_CHAT_LOBBY_PRIVACY_LEVEL_PUBLIC) {
if (lobby.lobby_flags & RS_CHAT_LOBBY_FLAGS_PUBLIC)
itemParent = publicSubLobbyItem;
} else {
else
itemParent = privateSubLobbyItem;
}
QTreeWidgetItem *item = NULL;
@ -533,23 +568,23 @@ void ChatLobbyWidget::updateDisplay()
}
QIcon icon;
if (item == NULL) {
item = new RSTreeWidgetItem(compareRole, TYPE_LOBBY);
icon = (lobby.lobby_privacy_level == RS_CHAT_LOBBY_PRIVACY_LEVEL_PUBLIC) ? QIcon(IMAGE_PUBLIC) : QIcon(IMAGE_PRIVATE);
itemParent->addChild(item);
} else {
if (!item->data(COLUMN_DATA, ROLE_SUBSCRIBED).toBool()) {
// Replace icon
icon = (lobby.lobby_privacy_level == RS_CHAT_LOBBY_PRIVACY_LEVEL_PUBLIC) ? QIcon(IMAGE_PUBLIC) : QIcon(IMAGE_PRIVATE);
}
}
if (item == NULL) {
item = new RSTreeWidgetItem(compareRole, TYPE_LOBBY);
icon = (lobby.lobby_flags & RS_CHAT_LOBBY_FLAGS_PUBLIC) ? QIcon(IMAGE_PUBLIC) : QIcon(IMAGE_PRIVATE);
itemParent->addChild(item);
} else {
if (!item->data(COLUMN_DATA, ROLE_SUBSCRIBED).toBool()) {
// Replace icon
icon = (lobby.lobby_flags & RS_CHAT_LOBBY_FLAGS_PUBLIC) ? QIcon(IMAGE_PUBLIC) : QIcon(IMAGE_PRIVATE);
}
}
if (!icon.isNull()) {
item->setIcon(COLUMN_NAME, icon);
}
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);
privateSubLobbyItem->setHidden(privateSubLobbyItem->childCount()==0);
@ -581,17 +616,36 @@ void ChatLobbyWidget::showLobby(QTreeWidgetItem *item)
else
ui.stackedWidget->setCurrentWidget(_lobby_infos[id].dialog) ;
}
static void subscribeLobby(QTreeWidgetItem *item)
void ChatLobbyWidget::subscribeChatLobbyAs()
{
if (item == NULL || item->type() != TYPE_LOBBY) {
return;
}
QTreeWidgetItem *item = ui.lobbyTreeWidget->currentItem();
ChatLobbyId id = item->data(COLUMN_DATA, ROLE_ID).toULongLong();
if (rsMsgs->joinVisibleChatLobby(id)) {
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) {
return;
}
ChatLobbyId id = item->data(COLUMN_DATA, ROLE_ID).toULongLong();
RsGxsId gxs_id ;
if(rsMsgs->getDefaultIdentityForChatLobby(gxs_id) && !gxs_id.isNull() && rsMsgs->joinVisibleChatLobby(id,gxs_id))
ChatDialog::chatFriend(ChatId(id),true) ;
}
}
void ChatLobbyWidget::autoSubscribeLobby(QTreeWidgetItem *item)
@ -603,7 +657,7 @@ void ChatLobbyWidget::autoSubscribeLobby(QTreeWidgetItem *item)
ChatLobbyId id = item->data(COLUMN_DATA, ROLE_ID).toULongLong();
bool isAutoSubscribe = rsMsgs->getLobbyAutoSubscribe(id);
rsMsgs->setLobbyAutoSubscribe(id, !isAutoSubscribe);
if (!isAutoSubscribe) subscribeLobby(item);
if (!isAutoSubscribe) subscribeChatLobbyAtItem(item);
}
void ChatLobbyWidget::showBlankPage(ChatLobbyId id)
@ -621,7 +675,7 @@ void ChatLobbyWidget::showBlankPage(ChatLobbyId id)
ui.lobbyname_lineEdit->setText( RsHtml::plainText(it->lobby_name) );
ui.lobbyid_lineEdit->setText( QString::number((*it).lobby_id,16) );
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.lobbyInfoLabel->setText(tr("You're not subscribed to this lobby; Double click-it to enter and chat.") );
@ -640,12 +694,12 @@ void ChatLobbyWidget::showBlankPage(ChatLobbyId id)
void ChatLobbyWidget::subscribeItem()
{
subscribeLobby(ui.lobbyTreeWidget->currentItem());
subscribeChatLobbyAtItem(ui.lobbyTreeWidget->currentItem());
}
void ChatLobbyWidget::autoSubscribeItem()
{
autoSubscribeLobby(ui.lobbyTreeWidget->currentItem());
autoSubscribeLobby(ui.lobbyTreeWidget->currentItem());
}
QTreeWidgetItem *ChatLobbyWidget::getTreeWidgetItem(ChatLobbyId id)
@ -786,7 +840,7 @@ void ChatLobbyWidget::updateCurrentLobby()
if(_lobby_infos.find(id) != _lobby_infos.end()) {
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].unread_count = 0;
item->setIcon(COLUMN_NAME, icon) ;
@ -823,37 +877,62 @@ void ChatLobbyWidget::updateMessageChanged(ChatLobbyId id)
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)))) {
cld->displayLobbyEvent(event_type, nickname, str);
cld->displayLobbyEvent(event_type, RsGxsId(gxs_id.toStdString()), str);
}
}
void ChatLobbyWidget::readChatLobbyInvites()
{
std::list<ChatLobbyInvite> invites;
rsMsgs->getPendingChatLobbyInvites(invites);
std::list<ChatLobbyInvite> invites;
rsMsgs->getPendingChatLobbyInvites(invites);
for(std::list<ChatLobbyInvite>::const_iterator it(invites.begin());it!=invites.end();++it) {
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)) {
std::cerr << "Accepting invite to lobby " << (*it).lobby_name << std::endl;
RsGxsId default_id ;
rsMsgs->getDefaultIdentityForChatLobby(default_id) ;
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);
RsPeerId vpid;
if(rsMsgs->getVirtualPeerId((*it).lobby_id,vpid )) {
ChatDialog::chatFriend(ChatId((*it).lobby_id),true);
} else {
std::cerr << "No lobby known with id 0x" << std::hex << (*it).lobby_id << std::dec << std::endl;
}
} else {
rsMsgs->denyLobbyInvite((*it).lobby_id);
}
}
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;
if(rsMsgs->getVirtualPeerId((*it).lobby_id,vpid ))
ChatDialog::chatFriend(ChatId((*it).lobby_id),true);
else
std::cerr << "No lobby known with id 0x" << std::hex << (*it).lobby_id << std::dec << std::endl;
}
}
void ChatLobbyWidget::filterColumnChanged(int)

View File

@ -7,6 +7,9 @@
#define IMAGE_CHATLOBBY ":/images/chat_32.png"
#define CHAT_LOBBY_PRIVACY_LEVEL_PUBLIC 1
#define CHAT_LOBBY_PRIVACY_LEVEL_PRIVATE 2
class RSTreeWidgetItemCompareRole;
class ChatTabWidget ;
class ChatLobbyDialog ;
@ -55,12 +58,13 @@ protected slots:
void unsubscribeItem();
void itemDoubleClicked(QTreeWidgetItem *item, int column);
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 showLobby(QTreeWidgetItem *lobby_item) ;
void showBlankPage(ChatLobbyId id) ;
void unsubscribeChatLobby(ChatLobbyId id) ;
void updateTypingStatus(ChatLobbyId id) ;
void unsubscribeChatLobby(ChatLobbyId id) ;
void subscribeChatLobbyAs() ;
void updateTypingStatus(ChatLobbyId id) ;
void resetLobbyTreeIcons() ;
void updateMessageChanged(ChatLobbyId);
void updatePeerEntering(ChatLobbyId);
@ -78,6 +82,8 @@ private slots:
private:
void autoSubscribeLobby(QTreeWidgetItem *item);
void subscribeChatLobby(ChatLobbyId id) ;
void subscribeChatLobbyAtItem(QTreeWidgetItem *item) ;
bool filterItem(QTreeWidgetItem *item, const QString &text, int filterColumn);

View File

@ -34,16 +34,19 @@
#include <gui/common/html.h>
#include "gui/common/RSTreeWidgetItem.h"
#include "gui/common/FriendSelectionDialog.h"
#include "gui/gxs/GxsIdTreeWidgetItem.h"
#include "gui/gxs/GxsIdChooser.h"
#include "util/HandleRichText.h"
#include <retroshare/rsnotify.h>
#include <time.h>
#define COLUMN_ICON 0
#define COLUMN_NAME 1
#define COLUMN_ICON 0
#define COLUMN_NAME 1
#define COLUMN_ACTIVITY 2
#define COLUMN_COUNT 3
#define COLUMN_ID 3
#define COLUMN_COUNT 4
/** Default constructor */
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);
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(itemDoubleClicked(QTreeWidgetItem*,int)), this, SLOT(participantsTreeWidgetDoubleClicked(QTreeWidgetItem*,int)));
ui.participantsList->setColumnCount(COLUMN_COUNT);
ui.participantsList->setColumnWidth(COLUMN_ICON, 20);
ui.participantsList->setColumnCount(COLUMN_COUNT);
ui.participantsList->setColumnWidth(COLUMN_ICON, 20);
ui.participantsList->setColumnHidden(COLUMN_ACTIVITY,true);
ui.participantsList->setColumnHidden(COLUMN_ID,true);
muteAct = new QAction(QIcon(), tr("Mute participant"), this);
connect(muteAct, SIGNAL(triggered()), this, SLOT(changePartipationState()));
distantChatAct = new QAction(QIcon(), tr("Start private chat"), this);
connect(muteAct, SIGNAL(triggered()), this, SLOT(changePartipationState()));
connect(distantChatAct, SIGNAL(triggered()), this, SLOT(distantChatParticipant()));
// Add a button to invite friends.
//
@ -73,6 +80,9 @@ ChatLobbyDialog::ChatLobbyDialog(const ChatLobbyId& lid, QWidget *parent, Qt::Wi
inviteFriendsButton->setAutoRaise(true) ;
inviteFriendsButton->setToolTip(tr("Invite friends to this lobby"));
mParticipantCompareRole = new RSTreeWidgetItemCompareRole;
mParticipantCompareRole->setRole(0, Qt::UserRole);
{
QIcon icon ;
icon.addPixmap(QPixmap(":/images/edit_add24.png")) ;
@ -82,9 +92,19 @@ ChatLobbyDialog::ChatLobbyDialog(const ChatLobbyId& lid, QWidget *parent, Qt::Wi
connect(inviteFriendsButton, SIGNAL(clicked()), this , SLOT(inviteFriends()));
getChatWidget()->addChatBarWidget(inviteFriendsButton) ;
getChatWidget()->addChatBarWidget(inviteFriendsButton) ;
unsubscribeButton = new QToolButton ;
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->setMinimumSize(QSize(28,28)) ;
unsubscribeButton->setMaximumSize(QSize(28,28)) ;
unsubscribeButton->setText(QString()) ;
@ -136,26 +156,34 @@ void ChatLobbyDialog::participantsTreeWidgetCustomPopupMenu(QPoint)
QMenu contextMnu(this);
contextMnu.addAction(muteAct);
contextMnu.addAction(muteAct);
contextMnu.addAction(distantChatAct);
muteAct->setCheckable(true);
muteAct->setEnabled(false);
muteAct->setChecked(false);
if (selectedItems.size()) {
muteAct->setChecked(false);
std::string nickName;
rsMsgs->getNickNameForChatLobby(lobbyId, nickName);
if(selectedItems.count()>1 || (selectedItems.at(0)->text(COLUMN_NAME).toStdString()!=nickName))
if (selectedItems.size())
{
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;
for (item = selectedItems.begin(); item != selectedItems.end(); ++item) {
if (isParticipantMuted((*item)->text(COLUMN_NAME))) {
muteAct->setChecked(true);
break;
}
}
}
QList<QTreeWidgetItem*>::iterator item;
for (item = selectedItems.begin(); item != selectedItems.end(); ++item) {
RsGxsId gxsid ;
if ( dynamic_cast<GxsIdRSTreeWidgetItem*>(*item)->getId(gxsid) && isParticipantMuted(gxsid))
{
muteAct->setChecked(true);
break;
}
}
}
distantChatAct->setEnabled(selectedItems.count()==1 && RsGxsId(selectedItems.front()->text(COLUMN_ID).toStdString())!=nickName) ;
}
contextMnu.exec(QCursor::pos());
@ -163,48 +191,50 @@ void ChatLobbyDialog::participantsTreeWidgetCustomPopupMenu(QPoint)
void ChatLobbyDialog::init()
{
std::list<ChatLobbyInfo> lobbies;
rsMsgs->getChatLobbyList(lobbies);
ChatLobbyInfo linfo ;
QString title;
std::list<ChatLobbyInfo>::const_iterator lobbyIt;
for (lobbyIt = lobbies.begin(); lobbyIt != lobbies.end(); ++lobbyIt) {
if (lobbyIt->lobby_id == lobbyId) {
title = QString::fromUtf8((*lobbyIt).lobby_name.c_str());
QString msg = tr("Welcome to lobby %1").arg(RsHtml::plainText(lobbyIt->lobby_name));
_lobby_name = QString::fromUtf8(lobbyIt->lobby_name.c_str()) ;
if (!lobbyIt->lobby_topic.empty()) {
msg += "\n" + tr("Topic: %1").arg(RsHtml::plainText(lobbyIt->lobby_topic));
}
ui.chatWidget->setWelcomeMessage(msg);
break;
std::list<ChatLobbyInfo>::const_iterator lobbyIt;
if(rsMsgs->getChatLobbyInfo(lobbyId,linfo))
{
title = QString::fromUtf8(linfo.lobby_name.c_str());
QString msg = tr("Welcome to lobby %1").arg(RsHtml::plainText(linfo.lobby_name));
_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);
}
ChatDialog::init(ChatId(lobbyId), title);
std::string nickName;
rsMsgs->getNickNameForChatLobby(lobbyId, nickName);
ui.chatWidget->setName(QString::fromUtf8(nickName.c_str()));
RsGxsId gxs_id;
rsMsgs->getIdentityForChatLobby(lobbyId, gxs_id);
ui.chatWidget->addToolsAction(ui.actionChangeNickname);
ui.chatWidget->setDefaultExtraFileFlags(RS_FILE_REQ_ANONYMOUS_ROUTING);
RsIdentityDetails details ;
rsIdentity->getIdDetails(gxs_id,details) ;
lastUpdateListTime = 0;
ui.chatWidget->setName(QString::fromUtf8(details.mNickname.c_str()));
ui.chatWidget->addToolsAction(ui.actionChangeNickname);
ui.chatWidget->setDefaultExtraFileFlags(RS_FILE_REQ_ANONYMOUS_ROUTING);
lastUpdateListTime = 0;
/* Hide or show the participants frames */
showParticipantsFrame(PeerSettings->getShowParticipantsFrame(ChatId(lobbyId)));
// add to window
// add to window
dynamic_cast<ChatLobbyWidget*>(MainWindow::getPage(MainWindow::ChatLobby))->addChatPage(this) ;
dynamic_cast<ChatLobbyWidget*>(MainWindow::getPage(MainWindow::ChatLobby))->addChatPage(this) ;
/** List of muted Participants */
mutedParticipants = new QStringList;
// load settings
processSettings(true);
/** List of muted Participants */
mutedParticipants.clear() ;
// load settings
processSettings(true);
}
/** Destructor. */
@ -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
*/
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
std::string newNickname;
if (rsMsgs->getNickNameForChatLobby(lobbyId, newNickname)) {
ui.chatWidget->setName(QString::fromUtf8(newNickname.c_str()));
RsGxsId newid;
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()
{
QInputDialog dialog;
dialog.setWindowTitle(tr("Change nick name"));
dialog.setLabelText(tr("Please enter your new nick name"));
RsGxsId current_id;
rsMsgs->getIdentityForChatLobby(lobbyId, current_id);
std::string nickName;
rsMsgs->getNickNameForChatLobby(lobbyId, nickName);
dialog.setTextValue(QString::fromUtf8(nickName.c_str()));
RsGxsId new_id ;
ownIdChooser->getChosenId(new_id) ;
if (dialog.exec() == QDialog::Accepted && !dialog.textValue().isEmpty()) {
setNickname(dialog.textValue());
}
if(!new_id.isNull() && new_id != current_id)
setIdentity(new_id);
}
/**
@ -288,9 +320,17 @@ void ChatLobbyDialog::addChatMsg(const ChatMessage& msg)
QDateTime sendTime = QDateTime::fromTime_t(msg.sendTime);
QDateTime recvTime = QDateTime::fromTime_t(msg.recvTime);
QString message = QString::fromUtf8(msg.msg.c_str());
QString name = QString::fromUtf8(msg.lobby_peer_nickname.c_str());
RsGxsId gxs_id = msg.lobby_peer_gxs_id ;
if(!isParticipantMuted(name)) {
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()) + ")" ;
ui.chatWidget->addChatMsg(msg.incoming, name, sendTime, recvTime, message, ChatWidget::MSGTYPE_NORMAL);
emit messageReceived(id()) ;
}
@ -298,7 +338,7 @@ void ChatLobbyDialog::addChatMsg(const ChatMessage& msg)
// This is a trick to translate HTML into text.
QTextEdit editor;
editor.setHtml(message);
QString notifyMsg = name + ": " + editor.toPlainText();
QString notifyMsg = QString::fromStdString(gxs_id.toStdString()) + ": " + editor.toPlainText();
if(notifyMsg.length() > 30)
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);
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 (now > lastUpdateListTime) {
@ -325,76 +365,74 @@ void ChatLobbyDialog::addChatMsg(const ChatMessage& msg)
*/
void ChatLobbyDialog::updateParticipantsList()
{
std::list<ChatLobbyInfo> lInfos;
rsMsgs->getChatLobbyList(lInfos);
ChatLobbyInfo linfo;
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
for (; it!=lInfos.end() && (*it).lobby_id != lobbyId; ++it) ;
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())
foreach(QTreeWidgetItem *qtwiCur,qlOldParticipants)
if(cliInfo.gxs_ids.find(RsGxsId((*qtwiCur).text(COLUMN_ID).toStdString())) == cliInfo.gxs_ids.end())
{
//Old Participant go out, remove it
int index = ui.participantsList->indexOfTopLevelItem(qtwiCur);
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() );
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() );
QList<QTreeWidgetItem*> qlFoundParticipants=ui.participantsList->findItems(participant,Qt::MatchExactly,COLUMN_NAME);
QTreeWidgetItem *widgetitem;
QList<QTreeWidgetItem*> qlFoundParticipants=ui.participantsList->findItems(participant,Qt::MatchExactly,COLUMN_ID);
GxsIdRSTreeWidgetItem *widgetitem;
if (qlFoundParticipants.count()==0)
{
// 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);}
// TE: Add Wigdet to participantsList with Checkbox, to mute Participant
if (isParticipantMuted(participant)) {
widgetitem->setIcon(COLUMN_ICON, QIcon(":/images/redled.png"));
widgetitem = new GxsIdRSTreeWidgetItem(mParticipantCompareRole);
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));
} else {
widgetitem->setIcon(COLUMN_ICON, QIcon(":/images/greenled.png"));
} else {
widgetitem->setTextColor(COLUMN_NAME,ui.participantsList->palette().color(QPalette::Active, QPalette::Text));
}
}
time_t tLastAct=widgetitem->text(COLUMN_ACTIVITY).toInt();
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;
rsMsgs->getNickNameForChatLobby(lobbyId, nickName);
if (participant.toStdString()==nickName) widgetitem->setIcon(COLUMN_ICON, QIcon(":/images/yellowled.png"));
if(isParticipantMuted(it2->first))
widgetitem->setIcon(COLUMN_ICON, QIcon(":/images/ledoff1.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);
widgetitem->setToolTip(COLUMN_NAME,tr("Right click to mute/unmute participants<br/>Double click to address this person<br/>")
+tr("This participant is not active since:")
+qtLastAct.toString()
+tr(" seconds")
);
}
}
ui.participantsList->setSortingEnabled(true);
ui.participantsList->sortItems(COLUMN_NAME, Qt::AscendingOrder);
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:")
+qtLastAct.toString()
+tr(" seconds")
);
}
}
ui.participantsList->setSortingEnabled(true);
ui.participantsList->sortItems(COLUMN_NAME, Qt::AscendingOrder);
}
/**
@ -408,26 +446,27 @@ void ChatLobbyDialog::updateParticipantsList()
*/
void ChatLobbyDialog::changePartipationState()
{
QList<QTreeWidgetItem*> selectedItems = ui.participantsList->selectedItems();
QList<QTreeWidgetItem*> selectedItems = ui.participantsList->selectedItems();
if (selectedItems.isEmpty()) {
return;
}
QList<QTreeWidgetItem*>::iterator item;
for (item = selectedItems.begin(); item != selectedItems.end(); ++item) {
QString nickname = (*item)->text(COLUMN_NAME);
for (item = selectedItems.begin(); item != selectedItems.end(); ++item) {
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()) {
muteParticipant(nickname);
muteParticipant(gxs_id);
} else {
unMuteParticipant(nickname);
unMuteParticipant(gxs_id);
}
}
mutedParticipants->removeDuplicates();
updateParticipantsList();
}
@ -459,41 +498,77 @@ void ChatLobbyDialog::participantsTreeWidgetDoubleClicked(QTreeWidgetItem *item,
// updateParticipantsList();
}
void ChatLobbyDialog::muteParticipant(const QString &nickname) {
std::cerr << " Mute " << std::endl;
std::string myNickName;
rsMsgs->getNickNameForChatLobby(lobbyId, myNickName);
if (nickname.toStdString()!=myNickName)
mutedParticipants->append(nickname);
void ChatLobbyDialog::distantChatParticipant()
{
std::cerr << " initiating distant chat" << std::endl;
QList<QTreeWidgetItem*> selectedItems = ui.participantsList->selectedItems();
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) {
std::cerr << " UnMute " << std::endl;
mutedParticipants->removeAll(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;
mutedParticipants.erase(id);
}
/**
* 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;
rsMsgs->getChatLobbyList(linfos);
if(! rsMsgs->getChatLobbyInfo(lobbyId,clinfo))
return false ;
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 clinfo.gxs_ids.find(nickname) != clinfo.gxs_ids.end() ;
}
/**
@ -507,56 +582,88 @@ bool ChatLobbyDialog::isNicknameInLobby(const QString &nickname) {
*
* @param QString nickname to check
*/
bool ChatLobbyDialog::isParticipantMuted(const QString &participant)
bool ChatLobbyDialog::isParticipantMuted(const RsGxsId& participant)
{
// 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
{
QString qsParticipant="";
switch (event_type) {
case RS_CHAT_LOBBY_EVENT_PEER_LEFT:
qsParticipant=str;
ui.chatWidget->addChatMsg(true, tr("Lobby management"), QDateTime::currentDateTime(), QDateTime::currentDateTime(), tr("%1 has left the lobby.").arg(RsHtml::plainText(str)), ChatWidget::MSGTYPE_SYSTEM);
emit peerLeft(id()) ;
break;
case RS_CHAT_LOBBY_EVENT_PEER_JOINED:
qsParticipant=str;
ui.chatWidget->addChatMsg(true, tr("Lobby management"), QDateTime::currentDateTime(), QDateTime::currentDateTime(), tr("%1 joined the lobby.").arg(RsHtml::plainText(str)), ChatWidget::MSGTYPE_SYSTEM);
emit peerJoined(id()) ;
break;
case RS_CHAT_LOBBY_EVENT_PEER_STATUS:
qsParticipant=nickname;
ui.chatWidget->updateStatusString(RsHtml::plainText(nickname) + " %1", RsHtml::plainText(str));
if (!isParticipantMuted(nickname)) {
emit typingEventReceived(id()) ;
}
break;
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);
// 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)) {
muteParticipant(str);
}
break;
case RS_CHAT_LOBBY_EVENT_KEEP_ALIVE:
//std::cerr << "Received keep alive packet from " << nickname.toStdString() << " in lobby " << getPeerId() << std::endl;
break;
default:
std::cerr << "ChatLobbyDialog::displayLobbyEvent() Unhandled lobby event type " << event_type << std::endl;
}
RsIdentityDetails details ;
if (qsParticipant!=""){
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)));
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)
{
case RS_CHAT_LOBBY_EVENT_PEER_LEFT:
qsParticipant=gxs_id;
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()) ;
break;
case RS_CHAT_LOBBY_EVENT_PEER_JOINED:
qsParticipant=gxs_id;
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()) ;
break;
case RS_CHAT_LOBBY_EVENT_PEER_STATUS:
{
qsParticipant=gxs_id;
ui.chatWidget->updateStatusString(RsHtml::plainText(name) + " %1", RsHtml::plainText(str));
if (!isParticipantMuted(gxs_id))
emit typingEventReceived(id()) ;
}
break;
case RS_CHAT_LOBBY_EVENT_PEER_CHANGE_NICKNAME:
{
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
if (isParticipantMuted(gxs_id))
muteParticipant(RsGxsId(str.toStdString())) ;
}
break;
case RS_CHAT_LOBBY_EVENT_KEEP_ALIVE:
//std::cerr << "Received keep alive packet from " << nickname.toStdString() << " in lobby " << getPeerId() << std::endl;
break;
default:
std::cerr << "ChatLobbyDialog::displayLobbyEvent() Unhandled lobby event type " << event_type << std::endl;
}
updateParticipantsList() ;
if (!qsParticipant.isNull())
{
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() ;
}
bool ChatLobbyDialog::canClose()

View File

@ -24,8 +24,10 @@
#define _CHATLOBBYDIALOG_H
#include "ui_ChatLobbyDialog.h"
#include "gui/common/RSTreeWidgetItem.h"
#include "ChatDialog.h"
class GxsIdChooser ;
class QToolButton;
class ChatLobbyDialog: public ChatDialog
@ -35,14 +37,14 @@ class ChatLobbyDialog: public ChatDialog
friend class ChatDialog;
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 ChatWidget *getChatWidget();
virtual bool hasPeerStatus() { return false; }
virtual bool notifyBlink();
void setNickname(const QString &nickname);
bool isParticipantMuted(const QString &participant);
void setIdentity(const RsGxsId& gxs_id);
bool isParticipantMuted(const RsGxsId &participant);
ChatLobbyId id() const { return lobbyId ;}
private slots:
@ -71,31 +73,38 @@ protected:
virtual void addChatMsg(const ChatMessage &msg);
protected slots:
void changeNickname();
void changeNickname();
void changePartipationState();
void participantsTreeWidgetDoubleClicked(QTreeWidgetItem *item, int column);
void distantChatParticipant();
void participantsTreeWidgetDoubleClicked(QTreeWidgetItem *item, int column);
private:
void updateParticipantsList();
void muteParticipant(const QString &nickname);
void unMuteParticipant(const QString &nickname);
bool isNicknameInLobby(const QString &nickname);
QString getParticipantName(const RsGxsId& id) const;
void muteParticipant(const RsGxsId& id);
void unMuteParticipant(const RsGxsId& id);
bool isNicknameInLobby(const RsGxsId& id);
ChatLobbyId lobbyId;
QString _lobby_name ;
time_t lastUpdateListTime;
QToolButton *inviteFriendsButton ;
RSTreeWidgetItemCompareRole *mParticipantCompareRole ;
QToolButton *inviteFriendsButton ;
QToolButton *unsubscribeButton ;
/** Qt Designer generated object */
Ui::ChatLobbyDialog ui;
/** 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 *distantChatAct;
GxsIdChooser *ownIdChooser ;
};
#endif

View File

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

View File

@ -31,6 +31,7 @@
#include "gui/common/PeerDefs.h"
#include "ChatDialog.h"
#include "gui/ChatLobbyWidget.h"
CreateLobbyDialog::CreateLobbyDialog(const std::list<RsPeerId>& peer_list, int privacyLevel, QWidget *parent) :
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->setHeaderText(tr("Create Chat Lobby"));
std::string default_nick ;
rsMsgs->getDefaultNickNameForChatLobby(default_nick) ;
RsGxsId default_identity ;
rsMsgs->getDefaultIdentityForChatLobby(default_identity) ;
#if QT_VERSION >= 0x040700
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)")) ;
#endif
ui->nickName_LE->setText(QString::fromUtf8(default_nick.c_str())) ;
ui->idChooser_CB->loadIds(IDCHOOSER_ID_REQUIRED, default_identity);
//#if QT_VERSION >= 0x040700
// 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)")) ;
//#endif
// ui->nickName_LE->setText(QString::fromUtf8(default_nick.c_str())) ;
connect( ui->buttonBox, SIGNAL(accepted()), this, SLOT(createLobby()));
connect( ui->buttonBox, SIGNAL(rejected()), this, SLOT(close()));
connect( ui->lobbyName_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 */
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);
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();
@ -91,10 +94,17 @@ void CreateLobbyDialog::changeEvent(QEvent *e)
void CreateLobbyDialog::checkTextFields()
{
if(ui->lobbyName_LE->text() == "" || ui->nickName_LE->text() == "")
ui->buttonBox->button(QDialogButtonBox::Ok)->setEnabled(false) ;
else
ui->buttonBox->button(QDialogButtonBox::Ok)->setEnabled(true) ;
RsGxsId id ;
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) ;
break ;
}
}
void CreateLobbyDialog::createLobby()
@ -102,29 +112,36 @@ void CreateLobbyDialog::createLobby()
std::list<RsPeerId> shareList;
ui->keyShareList->selectedIds<RsPeerId,FriendSelectionWidget::IDTYPE_SSL>(shareList, false);
// if (shareList.empty()) {
// QMessageBox::warning(this, "RetroShare", tr("Please select at least one friend"), QMessageBox::Ok, QMessageBox::Ok);
// return;
// }
// if (shareList.empty()) {
// QMessageBox::warning(this, "RetroShare", tr("Please select at least one friend"), QMessageBox::Ok, QMessageBox::Ok);
// return;
// }
// create chat lobby !!
std::string lobby_name = ui->lobbyName_LE->text().toUtf8().constData() ;
std::string lobby_topic = ui->lobbyTopic_LE->text().toUtf8().constData() ;
// create chat lobby !!
std::string lobby_name = ui->lobbyName_LE->text().toUtf8().constData() ;
std::string lobby_topic = ui->lobbyTopic_LE->text().toUtf8().constData() ;
// add to group
// set nick name !
RsGxsId gxs_id ;
switch(ui->idChooser_CB->getChosenId(gxs_id))
{
case GxsIdChooser::NoId:
case GxsIdChooser::None:
return ;
}
// 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 ;
std::cerr << "gui: Created chat lobby " << std::hex << id << std::endl ;
ChatLobbyId id = rsMsgs->createChatLobby(lobby_name,gxs_id, lobby_topic, shareList, lobby_flags);
// set nick name !
std::cerr << "gui: Created chat lobby " << std::hex << id << std::endl ;
rsMsgs->setNickNameForChatLobby(id,ui->nickName_LE->text().toUtf8().constData()) ;
// open chat window !!
// open chat window !!
ChatDialog::chatFriend(ChatId(id)) ;
close();
close();
}

View File

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

View File

@ -122,6 +122,10 @@ static void loadPrivateIdsCallback(GxsIdDetailsType type, const RsIdentityDetail
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 id = QString::fromStdString(details.mId.toStdString());
@ -156,7 +160,9 @@ static void loadPrivateIdsCallback(GxsIdDetailsType type, const RsIdentityDetail
chooser->setItemData(index, (type == GXS_ID_DETAILS_TYPE_DONE) ? TYPE_FOUND_ID : TYPE_UNKNOWN_ID, ROLE_TYPE);
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)

View File

@ -892,10 +892,10 @@ void NotifyQt::UpdateGUI()
break;
}
ChatLobbyDialog *chatLobbyDialog = dynamic_cast<ChatLobbyDialog*>(chatDialog);
if (!chatLobbyDialog || chatLobbyDialog->isParticipantMuted(QString::fromUtf8(title.c_str()))) {
// participant is muted
break;
}
if (!chatLobbyDialog || chatLobbyDialog->isParticipantMuted(RsGxsId(title)))
break; // participant is muted
toaster = new Toaster(new ChatLobbyToaster(lobby_id, QString::fromUtf8(title.c_str()), QString::fromUtf8(msg.c_str())));
}
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_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;
QListWidgetItem *item = ui.publicList->currentItem();
@ -260,9 +269,11 @@ ChatPage::load()
privateStylePath = loadStyleInfo(ChatStyle::TYPE_PRIVATE, ui.privateList, ui.privateComboBoxVariant, privateStyleVariant);
historyStylePath = loadStyleInfo(ChatStyle::TYPE_HISTORY, ui.historyList, ui.historyComboBoxVariant, historyStyleVariant);
std::string nick ;
rsMsgs->getDefaultNickNameForChatLobby(nick) ;
ui.chatLobbyNick_LE->setText(QString::fromUtf8(nick.c_str())) ;
RsGxsId gxs_id ;
rsMsgs->getDefaultIdentityForChatLobby(gxs_id) ;
ui.chatLobbyIdentity_IC->loadIds(IDCHOOSER_ID_REQUIRED, gxs_id);
ui.chatLobbyIdentity_IC->setChosenId(gxs_id);
uint chatflags = Settings->getChatFlags();

View File

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

View File

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