mirror of
https://github.com/RetroShare/RetroShare.git
synced 2025-06-05 21:29:23 -04:00
- started changing distant chat so that it works with GXS ids instead of PGP ids. Something is still broken in
service control. Crypto is not done yet => distant chat is unencrypted. - changed GUI for distant chat. Removed invitation system. - added menu item to distant chat GXS ids from IdentityItem (only entry point for now). - fixed bug in chat lobbies causing re-connexion of lobbies not to happen everytime (bug reported bu Lain) git-svn-id: http://svn.code.sf.net/p/retroshare/code/trunk@7378 b45a01b8-16f6-495d-af2f-9b41ad6348cc
This commit is contained in:
parent
d18878aa9c
commit
b6c68d1812
22 changed files with 340 additions and 762 deletions
|
@ -44,7 +44,6 @@ static std::list<RsPeerId> waitingIds;
|
||||||
/****
|
/****
|
||||||
*#define PGRP_DEBUG 1
|
*#define PGRP_DEBUG 1
|
||||||
****/
|
****/
|
||||||
#define PGRP_DEBUG 1
|
|
||||||
|
|
||||||
#define DEFAULT_DOWNLOAD_KB_RATE (200.0)
|
#define DEFAULT_DOWNLOAD_KB_RATE (200.0)
|
||||||
#define DEFAULT_UPLOAD_KB_RATE (50.0)
|
#define DEFAULT_UPLOAD_KB_RATE (50.0)
|
||||||
|
|
|
@ -356,13 +356,9 @@ virtual ChatLobbyId createChatLobby(const std::string& lobby_name,const std::str
|
||||||
/* Distant chat */
|
/* Distant chat */
|
||||||
/****************************************/
|
/****************************************/
|
||||||
|
|
||||||
virtual bool createDistantChatInvite(const RsPgpId& pgp_id,time_t time_of_validity,std::string& encrypted_string) = 0 ;
|
virtual bool initiateDistantChatConnexion(const RsGxsId& pid,DistantChatPeerId& id,uint32_t& error_code) = 0;
|
||||||
virtual bool getDistantChatInviteList(std::vector<DistantChatInviteInfo>& invites) = 0;
|
virtual bool getDistantChatStatus(const DistantChatPeerId& pid,RsGxsId& gxs_id,uint32_t& status) = 0;
|
||||||
virtual bool initiateDistantChatConnexion(const std::string& encrypted_string,time_t validity_time,DistantChatPeerId& pid,uint32_t& error_code) = 0;
|
|
||||||
virtual bool initiateDistantChatConnexion(const DistantChatPeerId& pid,uint32_t& error_code) = 0;
|
|
||||||
virtual bool getDistantChatStatus(const DistantChatPeerId& pid,uint32_t& status,RsPgpId& pgp_id) = 0;
|
|
||||||
virtual bool closeDistantChatConnexion(const DistantChatPeerId& pid) = 0;
|
virtual bool closeDistantChatConnexion(const DistantChatPeerId& pid) = 0;
|
||||||
virtual bool removeDistantChatInvite(const DistantChatPeerId& pid) = 0 ;
|
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -359,32 +359,16 @@ void p3Msgs::getPendingChatLobbyInvites(std::list<ChatLobbyInvite>& invites)
|
||||||
{
|
{
|
||||||
mChatSrv->getPendingChatLobbyInvites(invites) ;
|
mChatSrv->getPendingChatLobbyInvites(invites) ;
|
||||||
}
|
}
|
||||||
bool p3Msgs::createDistantChatInvite(const RsPgpId& pgp_id,time_t time_of_validity,std::string& encrypted_string)
|
bool p3Msgs::initiateDistantChatConnexion(const RsGxsId& gxs_id,DistantChatPeerId& pid,uint32_t& error_code)
|
||||||
{
|
{
|
||||||
return mChatSrv->createDistantChatInvite(pgp_id,time_of_validity,encrypted_string) ;
|
return mChatSrv->initiateDistantChatConnexion(gxs_id,pid,error_code) ;
|
||||||
}
|
}
|
||||||
bool p3Msgs::getDistantChatInviteList(std::vector<DistantChatInviteInfo>& invites)
|
bool p3Msgs::getDistantChatStatus(const DistantChatPeerId& pid,RsGxsId& gxs_id,uint32_t& status)
|
||||||
{
|
{
|
||||||
return mChatSrv->getDistantChatInviteList(invites) ;
|
return mChatSrv->getDistantChatStatus(pid,gxs_id,status) ;
|
||||||
}
|
|
||||||
bool p3Msgs::initiateDistantChatConnexion(const std::string& encrypted_str,time_t validity_time,DistantChatPeerId& pid,uint32_t& error_code)
|
|
||||||
{
|
|
||||||
return mChatSrv->initiateDistantChatConnexion(encrypted_str,validity_time,pid,error_code) ;
|
|
||||||
}
|
|
||||||
bool p3Msgs::initiateDistantChatConnexion(const DistantChatPeerId& pid,uint32_t& error_code)
|
|
||||||
{
|
|
||||||
return mChatSrv->initiateDistantChatConnexion(pid,error_code) ;
|
|
||||||
}
|
|
||||||
bool p3Msgs::getDistantChatStatus(const DistantChatPeerId& pid,uint32_t& status,RsPgpId& pgp_id)
|
|
||||||
{
|
|
||||||
return mChatSrv->getDistantChatStatus(pid,status,pgp_id) ;
|
|
||||||
}
|
}
|
||||||
bool p3Msgs::closeDistantChatConnexion(const DistantChatPeerId& pid)
|
bool p3Msgs::closeDistantChatConnexion(const DistantChatPeerId& pid)
|
||||||
{
|
{
|
||||||
return mChatSrv->closeDistantChatConnexion(pid) ;
|
return mChatSrv->closeDistantChatConnexion(pid) ;
|
||||||
}
|
}
|
||||||
bool p3Msgs::removeDistantChatInvite(const DistantChatPeerId& pid)
|
|
||||||
{
|
|
||||||
return mChatSrv->removeDistantChatInvite(pid) ;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
|
@ -191,13 +191,9 @@ class p3Msgs: public RsMsgs
|
||||||
virtual bool getLobbyAutoSubscribe(const ChatLobbyId& lobby_id);
|
virtual bool getLobbyAutoSubscribe(const ChatLobbyId& lobby_id);
|
||||||
virtual ChatLobbyId createChatLobby(const std::string& lobby_name,const std::string& lobby_topic,const std::list<RsPeerId>& invited_friends,uint32_t privacy_type) ;
|
virtual ChatLobbyId createChatLobby(const std::string& lobby_name,const std::string& lobby_topic,const std::list<RsPeerId>& invited_friends,uint32_t privacy_type) ;
|
||||||
|
|
||||||
virtual bool createDistantChatInvite(const RsPgpId& pgp_id,time_t time_of_validity,std::string& encrypted_string) ;
|
virtual bool initiateDistantChatConnexion(const RsGxsId& gxs_id,DistantChatPeerId& pid,uint32_t& error_code) ;
|
||||||
virtual bool getDistantChatInviteList(std::vector<DistantChatInviteInfo>& invites);
|
virtual bool getDistantChatStatus(const DistantChatPeerId& pid,RsGxsId& gxs_id,uint32_t& status) ;
|
||||||
virtual bool initiateDistantChatConnexion(const std::string& encrypted_string,time_t validity_time,DistantChatPeerId& pid,uint32_t& error_code) ;
|
|
||||||
virtual bool initiateDistantChatConnexion(const DistantChatPeerId& pid,uint32_t& error_code) ;
|
|
||||||
virtual bool getDistantChatStatus(const DistantChatPeerId& pid,uint32_t& status,RsPgpId& pgp_id) ;
|
|
||||||
virtual bool closeDistantChatConnexion(const DistantChatPeerId& pid) ;
|
virtual bool closeDistantChatConnexion(const DistantChatPeerId& pid) ;
|
||||||
virtual bool removeDistantChatInvite(const DistantChatPeerId& pid) ;
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
|
|
|
@ -37,6 +37,7 @@
|
||||||
#include "retroshare/rsiface.h"
|
#include "retroshare/rsiface.h"
|
||||||
#include "retroshare/rspeers.h"
|
#include "retroshare/rspeers.h"
|
||||||
#include "retroshare/rsstatus.h"
|
#include "retroshare/rsstatus.h"
|
||||||
|
#include "retroshare/rsidentity.h"
|
||||||
#include "pqi/pqibin.h"
|
#include "pqi/pqibin.h"
|
||||||
#include "pqi/pqistore.h"
|
#include "pqi/pqistore.h"
|
||||||
#include "pqi/p3linkmgr.h"
|
#include "pqi/p3linkmgr.h"
|
||||||
|
@ -50,6 +51,7 @@
|
||||||
* #define CHAT_DEBUG 1
|
* #define CHAT_DEBUG 1
|
||||||
* #define DEBUG_DISTANT_CHAT 1
|
* #define DEBUG_DISTANT_CHAT 1
|
||||||
****/
|
****/
|
||||||
|
#define DEBUG_DISTANT_CHAT 1
|
||||||
|
|
||||||
static const int CONNECTION_CHALLENGE_MAX_COUNT = 20 ; // sends a connection challenge every 20 messages
|
static const int CONNECTION_CHALLENGE_MAX_COUNT = 20 ; // sends a connection challenge every 20 messages
|
||||||
static const time_t CONNECTION_CHALLENGE_MAX_MSG_AGE = 30 ; // maximum age of a message to be used in a connection challenge
|
static const time_t CONNECTION_CHALLENGE_MAX_MSG_AGE = 30 ; // maximum age of a message to be used in a connection challenge
|
||||||
|
@ -120,7 +122,6 @@ int p3ChatService::tick()
|
||||||
receiveChatQueue();
|
receiveChatQueue();
|
||||||
|
|
||||||
static time_t last_clean_time_lobby = 0 ;
|
static time_t last_clean_time_lobby = 0 ;
|
||||||
static time_t last_clean_time_dchat = 0 ;
|
|
||||||
static time_t last_req_chat_lobby_list = 0 ;
|
static time_t last_req_chat_lobby_list = 0 ;
|
||||||
|
|
||||||
time_t now = time(NULL) ;
|
time_t now = time(NULL) ;
|
||||||
|
@ -130,15 +131,8 @@ int p3ChatService::tick()
|
||||||
cleanLobbyCaches() ;
|
cleanLobbyCaches() ;
|
||||||
last_clean_time_lobby = now ;
|
last_clean_time_lobby = now ;
|
||||||
}
|
}
|
||||||
if(last_clean_time_dchat + DISTANT_CHAT_CLEANING_PERIOD < now)
|
|
||||||
{
|
|
||||||
cleanDistantChatInvites() ;
|
|
||||||
last_clean_time_dchat = now ;
|
|
||||||
}
|
|
||||||
if(last_req_chat_lobby_list + LOBBY_LIST_AUTO_UPDATE_TIME < now)
|
if(last_req_chat_lobby_list + LOBBY_LIST_AUTO_UPDATE_TIME < now)
|
||||||
{
|
{
|
||||||
cleanDistantChatInvites() ;
|
|
||||||
|
|
||||||
std::vector<VisibleChatLobbyRecord> visible_lobbies_tmp ;
|
std::vector<VisibleChatLobbyRecord> visible_lobbies_tmp ;
|
||||||
getListOfNearbyChatLobbies(visible_lobbies_tmp) ;
|
getListOfNearbyChatLobbies(visible_lobbies_tmp) ;
|
||||||
|
|
||||||
|
@ -301,26 +295,39 @@ void p3ChatService::sendStatusString( const RsPeerId& id , const std::string& st
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void p3ChatService::sendPrivateChatItem(RsChatItem *item)
|
bool p3ChatService::getHashFromVirtualPeerId(const TurtleVirtualPeerId& vpid,TurtleFileHash& hash)
|
||||||
{
|
|
||||||
bool found = false ;
|
|
||||||
|
|
||||||
{
|
{
|
||||||
RsStackMutex stack(mChatMtx); /********** STACK LOCKED MTX ******/
|
RsStackMutex stack(mChatMtx); /********** STACK LOCKED MTX ******/
|
||||||
|
|
||||||
for(std::map<TurtleFileHash,DistantChatPeerInfo>::const_iterator it=_distant_chat_peers.begin();it!=_distant_chat_peers.end();++it)
|
for(std::map<TurtleFileHash,DistantChatPeerInfo>::const_iterator it=_distant_chat_peers.begin();it!=_distant_chat_peers.end();++it)
|
||||||
if( it->second.virtual_peer_id == item->PeerId()) // _distant_chat_peers.find(item->PeerId()) !=_distant_chat_peers.end())
|
if( it->second.virtual_peer_id == vpid)
|
||||||
{
|
{
|
||||||
found = true ;
|
hash = it->first ;
|
||||||
break ;
|
return true ;
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if(found)
|
return false ;
|
||||||
|
}
|
||||||
|
|
||||||
|
void p3ChatService::sendPrivateChatItem(RsChatItem *item)
|
||||||
|
{
|
||||||
|
TurtleFileHash hash ;
|
||||||
|
|
||||||
|
if(getHashFromVirtualPeerId(item->PeerId(),hash)) // the hash is not used here. That can be optimized.
|
||||||
|
{
|
||||||
|
#ifdef CHAT_DEBUG
|
||||||
|
std::cerr << "p3ChatService::sendPrivateChatItem(): sending to " << item->PeerId() << ": interpreted as a distant chat virtual peer id." << std::endl;
|
||||||
|
#endif
|
||||||
sendTurtleData(item) ;
|
sendTurtleData(item) ;
|
||||||
|
}
|
||||||
else
|
else
|
||||||
|
{
|
||||||
|
#ifdef CHAT_DEBUG
|
||||||
|
std::cerr << "p3ChatService::sendPrivateChatItem(): sending to " << item->PeerId() << ": interpreted as friend peer id." << std::endl;
|
||||||
|
#endif
|
||||||
sendItem(item) ;
|
sendItem(item) ;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void p3ChatService::checkSizeAndSendMessage_deprecated(RsChatMsgItem *msg)
|
void p3ChatService::checkSizeAndSendMessage_deprecated(RsChatMsgItem *msg)
|
||||||
{
|
{
|
||||||
|
@ -481,10 +488,10 @@ bool p3ChatService::isOnline(const DistantChatPeerId& pid)
|
||||||
// check if the id is a tunnel id or a peer id.
|
// check if the id is a tunnel id or a peer id.
|
||||||
|
|
||||||
uint32_t status ;
|
uint32_t status ;
|
||||||
RsPgpId pgp_id ;
|
RsGxsId gxs_id ;
|
||||||
|
|
||||||
std::string hash ;
|
std::string hash ;
|
||||||
if(getDistantChatStatus(pid,status,pgp_id))
|
if(getDistantChatStatus(pid,gxs_id,status))
|
||||||
return true ;
|
return true ;
|
||||||
else
|
else
|
||||||
return mServiceCtrl->isPeerConnected(getServiceInfo().mServiceType, pid);
|
return mServiceCtrl->isPeerConnected(getServiceInfo().mServiceType, pid);
|
||||||
|
@ -900,7 +907,11 @@ void p3ChatService::handleRecvChatLobbyList(RsChatLobbyListItem *item)
|
||||||
std::cerr << "Warning: Peer " << item->PeerId() << "(" << rsPeers->getPeerName(item->PeerId()) << ") is sending a lobby list of " << item->lobby_ids.size() << " lobbies. This is unusual, and probably a attempt to crash you." << std::endl;
|
std::cerr << "Warning: Peer " << item->PeerId() << "(" << rsPeers->getPeerName(item->PeerId()) << ") is sending a lobby list of " << item->lobby_ids.size() << " lobbies. This is unusual, and probably a attempt to crash you." << std::endl;
|
||||||
|
|
||||||
std::list<ChatLobbyId> chatLobbyToSubscribe;
|
std::list<ChatLobbyId> chatLobbyToSubscribe;
|
||||||
|
std::list<ChatLobbyId> invitationNeeded ;
|
||||||
|
|
||||||
|
#ifdef CHAT_DEBUG
|
||||||
|
std::cerr << "Received chat lobby list from friend " << item->PeerId() << ", " << item->lobby_ids.size() << " elements." << std::endl;
|
||||||
|
#endif
|
||||||
{
|
{
|
||||||
time_t now = time(NULL) ;
|
time_t now = time(NULL) ;
|
||||||
|
|
||||||
|
@ -925,11 +936,30 @@ void p3ChatService::handleRecvChatLobbyList(RsChatLobbyListItem *item)
|
||||||
|
|
||||||
std::map<ChatLobbyId,ChatLobbyFlags>::const_iterator it(_known_lobbies_flags.find(item->lobby_ids[i])) ;
|
std::map<ChatLobbyId,ChatLobbyFlags>::const_iterator it(_known_lobbies_flags.find(item->lobby_ids[i])) ;
|
||||||
|
|
||||||
|
#ifdef CHAT_DEBUG
|
||||||
|
std::cerr << " lobby id " << std::hex << item->lobby_ids[i] << std::dec << ", " << item->lobby_names[i] << ", " << item->lobby_counts[i] << " participants" << std::endl;
|
||||||
|
#endif
|
||||||
if(it != _known_lobbies_flags.end() && (it->second & RS_CHAT_LOBBY_FLAGS_AUTO_SUBSCRIBE))
|
if(it != _known_lobbies_flags.end() && (it->second & RS_CHAT_LOBBY_FLAGS_AUTO_SUBSCRIBE))
|
||||||
{
|
{
|
||||||
|
#ifdef CHAT_DEBUG
|
||||||
|
std::cerr << " lobby is flagged as autosubscribed. Adding it to subscribe list." << std::endl;
|
||||||
|
#endif
|
||||||
ChatLobbyId clid = item->lobby_ids[i];
|
ChatLobbyId clid = item->lobby_ids[i];
|
||||||
chatLobbyToSubscribe.push_back(clid);
|
chatLobbyToSubscribe.push_back(clid);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// for subscribed lobbies, check that item->PeerId() is among the participating friends. If not, add him!
|
||||||
|
|
||||||
|
std::map<ChatLobbyId,ChatLobbyEntry>::iterator it2 = _chat_lobbys.find(item->lobby_ids[i]) ;
|
||||||
|
|
||||||
|
if(it2 != _chat_lobbys.end() && it2->second.participating_friends.find(item->PeerId()) == it2->second.participating_friends.end())
|
||||||
|
{
|
||||||
|
#ifdef CHAT_DEBUG
|
||||||
|
std::cerr << " lobby is currently subscribed but friend is not participating already -> adding to partipating friends and sending invite." << std::endl;
|
||||||
|
#endif
|
||||||
|
it2->second.participating_friends.insert(item->PeerId()) ;
|
||||||
|
invitationNeeded.push_back(item->lobby_ids[i]) ;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -937,6 +967,9 @@ void p3ChatService::handleRecvChatLobbyList(RsChatLobbyListItem *item)
|
||||||
for (it = chatLobbyToSubscribe.begin(); it != chatLobbyToSubscribe.end(); it++)
|
for (it = chatLobbyToSubscribe.begin(); it != chatLobbyToSubscribe.end(); it++)
|
||||||
joinVisibleChatLobby(*it);
|
joinVisibleChatLobby(*it);
|
||||||
|
|
||||||
|
for(std::list<ChatLobbyId>::const_iterator it = invitationNeeded.begin();it!=invitationNeeded.end();++it)
|
||||||
|
invitePeerToLobby(*it,item->PeerId(),false) ;
|
||||||
|
|
||||||
RsServer::notify()->notifyListChange(NOTIFY_LIST_CHAT_LOBBY_LIST, NOTIFY_TYPE_ADD) ;
|
RsServer::notify()->notifyListChange(NOTIFY_LIST_CHAT_LOBBY_LIST, NOTIFY_TYPE_ADD) ;
|
||||||
_should_reset_lobby_counts = false ;
|
_should_reset_lobby_counts = false ;
|
||||||
}
|
}
|
||||||
|
@ -1931,25 +1964,6 @@ bool p3ChatService::loadList(std::list<RsItem*>& load)
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
RsPrivateChatDistantInviteConfigItem *ditem = NULL ;
|
|
||||||
|
|
||||||
if(NULL != (ditem = dynamic_cast<RsPrivateChatDistantInviteConfigItem *>(*it)))
|
|
||||||
{
|
|
||||||
DistantChatInvite invite ;
|
|
||||||
|
|
||||||
memcpy(invite.aes_key,ditem->aes_key,DISTANT_CHAT_AES_KEY_SIZE) ;
|
|
||||||
invite.encrypted_radix64_string = ditem->encrypted_radix64_string ;
|
|
||||||
invite.destination_pgp_id = ditem->destination_pgp_id ;
|
|
||||||
invite.time_of_validity = ditem->time_of_validity ;
|
|
||||||
invite.last_hit_time = ditem->last_hit_time ;
|
|
||||||
invite.flags = ditem->flags ;
|
|
||||||
|
|
||||||
_distant_chat_invites[ditem->hash] = invite ;
|
|
||||||
|
|
||||||
delete *it ;
|
|
||||||
continue ;
|
|
||||||
}
|
|
||||||
|
|
||||||
RsConfigKeyValueSet *vitem = NULL ;
|
RsConfigKeyValueSet *vitem = NULL ;
|
||||||
|
|
||||||
if(NULL != (vitem = dynamic_cast<RsConfigKeyValueSet*>(*it)))
|
if(NULL != (vitem = dynamic_cast<RsConfigKeyValueSet*>(*it)))
|
||||||
|
@ -2018,22 +2032,6 @@ bool p3ChatService::saveList(bool& cleanup, std::list<RsItem*>& list)
|
||||||
list.push_back(ci);
|
list.push_back(ci);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* save ongoing distant chat invites */
|
|
||||||
|
|
||||||
for(std::map<TurtleFileHash,DistantChatInvite>::const_iterator it(_distant_chat_invites.begin());it!=_distant_chat_invites.end();++it)
|
|
||||||
{
|
|
||||||
RsPrivateChatDistantInviteConfigItem *ei = new RsPrivateChatDistantInviteConfigItem ;
|
|
||||||
ei->hash = it->first ;
|
|
||||||
memcpy(ei->aes_key,it->second.aes_key,DISTANT_CHAT_AES_KEY_SIZE) ;
|
|
||||||
ei->encrypted_radix64_string = it->second.encrypted_radix64_string ;
|
|
||||||
ei->destination_pgp_id = it->second.destination_pgp_id ;
|
|
||||||
ei->time_of_validity = it->second.time_of_validity ;
|
|
||||||
ei->last_hit_time = it->second.last_hit_time ;
|
|
||||||
ei->flags = it->second.flags ;
|
|
||||||
|
|
||||||
list.push_back(ei) ;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Save Default Nick Name */
|
/* Save Default Nick Name */
|
||||||
|
|
||||||
RsConfigKeyValueSet *vitem = new RsConfigKeyValueSet ;
|
RsConfigKeyValueSet *vitem = new RsConfigKeyValueSet ;
|
||||||
|
@ -2308,7 +2306,7 @@ bool p3ChatService::sendLobbyChat(const RsPeerId &id, const std::string& msg, co
|
||||||
#ifdef CHAT_DEBUG
|
#ifdef CHAT_DEBUG
|
||||||
std::cerr << "Sending chat lobby message to lobby " << std::hex << lobby_id << std::dec << std::endl;
|
std::cerr << "Sending chat lobby message to lobby " << std::hex << lobby_id << std::dec << std::endl;
|
||||||
std::cerr << "msg:" << std::endl;
|
std::cerr << "msg:" << std::endl;
|
||||||
std::wcerr << msg << std::endl;
|
std::cerr << msg << std::endl;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
RsChatLobbyMsgItem item ;
|
RsChatLobbyMsgItem item ;
|
||||||
|
@ -3089,26 +3087,35 @@ void p3ChatService::cleanLobbyCaches()
|
||||||
sendConnectionChallenge(*it) ;
|
sendConnectionChallenge(*it) ;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/******************************************************************************************************************/
|
||||||
|
/* Distant Chat */
|
||||||
|
/******************************************************************************************************************/
|
||||||
|
|
||||||
bool p3ChatService::handleTunnelRequest(const RsFileHash& hash,const RsPeerId& /*peer_id*/)
|
bool p3ChatService::handleTunnelRequest(const RsFileHash& hash,const RsPeerId& /*peer_id*/)
|
||||||
{
|
{
|
||||||
RsStackMutex stack(mChatMtx); /********** STACK LOCKED MTX ******/
|
RsStackMutex stack(mChatMtx); /********** STACK LOCKED MTX ******/
|
||||||
|
|
||||||
std::map<TurtleFileHash,DistantChatInvite>::iterator it = _distant_chat_invites.find(hash) ;
|
// look into owned GXS ids, and see if the hash corresponds to the expected hash
|
||||||
|
//
|
||||||
|
std::list<RsGxsId> own_id_list ;
|
||||||
|
rsIdentity->getOwnIds(own_id_list) ;
|
||||||
|
|
||||||
#ifdef DEBUG_DISTANT_CHAT
|
#ifdef DEBUG_DISTANT_CHAT
|
||||||
std::cerr << "p3ChatService::handleTunnelRequest: received tunnel request for hash " << hash << std::endl;
|
std::cerr << "p3ChatService::handleTunnelRequest: received tunnel request for hash " << hash << std::endl;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if(it == _distant_chat_invites.end())
|
for(std::list<RsGxsId>::const_iterator it(own_id_list.begin());it!=own_id_list.end();++it)
|
||||||
return false ;
|
if(hashFromDistantChatPeerId(DistantChatPeerId(*it)) == hash)
|
||||||
|
{
|
||||||
if(it->second.encrypted_radix64_string.empty()) // don't respond to collected invites. Only to the ones we actually created!
|
#ifdef DEBUG_DISTANT_CHAT
|
||||||
return false ;
|
std::cerr << " answering true!" << std::endl;
|
||||||
|
#endif
|
||||||
it->second.last_hit_time = time(NULL) ;
|
|
||||||
return true ;
|
return true ;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return false ;
|
||||||
|
}
|
||||||
|
|
||||||
void p3ChatService::addVirtualPeer(const TurtleFileHash& hash,const TurtleVirtualPeerId& virtual_peer_id,RsTurtleGenericTunnelItem::Direction dir)
|
void p3ChatService::addVirtualPeer(const TurtleFileHash& hash,const TurtleVirtualPeerId& virtual_peer_id,RsTurtleGenericTunnelItem::Direction dir)
|
||||||
{
|
{
|
||||||
#ifdef DEBUG_DISTANT_CHAT
|
#ifdef DEBUG_DISTANT_CHAT
|
||||||
|
@ -3151,23 +3158,17 @@ void p3ChatService::addVirtualPeer(const TurtleFileHash& hash,const TurtleVirtua
|
||||||
std::cerr << " Initing encryption parameters from existing distant chat invites." << std::endl;
|
std::cerr << " Initing encryption parameters from existing distant chat invites." << std::endl;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
std::map<TurtleFileHash,DistantChatInvite>::iterator it = _distant_chat_invites.find(hash) ;
|
|
||||||
|
|
||||||
if(it == _distant_chat_invites.end())
|
|
||||||
{
|
|
||||||
std::cerr << "(EE) Cannot find distant chat invite for hash " << hash << ": no chat invite found for that hash." << std::endl;
|
|
||||||
return ;
|
|
||||||
}
|
|
||||||
DistantChatPeerInfo info ;
|
DistantChatPeerInfo info ;
|
||||||
info.last_contact = now ;
|
info.last_contact = now ;
|
||||||
info.status = RS_DISTANT_CHAT_STATUS_TUNNEL_OK ;
|
info.status = RS_DISTANT_CHAT_STATUS_TUNNEL_OK ;
|
||||||
info.virtual_peer_id = virtual_peer_id ;
|
info.virtual_peer_id = virtual_peer_id ;
|
||||||
info.pgp_id = it->second.destination_pgp_id ;
|
info.gxs_id.clear() ; // unknown yet!
|
||||||
info.direction = dir ;
|
info.direction = dir ;
|
||||||
memcpy(info.aes_key,it->second.aes_key,DISTANT_CHAT_AES_KEY_SIZE) ;
|
|
||||||
|
#warning Unfinished code here causes serious security defect.
|
||||||
|
memset(info.aes_key,0,DISTANT_CHAT_AES_KEY_SIZE) ;
|
||||||
|
|
||||||
_distant_chat_peers[hash] = info ;
|
_distant_chat_peers[hash] = info ;
|
||||||
it->second.last_hit_time = now ;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// then we send an ACK packet to notify that the tunnel works. That's useful
|
// then we send an ACK packet to notify that the tunnel works. That's useful
|
||||||
|
@ -3189,7 +3190,7 @@ void p3ChatService::addVirtualPeer(const TurtleFileHash& hash,const TurtleVirtua
|
||||||
|
|
||||||
// Notify the GUI that the tunnel is up.
|
// Notify the GUI that the tunnel is up.
|
||||||
//
|
//
|
||||||
RsServer::notify()->notifyChatStatus(hash.toStdString(),"tunnel is up again!",true) ;
|
RsServer::notify()->notifyChatStatus(virtual_peer_id.toStdString(),"tunnel is up again!",true) ;
|
||||||
}
|
}
|
||||||
|
|
||||||
void p3ChatService::removeVirtualPeer(const TurtleFileHash& hash,const TurtleVirtualPeerId& virtual_peer_id)
|
void p3ChatService::removeVirtualPeer(const TurtleFileHash& hash,const TurtleVirtualPeerId& virtual_peer_id)
|
||||||
|
@ -3207,8 +3208,8 @@ void p3ChatService::removeVirtualPeer(const TurtleFileHash& hash,const TurtleVir
|
||||||
|
|
||||||
it->second.status = RS_DISTANT_CHAT_STATUS_TUNNEL_DN ;
|
it->second.status = RS_DISTANT_CHAT_STATUS_TUNNEL_DN ;
|
||||||
}
|
}
|
||||||
RsServer::notify()->notifyChatStatus(hash.toStdString(),"tunnel is down...",true) ;
|
RsServer::notify()->notifyChatStatus(virtual_peer_id.toStdString(),"tunnel is down...",true) ;
|
||||||
RsServer::notify()->notifyPeerStatusChanged(hash.toStdString(),RS_STATUS_OFFLINE) ;
|
RsServer::notify()->notifyPeerStatusChanged(virtual_peer_id.toStdString(),RS_STATUS_OFFLINE) ;
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef DEBUG_DISTANT_CHAT
|
#ifdef DEBUG_DISTANT_CHAT
|
||||||
|
@ -3225,13 +3226,13 @@ static void printBinaryData(void *data,uint32_t size)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
void p3ChatService::receiveTurtleData( RsTurtleGenericTunnelItem *gitem,const RsFileHash& hash,
|
void p3ChatService::receiveTurtleData( RsTurtleGenericTunnelItem *gitem,const RsFileHash& hash,
|
||||||
const RsPeerId& virtual_peer_id,RsTurtleGenericTunnelItem::Direction /*direction*/)
|
const RsPeerId& virtual_peer_id,RsTurtleGenericTunnelItem::Direction direction)
|
||||||
{
|
{
|
||||||
#ifdef DEBUG_DISTANT_CHAT
|
#ifdef DEBUG_DISTANT_CHAT
|
||||||
std::cerr << "p3ChatService::receiveTurtleData(): Received turtle data. " << std::endl;
|
std::cerr << "p3ChatService::receiveTurtleData(): Received turtle data. " << std::endl;
|
||||||
std::cerr << " hash = " << hash << std::endl;
|
std::cerr << " hash = " << hash << std::endl;
|
||||||
std::cerr << " vpid = " << virtual_peer_id << std::endl;
|
std::cerr << " vpid = " << virtual_peer_id << std::endl;
|
||||||
std::cerr << " dir = " << virtual_peer_id << std::endl;
|
std::cerr << " dir = " << direction << std::endl;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
RsTurtleGenericDataItem *item = dynamic_cast<RsTurtleGenericDataItem*>(gitem) ;
|
RsTurtleGenericDataItem *item = dynamic_cast<RsTurtleGenericDataItem*>(gitem) ;
|
||||||
|
@ -3336,8 +3337,15 @@ void p3ChatService::sendTurtleData(RsChatItem *item)
|
||||||
|
|
||||||
uint8_t aes_key[DISTANT_CHAT_AES_KEY_SIZE] ;
|
uint8_t aes_key[DISTANT_CHAT_AES_KEY_SIZE] ;
|
||||||
|
|
||||||
TurtleFileHash hash = hashFromVirtualPeerId(item->PeerId());
|
TurtleVirtualPeerId virtual_peer_id = item->PeerId();
|
||||||
TurtleVirtualPeerId virtual_peer_id ;
|
RsFileHash hash ;
|
||||||
|
|
||||||
|
if(!getHashFromVirtualPeerId(item->PeerId(),hash))
|
||||||
|
{
|
||||||
|
std::cerr << "Cannot get hash from virtual peer id " << item->PeerId() << ". Dropping the chat message." << std::endl;
|
||||||
|
delete[] buff ;
|
||||||
|
return ;
|
||||||
|
}
|
||||||
|
|
||||||
{
|
{
|
||||||
RsStackMutex stack(mChatMtx); /********** STACK LOCKED MTX ******/
|
RsStackMutex stack(mChatMtx); /********** STACK LOCKED MTX ******/
|
||||||
|
@ -3351,7 +3359,6 @@ void p3ChatService::sendTurtleData(RsChatItem *item)
|
||||||
}
|
}
|
||||||
it->second.last_contact = time(NULL) ;
|
it->second.last_contact = time(NULL) ;
|
||||||
memcpy(aes_key,it->second.aes_key,DISTANT_CHAT_AES_KEY_SIZE) ;
|
memcpy(aes_key,it->second.aes_key,DISTANT_CHAT_AES_KEY_SIZE) ;
|
||||||
virtual_peer_id = it->second.virtual_peer_id ;
|
|
||||||
}
|
}
|
||||||
#ifdef DEBUG_DISTANT_CHAT
|
#ifdef DEBUG_DISTANT_CHAT
|
||||||
std::cerr << "p3ChatService::sendTurtleData(): tunnel found. Encrypting data." << std::endl;
|
std::cerr << "p3ChatService::sendTurtleData(): tunnel found. Encrypting data." << std::endl;
|
||||||
|
@ -3403,214 +3410,32 @@ void p3ChatService::sendTurtleData(RsChatItem *item)
|
||||||
mTurtle->sendTurtleData(virtual_peer_id,gitem) ;
|
mTurtle->sendTurtleData(virtual_peer_id,gitem) ;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool p3ChatService::createDistantChatInvite(const RsPgpId& pgp_id,time_t time_of_validity,std::string& encrypted_radix64_string)
|
bool p3ChatService::initiateDistantChatConnexion(const RsGxsId& gxs_id,DistantChatPeerId& pid,uint32_t& error_code)
|
||||||
{
|
{
|
||||||
// create the invite
|
pid = DistantChatPeerId(gxs_id) ; // the two ids have the same size. Still, I prefer to have 2 different types.
|
||||||
|
|
||||||
time_t now = time(NULL) ;
|
|
||||||
|
|
||||||
DistantChatInvite invite ;
|
|
||||||
invite.time_of_validity = now + time_of_validity ;
|
|
||||||
invite.last_hit_time = now ;
|
|
||||||
|
|
||||||
RAND_bytes( (unsigned char *)&invite.aes_key[0],DISTANT_CHAT_AES_KEY_SIZE ) ; // generate a random AES encryption key
|
|
||||||
|
|
||||||
// Create a random hash for that invite.
|
|
||||||
//
|
|
||||||
RsFileHash hash = RsFileHash::random();
|
|
||||||
|
|
||||||
#ifdef DEBUG_DISTANT_CHAT
|
|
||||||
std::cerr << "Created new distant chat invite: " << std::endl;
|
|
||||||
std::cerr << " validity time stamp = " << invite.time_of_validity << std::endl;
|
|
||||||
std::cerr << " hash = " << hash << std::endl;
|
|
||||||
std::cerr << " encryption key = " << t_GenericIdType<DISTANT_CHAT_AES_KEY_SIZE,true,0x0001>(invite.aes_key) << std::endl;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// Now encrypt the data to create the link info. We need
|
|
||||||
//
|
|
||||||
// [E] - the hash
|
|
||||||
// [E] - the aes key
|
|
||||||
// [E] - the signature
|
|
||||||
// - pgp id
|
|
||||||
// - timestamp
|
|
||||||
//
|
|
||||||
// The link will be
|
|
||||||
//
|
|
||||||
// retroshare://chat?time_stamp=3243242&private_data=[radix64 string]
|
|
||||||
|
|
||||||
uint32_t header_size = DISTANT_CHAT_AES_KEY_SIZE + DISTANT_CHAT_HASH_SIZE + PGP_KEY_ID_SIZE;
|
|
||||||
unsigned char *data = new unsigned char[header_size+800] ;
|
|
||||||
|
|
||||||
RsPgpId OwnId(AuthGPG::getAuthGPG()->getGPGOwnId());
|
|
||||||
|
|
||||||
memcpy(data ,Sha1CheckSum(hash).toByteArray(),DISTANT_CHAT_HASH_SIZE) ;
|
|
||||||
memcpy(data+DISTANT_CHAT_HASH_SIZE ,invite.aes_key ,DISTANT_CHAT_AES_KEY_SIZE) ;
|
|
||||||
memcpy(data+DISTANT_CHAT_HASH_SIZE+DISTANT_CHAT_AES_KEY_SIZE,OwnId.toByteArray(),PGP_KEY_ID_SIZE) ;
|
|
||||||
|
|
||||||
#ifdef DEBUG_DISTANT_CHAT
|
|
||||||
std::cerr << "Performing signature " << std::endl;
|
|
||||||
#endif
|
|
||||||
uint32_t signlen = 800;
|
|
||||||
|
|
||||||
if(!AuthGPG::getAuthGPG()->SignDataBin(data,header_size,data+header_size,&signlen))
|
|
||||||
return false ;
|
|
||||||
|
|
||||||
#ifdef DEBUG_DISTANT_CHAT
|
|
||||||
std::cerr << "Signature length = " << signlen << std::endl;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// Then encrypt the whole data into a single string.
|
|
||||||
|
|
||||||
unsigned char *encrypted_data = new unsigned char[2000] ;
|
|
||||||
uint32_t encrypted_size = 2000 ;
|
|
||||||
|
|
||||||
if(!AuthGPG::getAuthGPG()->encryptDataBin(pgp_id,(unsigned char *)data,signlen+header_size,encrypted_data,&encrypted_size))
|
|
||||||
return false ;
|
|
||||||
|
|
||||||
#ifdef DEBUG_DISTANT_CHAT
|
|
||||||
std::cerr << "Encrypted data size: " << encrypted_size << std::endl;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
Radix64::encode((const char *)encrypted_data,encrypted_size,invite.encrypted_radix64_string) ;
|
|
||||||
invite.destination_pgp_id = pgp_id ;
|
|
||||||
|
|
||||||
{
|
|
||||||
RsStackMutex stack(mChatMtx); /********** STACK LOCKED MTX ******/
|
|
||||||
_distant_chat_invites[hash] = invite ;
|
|
||||||
}
|
|
||||||
|
|
||||||
encrypted_radix64_string = invite.encrypted_radix64_string ;
|
|
||||||
#ifdef DEBUG_DISTANT_CHAT
|
|
||||||
std::cerr << "Encrypted radix64 string: " << invite.encrypted_radix64_string << std::endl;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
IndicateConfigChanged();
|
|
||||||
return true ;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool p3ChatService::initiateDistantChatConnexion(const std::string& encrypted_str,time_t time_of_validity,DistantChatPeerId& pid,uint32_t& error_code)
|
|
||||||
{
|
|
||||||
// Un-radix the string.
|
|
||||||
//
|
|
||||||
char *encrypted_data_bin = NULL ;
|
|
||||||
size_t encrypted_data_len ;
|
|
||||||
|
|
||||||
Radix64::decode(encrypted_str,encrypted_data_bin,encrypted_data_len) ;
|
|
||||||
|
|
||||||
// Decrypt it.
|
|
||||||
//
|
|
||||||
uint32_t data_size = encrypted_data_len+1000;
|
|
||||||
unsigned char *data = new unsigned char[data_size] ;
|
|
||||||
|
|
||||||
if(!AuthGPG::getAuthGPG()->decryptDataBin((unsigned char *)encrypted_data_bin,encrypted_data_len,data,&data_size))
|
|
||||||
{
|
|
||||||
error_code = RS_DISTANT_CHAT_ERROR_DECRYPTION_FAILED ;
|
|
||||||
return false ;
|
|
||||||
}
|
|
||||||
delete[] encrypted_data_bin ;
|
|
||||||
|
|
||||||
#ifdef DEBUG_DISTANT_CHAT
|
|
||||||
std::cerr << "Chat invite was successfuly decrypted!" << std::endl;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
uint32_t header_size = DISTANT_CHAT_HASH_SIZE + DISTANT_CHAT_AES_KEY_SIZE + PGP_KEY_ID_SIZE ;
|
|
||||||
|
|
||||||
RsPgpId pgp_id( data + DISTANT_CHAT_HASH_SIZE + DISTANT_CHAT_AES_KEY_SIZE ) ;
|
|
||||||
|
|
||||||
#ifdef DEBUG_DISTANT_CHAT
|
|
||||||
std::cerr << "Got this PGP id: " << pgp_id.toStdString() << std::endl;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
PGPFingerprintType fingerprint ;
|
|
||||||
if(!AuthGPG::getAuthGPG()->getKeyFingerprint(pgp_id,fingerprint))
|
|
||||||
{
|
|
||||||
error_code = RS_DISTANT_CHAT_ERROR_UNKNOWN_KEY ;
|
|
||||||
return false ;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool signature_checked = AuthGPG::getAuthGPG()->VerifySignBin(data,header_size,data+header_size,data_size-header_size,fingerprint) ;
|
|
||||||
|
|
||||||
#ifdef DEBUG_DISTANT_CHAT
|
|
||||||
std::cerr << "Signature successfuly verified!" << std::endl;
|
|
||||||
#endif
|
|
||||||
TurtleFileHash hash(data);
|
|
||||||
pid = virtualPeerIdFromHash(hash) ;
|
|
||||||
|
|
||||||
startClientDistantChatConnection(hash,pgp_id,data+DISTANT_CHAT_HASH_SIZE) ;
|
|
||||||
|
|
||||||
// Finally, save the decrypted chat info, so that we can display some info in the GUI in case we want to re-use the link
|
|
||||||
//
|
|
||||||
DistantChatInvite dinvite ;
|
|
||||||
|
|
||||||
dinvite.encrypted_radix64_string = "" ; // means that it's not issued by us
|
|
||||||
dinvite.destination_pgp_id = pgp_id;
|
|
||||||
dinvite.time_of_validity = time_of_validity ;
|
|
||||||
dinvite.last_hit_time = time(NULL) ;
|
|
||||||
dinvite.flags = RS_DISTANT_CHAT_FLAG_SIGNED | (signature_checked ? RS_DISTANT_CHAT_FLAG_SIGNATURE_OK : 0) ;
|
|
||||||
memcpy(dinvite.aes_key,data+DISTANT_CHAT_HASH_SIZE,DISTANT_CHAT_AES_KEY_SIZE) ;
|
|
||||||
|
|
||||||
{
|
|
||||||
RsStackMutex stack(mChatMtx); /********** STACK LOCKED MTX ******/
|
|
||||||
_distant_chat_invites[hash] = dinvite ;
|
|
||||||
}
|
|
||||||
#ifdef DEBUG_DISTANT_CHAT
|
|
||||||
std::cerr << "Saving info for decrypted link, for later use:" << std::endl;
|
|
||||||
std::cerr << " destination pgp id: " << dinvite.destination_pgp_id << std::endl;
|
|
||||||
std::cerr << " validity : " << dinvite.time_of_validity << std::endl;
|
|
||||||
std::cerr << " last hit time : " << dinvite.last_hit_time << std::endl;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
delete[] data ;
|
|
||||||
|
|
||||||
// And notify about chatting.
|
|
||||||
|
|
||||||
error_code = signature_checked ? RS_DISTANT_CHAT_ERROR_NO_ERROR : RS_DISTANT_CHAT_ERROR_UNKNOWN_KEY;
|
|
||||||
|
|
||||||
RsServer::notify()->AddPopupMessage(RS_POPUP_CHAT, hash.toStdString(), "Distant peer", "Conversation starts...");
|
|
||||||
|
|
||||||
// Save config, since a new invite was added.
|
|
||||||
//
|
|
||||||
IndicateConfigChanged() ;
|
|
||||||
return true ;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool p3ChatService::initiateDistantChatConnexion(const DistantChatPeerId& pid,uint32_t& error_code)
|
|
||||||
{
|
|
||||||
RsPgpId pgp_id ;
|
|
||||||
unsigned char aes_key[DISTANT_CHAT_AES_KEY_SIZE] ;
|
unsigned char aes_key[DISTANT_CHAT_AES_KEY_SIZE] ;
|
||||||
|
|
||||||
TurtleFileHash hash = hashFromVirtualPeerId(pid) ;
|
TurtleFileHash hash = hashFromDistantChatPeerId(pid) ;
|
||||||
{
|
|
||||||
RsStackMutex stack(mChatMtx); /********** STACK LOCKED MTX ******/
|
|
||||||
|
|
||||||
std::map<RsFileHash,DistantChatInvite>::iterator it = _distant_chat_invites.find(hash) ;
|
#warning Unfinished code here causes serious security defect.
|
||||||
|
memset(aes_key,0,DISTANT_CHAT_AES_KEY_SIZE) ;
|
||||||
|
|
||||||
if(it == _distant_chat_invites.end())
|
startClientDistantChatConnection(hash,gxs_id,aes_key) ;
|
||||||
{
|
|
||||||
error_code = RS_DISTANT_CHAT_ERROR_UNKNOWN_HASH ;
|
|
||||||
return false ;
|
|
||||||
}
|
|
||||||
it->second.last_hit_time = time(NULL) ;
|
|
||||||
pgp_id = it->second.destination_pgp_id;
|
|
||||||
|
|
||||||
memcpy(aes_key,it->second.aes_key,DISTANT_CHAT_AES_KEY_SIZE) ;
|
RsServer::notify()->AddPopupMessage(RS_POPUP_CHAT, pid.toStdString(), "Distant peer", "Conversation starts...");
|
||||||
}
|
|
||||||
|
|
||||||
startClientDistantChatConnection(hash,pgp_id,aes_key) ;
|
|
||||||
|
|
||||||
RsServer::notify()->AddPopupMessage(RS_POPUP_CHAT, hash.toStdString(), "Distant peer", "Conversation starts...");
|
|
||||||
|
|
||||||
error_code = RS_DISTANT_CHAT_ERROR_NO_ERROR ;
|
error_code = RS_DISTANT_CHAT_ERROR_NO_ERROR ;
|
||||||
return true ;
|
return true ;
|
||||||
}
|
}
|
||||||
|
|
||||||
void p3ChatService::startClientDistantChatConnection(const RsFileHash& hash,const RsPgpId& pgp_id,const unsigned char *aes_key_buf)
|
void p3ChatService::startClientDistantChatConnection(const RsFileHash& hash,const RsGxsId& gxs_id,const unsigned char *aes_key_buf)
|
||||||
{
|
{
|
||||||
DistantChatPeerInfo info ;
|
DistantChatPeerInfo info ;
|
||||||
|
|
||||||
info.last_contact = time(NULL) ;
|
info.last_contact = time(NULL) ;
|
||||||
info.status = RS_DISTANT_CHAT_STATUS_TUNNEL_DN ;
|
info.status = RS_DISTANT_CHAT_STATUS_TUNNEL_DN ;
|
||||||
info.pgp_id = pgp_id ;
|
info.gxs_id = gxs_id ;
|
||||||
info.direction = RsTurtleGenericTunnelItem::DIRECTION_SERVER ;
|
info.direction = RsTurtleGenericTunnelItem::DIRECTION_SERVER ;
|
||||||
memcpy(info.aes_key,aes_key_buf,DISTANT_CHAT_AES_KEY_SIZE) ;
|
memcpy(info.aes_key,aes_key_buf,DISTANT_CHAT_AES_KEY_SIZE) ;
|
||||||
|
|
||||||
|
@ -3628,35 +3453,6 @@ void p3ChatService::startClientDistantChatConnection(const RsFileHash& hash,cons
|
||||||
mTurtle->monitorTunnels(hash,this) ;
|
mTurtle->monitorTunnels(hash,this) ;
|
||||||
}
|
}
|
||||||
|
|
||||||
void p3ChatService::cleanDistantChatInvites()
|
|
||||||
{
|
|
||||||
RsStackMutex stack(mChatMtx); /********** STACK LOCKED MTX ******/
|
|
||||||
|
|
||||||
time_t now = time(NULL) ;
|
|
||||||
|
|
||||||
#ifdef DEBUG_DISTANT_CHAT
|
|
||||||
std::cerr << "p3ChatService::cleanDistantChatInvites: " << std::endl;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
for(std::map<TurtleFileHash,DistantChatInvite>::iterator it(_distant_chat_invites.begin());it!=_distant_chat_invites.end(); )
|
|
||||||
if(it->second.time_of_validity < now)
|
|
||||||
{
|
|
||||||
#ifdef DEBUG_DISTANT_CHAT
|
|
||||||
std::cerr << " Removing hash " << it->first << std::endl;
|
|
||||||
#endif
|
|
||||||
std::map<TurtleFileHash,DistantChatInvite>::iterator tmp(it) ;
|
|
||||||
++it ;
|
|
||||||
_distant_chat_invites.erase(tmp) ;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
#ifdef DEBUG_DISTANT_CHAT
|
|
||||||
std::cerr << " Keeping hash " << it->first << std::endl;
|
|
||||||
#endif
|
|
||||||
++it ;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
DistantChatPeerId p3ChatService::virtualPeerIdFromHash(const TurtleFileHash& hash)
|
DistantChatPeerId p3ChatService::virtualPeerIdFromHash(const TurtleFileHash& hash)
|
||||||
{
|
{
|
||||||
if(DistantChatPeerId::SIZE_IN_BYTES > Sha1CheckSum::SIZE_IN_BYTES)
|
if(DistantChatPeerId::SIZE_IN_BYTES > Sha1CheckSum::SIZE_IN_BYTES)
|
||||||
|
@ -3664,7 +3460,7 @@ DistantChatPeerId p3ChatService::virtualPeerIdFromHash(const TurtleFileHash& has
|
||||||
|
|
||||||
return DistantChatPeerId(hash.toByteArray()) ;
|
return DistantChatPeerId(hash.toByteArray()) ;
|
||||||
}
|
}
|
||||||
TurtleFileHash p3ChatService::hashFromVirtualPeerId(const DistantChatPeerId& pid)
|
TurtleFileHash p3ChatService::hashFromDistantChatPeerId(const DistantChatPeerId& pid)
|
||||||
{
|
{
|
||||||
if(DistantChatPeerId::SIZE_IN_BYTES > Sha1CheckSum::SIZE_IN_BYTES)
|
if(DistantChatPeerId::SIZE_IN_BYTES > Sha1CheckSum::SIZE_IN_BYTES)
|
||||||
std::cerr << __PRETTY_FUNCTION__ << ": Serious inconsistency error." << std::endl;
|
std::cerr << __PRETTY_FUNCTION__ << ": Serious inconsistency error." << std::endl;
|
||||||
|
@ -3675,30 +3471,12 @@ TurtleFileHash p3ChatService::hashFromVirtualPeerId(const DistantChatPeerId& pid
|
||||||
|
|
||||||
return Sha1CheckSum(tmp);
|
return Sha1CheckSum(tmp);
|
||||||
}
|
}
|
||||||
bool p3ChatService::getDistantChatInviteList(std::vector<DistantChatInviteInfo>& invites)
|
|
||||||
{
|
|
||||||
invites.clear() ;
|
|
||||||
|
|
||||||
RsStackMutex stack(mChatMtx); /********** STACK LOCKED MTX ******/
|
bool p3ChatService::getDistantChatStatus(const DistantChatPeerId& pid,RsGxsId& gxs_id,uint32_t& status)
|
||||||
for(std::map<TurtleFileHash,DistantChatInvite>::const_iterator it(_distant_chat_invites.begin());it!=_distant_chat_invites.end();++it)
|
|
||||||
{
|
|
||||||
DistantChatInviteInfo info ;
|
|
||||||
info.pid = virtualPeerIdFromHash(it->first) ;
|
|
||||||
info.encrypted_radix64_string = it->second.encrypted_radix64_string ;
|
|
||||||
info.time_of_validity = it->second.time_of_validity ;
|
|
||||||
info.destination_pgp_id = it->second.destination_pgp_id ;
|
|
||||||
info.invite_flags = it->second.flags ;
|
|
||||||
|
|
||||||
invites.push_back(info);
|
|
||||||
}
|
|
||||||
return true ;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool p3ChatService::getDistantChatStatus(const DistantChatPeerId& pid,uint32_t& status,RsPgpId& pgp_id)
|
|
||||||
{
|
{
|
||||||
RsStackMutex stack(mChatMtx); /********** STACK LOCKED MTX ******/
|
RsStackMutex stack(mChatMtx); /********** STACK LOCKED MTX ******/
|
||||||
|
|
||||||
TurtleFileHash hash = hashFromVirtualPeerId(pid) ;
|
TurtleFileHash hash = hashFromDistantChatPeerId(pid) ;
|
||||||
std::map<TurtleFileHash,DistantChatPeerInfo>::const_iterator it = _distant_chat_peers.find(hash) ;
|
std::map<TurtleFileHash,DistantChatPeerInfo>::const_iterator it = _distant_chat_peers.find(hash) ;
|
||||||
|
|
||||||
if(it == _distant_chat_peers.end())
|
if(it == _distant_chat_peers.end())
|
||||||
|
@ -3708,7 +3486,7 @@ bool p3ChatService::getDistantChatStatus(const DistantChatPeerId& pid,uint32_t&
|
||||||
}
|
}
|
||||||
|
|
||||||
status = it->second.status ;
|
status = it->second.status ;
|
||||||
pgp_id = it->second.pgp_id ;
|
gxs_id = it->second.gxs_id ;
|
||||||
|
|
||||||
return true ;
|
return true ;
|
||||||
}
|
}
|
||||||
|
@ -3719,7 +3497,7 @@ bool p3ChatService::closeDistantChatConnexion(const DistantChatPeerId& pid)
|
||||||
// - client needs to stop asking for tunnels => remove the hash from the list of tunnelled files
|
// - client needs to stop asking for tunnels => remove the hash from the list of tunnelled files
|
||||||
// - server needs to only close the window and let the tunnel die. But the window should only open if a message arrives.
|
// - server needs to only close the window and let the tunnel die. But the window should only open if a message arrives.
|
||||||
|
|
||||||
TurtleFileHash hash = hashFromVirtualPeerId(pid) ;
|
TurtleFileHash hash = hashFromDistantChatPeerId(pid) ;
|
||||||
|
|
||||||
bool is_client = false ;
|
bool is_client = false ;
|
||||||
RsPeerId virtual_peer_id ;
|
RsPeerId virtual_peer_id ;
|
||||||
|
@ -3775,7 +3553,7 @@ void p3ChatService::markDistantChatAsClosed(const DistantChatPeerId& pid)
|
||||||
{
|
{
|
||||||
RsStackMutex stack(mChatMtx); /********** STACK LOCKED MTX ******/
|
RsStackMutex stack(mChatMtx); /********** STACK LOCKED MTX ******/
|
||||||
|
|
||||||
TurtleFileHash hash = hashFromVirtualPeerId(pid) ;
|
TurtleFileHash hash = hashFromDistantChatPeerId(pid) ;
|
||||||
std::map<TurtleFileHash,DistantChatPeerInfo>::iterator it = _distant_chat_peers.find(hash) ;
|
std::map<TurtleFileHash,DistantChatPeerInfo>::iterator it = _distant_chat_peers.find(hash) ;
|
||||||
|
|
||||||
if(it == _distant_chat_peers.end()) // server side. Nothing to do.
|
if(it == _distant_chat_peers.end()) // server side. Nothing to do.
|
||||||
|
@ -3787,26 +3565,6 @@ void p3ChatService::markDistantChatAsClosed(const DistantChatPeerId& pid)
|
||||||
it->second.status = RS_DISTANT_CHAT_STATUS_REMOTELY_CLOSED ;
|
it->second.status = RS_DISTANT_CHAT_STATUS_REMOTELY_CLOSED ;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool p3ChatService::removeDistantChatInvite(const DistantChatPeerId& pid)
|
|
||||||
{
|
|
||||||
RsStackMutex stack(mChatMtx); /********** STACK LOCKED MTX ******/
|
|
||||||
|
|
||||||
TurtleFileHash hash= hashFromVirtualPeerId(pid) ;
|
|
||||||
std::map<TurtleFileHash,DistantChatInvite>::iterator it = _distant_chat_invites.find(hash) ;
|
|
||||||
|
|
||||||
if(it == _distant_chat_invites.end()) // server side. Nothing to do.
|
|
||||||
{
|
|
||||||
std::cerr << "Cannot find distant chat invite for hash " << hash << std::endl;
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
_distant_chat_invites.erase(it) ;
|
|
||||||
|
|
||||||
IndicateConfigChanged() ;
|
|
||||||
|
|
||||||
return true ;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -332,40 +332,21 @@ class p3ChatService: public p3Service, public p3Config, public pqiServiceMonitor
|
||||||
// Creates the invite if the public key of the distant peer is available.
|
// Creates the invite if the public key of the distant peer is available.
|
||||||
// Om success, stores the invite in the map above, so that we can respond to tunnel requests.
|
// Om success, stores the invite in the map above, so that we can respond to tunnel requests.
|
||||||
//
|
//
|
||||||
bool createDistantChatInvite(const RsPgpId& pgp_id,time_t time_of_validity,std::string& enc_b64_string) ;
|
bool initiateDistantChatConnexion(const RsGxsId& gxs_id,DistantChatPeerId& pid,uint32_t& error_code) ;
|
||||||
bool getDistantChatInviteList(std::vector<DistantChatInviteInfo>& invites) ;
|
|
||||||
bool initiateDistantChatConnexion(const std::string& encrypted_string,time_t time_of_validity,DistantChatPeerId& pid,uint32_t& error_code) ; // from encrypted data
|
|
||||||
bool initiateDistantChatConnexion(const DistantChatPeerId& pid,uint32_t& error_code) ; // from known hash of a decrypted link
|
|
||||||
bool closeDistantChatConnexion(const DistantChatPeerId& pid) ;
|
bool closeDistantChatConnexion(const DistantChatPeerId& pid) ;
|
||||||
bool removeDistantChatInvite(const DistantChatPeerId& pid) ;
|
virtual bool getDistantChatStatus(const DistantChatPeerId& hash,RsGxsId& gxs_id,uint32_t& status) ;
|
||||||
|
|
||||||
virtual bool getDistantChatStatus(const DistantChatPeerId& hash,uint32_t& status,RsPgpId& pgp_id) ;
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
struct DistantChatInvite
|
|
||||||
{
|
|
||||||
unsigned char aes_key[16] ;
|
|
||||||
std::string encrypted_radix64_string ;
|
|
||||||
RsPgpId destination_pgp_id ;
|
|
||||||
time_t time_of_validity ;
|
|
||||||
time_t last_hit_time ;
|
|
||||||
uint32_t flags ;
|
|
||||||
};
|
|
||||||
struct DistantChatPeerInfo
|
struct DistantChatPeerInfo
|
||||||
{
|
{
|
||||||
time_t last_contact ; // used to send keep alive packets
|
time_t last_contact ; // used to send keep alive packets
|
||||||
unsigned char aes_key[16] ; // key to encrypt packets
|
unsigned char aes_key[16] ; // key to encrypt packets
|
||||||
uint32_t status ; // info: do we have a tunnel ?
|
uint32_t status ; // info: do we have a tunnel ?
|
||||||
RsPeerId virtual_peer_id; // given by the turtle router. Identifies the tunnel.
|
RsPeerId virtual_peer_id; // given by the turtle router. Identifies the tunnel.
|
||||||
RsPgpId pgp_id ; // pgp id of the peer we're talking to.
|
RsGxsId gxs_id ; // pgp id of the peer we're talking to.
|
||||||
RsTurtleGenericTunnelItem::Direction direction ; // specifiec wether we are client(managing the tunnel) or server.
|
RsTurtleGenericTunnelItem::Direction direction ; // specifiec wether we are client(managing the tunnel) or server.
|
||||||
};
|
};
|
||||||
|
|
||||||
// This map contains the ongoing invites. This is the list where to look to
|
|
||||||
// handle tunnel requests.
|
|
||||||
//
|
|
||||||
std::map<TurtleFileHash,DistantChatInvite> _distant_chat_invites ;
|
|
||||||
|
|
||||||
// This maps contains the current peers to talk to with distant chat.
|
// This maps contains the current peers to talk to with distant chat.
|
||||||
//
|
//
|
||||||
std::map<TurtleFileHash,DistantChatPeerInfo> _distant_chat_peers ;
|
std::map<TurtleFileHash,DistantChatPeerInfo> _distant_chat_peers ;
|
||||||
|
@ -382,12 +363,12 @@ class p3ChatService: public p3Service, public p3Config, public pqiServiceMonitor
|
||||||
void addVirtualPeer(const TurtleFileHash&, const TurtleVirtualPeerId&,RsTurtleGenericTunnelItem::Direction dir) ;
|
void addVirtualPeer(const TurtleFileHash&, const TurtleVirtualPeerId&,RsTurtleGenericTunnelItem::Direction dir) ;
|
||||||
void removeVirtualPeer(const TurtleFileHash&, const TurtleVirtualPeerId&) ;
|
void removeVirtualPeer(const TurtleFileHash&, const TurtleVirtualPeerId&) ;
|
||||||
void markDistantChatAsClosed(const TurtleVirtualPeerId& vpid) ;
|
void markDistantChatAsClosed(const TurtleVirtualPeerId& vpid) ;
|
||||||
void startClientDistantChatConnection(const RsFileHash& hash,const RsPgpId& pgp_id,const unsigned char *aes_key_buf) ;
|
void startClientDistantChatConnection(const RsFileHash& hash,const RsGxsId& gxs_id,const unsigned char *aes_key_buf) ;
|
||||||
bool findHashForVirtualPeerId(const TurtleVirtualPeerId& pid,RsFileHash& hash) ;
|
bool getHashFromVirtualPeerId(const TurtleVirtualPeerId& pid,RsFileHash& hash) ;
|
||||||
|
TurtleFileHash hashFromDistantChatPeerId(const DistantChatPeerId& pid) ;
|
||||||
|
|
||||||
// Utility functions
|
// Utility functions
|
||||||
|
|
||||||
void cleanDistantChatInvites() ;
|
|
||||||
void sendTurtleData(RsChatItem *) ;
|
void sendTurtleData(RsChatItem *) ;
|
||||||
void sendPrivateChatItem(RsChatItem *) ;
|
void sendPrivateChatItem(RsChatItem *) ;
|
||||||
|
|
||||||
|
|
|
@ -6,18 +6,19 @@
|
||||||
#include <QGraphicsItem>
|
#include <QGraphicsItem>
|
||||||
#include <QGraphicsSceneMouseEvent>
|
#include <QGraphicsSceneMouseEvent>
|
||||||
|
|
||||||
|
#include "IdentityItem.h"
|
||||||
#include "CircleItem.h"
|
#include "CircleItem.h"
|
||||||
|
|
||||||
#define IMAGE_MAKEFRIEND ""
|
#define IMAGE_MAKEFRIEND ""
|
||||||
|
|
||||||
CircleItem *CircleItem::_selected_node = NULL ;
|
CircleItem *CircleItem::_selected_node = NULL ;
|
||||||
|
|
||||||
CircleItem::CircleItem(const RsGroupMetaData& group_info)
|
CircleItem::CircleItem(const RsGroupMetaData& group_info, const RsGxsCircleDetails& details)
|
||||||
: _group_info(group_info)
|
: _group_info(group_info), _circle_details(details)
|
||||||
{
|
{
|
||||||
std::cerr << "Created group item for id=" <<group_info.mGroupId << std::endl;
|
std::cerr << "Created group item for id=" <<group_info.mGroupId << std::endl;
|
||||||
|
|
||||||
// setFlag(ItemIsMovable);
|
setFlag(ItemIsMovable);
|
||||||
setAcceptHoverEvents(true) ;
|
setAcceptHoverEvents(true) ;
|
||||||
#if QT_VERSION >= 0x040600
|
#if QT_VERSION >= 0x040600
|
||||||
setFlag(ItemSendsGeometryChanges);
|
setFlag(ItemSendsGeometryChanges);
|
||||||
|
@ -27,6 +28,16 @@ CircleItem::CircleItem(const RsGroupMetaData& group_info)
|
||||||
|
|
||||||
mDeterminedBB = false ;
|
mDeterminedBB = false ;
|
||||||
mBBWidth = 40 ;
|
mBBWidth = 40 ;
|
||||||
|
|
||||||
|
/* update friend lists */
|
||||||
|
|
||||||
|
// update the position of all members
|
||||||
|
|
||||||
|
uint32_t n=details.mUnknownPeers.size() ;
|
||||||
|
|
||||||
|
_angles.resize(n) ;
|
||||||
|
for(uint32_t i=0;i<n;++i)
|
||||||
|
_angles[i] = 2*M_PI/n ;
|
||||||
}
|
}
|
||||||
|
|
||||||
void CircleItem::hoverEnterEvent(QGraphicsSceneHoverEvent *e)
|
void CircleItem::hoverEnterEvent(QGraphicsSceneHoverEvent *e)
|
||||||
|
@ -48,31 +59,43 @@ void CircleItem::hoverLeaveEvent(QGraphicsSceneHoverEvent *e)
|
||||||
update() ;
|
update() ;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
QRectF CircleItem::boundingRect() const
|
QRectF CircleItem::boundingRect() const
|
||||||
{
|
{
|
||||||
static const bool mDeterminedBB = false ;
|
static const bool mDeterminedBB = false ;
|
||||||
static const int mBBWidth = 40 ;
|
static const int mBBWidth = 40 ;
|
||||||
|
|
||||||
return QRectF(-(int)IMG_SIZE/2-10, -(int)IMG_SIZE/2-10, (int)IMG_SIZE+20,(int)IMG_SIZE+35) ;
|
return QRectF(-(int)IMG_SIZE/2 - CRC_SIZE, -(int)IMG_SIZE/2 - CRC_SIZE, IMG_SIZE+2*CRC_SIZE,IMG_SIZE+2*CRC_SIZE) ;
|
||||||
}
|
}
|
||||||
|
|
||||||
void CircleItem::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *)
|
void CircleItem::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *)
|
||||||
{
|
{
|
||||||
painter->setPen(Qt::NoPen);
|
|
||||||
painter->setBrush(Qt::lightGray);
|
|
||||||
painter->drawEllipse(-7, -7, 20, 20);
|
|
||||||
|
|
||||||
QRadialGradient gradient(-10, -IMG_SIZE/3.0, IMG_SIZE*1.5);
|
|
||||||
gradient.setColorAt(0.0f,Qt::lightGray) ;
|
|
||||||
gradient.setColorAt(1.0f,Qt::darkGray) ;
|
|
||||||
painter->setBrush(gradient);
|
|
||||||
|
|
||||||
if(_selected)
|
if(_selected)
|
||||||
painter->setOpacity(0.7) ;
|
painter->setOpacity(0.7) ;
|
||||||
else
|
else
|
||||||
painter->setOpacity(1.0) ;
|
painter->setOpacity(1.0) ;
|
||||||
|
|
||||||
|
// draw a circle in the center
|
||||||
|
//
|
||||||
|
QRadialGradient gradient(-10, -IMG_SIZE/3.0, IMG_SIZE*1.5);
|
||||||
|
gradient.setColorAt(0.0f,Qt::lightGray) ;
|
||||||
|
gradient.setColorAt(1.0f,Qt::darkGray) ;
|
||||||
|
painter->setBrush(gradient);
|
||||||
|
|
||||||
|
painter->setPen(Qt::NoPen);
|
||||||
|
painter->setBrush(Qt::lightGray);
|
||||||
|
painter->drawEllipse(-7, -7, 20, 20);
|
||||||
|
|
||||||
|
// Now draw all members of this circle into a circle
|
||||||
|
//
|
||||||
|
uint32_t i=0 ;
|
||||||
|
for(std::set<RsGxsId>::const_iterator it(_circle_details.mUnknownPeers.begin());it!= _circle_details.mUnknownPeers.end();++it)
|
||||||
|
{
|
||||||
|
painter->drawImage(QPoint(CRC_SIZE*cos(_angles[i]) -(int)IMG_SIZE/2, CRC_SIZE*sin(_angles[i]) -(int)IMG_SIZE/2), IdentityItem::makeDefaultIcon(RsGxsGroupId(*it))) ;
|
||||||
|
++i ;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Draw the name of the circle
|
||||||
|
//
|
||||||
painter->setPen(QPen(Qt::black, 0));
|
painter->setPen(QPen(Qt::black, 0));
|
||||||
|
|
||||||
//painter->drawRoundedRect(QRectF(-(int)IMG_SIZE/2-10, -(int)IMG_SIZE/2-10, 20+IMG_SIZE, 20+IMG_SIZE),20,15) ;
|
//painter->drawRoundedRect(QRectF(-(int)IMG_SIZE/2-10, -(int)IMG_SIZE/2-10, 20+IMG_SIZE, 20+IMG_SIZE),20,15) ;
|
||||||
|
|
|
@ -2,14 +2,14 @@
|
||||||
|
|
||||||
#include <QGraphicsItem>
|
#include <QGraphicsItem>
|
||||||
|
|
||||||
#include <retroshare/rsidentity.h>
|
#include <retroshare/rsgxscircles.h>
|
||||||
|
|
||||||
class CircleItem: public QObject, public QGraphicsItem
|
class CircleItem: public QObject, public QGraphicsItem
|
||||||
{
|
{
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
|
||||||
public:
|
public:
|
||||||
CircleItem(const RsGroupMetaData& gxs_group_info) ;
|
CircleItem(const RsGroupMetaData& gxs_group_info,const RsGxsCircleDetails& details) ;
|
||||||
|
|
||||||
QRectF boundingRect() const ;
|
QRectF boundingRect() const ;
|
||||||
//QPainterPath shape() const ;
|
//QPainterPath shape() const ;
|
||||||
|
@ -18,7 +18,9 @@ class CircleItem: public QObject, public QGraphicsItem
|
||||||
|
|
||||||
//static QImage makeDefaultIcon(const RsGxsGroupId& id) ;
|
//static QImage makeDefaultIcon(const RsGxsGroupId& id) ;
|
||||||
|
|
||||||
static const int IMG_SIZE = 64;
|
static const int IMG_SIZE = 32;
|
||||||
|
static const int CRC_SIZE = 128;
|
||||||
|
|
||||||
static CircleItem *_selected_node ;
|
static CircleItem *_selected_node ;
|
||||||
|
|
||||||
const RsGroupMetaData& groupInfo() const { return _group_info ; }
|
const RsGroupMetaData& groupInfo() const { return _group_info ; }
|
||||||
|
@ -35,9 +37,12 @@ signals:
|
||||||
virtual void contextMenuEvent(QGraphicsSceneContextMenuEvent *) ;
|
virtual void contextMenuEvent(QGraphicsSceneContextMenuEvent *) ;
|
||||||
|
|
||||||
RsGroupMetaData _group_info ;
|
RsGroupMetaData _group_info ;
|
||||||
|
RsGxsCircleDetails _circle_details ;
|
||||||
|
|
||||||
bool mDeterminedBB;
|
bool mDeterminedBB;
|
||||||
bool mBBWidth;
|
bool mBBWidth;
|
||||||
bool _selected ;
|
bool _selected ;
|
||||||
|
|
||||||
|
std::vector<float> _angles ;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -25,7 +25,8 @@ GroupListView::GroupListView(QWidget *)
|
||||||
mStateHelper = new UIStateHelper(this);
|
mStateHelper = new UIStateHelper(this);
|
||||||
//mStateHelper->addWidget(IDDIALOG_IDLIST, ui.treeWidget_IdList);
|
//mStateHelper->addWidget(IDDIALOG_IDLIST, ui.treeWidget_IdList);
|
||||||
|
|
||||||
mIdQueue = new TokenQueue(rsIdentity->getTokenService(), this);
|
mIdentityQueue = new TokenQueue(rsIdentity->getTokenService(), this);
|
||||||
|
mCirclesQueue = new TokenQueue(rsGxsCircles->getTokenService(), this);
|
||||||
|
|
||||||
QGraphicsScene *scene = new QGraphicsScene(QRectF(0,0,width(),height()),this);
|
QGraphicsScene *scene = new QGraphicsScene(QRectF(0,0,width(),height()),this);
|
||||||
scene->setItemIndexMethod(QGraphicsScene::NoIndex);
|
scene->setItemIndexMethod(QGraphicsScene::NoIndex);
|
||||||
|
@ -199,7 +200,14 @@ void GroupListView::insertCircles(uint32_t token)
|
||||||
std::cerr << " Group: " << vit->mGroupName;
|
std::cerr << " Group: " << vit->mGroupName;
|
||||||
std::cerr << std::endl;
|
std::cerr << std::endl;
|
||||||
|
|
||||||
CircleItem *gitem = new CircleItem( *vit ) ;
|
RsGxsCircleDetails details ;
|
||||||
|
|
||||||
|
if(!rsGxsCircles->getCircleDetails(RsGxsCircleId(vit->mGroupId), details))
|
||||||
|
{
|
||||||
|
std::cerr << "(EE) Cannot get details for circle id " << vit->mGroupId << ". Circle item is not created!" << std::endl;
|
||||||
|
continue ;
|
||||||
|
}
|
||||||
|
CircleItem *gitem = new CircleItem( *vit, details ) ;
|
||||||
|
|
||||||
_circles_items[(*vit).mGroupId] = gitem ;
|
_circles_items[(*vit).mGroupId] = gitem ;
|
||||||
|
|
||||||
|
@ -209,29 +217,6 @@ void GroupListView::insertCircles(uint32_t token)
|
||||||
|
|
||||||
scene()->addItem(gitem) ;
|
scene()->addItem(gitem) ;
|
||||||
++i ;
|
++i ;
|
||||||
|
|
||||||
//groupItem->setText(CIRCLEGROUP_CIRCLE_COL_GROUPNAME, QString::fromUtf8(vit->mGroupName.c_str()));
|
|
||||||
//groupItem->setText(CIRCLEGROUP_CIRCLE_COL_GROUPID, QString::fromStdString(vit->mGroupId.toStdString()));
|
|
||||||
|
|
||||||
//if (vit->mCircleType == GXS_CIRCLE_TYPE_LOCAL)
|
|
||||||
//{
|
|
||||||
// personalCirclesItem->addChild(groupItem);
|
|
||||||
//}
|
|
||||||
//else
|
|
||||||
//{
|
|
||||||
// if (vit->mSubscribeFlags & GXS_SERV::GROUP_SUBSCRIBE_ADMIN)
|
|
||||||
// {
|
|
||||||
// externalAdminCirclesItem->addChild(groupItem);
|
|
||||||
// }
|
|
||||||
// else if (vit->mSubscribeFlags & GXS_SERV::GROUP_SUBSCRIBE_SUBSCRIBED)
|
|
||||||
// {
|
|
||||||
// externalSubCirclesItem->addChild(groupItem);
|
|
||||||
// }
|
|
||||||
// else
|
|
||||||
// {
|
|
||||||
// externalOtherCirclesItem->addChild(groupItem);
|
|
||||||
// }
|
|
||||||
//}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -239,40 +224,40 @@ void GroupListView::requestIdList()
|
||||||
{
|
{
|
||||||
std::cerr << "Requesting ID list..." << std::endl;
|
std::cerr << "Requesting ID list..." << std::endl;
|
||||||
|
|
||||||
if (!mIdQueue)
|
if (!mIdentityQueue)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
mStateHelper->setLoading(GLVIEW_IDLIST, true);
|
mStateHelper->setLoading(GLVIEW_IDLIST, true);
|
||||||
//mStateHelper->setLoading(GLVIEW_IDDETAILS, true);
|
//mStateHelper->setLoading(GLVIEW_IDDETAILS, true);
|
||||||
//mStateHelper->setLoading(GLVIEW_REPLIST, true);
|
//mStateHelper->setLoading(GLVIEW_REPLIST, true);
|
||||||
|
|
||||||
mIdQueue->cancelActiveRequestTokens(GLVIEW_IDLIST);
|
mIdentityQueue->cancelActiveRequestTokens(GLVIEW_IDLIST);
|
||||||
|
|
||||||
RsTokReqOptions opts;
|
RsTokReqOptions opts;
|
||||||
opts.mReqType = GXS_REQUEST_TYPE_GROUP_DATA;
|
opts.mReqType = GXS_REQUEST_TYPE_GROUP_DATA;
|
||||||
|
|
||||||
uint32_t token;
|
uint32_t token;
|
||||||
|
|
||||||
mIdQueue->requestGroupInfo(token, RS_TOKREQ_ANSTYPE_DATA, opts, GLVIEW_IDLIST);
|
mIdentityQueue->requestGroupInfo(token, RS_TOKREQ_ANSTYPE_DATA, opts, GLVIEW_IDLIST);
|
||||||
}
|
}
|
||||||
void GroupListView::requestCirclesList()
|
void GroupListView::requestCirclesList()
|
||||||
{
|
{
|
||||||
std::cerr << "Requesting Circles list..." << std::endl;
|
std::cerr << "Requesting Circles list..." << std::endl;
|
||||||
|
|
||||||
if (!mIdQueue)
|
if (!mCirclesQueue)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
mStateHelper->setLoading(GLVIEW_CIRCLES, true);
|
mStateHelper->setLoading(GLVIEW_CIRCLES, true);
|
||||||
//mStateHelper->setLoading(GLVIEW_IDDETAILS, true);
|
//mStateHelper->setLoading(GLVIEW_IDDETAILS, true);
|
||||||
//mStateHelper->setLoading(GLVIEW_REPLIST, true);
|
//mStateHelper->setLoading(GLVIEW_REPLIST, true);
|
||||||
|
|
||||||
mIdQueue->cancelActiveRequestTokens(GLVIEW_CIRCLES);
|
mCirclesQueue->cancelActiveRequestTokens(GLVIEW_CIRCLES);
|
||||||
|
|
||||||
RsTokReqOptions opts;
|
RsTokReqOptions opts;
|
||||||
opts.mReqType = GXS_REQUEST_TYPE_GROUP_META;
|
opts.mReqType = GXS_REQUEST_TYPE_GROUP_META;
|
||||||
|
|
||||||
uint32_t token;
|
uint32_t token;
|
||||||
mIdQueue->requestGroupInfo(token, RS_TOKREQ_ANSTYPE_SUMMARY, opts, GLVIEW_CIRCLES);
|
mCirclesQueue->requestGroupInfo(token, RS_TOKREQ_ANSTYPE_SUMMARY, opts, GLVIEW_CIRCLES);
|
||||||
}
|
}
|
||||||
void GroupListView::forceRedraw()
|
void GroupListView::forceRedraw()
|
||||||
{
|
{
|
||||||
|
|
|
@ -71,7 +71,9 @@ private:
|
||||||
float _friction_factor ;
|
float _friction_factor ;
|
||||||
//NodeId _current_node ;
|
//NodeId _current_node ;
|
||||||
|
|
||||||
TokenQueue *mIdQueue;
|
TokenQueue *mIdentityQueue;
|
||||||
|
TokenQueue *mCirclesQueue;
|
||||||
|
|
||||||
UIStateHelper *mStateHelper;
|
UIStateHelper *mStateHelper;
|
||||||
|
|
||||||
std::map<RsGxsGroupId,IdentityItem *> _identity_items ;
|
std::map<RsGxsGroupId,IdentityItem *> _identity_items ;
|
||||||
|
|
|
@ -1,11 +1,15 @@
|
||||||
#include <math.h>
|
#include <math.h>
|
||||||
|
|
||||||
|
#include <retroshare/rsmsgs.h>
|
||||||
|
|
||||||
#include <QPainter>
|
#include <QPainter>
|
||||||
|
#include <QMessageBox>
|
||||||
#include <QMenu>
|
#include <QMenu>
|
||||||
#include <QStyle>
|
#include <QStyle>
|
||||||
#include <QGraphicsItem>
|
#include <QGraphicsItem>
|
||||||
#include <QGraphicsSceneMouseEvent>
|
#include <QGraphicsSceneMouseEvent>
|
||||||
|
|
||||||
|
#include <gui/chat/ChatDialog.h>
|
||||||
#include "IdentityItem.h"
|
#include "IdentityItem.h"
|
||||||
|
|
||||||
#define IMAGE_MAKEFRIEND ""
|
#define IMAGE_MAKEFRIEND ""
|
||||||
|
@ -143,9 +147,7 @@ void IdentityItem::paint(QPainter *painter, const QStyleOptionGraphicsItem *opti
|
||||||
|
|
||||||
painter->drawRoundedRect(QRectF(-(int)IMG_SIZE/2-10, -(int)IMG_SIZE/2-10, 20+IMG_SIZE, 20+IMG_SIZE),20,15) ;
|
painter->drawRoundedRect(QRectF(-(int)IMG_SIZE/2-10, -(int)IMG_SIZE/2-10, 20+IMG_SIZE, 20+IMG_SIZE),20,15) ;
|
||||||
painter->drawImage(QPoint(-(int)IMG_SIZE/2, -(int)IMG_SIZE/2), makeDefaultIcon(_group_info.mMeta.mGroupId)) ;
|
painter->drawImage(QPoint(-(int)IMG_SIZE/2, -(int)IMG_SIZE/2), makeDefaultIcon(_group_info.mMeta.mGroupId)) ;
|
||||||
//painter->drawRect(-(int)IMG_SIZE/2, -(int)IMG_SIZE/2, IMG_SIZE, IMG_SIZE);
|
|
||||||
|
|
||||||
//std::string desc_string = _group_info.mMeta.mGroupId.toStdString() ;
|
|
||||||
std::string desc_string = _group_info.mMeta.mGroupName ;
|
std::string desc_string = _group_info.mMeta.mGroupName ;
|
||||||
|
|
||||||
painter->drawText(-8*desc_string.size()/2, IMG_SIZE/2+24, QString::fromUtf8(desc_string.c_str()));
|
painter->drawText(-8*desc_string.size()/2, IMG_SIZE/2+24, QString::fromUtf8(desc_string.c_str()));
|
||||||
|
@ -160,16 +162,6 @@ void IdentityItem::paint(QPainter *painter, const QStyleOptionGraphicsItem *opti
|
||||||
|
|
||||||
QVariant IdentityItem::itemChange(GraphicsItemChange change, const QVariant &value)
|
QVariant IdentityItem::itemChange(GraphicsItemChange change, const QVariant &value)
|
||||||
{
|
{
|
||||||
// switch (change) {
|
|
||||||
// case ItemPositionHasChanged:
|
|
||||||
// foreach (Edge *edge, edgeList)
|
|
||||||
// edge->adjust();
|
|
||||||
// graph->itemMoved();
|
|
||||||
// break;
|
|
||||||
// default:
|
|
||||||
// break;
|
|
||||||
// };
|
|
||||||
|
|
||||||
return QGraphicsItem::itemChange(change, value);
|
return QGraphicsItem::itemChange(change, value);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -188,16 +180,22 @@ void IdentityItem::contextMenuEvent(QGraphicsSceneContextMenuEvent *event)
|
||||||
{
|
{
|
||||||
QMenu contextMnu ;
|
QMenu contextMnu ;
|
||||||
|
|
||||||
//if(_type == GraphWidget::ELASTIC_NODE_TYPE_FRIEND)
|
|
||||||
// contextMnu.addAction(QIcon(IMAGE_DENIED), QObject::tr( "Deny friend" ), this, SLOT(denyFriend()) );
|
|
||||||
//else if(_type != GraphWidget::ELASTIC_NODE_TYPE_OWN)
|
|
||||||
// contextMnu.addAction(QIcon(IMAGE_MAKEFRIEND), QObject::tr( "Make friend" ), this, SLOT(makeFriend()) );
|
|
||||||
|
|
||||||
contextMnu.addAction(QIcon(IMAGE_MAKEFRIEND), QObject::tr( "Peer details" ), this, SLOT(peerDetails()) );
|
contextMnu.addAction(QIcon(IMAGE_MAKEFRIEND), QObject::tr( "Peer details" ), this, SLOT(peerDetails()) );
|
||||||
|
contextMnu.addAction(QIcon(IMAGE_MAKEFRIEND), QObject::tr( "Chat this peer" ), this, SLOT(distantChat()) );
|
||||||
contextMnu.exec(event->screenPos());
|
contextMnu.exec(event->screenPos());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void IdentityItem::distantChat()
|
||||||
|
{
|
||||||
|
DistantChatPeerId virtual_peer_id ;
|
||||||
|
uint32_t error_code ;
|
||||||
|
|
||||||
|
if(!rsMsgs->initiateDistantChatConnexion(RsGxsId(_group_info.mMeta.mGroupId), virtual_peer_id, error_code))
|
||||||
|
QMessageBox::information(NULL,"Distant cannot work","Distant chat refused with this peer. Reason: "+QString::number(error_code)) ;
|
||||||
|
else
|
||||||
|
ChatDialog::chatFriend(virtual_peer_id);
|
||||||
|
}
|
||||||
|
|
||||||
void IdentityItem::mouseReleaseEvent(QGraphicsSceneMouseEvent *event)
|
void IdentityItem::mouseReleaseEvent(QGraphicsSceneMouseEvent *event)
|
||||||
{
|
{
|
||||||
//_selected_node = NULL ;
|
//_selected_node = NULL ;
|
||||||
|
|
|
@ -22,6 +22,10 @@ class IdentityItem: public QObject, public QGraphicsItem
|
||||||
static IdentityItem *_selected_node ;
|
static IdentityItem *_selected_node ;
|
||||||
|
|
||||||
const RsGxsIdGroup& groupInfo() const { return _group_info ; }
|
const RsGxsIdGroup& groupInfo() const { return _group_info ; }
|
||||||
|
|
||||||
|
public slots:
|
||||||
|
void distantChat() ;
|
||||||
|
|
||||||
signals:
|
signals:
|
||||||
void itemChanged() ;
|
void itemChanged() ;
|
||||||
|
|
||||||
|
|
|
@ -1270,48 +1270,49 @@ static void processList(const QStringList &list, const QString &textSingular, co
|
||||||
// MessageComposer::msgDistantPeer(link._hash.toStdString(),link._GPGid.toStdString()) ;
|
// MessageComposer::msgDistantPeer(link._hash.toStdString(),link._GPGid.toStdString()) ;
|
||||||
}
|
}
|
||||||
break ;
|
break ;
|
||||||
case TYPE_PRIVATE_CHAT:
|
|
||||||
{
|
|
||||||
std::cerr << "Opening a private chat window " << std::endl;
|
|
||||||
std::cerr << " time_stamp = " << link._time_stamp << std::endl;
|
|
||||||
std::cerr << " enc-string = " << link._encrypted_chat_info.toStdString() << std::endl;
|
|
||||||
std::cerr << " PGP Id = " << link._GPGid.toStdString() << std::endl;
|
|
||||||
|
|
||||||
if(link._time_stamp < time(NULL))
|
// case TYPE_PRIVATE_CHAT:
|
||||||
{
|
// {
|
||||||
QMessageBox::information(NULL,QObject::tr("Chat link is expired"),QObject::tr("This chat link is expired. The destination peer will not answer.")) ;
|
// std::cerr << "Opening a private chat window " << std::endl;
|
||||||
break ;
|
// std::cerr << " time_stamp = " << link._time_stamp << std::endl;
|
||||||
}
|
// std::cerr << " enc-string = " << link._encrypted_chat_info.toStdString() << std::endl;
|
||||||
if(RsPgpId(link._GPGid.toStdString()) != rsPeers->getGPGOwnId())
|
// std::cerr << " PGP Id = " << link._GPGid.toStdString() << std::endl;
|
||||||
{
|
//
|
||||||
QMessageBox::information(NULL,QObject::tr("Chat link cannot be decrypted"),QObject::tr("This chat link is encrypted with a key that is not yours. You can't use it. Key ID = ")+link._GPGid) ;
|
// if(link._time_stamp < time(NULL))
|
||||||
break ;
|
// {
|
||||||
}
|
// QMessageBox::information(NULL,QObject::tr("Chat link is expired"),QObject::tr("This chat link is expired. The destination peer will not answer.")) ;
|
||||||
|
// break ;
|
||||||
DistantChatPeerId dpid ;
|
// }
|
||||||
uint32_t error_code ;
|
// if(RsPgpId(link._GPGid.toStdString()) != rsPeers->getGPGOwnId())
|
||||||
|
// {
|
||||||
if(!rsMsgs->initiateDistantChatConnexion(link._encrypted_chat_info.toStdString(),link._time_stamp,dpid,error_code))
|
// QMessageBox::information(NULL,QObject::tr("Chat link cannot be decrypted"),QObject::tr("This chat link is encrypted with a key that is not yours. You can't use it. Key ID = ")+link._GPGid) ;
|
||||||
{
|
// break ;
|
||||||
QString error_msg ;
|
// }
|
||||||
switch(error_code)
|
//
|
||||||
{
|
// DistantChatPeerId dpid ;
|
||||||
default:
|
// uint32_t error_code ;
|
||||||
case RS_DISTANT_CHAT_ERROR_DECRYPTION_FAILED: error_msg = QObject::tr("The link could not be decrypted.") ; break ;
|
//
|
||||||
case RS_DISTANT_CHAT_ERROR_SIGNATURE_MISMATCH: error_msg = QObject::tr("The link signature cannot be checked.") ; break ;
|
// if(!rsMsgs->initiateDistantChatConnexion(link._encrypted_chat_info.toStdString(),link._time_stamp,dpid,error_code))
|
||||||
case RS_DISTANT_CHAT_ERROR_UNKNOWN_KEY: error_msg = QObject::tr("The link is signed by an unknown key.") ; break ;
|
// {
|
||||||
}
|
// QString error_msg ;
|
||||||
QMessageBox::information(NULL,QObject::tr("Chat connection is not possible"),error_msg) ;
|
// switch(error_code)
|
||||||
}
|
// {
|
||||||
else
|
// default:
|
||||||
{
|
// case RS_DISTANT_CHAT_ERROR_DECRYPTION_FAILED: error_msg = QObject::tr("The link could not be decrypted.") ; break ;
|
||||||
if(error_code == RS_DISTANT_CHAT_ERROR_UNKNOWN_KEY)
|
// case RS_DISTANT_CHAT_ERROR_SIGNATURE_MISMATCH: error_msg = QObject::tr("The link signature cannot be checked.") ; break ;
|
||||||
QMessageBox::information(NULL,QObject::tr("Chat connection is unauthenticated"),QObject::tr("Signature check failed!\nMake sure you know who you're talking to.")) ;
|
// case RS_DISTANT_CHAT_ERROR_UNKNOWN_KEY: error_msg = QObject::tr("The link is signed by an unknown key.") ; break ;
|
||||||
|
// }
|
||||||
ChatDialog::chatFriend(dpid);
|
// QMessageBox::information(NULL,QObject::tr("Chat connection is not possible"),error_msg) ;
|
||||||
}
|
// }
|
||||||
}
|
// else
|
||||||
break ;
|
// {
|
||||||
|
// if(error_code == RS_DISTANT_CHAT_ERROR_UNKNOWN_KEY)
|
||||||
|
// QMessageBox::information(NULL,QObject::tr("Chat connection is unauthenticated"),QObject::tr("Signature check failed!\nMake sure you know who you're talking to.")) ;
|
||||||
|
//
|
||||||
|
// ChatDialog::chatFriend(dpid);
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// break ;
|
||||||
|
|
||||||
case TYPE_FILE:
|
case TYPE_FILE:
|
||||||
case TYPE_EXTRAFILE:
|
case TYPE_EXTRAFILE:
|
||||||
|
|
|
@ -98,9 +98,9 @@ void ChatDialog::init(const RsPeerId &peerId, const QString &title)
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32_t distant_peer_status ;
|
uint32_t distant_peer_status ;
|
||||||
RsPgpId distant_chat_pgp_id ;
|
RsGxsId distant_chat_gxs_id ;
|
||||||
|
|
||||||
if(rsMsgs->getDistantChatStatus(peerId,distant_peer_status,distant_chat_pgp_id))
|
if(rsMsgs->getDistantChatStatus(peerId,distant_chat_gxs_id,distant_peer_status))
|
||||||
chatflags = RS_CHAT_OPEN | RS_CHAT_FOCUS; // use own flags
|
chatflags = RS_CHAT_OPEN | RS_CHAT_FOCUS; // use own flags
|
||||||
|
|
||||||
if (chatflags & RS_CHAT_OPEN) {
|
if (chatflags & RS_CHAT_OPEN) {
|
||||||
|
@ -118,8 +118,8 @@ void ChatDialog::init(const RsPeerId &peerId, const QString &title)
|
||||||
} else if(distant_peer_status > 0) {
|
} else if(distant_peer_status > 0) {
|
||||||
cd = new PopupDistantChatDialog();
|
cd = new PopupDistantChatDialog();
|
||||||
chatDialogs[peerId] = cd;
|
chatDialogs[peerId] = cd;
|
||||||
std::string peer_name = rsPeers->getGPGName(distant_chat_pgp_id) ;
|
QString peer_name = cd->getPeerName(peerId) ;
|
||||||
cd->init(peerId, tr("Talking to ")+QString::fromStdString(peer_name)+" (PGP id="+QString::fromStdString(distant_chat_pgp_id.toStdString())+")") ;
|
cd->init(peerId, tr("Talking to ")+peer_name+" (GXS id="+QString::fromStdString(distant_chat_gxs_id.toStdString())+")") ;
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
RsPeerDetails sslDetails;
|
RsPeerDetails sslDetails;
|
||||||
|
@ -210,10 +210,10 @@ void ChatDialog::init(const RsPeerId &peerId, const QString &title)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
RsPgpId distant_chat_pgp_id ;
|
RsGxsId distant_chat_gxs_id ;
|
||||||
uint32_t distant_peer_status ;
|
uint32_t distant_peer_status ;
|
||||||
|
|
||||||
if(rsMsgs->getDistantChatStatus(peerId,distant_peer_status,distant_chat_pgp_id))
|
if(rsMsgs->getDistantChatStatus(peerId,distant_chat_gxs_id,distant_peer_status))
|
||||||
{
|
{
|
||||||
getChat(peerId, forceFocus ? RS_CHAT_OPEN | RS_CHAT_FOCUS : RS_CHAT_OPEN ); // use own flags
|
getChat(peerId, forceFocus ? RS_CHAT_OPEN | RS_CHAT_FOCUS : RS_CHAT_OPEN ); // use own flags
|
||||||
return ;
|
return ;
|
||||||
|
|
|
@ -49,6 +49,7 @@
|
||||||
#include "util/HandleRichText.h"
|
#include "util/HandleRichText.h"
|
||||||
|
|
||||||
#include <retroshare/rsstatus.h>
|
#include <retroshare/rsstatus.h>
|
||||||
|
#include <retroshare/rsidentity.h>
|
||||||
#include <retroshare/rspeers.h>
|
#include <retroshare/rspeers.h>
|
||||||
#include <retroshare/rshistory.h>
|
#include <retroshare/rshistory.h>
|
||||||
#include <retroshare/rsmsgs.h>
|
#include <retroshare/rsmsgs.h>
|
||||||
|
@ -187,8 +188,8 @@ void ChatWidget::init(const RsPeerId &peerId, const QString &title)
|
||||||
mChatType = CHATTYPE_LOBBY;
|
mChatType = CHATTYPE_LOBBY;
|
||||||
} else {
|
} else {
|
||||||
uint32_t status;
|
uint32_t status;
|
||||||
RsPgpId pgp_id;
|
RsGxsId gxs_id;
|
||||||
if (rsMsgs->getDistantChatStatus(peerId, status, pgp_id)) {
|
if (rsMsgs->getDistantChatStatus(peerId, gxs_id, status)) {
|
||||||
mChatType = CHATTYPE_DISTANT;
|
mChatType = CHATTYPE_DISTANT;
|
||||||
} else {
|
} else {
|
||||||
mChatType = CHATTYPE_PRIVATE;
|
mChatType = CHATTYPE_PRIVATE;
|
||||||
|
@ -952,10 +953,16 @@ void ChatWidget::updateStatus(const QString &peer_id, int status)
|
||||||
|
|
||||||
QString peerName ;
|
QString peerName ;
|
||||||
uint32_t stts ;
|
uint32_t stts ;
|
||||||
RsPgpId pgp_id ;
|
RsGxsId gxs_id ;
|
||||||
|
|
||||||
if(rsMsgs->getDistantChatStatus(peerId,stts,pgp_id))
|
if(rsMsgs->getDistantChatStatus(peerId,gxs_id,stts))
|
||||||
peerName = QString::fromUtf8(rsPeers->getGPGName(pgp_id).c_str());
|
{
|
||||||
|
RsIdentityDetails details ;
|
||||||
|
if(rsIdentity->getIdDetails(gxs_id,details))
|
||||||
|
peerName = QString::fromUtf8( details.mNickname.c_str() ) ;
|
||||||
|
else
|
||||||
|
peerName = QString::fromStdString(gxs_id.toStdString()) ;
|
||||||
|
}
|
||||||
else
|
else
|
||||||
peerName = QString::fromUtf8(rsPeers->getPeerName(peerId).c_str());
|
peerName = QString::fromUtf8(rsPeers->getPeerName(peerId).c_str());
|
||||||
|
|
||||||
|
|
|
@ -25,6 +25,7 @@
|
||||||
|
|
||||||
#include <retroshare/rsstatus.h>
|
#include <retroshare/rsstatus.h>
|
||||||
#include <retroshare/rspeers.h>
|
#include <retroshare/rspeers.h>
|
||||||
|
#include <retroshare/rsidentity.h>
|
||||||
|
|
||||||
#include "RsAutoUpdatePage.h"
|
#include "RsAutoUpdatePage.h"
|
||||||
#include "PopupDistantChatDialog.h"
|
#include "PopupDistantChatDialog.h"
|
||||||
|
@ -74,8 +75,8 @@ void PopupDistantChatDialog::updateDisplay()
|
||||||
//
|
//
|
||||||
|
|
||||||
uint32_t status= RS_DISTANT_CHAT_STATUS_UNKNOWN;
|
uint32_t status= RS_DISTANT_CHAT_STATUS_UNKNOWN;
|
||||||
RsPgpId pgp_id ;
|
RsGxsId gxs_id ;
|
||||||
rsMsgs->getDistantChatStatus(_pid,status,pgp_id) ;
|
rsMsgs->getDistantChatStatus(_pid,gxs_id,status) ;
|
||||||
|
|
||||||
switch(status)
|
switch(status)
|
||||||
{
|
{
|
||||||
|
@ -116,8 +117,8 @@ void PopupDistantChatDialog::closeEvent(QCloseEvent *e)
|
||||||
//std::cerr << "Closing window => closing distant chat for hash " << _pid << std::endl;
|
//std::cerr << "Closing window => closing distant chat for hash " << _pid << std::endl;
|
||||||
|
|
||||||
uint32_t status= RS_DISTANT_CHAT_STATUS_UNKNOWN;
|
uint32_t status= RS_DISTANT_CHAT_STATUS_UNKNOWN;
|
||||||
RsPgpId pgp_id ;
|
RsGxsId gxs_id ;
|
||||||
rsMsgs->getDistantChatStatus(_pid,status,pgp_id) ;
|
rsMsgs->getDistantChatStatus(_pid,gxs_id,status) ;
|
||||||
|
|
||||||
if(status != RS_DISTANT_CHAT_STATUS_REMOTELY_CLOSED)
|
if(status != RS_DISTANT_CHAT_STATUS_REMOTELY_CLOSED)
|
||||||
{
|
{
|
||||||
|
@ -140,10 +141,21 @@ void PopupDistantChatDialog::closeEvent(QCloseEvent *e)
|
||||||
QString PopupDistantChatDialog::getPeerName(const DistantChatPeerId &id) const
|
QString PopupDistantChatDialog::getPeerName(const DistantChatPeerId &id) const
|
||||||
{
|
{
|
||||||
uint32_t status ;
|
uint32_t status ;
|
||||||
RsPgpId pgp_id ;
|
RsGxsId gxs_id ;
|
||||||
|
|
||||||
if(rsMsgs->getDistantChatStatus(id,status,pgp_id))
|
if(rsMsgs->getDistantChatStatus(id,gxs_id,status))
|
||||||
return QString::fromStdString(rsPeers->getGPGName(pgp_id)) ;
|
{
|
||||||
|
RsIdentityDetails details ;
|
||||||
|
|
||||||
|
for(int i=0;i<3;++i)
|
||||||
|
if(rsIdentity->getIdDetails(gxs_id,details))
|
||||||
|
return QString::fromUtf8( details.mNickname.c_str() ) ;
|
||||||
|
else
|
||||||
|
usleep(500000) ; // sleep for 500 msec.
|
||||||
|
|
||||||
|
return QString::fromStdString(id.toStdString()) ;
|
||||||
|
}
|
||||||
else
|
else
|
||||||
return ChatDialog::getPeerName(id) ;
|
return ChatDialog::getPeerName(id) ;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -31,8 +31,6 @@ class PopupDistantChatDialog: public PopupChatDialog
|
||||||
{
|
{
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
|
||||||
friend class ChatDialog;
|
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
/** Default constructor */
|
/** Default constructor */
|
||||||
PopupDistantChatDialog(QWidget *parent = 0, Qt::WindowFlags flags = 0);
|
PopupDistantChatDialog(QWidget *parent = 0, Qt::WindowFlags flags = 0);
|
||||||
|
@ -51,6 +49,8 @@ class PopupDistantChatDialog: public PopupChatDialog
|
||||||
QTimer *_update_timer ;
|
QTimer *_update_timer ;
|
||||||
DistantChatPeerId _pid ;
|
DistantChatPeerId _pid ;
|
||||||
QLabel *_status_label ;
|
QLabel *_status_label ;
|
||||||
|
|
||||||
|
friend class ChatDialog;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -204,8 +204,12 @@ void GxsGroupFrameDialog::todo()
|
||||||
QMessageBox::information(this, "Todo", text(TEXT_TODO));
|
QMessageBox::information(this, "Todo", text(TEXT_TODO));
|
||||||
}
|
}
|
||||||
|
|
||||||
void GxsGroupFrameDialog::groupTreeCustomPopupMenu(QPoint /*point*/)
|
void GxsGroupFrameDialog::groupTreeCustomPopupMenu(QPoint point)
|
||||||
{
|
{
|
||||||
|
QString id = "" ;//ui->groupTreeWidget->itemIdAt(point);
|
||||||
|
if (id.isEmpty()) return;
|
||||||
|
|
||||||
|
mGroupId = RsGxsGroupId(id.toStdString());
|
||||||
int subscribeFlags = ui->groupTreeWidget->subscribeFlags(QString::fromStdString(mGroupId.toStdString()));
|
int subscribeFlags = ui->groupTreeWidget->subscribeFlags(QString::fromStdString(mGroupId.toStdString()));
|
||||||
|
|
||||||
bool isAdmin = IS_GROUP_ADMIN(subscribeFlags);
|
bool isAdmin = IS_GROUP_ADMIN(subscribeFlags);
|
||||||
|
|
|
@ -29,7 +29,6 @@
|
||||||
#include <retroshare/rspeers.h>
|
#include <retroshare/rspeers.h>
|
||||||
#include "ChatPage.h"
|
#include "ChatPage.h"
|
||||||
#include <gui/RetroShareLink.h>
|
#include <gui/RetroShareLink.h>
|
||||||
#include <gui/CreateMsgLinkDialog.h>
|
|
||||||
#include "gui/chat/ChatStyle.h"
|
#include "gui/chat/ChatStyle.h"
|
||||||
#include "gui/chat/ChatDialog.h"
|
#include "gui/chat/ChatDialog.h"
|
||||||
#include "gui/notifyqt.h"
|
#include "gui/notifyqt.h"
|
||||||
|
@ -105,7 +104,6 @@ ChatPage::ChatPage(QWidget * parent, Qt::WindowFlags flags)
|
||||||
ui.minimumContrast->hide();
|
ui.minimumContrast->hide();
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
connect(ui._personal_invites_LW, SIGNAL(customContextMenuRequested(QPoint)), this, SLOT(personalInvites_customPopupMenu(QPoint)));
|
|
||||||
connect(ui._collected_contacts_LW, SIGNAL(customContextMenuRequested(QPoint)), this, SLOT(collectedContacts_customPopupMenu(QPoint)));
|
connect(ui._collected_contacts_LW, SIGNAL(customContextMenuRequested(QPoint)), this, SLOT(collectedContacts_customPopupMenu(QPoint)));
|
||||||
|
|
||||||
/* Hide platform specific features */
|
/* Hide platform specific features */
|
||||||
|
@ -131,8 +129,6 @@ void ChatPage::collectedContacts_customPopupMenu(QPoint p)
|
||||||
if(selected.size() == 1)
|
if(selected.size() == 1)
|
||||||
contextMnu.addAction( QIcon(IMAGE_CHAT_OPEN), tr("Open secured chat tunnel"), this, SLOT(collectedInvite_openDistantChat()) ) ;
|
contextMnu.addAction( QIcon(IMAGE_CHAT_OPEN), tr("Open secured chat tunnel"), this, SLOT(collectedInvite_openDistantChat()) ) ;
|
||||||
|
|
||||||
contextMnu.addAction( QIcon(IMAGE_CHAT_DELETE), tr("Delete this invite"), this, SLOT(collectedInvite_delete()) ) ;
|
|
||||||
|
|
||||||
contextMnu.exec(QCursor::pos());
|
contextMnu.exec(QCursor::pos());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -140,110 +136,16 @@ void ChatPage::collectedInvite_openDistantChat()
|
||||||
{
|
{
|
||||||
QList<QListWidgetItem*> selected = ui._collected_contacts_LW->selectedItems() ;
|
QList<QListWidgetItem*> selected = ui._collected_contacts_LW->selectedItems() ;
|
||||||
|
|
||||||
RsPeerId virtual_peer_id( (*selected.begin())->data(Qt::UserRole).toString().toStdString() );
|
RsGxsId gxs_id( (*selected.begin())->data(Qt::UserRole).toString().toStdString() );
|
||||||
|
|
||||||
std::cerr << "Openning secured chat tunnel for virtual peer id " << virtual_peer_id << ". Please wait..." << std::endl;
|
std::cerr << "Openning secured chat tunnel for virtual peer id " << gxs_id << ". Please wait..." << std::endl;
|
||||||
uint32_t error_code ;
|
uint32_t error_code ;
|
||||||
|
DistantChatPeerId dcpid ;
|
||||||
|
|
||||||
if(!rsMsgs->initiateDistantChatConnexion(virtual_peer_id,error_code))
|
if(!rsMsgs->initiateDistantChatConnexion(gxs_id,dcpid,error_code))
|
||||||
QMessageBox::critical(NULL,tr("Can't open distant chat"),tr("Cannot open distant chat. Error code=")+QString::number(error_code)) ;
|
QMessageBox::critical(NULL,tr("Can't open distant chat"),tr("Cannot open distant chat. Error code=")+QString::number(error_code)) ;
|
||||||
else
|
else
|
||||||
ChatDialog::chatFriend(virtual_peer_id);
|
ChatDialog::chatFriend(dcpid);
|
||||||
}
|
|
||||||
|
|
||||||
void ChatPage::collectedInvite_delete()
|
|
||||||
{
|
|
||||||
QList<QListWidgetItem*> selected = ui._collected_contacts_LW->selectedItems() ;
|
|
||||||
|
|
||||||
for(QList<QListWidgetItem*>::const_iterator it(selected.begin());it!=selected.end();++it)
|
|
||||||
{
|
|
||||||
RsPeerId virtual_peer_id ( (*it)->data(Qt::UserRole).toString().toStdString() );
|
|
||||||
|
|
||||||
std::cerr << "Removing chat invite for virtual_peer_id " << virtual_peer_id << std::endl;
|
|
||||||
|
|
||||||
if(!rsMsgs->removeDistantChatInvite(virtual_peer_id))
|
|
||||||
QMessageBox::critical(NULL,tr("Can't open distant chat"),tr("Cannot remove distant chat invite.")) ;
|
|
||||||
}
|
|
||||||
|
|
||||||
load() ;
|
|
||||||
}
|
|
||||||
|
|
||||||
void ChatPage::personalInvites_customPopupMenu(QPoint p)
|
|
||||||
{
|
|
||||||
// items: create invite, copy to clipboard, delete
|
|
||||||
std::cerr << "In custom popup menu" << std::endl;
|
|
||||||
|
|
||||||
QList<QListWidgetItem*> selected = ui._personal_invites_LW->selectedItems() ;
|
|
||||||
|
|
||||||
QMenu contextMnu( this );
|
|
||||||
|
|
||||||
contextMnu.addAction( QIcon(IMAGE_CHAT_CREATE), tr("Create a chat invitation"), this, SLOT(personalInvites_create()) ) ;
|
|
||||||
|
|
||||||
if(!selected.empty())
|
|
||||||
{
|
|
||||||
contextMnu.addAction( QIcon(IMAGE_CHAT_COPY), tr("Copy link to clipboard"), this, SLOT(personalInvites_copyLink()) ) ;
|
|
||||||
contextMnu.addAction( QIcon(IMAGE_CHAT_DELETE), tr("Delete this invite"), this, SLOT(personalInvites_delete()) ) ;
|
|
||||||
}
|
|
||||||
|
|
||||||
contextMnu.exec(QCursor::pos());
|
|
||||||
}
|
|
||||||
|
|
||||||
void ChatPage::personalInvites_copyLink()
|
|
||||||
{
|
|
||||||
QList<QListWidgetItem*> selected = ui._personal_invites_LW->selectedItems() ;
|
|
||||||
QList<RetroShareLink> links ;
|
|
||||||
|
|
||||||
std::vector<DistantChatInviteInfo> invites ;
|
|
||||||
rsMsgs->getDistantChatInviteList(invites) ;
|
|
||||||
|
|
||||||
for(QList<QListWidgetItem*>::const_iterator it(selected.begin());it!=selected.end();++it)
|
|
||||||
{
|
|
||||||
RsPeerId virtual_peer_id ( (*it)->data(Qt::UserRole).toString().toStdString() );
|
|
||||||
|
|
||||||
bool found = false ;
|
|
||||||
for(uint32_t i=0;i<invites.size();++i)
|
|
||||||
if(invites[i].pid == virtual_peer_id)
|
|
||||||
{
|
|
||||||
RetroShareLink link ;
|
|
||||||
|
|
||||||
if(!link.createPrivateChatInvite(invites[i].time_of_validity,QString::fromStdString(invites[i].destination_pgp_id.toStdString()),QString::fromStdString(invites[i].encrypted_radix64_string)))
|
|
||||||
{
|
|
||||||
std::cerr << "Cannot create link." << std::endl;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
links.push_back(link) ;
|
|
||||||
break ;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if(!links.empty())
|
|
||||||
RSLinkClipboard::copyLinks(links) ;
|
|
||||||
}
|
|
||||||
|
|
||||||
void ChatPage::personalInvites_delete()
|
|
||||||
{
|
|
||||||
QList<QListWidgetItem*> selected = ui._personal_invites_LW->selectedItems() ;
|
|
||||||
QList<RetroShareLink> links ;
|
|
||||||
|
|
||||||
for(QList<QListWidgetItem*>::const_iterator it(selected.begin());it!=selected.end();++it)
|
|
||||||
{
|
|
||||||
RsPeerId virtual_peer_id ( (*it)->data(Qt::UserRole).toString().toStdString() );
|
|
||||||
|
|
||||||
rsMsgs->removeDistantChatInvite(virtual_peer_id) ;
|
|
||||||
}
|
|
||||||
load() ;
|
|
||||||
}
|
|
||||||
|
|
||||||
void ChatPage::personalInvites_create()
|
|
||||||
{
|
|
||||||
// Call the link creation box
|
|
||||||
|
|
||||||
CreateMsgLinkDialog::createNewChatLink() ;
|
|
||||||
|
|
||||||
// Now update the page
|
|
||||||
//
|
|
||||||
load() ;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Saves the changes on this page */
|
/** Saves the changes on this page */
|
||||||
|
@ -388,18 +290,8 @@ ChatPage::load()
|
||||||
|
|
||||||
// load personal invites
|
// load personal invites
|
||||||
//
|
//
|
||||||
std::vector<DistantChatInviteInfo> invites ;
|
#ifdef TO_BE_DONE
|
||||||
rsMsgs->getDistantChatInviteList(invites) ;
|
for()
|
||||||
|
|
||||||
ui._personal_invites_LW->clear() ;
|
|
||||||
ui._collected_contacts_LW->clear() ;
|
|
||||||
|
|
||||||
for(uint32_t i=0;i<invites.size();++i)
|
|
||||||
{
|
|
||||||
RsPeerDetails detail ;
|
|
||||||
rsPeers->getGPGDetails(invites[i].destination_pgp_id,detail) ;
|
|
||||||
|
|
||||||
if(invites[i].encrypted_radix64_string.empty())
|
|
||||||
{
|
{
|
||||||
QListWidgetItem *item = new QListWidgetItem;
|
QListWidgetItem *item = new QListWidgetItem;
|
||||||
item->setData(Qt::DisplayRole,tr("Private chat invite from ")+QString::fromUtf8(detail.name.c_str())) ;
|
item->setData(Qt::DisplayRole,tr("Private chat invite from ")+QString::fromUtf8(detail.name.c_str())) ;
|
||||||
|
@ -409,37 +301,12 @@ ChatPage::load()
|
||||||
tt += "\n" + QString("PGP id : ") + QString::fromStdString(invites[i].destination_pgp_id.toStdString()) ;
|
tt += "\n" + QString("PGP id : ") + QString::fromStdString(invites[i].destination_pgp_id.toStdString()) ;
|
||||||
tt += "\n" + QString("Valid until : ") + QDateTime::fromTime_t(invites[i].time_of_validity).toString() ;
|
tt += "\n" + QString("Valid until : ") + QDateTime::fromTime_t(invites[i].time_of_validity).toString() ;
|
||||||
|
|
||||||
if(invites[i].invite_flags & RS_DISTANT_CHAT_FLAG_SIGNED)
|
|
||||||
if(invites[i].invite_flags & RS_DISTANT_CHAT_FLAG_SIGNATURE_OK)
|
|
||||||
{
|
|
||||||
tt += "\n"+tr("Authenticated signature") ;
|
|
||||||
item->setIcon(QIcon(":images/stock_signature_ok.png")) ;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
tt += "\n"+tr("Signed with key not in keyring") ;
|
|
||||||
item->setIcon(QIcon(":images/stock_signature_unverified.png")) ;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
tt += "\n"+tr("Not signed.") ;
|
|
||||||
item->setIcon(QIcon(":images/stock_signature_missing.png")) ;
|
|
||||||
}
|
|
||||||
|
|
||||||
item->setData(Qt::UserRole,QString::fromStdString(invites[i].pid.toStdString())) ;
|
item->setData(Qt::UserRole,QString::fromStdString(invites[i].pid.toStdString())) ;
|
||||||
item->setToolTip(tt) ;
|
item->setToolTip(tt) ;
|
||||||
|
|
||||||
ui._collected_contacts_LW->insertItem(0,item) ;
|
ui._collected_contacts_LW->insertItem(0,item) ;
|
||||||
}
|
}
|
||||||
else
|
#endif
|
||||||
{
|
|
||||||
QListWidgetItem *item = new QListWidgetItem;
|
|
||||||
item->setData(Qt::DisplayRole,tr("Private chat invite to ")+QString::fromStdString(detail.name)+" ("+QString::fromStdString(invites[i].destination_pgp_id.toStdString())+", " + QString::fromStdString(detail.name) + ", valid until " + QDateTime::fromTime_t(invites[i].time_of_validity).toString() + ")") ;
|
|
||||||
item->setData(Qt::UserRole,QString::fromStdString(invites[i].pid.toStdString())) ;
|
|
||||||
|
|
||||||
ui._personal_invites_LW->insertItem(0,item) ;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void ChatPage::on_pushButtonChangeChatFont_clicked()
|
void ChatPage::on_pushButtonChangeChatFont_clicked()
|
||||||
|
|
|
@ -53,15 +53,8 @@ class ChatPage : public ConfigPage
|
||||||
void on_privateList_currentRowChanged(int currentRow);
|
void on_privateList_currentRowChanged(int currentRow);
|
||||||
void on_historyList_currentRowChanged(int currentRow);
|
void on_historyList_currentRowChanged(int currentRow);
|
||||||
|
|
||||||
void personalInvites_customPopupMenu(QPoint) ;
|
|
||||||
void collectedContacts_customPopupMenu(QPoint) ;
|
void collectedContacts_customPopupMenu(QPoint) ;
|
||||||
|
|
||||||
void personalInvites_copyLink() ;
|
|
||||||
void personalInvites_delete() ;
|
|
||||||
void personalInvites_create() ;
|
|
||||||
|
|
||||||
void collectedInvite_openDistantChat() ;
|
void collectedInvite_openDistantChat() ;
|
||||||
void collectedInvite_delete() ;
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void setPreviewMessages(QString &stylePath, QString styleVariant, QTextBrowser *textBrowser);
|
void setPreviewMessages(QString &stylePath, QString styleVariant, QTextBrowser *textBrowser);
|
||||||
|
|
|
@ -14,7 +14,7 @@
|
||||||
<item row="3" column="0">
|
<item row="3" column="0">
|
||||||
<widget class="QTabWidget" name="tabWidget">
|
<widget class="QTabWidget" name="tabWidget">
|
||||||
<property name="currentIndex">
|
<property name="currentIndex">
|
||||||
<number>0</number>
|
<number>1</number>
|
||||||
</property>
|
</property>
|
||||||
<widget class="QWidget" name="general">
|
<widget class="QWidget" name="general">
|
||||||
<attribute name="title">
|
<attribute name="title">
|
||||||
|
@ -344,40 +344,6 @@
|
||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
<item>
|
|
||||||
<widget class="QGroupBox" name="groupBox_3">
|
|
||||||
<property name="sizePolicy">
|
|
||||||
<sizepolicy hsizetype="Preferred" vsizetype="MinimumExpanding">
|
|
||||||
<horstretch>0</horstretch>
|
|
||||||
<verstretch>0</verstretch>
|
|
||||||
</sizepolicy>
|
|
||||||
</property>
|
|
||||||
<property name="minimumSize">
|
|
||||||
<size>
|
|
||||||
<width>0</width>
|
|
||||||
<height>100</height>
|
|
||||||
</size>
|
|
||||||
</property>
|
|
||||||
<property name="title">
|
|
||||||
<string>Your personal invites</string>
|
|
||||||
</property>
|
|
||||||
<layout class="QHBoxLayout" name="horizontalLayout_2">
|
|
||||||
<item>
|
|
||||||
<widget class="QListWidget" name="_personal_invites_LW">
|
|
||||||
<property name="sizePolicy">
|
|
||||||
<sizepolicy hsizetype="Expanding" vsizetype="Ignored">
|
|
||||||
<horstretch>0</horstretch>
|
|
||||||
<verstretch>0</verstretch>
|
|
||||||
</sizepolicy>
|
|
||||||
</property>
|
|
||||||
<property name="contextMenuPolicy">
|
|
||||||
<enum>Qt::CustomContextMenu</enum>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
</layout>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item>
|
<item>
|
||||||
<widget class="QGroupBox" name="groupBox_4">
|
<widget class="QGroupBox" name="groupBox_4">
|
||||||
<property name="sizePolicy">
|
<property name="sizePolicy">
|
||||||
|
@ -387,7 +353,7 @@
|
||||||
</sizepolicy>
|
</sizepolicy>
|
||||||
</property>
|
</property>
|
||||||
<property name="title">
|
<property name="title">
|
||||||
<string>Collected contacts</string>
|
<string>People around you can chat to</string>
|
||||||
</property>
|
</property>
|
||||||
<layout class="QHBoxLayout" name="horizontalLayout_4">
|
<layout class="QHBoxLayout" name="horizontalLayout_4">
|
||||||
<item>
|
<item>
|
||||||
|
|
|
@ -309,7 +309,6 @@ HEADERS += rshare.h \
|
||||||
gui/MainWindow.h \
|
gui/MainWindow.h \
|
||||||
gui/RSHumanReadableDelegate.h \
|
gui/RSHumanReadableDelegate.h \
|
||||||
gui/AboutDialog.h \
|
gui/AboutDialog.h \
|
||||||
gui/CreateMsgLinkDialog.h \
|
|
||||||
gui/NetworkView.h \
|
gui/NetworkView.h \
|
||||||
gui/MessengerWindow.h \
|
gui/MessengerWindow.h \
|
||||||
gui/FriendsDialog.h \
|
gui/FriendsDialog.h \
|
||||||
|
@ -526,7 +525,6 @@ FORMS += gui/StartDialog.ui \
|
||||||
gui/FileTransfer/TurtleRouterStatistics.ui \
|
gui/FileTransfer/TurtleRouterStatistics.ui \
|
||||||
gui/FileTransfer/DetailsDialog.ui \
|
gui/FileTransfer/DetailsDialog.ui \
|
||||||
gui/MainWindow.ui \
|
gui/MainWindow.ui \
|
||||||
gui/CreateMsgLinkDialog.ui \
|
|
||||||
gui/NetworkView.ui \
|
gui/NetworkView.ui \
|
||||||
gui/MessengerWindow.ui \
|
gui/MessengerWindow.ui \
|
||||||
gui/FriendsDialog.ui \
|
gui/FriendsDialog.ui \
|
||||||
|
@ -634,7 +632,6 @@ SOURCES += main.cpp \
|
||||||
gui/graphframe.cpp \
|
gui/graphframe.cpp \
|
||||||
gui/mainpagestack.cpp \
|
gui/mainpagestack.cpp \
|
||||||
gui/MainWindow.cpp \
|
gui/MainWindow.cpp \
|
||||||
gui/CreateMsgLinkDialog.cpp \
|
|
||||||
gui/NetworkView.cpp \
|
gui/NetworkView.cpp \
|
||||||
gui/MessengerWindow.cpp \
|
gui/MessengerWindow.cpp \
|
||||||
gui/FriendsDialog.cpp \
|
gui/FriendsDialog.cpp \
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue