Merge branch 'master'

This commit is contained in:
zeners 2016-03-26 23:24:29 +01:00
commit 922644f03e
56 changed files with 6676 additions and 4685 deletions

47
TODO.circles.txt Normal file
View file

@ -0,0 +1,47 @@
Legend:
[X]: done, [ ]: pending, [-]: Cancelled, [/]: ongoing
GUI
[X] disable edit circles or make it work
[X] make GUI update when creating a circle
[ ] handle the display of encrypted forums/channels/etc when we do not have the keys
[ ] disable posting to circles for which we do not have the rights
[ ] warn about creating a circle without one of your ids in it
[X] group "show details" should be made up to date for restrinction options
[ ] allow to share circles publish rights
[X] allow non admin to see circles details but not edit
[ ] update TS of groups linked to a modified circle, so as to cause updates when a new member is addded to the group
[X] forums GUI should show correct restriction options for restricted forums
[X] changing a circle's name should update the GUI
[ ] make sure we cannot post in forums using IDs that are not in the circle
[ ] make sure unauthorised ids are rejected when validating posts from a circle restricted group
[ ] add GUI for local circles in circle GUI
[ ] share publish rights between circles
[ ] clean GUI (hide IDs)
Tests
[X] create a safe testing environment: 2 peers with no other contacts, 2 IDs each, and some forums
[X] test #001: transactions should encrypt and decrypt ok on both sides
[X] test #002: peers inside a circles should see the data
[X] test #003: peers outside of a circles shouldn't see the data
[-] test #004: peers subscribed to encrypted circles shouldn't keep asking for the data if they cannot decrypt
[X] test #005: peers can be added/removed from circles, and the circles update between friends
[ ] test #006: peers subscribed to encrypted circles who recently got added to the circle should get the data
[ ] test #007: peers outside a circle shouldn't be able to post (or posts shouldn't propagate)
Backend
[X] add debug output later RS_NXS_DEBUG_7 in rsgxsnetservice.cc for the crypto layer
Bugs
[X] Peers cannot be removed from a circle
[X] Context menu should not allow to edit non admin circles
[X] Editing circles make them subscribed, even non admin ones.
[X] Disable autosync for circles (in rsinit.cc)
[-] Add explicit circle sync request for all grps restricted to a circle (same as IDs)
[X] when a peer receives a circle, there is no way to view its details, only the id is available
[X] if a peer has circles available in "Circles (others)"... if you click on
"Create Circle" on the gui, then all circles are automatically subscribed

View file

@ -66,6 +66,7 @@ public:
std::cerr << "!!!!!! Received Data status from global router, but the client service is not handling it !!!!!!!!!!" << std::endl ;
std::cerr << " message ID = " << received_id << std::endl;
std::cerr << " data status = " << data_status << std::endl;
std::cerr << " signer ID = " << signer_id << std::endl;
}
// This function is mandatory. It should do two things:

View file

@ -34,6 +34,11 @@
* #define GXS_SECURITY_DEBUG 1
***/
static const uint32_t MULTI_ENCRYPTION_FORMAT_v001_HEADER = 0xFACE;
static const uint32_t MULTI_ENCRYPTION_FORMAT_v001_HEADER_SIZE = 2 ;
static const uint32_t MULTI_ENCRYPTION_FORMAT_v001_NUMBER_OF_KEYS_SIZE = 2 ;
static const uint32_t MULTI_ENCRYPTION_FORMAT_v001_ENCRYPTED_KEY_SIZE = 256 ;
static RsGxsId getRsaKeyFingerprint(RSA *pubkey)
{
int lenn = BN_num_bytes(pubkey -> n);
@ -93,7 +98,9 @@ static void setRSAPublicKeyData(RsTlvSecurityKey & key, RSA *rsa_pub)
bool GxsSecurity::checkPrivateKey(const RsTlvSecurityKey& key)
{
#ifdef GXS_SECURITY_DEBUG
std::cerr << "Checking private key " << key.keyId << " ..." << std::endl;
#endif
if( (key.keyFlags & RSTLV_KEY_TYPE_MASK) != RSTLV_KEY_TYPE_FULL)
{
@ -128,7 +135,9 @@ bool GxsSecurity::checkPrivateKey(const RsTlvSecurityKey& key)
}
bool GxsSecurity::checkPublicKey(const RsTlvSecurityKey& key)
{
#ifdef GXS_SECURITY_DEBUG
std::cerr << "Checking public key " << key.keyId << " ..." << std::endl;
#endif
if( (key.keyFlags & RSTLV_KEY_TYPE_MASK) != RSTLV_KEY_TYPE_PUBLIC_ONLY)
{
@ -224,7 +233,7 @@ bool GxsSecurity::extractPublicKey(const RsTlvSecurityKey& private_key,RsTlvSecu
{
std::cerr << std::endl;
std::cerr << "WARNING: GXS ID key pair " << private_key.keyId << " has inconsistent fingerprint. This is an old key " << std::endl;
std::cerr << " that is unsecured (can be faked easily) should not be used anymore. Please delete it." << std::endl;
std::cerr << " that is unsecure (can be faked easily). You should delete it!" << std::endl;
std::cerr << std::endl;
public_key.keyId = private_key.keyId ;
@ -410,6 +419,11 @@ bool GxsSecurity::encrypt(uint8_t *& out, uint32_t &outlen, const uint8_t *in, u
#ifdef DISTRIB_DEBUG
std::cerr << "GxsSecurity::encrypt() " << std::endl;
#endif
// Encrypts (in,inlen) into (out,outlen) using the given RSA public key.
// The format of the encrypted data is:
//
// [--- Encrypted session key length ---|--- Encrypted session key ---|--- IV ---|---- Encrypted data ---]
//
RSA *tmpkey = ::extractPublicKey(key) ;
RSA *rsa_publish_pub = RSAPublicKey_dup(tmpkey) ;
@ -511,11 +525,157 @@ bool GxsSecurity::encrypt(uint8_t *& out, uint32_t &outlen, const uint8_t *in, u
return true;
}
bool GxsSecurity::encrypt(uint8_t *& out, uint32_t &outlen, const uint8_t *in, uint32_t inlen, const std::vector<RsTlvSecurityKey>& keys)
{
#ifdef DISTRIB_DEBUG
std::cerr << "GxsSecurity::encrypt() " << std::endl;
#endif
// Encrypts (in,inlen) into (out,outlen) using the given RSA public key.
// The format of the encrypted data is:
//
// [--- ID ---|--- number of encrypted keys---| n * (--- Encrypted session keys ---) |--- IV ---|---- Encrypted data ---]
// 2 bytes 2 byte = n 256 bytes EVP_MAX_IV_LENGTH Rest of packet
//
out = NULL ;
try
{
std::vector<EVP_PKEY *> public_keys(keys.size(),NULL);
for(uint32_t i=0;i<keys.size();++i)
{
RSA *tmpkey = ::extractPublicKey(keys[i]) ;
RSA *rsa_publish_pub = RSAPublicKey_dup(tmpkey) ;
RSA_free(tmpkey) ;
if(rsa_publish_pub != NULL)
{
public_keys[i] = EVP_PKEY_new();
EVP_PKEY_assign_RSA(public_keys[i], rsa_publish_pub);
}
else
{
std::cerr << "GxsSecurity(): Could not generate public key for key id " << keys[i].keyId << std::endl;
throw std::runtime_error("Cannot extract public key") ;
}
}
EVP_CIPHER_CTX ctx;
unsigned char iv[EVP_MAX_IV_LENGTH];
EVP_CIPHER_CTX_init(&ctx);
std::vector<unsigned char *> ek(keys.size(),NULL) ;
std::vector<int> eklen(keys.size(),0) ;
for(uint32_t i=0;i<keys.size();++i)
{
int max_evp_key_size = EVP_PKEY_size(public_keys[i]);
if(max_evp_key_size != MULTI_ENCRYPTION_FORMAT_v001_ENCRYPTED_KEY_SIZE)
throw std::runtime_error("EVP_PKEY_size should be equal to 256. It's not!") ;
ek[i] = (unsigned char*)rs_malloc(max_evp_key_size);
if(ek[i] == NULL)
throw std::runtime_error("malloc error on encrypted keys") ;
}
const EVP_CIPHER *cipher = EVP_aes_128_cbc();
int cipher_block_size = EVP_CIPHER_block_size(cipher);
// intialize context and send store encrypted cipher in ek
if(!EVP_SealInit(&ctx, EVP_aes_128_cbc(), ek.data(), eklen.data(), iv, public_keys.data(), keys.size()))
return false;
int total_ek_size = MULTI_ENCRYPTION_FORMAT_v001_ENCRYPTED_KEY_SIZE * keys.size() ;
int max_outlen = MULTI_ENCRYPTION_FORMAT_v001_HEADER_SIZE + MULTI_ENCRYPTION_FORMAT_v001_NUMBER_OF_KEYS_SIZE + total_ek_size + EVP_MAX_IV_LENGTH + (inlen + cipher_block_size) ;
// now assign memory to out accounting for data, and cipher block size, key length, and key length val
out = (uint8_t*)rs_malloc(max_outlen);
if(out == NULL)
return false ;
int out_offset = 0;
// header
out[out_offset++] = MULTI_ENCRYPTION_FORMAT_v001_HEADER & 0xff ;
out[out_offset++] = (MULTI_ENCRYPTION_FORMAT_v001_HEADER >> 8) & 0xff ;
// number of keys
out[out_offset++] = keys.size() & 0xff ;
out[out_offset++] = (keys.size() >> 8) & 0xff ;
// encrypted keys, each preceeded with its length
for(uint32_t i=0;i<keys.size();++i)
{
if(eklen[i] != MULTI_ENCRYPTION_FORMAT_v001_ENCRYPTED_KEY_SIZE)
{
std::cerr << "(EE) eklen[i]=" << eklen[i] << " in " << __PRETTY_FUNCTION__ << " for key id " << keys[i].keyId << ". This is unexpected. Cannot encrypt." << std::endl;
throw std::runtime_error("Encryption error") ;
}
memcpy((unsigned char*)out + out_offset, ek[i],eklen[i]) ;
out_offset += eklen[i] ;
}
memcpy((unsigned char*)out + out_offset, iv, EVP_MAX_IV_LENGTH);
out_offset += EVP_MAX_IV_LENGTH;
int out_currOffset = 0;
// now encrypt actual data
if(!EVP_SealUpdate(&ctx, (unsigned char*) out + out_offset, &out_currOffset, (unsigned char*) in, inlen))
throw std::runtime_error("Encryption error in SealUpdate()") ;
// move along to partial block space
out_offset += out_currOffset;
// add padding
if(!EVP_SealFinal(&ctx, (unsigned char*) out + out_offset, &out_currOffset))
throw std::runtime_error("Encryption error in SealFinal()") ;
// move to end
out_offset += out_currOffset;
// make sure offset has not gone passed valid memory bounds
if(out_offset > max_outlen)
throw std::runtime_error("Memory used by encryption exceeds allocated memory block") ;
// free encrypted key data
for(uint32_t i=0;i<keys.size();++i)
if(ek[i]) free(ek[i]);
outlen = out_offset;
return true;
}
catch(std::exception& e)
{
std::cerr << "(EE) Exception caught while encrypting: " << e.what() << std::endl;
if(out) free(out) ;
out = NULL ;
return false ;
}
}
bool GxsSecurity::decrypt(uint8_t *& out, uint32_t & outlen, const uint8_t *in, uint32_t inlen, const RsTlvSecurityKey& key)
{
// Decrypts (in,inlen) into (out,outlen) using the given RSA public key.
// The format of the encrypted data (in) is:
//
// [--- Encrypted session key length ---|--- Encrypted session key ---|--- IV ---|---- Encrypted data ---]
//
// This method can be used to decrypt multi-encrypted data, if passing he correct encrypted key block (corresponding to the given key)
#ifdef DISTRIB_DEBUG
#ifdef GXS_SECURITY_DEBUG
std::cerr << "GxsSecurity::decrypt() " << std::endl;
#endif
RSA *rsa_publish = extractPrivateKey(key) ;
@ -531,7 +691,7 @@ bool GxsSecurity::decrypt(uint8_t *& out, uint32_t & outlen, const uint8_t *in,
}
else
{
#ifdef DISTRIB_DEBUG
#ifdef GXS_SECURITY_DEBUG
std::cerr << "GxsSecurity(): Could not generate publish key " << grpId
<< std::endl;
#endif
@ -572,9 +732,13 @@ bool GxsSecurity::decrypt(uint8_t *& out, uint32_t & outlen, const uint8_t *in,
const EVP_CIPHER* cipher = EVP_aes_128_cbc();
if(!EVP_OpenInit(&ctx, cipher, ek, eklen, iv, privateKey)) return false;
if(!EVP_OpenInit(&ctx, cipher, ek, eklen, iv, privateKey))
{
std::cerr << "(EE) Cannot decrypt data. Most likely reason: private GXS key is missing." << std::endl;
return false;
}
if(inlen < in_offset)
if(inlen < (uint32_t)in_offset)
{
std::cerr << "Severe error in " << __PRETTY_FUNCTION__ << ": cannot encrypt. " << std::endl;
return false ;
@ -606,7 +770,144 @@ bool GxsSecurity::decrypt(uint8_t *& out, uint32_t & outlen, const uint8_t *in,
return true;
}
bool GxsSecurity::decrypt(uint8_t *& out, uint32_t & outlen, const uint8_t *in, uint32_t inlen, const std::vector<RsTlvSecurityKey>& keys)
{
// Decrypts (in,inlen) into (out,outlen) using one of the given RSA public keys, trying them all in a row.
// The format of the encrypted data is:
//
// [--- ID ---|--- number of encrypted keys---| n * (--- Encrypted session keys ---) |--- IV ---|---- Encrypted data ---]
// 2 bytes 2 byte = n 256 bytes EVP_MAX_IV_LENGTH Rest of packet
//
// This method can be used to decrypt multi-encrypted data, if passing he correct encrypted key block (corresponding to the given key)
#ifdef DISTRIB_DEBUG
std::cerr << "GxsSecurity::decrypt() " << std::endl;
#endif
try
{
// check that the input block has a valid format.
uint32_t offset = 0 ;
uint16_t format_id = in[offset] + (in[offset+1] << 8) ;
if(format_id != MULTI_ENCRYPTION_FORMAT_v001_HEADER)
{
std::cerr << "Unrecognised format in encrypted block. Header id = " << std::hex << format_id << std::dec << std::endl;
throw std::runtime_error("Unrecognised format in encrypted block.") ;
}
offset += MULTI_ENCRYPTION_FORMAT_v001_HEADER_SIZE;
// read number of encrypted keys
uint32_t number_of_keys = in[offset] + (in[offset+1] << 8) ;
offset += MULTI_ENCRYPTION_FORMAT_v001_NUMBER_OF_KEYS_SIZE;
// reach the actual data offset
uint32_t encrypted_keys_offset = offset ;
uint32_t encrypted_block_size = 0 ;
uint32_t IV_offset = offset + number_of_keys * MULTI_ENCRYPTION_FORMAT_v001_ENCRYPTED_KEY_SIZE ;
uint32_t encrypted_block_offset = IV_offset + EVP_MAX_IV_LENGTH ;
// read IV offset
if(encrypted_block_offset >= inlen)
throw std::runtime_error("Offset error") ;
encrypted_block_size = inlen - encrypted_block_offset ;
#ifdef GXS_SECURITY_DEBUG
std::cerr << " number of keys in envelop: " << number_of_keys << std::endl;
std::cerr << " IV offset : " << IV_offset << std::endl;
std::cerr << " encrypted block offset : " << encrypted_block_offset << std::endl;
std::cerr << " encrypted block size : " << encrypted_block_size << std::endl;
#endif
// decrypt
EVP_CIPHER_CTX ctx;
EVP_CIPHER_CTX_init(&ctx);
bool succeed = false;
for(uint32_t j=0;j<keys.size() && !succeed;++j)
{
RSA *rsa_private = extractPrivateKey(keys[j]) ;
EVP_PKEY *privateKey = NULL;
#ifdef GXS_SECURITY_DEBUG
std::cerr << " trying key " << keys[j].keyId << std::endl;
#endif
if(rsa_private != NULL)
{
privateKey = EVP_PKEY_new();
EVP_PKEY_assign_RSA(privateKey, rsa_private);
}
else
{
RSA_free(rsa_private) ;
std::cerr << "(EE) Cannot extract private key from key Id " << keys[j].keyId << ". This is a bug. Non owned key?" << std::endl;
continue ;
}
for(uint32_t i=0;i<number_of_keys && !succeed;++i)
{
succeed = EVP_OpenInit(&ctx, EVP_aes_128_cbc(),in + encrypted_keys_offset + i*MULTI_ENCRYPTION_FORMAT_v001_ENCRYPTED_KEY_SIZE , MULTI_ENCRYPTION_FORMAT_v001_ENCRYPTED_KEY_SIZE, in+IV_offset, privateKey);
#ifdef GXS_SECURITY_DEBUG
std::cerr << " encrypted key at offset " << encrypted_keys_offset + i*MULTI_ENCRYPTION_FORMAT_v001_ENCRYPTED_KEY_SIZE << ": " << succeed << std::endl;
#endif
}
EVP_PKEY_free(privateKey) ;
}
if(!succeed)
throw std::runtime_error("No matching key available.") ;
#ifdef GXS_SECURITY_DEBUG
std::cerr << " now decrypting with the matching key." << std::endl;
#endif
out = (uint8_t*)rs_malloc(encrypted_block_size) ;
if(out == NULL)
throw std::runtime_error("Memory allocation error") ;
int out_currOffset = 0 ;
if(!EVP_OpenUpdate(&ctx, (unsigned char*) out, &out_currOffset, (unsigned char*)in + encrypted_block_offset, encrypted_block_size))
throw std::runtime_error("Decryption error in EVP_OpenUpdate") ;
outlen = out_currOffset;
if(!EVP_OpenFinal(&ctx, (unsigned char*)out + out_currOffset, &out_currOffset))
throw std::runtime_error("Decryption error in EVP_OpenFinal") ;
outlen += out_currOffset;
#ifdef GXS_SECURITY_DEBUG
std::cerr << " successfully decrypted block of size " << outlen << std::endl;
#endif
return true;
}
catch(std::exception& e)
{
// cleanup and return false
#ifdef GXS_SECURITY_DEBUG
std::cerr << " (EE) error caught: " << e.what() << std::endl;
#endif
if(out)
{
free(out) ;
out = NULL ;
}
return false;
}
}
bool GxsSecurity::validateNxsGrp(const RsNxsGrp& grp, const RsTlvKeySignature& sign, const RsTlvSecurityKey& key)
{
#ifdef GXS_SECURITY_DEBUG

View file

@ -64,6 +64,7 @@ class GxsSecurity
*@param inlen
*/
static bool encrypt(uint8_t *&out, uint32_t &outlen, const uint8_t *in, uint32_t inlen, const RsTlvSecurityKey& key) ;
static bool encrypt(uint8_t *&out, uint32_t &outlen, const uint8_t *in, uint32_t inlen, const std::vector<RsTlvSecurityKey>& keys) ;
/**
* Decrypts data using evelope decryption (taken from open ssl's evp_sealinit )
@ -75,6 +76,7 @@ class GxsSecurity
* @return false if encryption failed
*/
static bool decrypt(uint8_t *&out, uint32_t &outlen, const uint8_t *in, uint32_t inlen, const RsTlvSecurityKey& key) ;
static bool decrypt(uint8_t *& out, uint32_t & outlen, const uint8_t *in, uint32_t inlen, const std::vector<RsTlvSecurityKey>& keys);
/*!
* uses grp signature to check if group has been

View file

@ -156,6 +156,11 @@ RsGenExchange::~RsGenExchange()
}
bool RsGenExchange::getGroupServerUpdateTS(const RsGxsGroupId& gid, time_t& grp_server_update_TS, time_t& msg_server_update_TS)
{
return mNetService->getGroupServerUpdateTS(gid,grp_server_update_TS,msg_server_update_TS) ;
}
void RsGenExchange::data_tick()
{
@ -234,6 +239,11 @@ void RsGenExchange::tick()
RsGxsGroupChange* gc = new RsGxsGroupChange(RsGxsNotify::TYPE_PROCESSED, false);
gc->mGrpIdList = grpIds;
#ifdef GEN_EXCH_DEBUG
std::cerr << " adding the following grp ids to notification: " << std::endl;
for(std::list<RsGxsGroupId>::const_iterator it(grpIds.begin());it!=grpIds.end();++it)
std::cerr << " " << *it << std::endl;
#endif
mNotifications.push_back(gc);
}
@ -1137,8 +1147,13 @@ void RsGenExchange::receiveChanges(std::vector<RsGxsNotify*>& changes)
out.mGrps.splice(out.mGrps.end(), gc->mGrpIdList);
}
}
else
std::cerr << "(EE) Unknown changes type!!" << std::endl;
delete n;
}
changes.clear() ;
RsServer::notify()->notifyGxsChange(out);
}
@ -1153,6 +1168,8 @@ bool RsGenExchange::subscribeToGroup(uint32_t& token, const RsGxsGroupId& grpId,
if(mNetService != NULL)
mNetService->subscribeStatusChanged(grpId,subscribe) ;
else
std::cerr << "(EE) No mNetService in RsGenExchange for service 0x" << std::hex << mServType << std::dec << std::endl;
return true;
}
@ -1814,6 +1831,11 @@ void RsGenExchange::processGrpMetaChanges()
RsGxsGroupChange* gc = new RsGxsGroupChange(RsGxsNotify::TYPE_PROCESSED, true);
gc->mGrpIdList = grpChanged;
mNotifications.push_back(gc);
#ifdef GEN_EXCH_DEBUG
std::cerr << " adding the following grp ids to notification: " << std::endl;
for(std::list<RsGxsGroupId>::const_iterator it(grpChanged.begin());it!=grpChanged.end();++it)
std::cerr << " " << *it << std::endl;
#endif
}
}
@ -2458,6 +2480,11 @@ void RsGenExchange::publishGrps()
RsGxsGroupChange* gc = new RsGxsGroupChange(RsGxsNotify::TYPE_PUBLISH, false);
gc->mGrpIdList = grpChanged;
mNotifications.push_back(gc);
#ifdef GEN_EXCH_DEBUG
std::cerr << " adding the following grp ids to notification: " << std::endl;
for(std::list<RsGxsGroupId>::const_iterator it(grpChanged.begin());it!=grpChanged.end();++it)
std::cerr << " " << *it << std::endl;
#endif
}
}
@ -2788,22 +2815,22 @@ void RsGenExchange::processRecvdGroups()
grp->metaData = meta;
uint8_t ret = validateGrp(grp);
if(ret == VALIDATE_SUCCESS)
{
meta->mGroupStatus = GXS_SERV::GXS_GRP_STATUS_UNPROCESSED | GXS_SERV::GXS_GRP_STATUS_UNREAD;
meta->mSubscribeFlags = GXS_SERV::GROUP_SUBSCRIBE_NOT_SUBSCRIBED;
computeHash(grp->grp, meta->mHash);
// group has been validated. Let's notify the global router for the clue
if(!meta->mAuthorId.isNull())
{
#ifdef GEN_EXCH_DEBUG
std::cerr << "Group routage info: Identity=" << meta->mAuthorId << " from " << grp->PeerId() << std::endl;
#endif
if(!meta->mAuthorId.isNull())
mRoutingClues[meta->mAuthorId].insert(grp->PeerId()) ;
}
// This has been moved here (as opposed to inside part for new groups below) because it is used to update the server TS when updates
// of grp metadata arrive.
@ -2816,6 +2843,8 @@ void RsGenExchange::processRecvdGroups()
if(meta->mCircleType == GXS_CIRCLE_TYPE_YOUREYESONLY)
meta->mOriginator = grp->PeerId();
meta->mSubscribeFlags = GXS_SERV::GROUP_SUBSCRIBE_NOT_SUBSCRIBED;
grps.insert(std::make_pair(grp, meta));
grpIds.push_back(grp->grpId);
}
@ -2876,6 +2905,11 @@ void RsGenExchange::processRecvdGroups()
c->mGrpIdList = grpIds;
mNotifications.push_back(c);
mDataStore->storeGroup(grps);
#ifdef GEN_EXCH_DEBUG
std::cerr << " adding the following grp ids to notification: " << std::endl;
for(std::list<RsGxsGroupId>::const_iterator it(grpIds.begin());it!=grpIds.end();++it)
std::cerr << " " << *it << std::endl;
#endif
}
}
@ -2936,22 +2970,35 @@ void RsGenExchange::performUpdateValidation()
else
{
delete gu.newGrp;
gu.newGrp = NULL ;
}
delete gu.oldGrpMeta;
gu.oldGrpMeta = NULL ;
}
mDataStore->updateGroup(grps);
// notify the client
RsGxsGroupChange* c = new RsGxsGroupChange(RsGxsNotify::TYPE_RECEIVE, true);
for(uint32_t i=0;i<mGroupUpdates.size();++i)
c->mGrpIdList.push_back(mGroupUpdates[i].oldGrpMeta->mGroupId) ;
if(mGroupUpdates[i].newGrp != NULL)
{
c->mGrpIdList.push_back(mGroupUpdates[i].newGrp->grpId) ;
#ifdef GEN_EXCH_DEBUG
std::cerr << " " << mGroupUpdates[i].newGrp->grpId << std::endl;
#endif
}
mNotifications.push_back(c);
// Warning: updateGroup will destroy the objects in grps. Dont use it afterwards!
mDataStore->updateGroup(grps);
#ifdef GEN_EXCH_DEBUG
std::cerr << " adding the following grp ids to notification: " << std::endl;
#endif
// cleanup
mGroupUpdates.clear();

View file

@ -616,6 +616,14 @@ public:
void shareGroupPublishKey(const RsGxsGroupId& grpId,const std::set<RsPeerId>& peers) ;
/*!
* Returns the local TS of the group as known by the network service.
* This is useful to allow various network services to sync their update TS
* when needed. Typical use case is forums and circles.
* @param gid GroupId the TS is which is requested
*/
bool getGroupServerUpdateTS(const RsGxsGroupId& gid,time_t& grp_server_update_TS,time_t& msg_server_update_TS) ;
protected:
/** Notifications **/

View file

@ -123,15 +123,11 @@ public:
virtual bool encryptData(const uint8_t *clear_data,uint32_t clear_data_size,uint8_t *& encrypted_data,uint32_t& encrypted_data_size,const RsGxsId& encryption_key_id,bool force_load,uint32_t& encryption_error) = 0 ;
virtual bool decryptData(const uint8_t *encrypted_data,uint32_t encrypted_data_size,uint8_t *& clear_data,uint32_t& clear_data_size,const RsGxsId& encryption_key_id,uint32_t& encryption_error) = 0 ;
// virtual bool getPublicKey(const RsGxsId &id, RsTlvSecurityKey &key) = 0;
virtual bool getOwnIds(std::list<RsGxsId>& ids) = 0;
virtual bool isOwnId(const RsGxsId& key_id) = 0 ;
virtual void timeStampKey(const RsGxsId& key_id) = 0 ;
// virtual void networkRequestPublicKey(const RsGxsId& key_id,const std::list<RsPeerId>& peer_ids) = 0 ;
// Key related interface - used for validating msgs and groups.
/*!
* Use to query a whether given key is available by its key reference
@ -167,9 +163,6 @@ public:
virtual bool getKey(const RsGxsId &id, RsTlvSecurityKey &key) = 0;
virtual bool getPrivateKey(const RsGxsId &id, RsTlvSecurityKey &key) = 0; // For signing outgoing messages.
virtual bool getIdDetails(const RsGxsId& id, RsIdentityDetails& details) = 0 ; // Proxy function so that we get p3Identity info from Gxs
#ifdef SUSPENDED
#endif
};
class GixsReputation
@ -218,9 +211,13 @@ class RsGcxs
virtual bool isLoaded(const RsGxsCircleId &circleId) = 0;
virtual bool loadCircle(const RsGxsCircleId &circleId) = 0;
virtual int canSend(const RsGxsCircleId &circleId, const RsPgpId &id) = 0;
virtual int canSend(const RsGxsCircleId &circleId, const RsPgpId &id,bool& should_encrypt) = 0;
virtual int canReceive(const RsGxsCircleId &circleId, const RsPgpId &id) = 0;
virtual bool recipients(const RsGxsCircleId &circleId, std::list<RsPgpId>& friendlist) = 0;
virtual bool recipients(const RsGxsCircleId &circleId, std::list<RsGxsId>& idlist) = 0;
virtual bool isRecipient(const RsGxsCircleId &circleId, const RsGxsId& id) = 0;
virtual bool getLocalCircleServerUpdateTS(const RsGxsCircleId& gid,time_t& grp_server_update_TS,time_t& msg_server_update_TS) =0;
};
@ -233,6 +230,10 @@ public:
:RsGenExchange(gds,ns,serviceSerialiser,mServType, gixs, authenPolicy) { return; }
virtual ~RsGxsCircleExchange() { return; }
virtual bool getLocalCircleServerUpdateTS(const RsGxsCircleId& gid,time_t& grp_server_update_TS,time_t& msg_server_update_TS)
{
return RsGenExchange::getGroupServerUpdateTS(RsGxsGroupId(gid),grp_server_update_TS,msg_server_update_TS) ;
}
};

File diff suppressed because it is too large Load diff

View file

@ -91,7 +91,7 @@ public:
RsNxsNetMgr *netMgr,
RsNxsObserver *nxsObs, // used to be = NULL.
const RsServiceInfo serviceInfo,
RsGixsReputation* reputations = NULL, RsGcxs* circles = NULL,
RsGixsReputation* reputations = NULL, RsGcxs* circles = NULL, RsGixs *gixs=NULL,
PgpAuxUtils *pgpUtils = NULL,
bool grpAutoSync = true, bool msgAutoSync = true);
@ -154,6 +154,8 @@ public:
virtual void rejectMessage(const RsGxsMessageId& msg_id) ;
virtual bool getGroupServerUpdateTS(const RsGxsGroupId& gid,time_t& grp_server_update_TS,time_t& msg_server_update_TS) ;
/* p3Config methods */
public:
@ -215,7 +217,7 @@ private:
* @param item the transaction item to process
* @return false ownership of item left with callee
*/
bool locked_processTransac(RsNxsTransac* item);
bool locked_processTransac(RsNxsTransacItem* item);
/*!
* This adds a transaction
@ -318,19 +320,19 @@ private:
* of groups held by user
* @param item contains grp sync info
*/
void handleRecvSyncGroup(RsNxsSyncGrp* item);
void handleRecvSyncGroup(RsNxsSyncGrpReqItem* item);
/*!
* Handles an nxs item for group statistics
* @param item contaims update time stamp and number of messages
*/
void handleRecvSyncGrpStatistics(RsNxsSyncGrpStats *grs);
void handleRecvSyncGrpStatistics(RsNxsSyncGrpStatsItem *grs);
/*!
* Handles an nxs item for msgs synchronisation
* @param item contaims msg sync info
*/
void handleRecvSyncMessage(RsNxsSyncMsg* item);
void handleRecvSyncMessage(RsNxsSyncMsgReqItem* item);
/*!
* Handles an nxs item for group publish key
@ -349,22 +351,21 @@ private:
* @param toVet groupid/peer to vet are stored here if their circle id is not cached
* @return false, if you cannot send to this peer, true otherwise
*/
bool canSendGrpId(const RsPeerId& sslId, RsGxsGrpMetaData& grpMeta, std::vector<GrpIdCircleVet>& toVet);
bool canSendMsgIds(const std::vector<RsGxsMsgMetaData*>& msgMetas, const RsGxsGrpMetaData&, const RsPeerId& sslId);
bool canSendGrpId(const RsPeerId& sslId, RsGxsGrpMetaData& grpMeta, std::vector<GrpIdCircleVet>& toVet, bool &should_encrypt);
bool canSendMsgIds(std::vector<RsGxsMsgMetaData*>& msgMetas, const RsGxsGrpMetaData&, const RsPeerId& sslId, RsGxsCircleId &should_encrypt_id);
bool checkCanRecvMsgFromPeer(const RsPeerId& sslId, const RsGxsGrpMetaData& meta);
void locked_createTransactionFromPending(MsgRespPending* grpPend);
void locked_createTransactionFromPending(GrpRespPending* msgPend);
void locked_createTransactionFromPending(GrpCircleIdRequestVetting* grpPend);
void locked_createTransactionFromPending(MsgCircleIdsRequestVetting* grpPend);
bool locked_createTransactionFromPending(GrpCircleIdRequestVetting* grpPend) ;
bool locked_createTransactionFromPending(MsgCircleIdsRequestVetting* grpPend) ;
void locked_pushMsgTransactionFromList(std::list<RsNxsItem*>& reqList, const RsPeerId& peerId, const uint32_t& transN);
void locked_pushGrpTransactionFromList(std::list<RsNxsItem*>& reqList, const RsPeerId& peerId, const uint32_t& transN);
void locked_pushGrpTransactionFromList(std::list<RsNxsItem*>& reqList, const RsPeerId& peerId, const uint32_t& transN); // forms a grp list request
void locked_pushMsgTransactionFromList(std::list<RsNxsItem*>& reqList, const RsPeerId& peerId, const uint32_t& transN); // forms a msg list request
void locked_pushGrpRespFromList(std::list<RsNxsItem*>& respList, const RsPeerId& peer, const uint32_t& transN);
void locked_pushMsgRespFromList(std::list<RsNxsItem*>& itemL, const RsPeerId& sslId, const RsGxsGroupId &grp_id, const uint32_t& transN);
void syncWithPeers();
void syncGrpStatistics();
void addGroupItemToList(NxsTransaction*& tr,
@ -375,15 +376,15 @@ private:
void processExplicitGroupRequests();
void locked_doMsgUpdateWork(const RsNxsTransac* nxsTrans, const RsGxsGroupId& grpId);
void locked_doMsgUpdateWork(const RsNxsTransacItem* nxsTrans, const RsGxsGroupId& grpId);
void updateServerSyncTS();
#ifdef TO_REMOVE
void updateClientSyncTS();
#endif
bool locked_CanReceiveUpdate(const RsNxsSyncGrp* item);
bool locked_CanReceiveUpdate(const RsNxsSyncMsg* item);
bool locked_CanReceiveUpdate(const RsNxsSyncGrpReqItem *item);
bool locked_CanReceiveUpdate(const RsNxsSyncMsgReqItem* item);
private:
@ -450,8 +451,15 @@ private:
void locked_stampPeerGroupUpdateTime(const RsPeerId& pid,const RsGxsGroupId& grpId,time_t tm,uint32_t n_messages) ;
/*!
* encrypts/decrypts the transaction for the destination circle id.
*/
bool encryptSingleNxsItem(RsNxsItem *item, const RsGxsCircleId& destination_circle, RsNxsItem *& encrypted_item, uint32_t &status) ;
bool processTransactionForDecryption(NxsTransaction *tr); // return false when the keys are not loaded => need retry later
void cleanRejectedMessages();
void processObserverNotifications();
private:
@ -469,8 +477,8 @@ private:
/*** transactions ***/
/*** synchronisation ***/
std::list<RsNxsSyncGrp*> mSyncGrp;
std::list<RsNxsSyncMsg*> mSyncMsg;
std::list<RsNxsSyncGrpItem*> mSyncGrp;
std::list<RsNxsSyncMsgItem*> mSyncMsg;
/*** synchronisation ***/
RsNxsObserver* mObserver;
@ -496,6 +504,7 @@ private:
int mUpdateCounter ;
RsGcxs* mCircles;
RsGixs *mGixs;
RsGixsReputation* mReputations;
PgpAuxUtils *mPgpUtils;
bool mGrpAutoSync;
@ -516,7 +525,6 @@ public:
typedef std::map<RsPeerId, RsGxsMsgUpdateItem*> ClientMsgMap;
typedef std::map<RsGxsGroupId, RsGxsServerMsgUpdateItem*> ServerMsgMap;
typedef std::map<RsPeerId, RsGxsGrpUpdateItem*> ClientGrpMap;
private:
ClientMsgMap mClientMsgUpdateMap;

View file

@ -222,12 +222,12 @@ bool GrpCircleVetting::expired()
{
return time(NULL) > (mTimeStamp + EXPIRY_PERIOD_OFFSET);
}
bool GrpCircleVetting::canSend(const SSLIdType& peerId, const RsGxsCircleId& circleId)
bool GrpCircleVetting::canSend(const SSLIdType& peerId, const RsGxsCircleId& circleId,bool& should_encrypt)
{
if(mCircles->isLoaded(circleId))
{
const RsPgpId& pgpId = mPgpUtils->getPGPId(peerId);
return mCircles->canSend(circleId, pgpId);
return mCircles->canSend(circleId, pgpId,should_encrypt);
}
mCircles->loadCircle(circleId);
@ -250,7 +250,7 @@ bool GrpCircleIdRequestVetting::cleared()
if(!gic.mCleared)
{
if(canSend(mPeerId, gic.mCircleId))
if(canSend(mPeerId, gic.mCircleId,gic.mShouldEncrypt))
{
gic.mCleared = true;
count++;
@ -284,9 +284,30 @@ MsgCircleIdsRequestVetting::MsgCircleIdsRequestVetting(RsGcxs* const circles,
bool MsgCircleIdsRequestVetting::cleared()
{
if(!mCircles->isLoaded(mCircleId))
{
mCircles->loadCircle(mCircleId);
return false ;
}
return canSend(mPeerId, mCircleId);
for(uint32_t i=0;i<mMsgs.size();)
if(!mCircles->isRecipient(mCircleId,mMsgs[i].mAuthorId))
{
std::cerr << "(WW) MsgCircleIdsRequestVetting::cleared() filtering out message " << mMsgs[i].mMsgId << " because it's signed by author " << mMsgs[i].mAuthorId << " which is not in circle " << mCircleId << std::endl;
mMsgs[i] = mMsgs[mMsgs.size()-1] ;
mMsgs.pop_back();
}
else
++i ;
RsPgpId pgpId = mPgpUtils->getPGPId(mPeerId);
bool can_send_res = mCircles->canSend(mCircleId, pgpId,mShouldEncrypt);
if(mShouldEncrypt) // that means the circle is external
return true ;
else
return can_send_res ;
}
int MsgCircleIdsRequestVetting::getType() const

View file

@ -66,7 +66,7 @@ public:
* c timeout set for this transaction
* c and itemCount
*/
RsNxsTransac* mTransaction;
RsNxsTransacItem* mTransaction;
std::list<RsNxsItem*> mItems; // items received or sent
};
@ -214,7 +214,9 @@ public:
RsGxsGroupId mGroupId;
RsGxsCircleId mCircleId;
RsGxsId mAuthorId;
bool mCleared;
bool mShouldEncrypt;
};
class MsgIdCircleVet
@ -252,9 +254,7 @@ public:
virtual bool cleared() = 0;
protected:
bool canSend(const RsPeerId& peerId, const RsGxsCircleId& circleId);
private:
bool canSend(const RsPeerId& peerId, const RsGxsCircleId& circleId, bool& should_encrypt);
RsGcxs* const mCircles;
PgpAuxUtils *mPgpUtils;
@ -286,6 +286,7 @@ public:
RsGxsGroupId mGrpId;
RsPeerId mPeerId;
RsGxsCircleId mCircleId;
bool mShouldEncrypt;
};

View file

@ -134,6 +134,16 @@ public:
* \param msgId
*/
virtual void rejectMessage(const RsGxsMessageId& msgId) =0;
/*!
* \brief getGroupServerUpdateTS
* Returns the server update time stamp for that group. This is used for synchronisation of TS between
* various network exchange services, suhc as channels/circles or forums/circles
* \param gid group for that request
* \param tm time stamp computed
* \return false if the group is not found, true otherwise
*/
virtual bool getGroupServerUpdateTS(const RsGxsGroupId& gid,time_t& grp_server_update_TS,time_t& msg_server_update_TS) =0;
};
#endif // RSGNP_H

View file

@ -111,8 +111,8 @@ class RsGxsCircleDetails
&& mCircleName == rGxsDetails.mCircleName
&& mCircleType == rGxsDetails.mCircleType
&& mIsExternal == rGxsDetails.mIsExternal
&& mUnknownPeers == rGxsDetails.mUnknownPeers
&& mAllowedPeers == rGxsDetails.mAllowedPeers
&& mAllowedAnonPeers == rGxsDetails.mAllowedAnonPeers
&& mAllowedSignedPeers == rGxsDetails.mAllowedSignedPeers
);
}
@ -121,13 +121,13 @@ class RsGxsCircleDetails
|| mCircleName != rGxsDetails.mCircleName
|| mCircleType != rGxsDetails.mCircleType
|| mIsExternal != rGxsDetails.mIsExternal
|| mUnknownPeers != rGxsDetails.mUnknownPeers
|| mAllowedPeers != rGxsDetails.mAllowedPeers
|| mAllowedAnonPeers != rGxsDetails.mAllowedAnonPeers
|| mAllowedSignedPeers != rGxsDetails.mAllowedSignedPeers
);
}
std::set<RsGxsId> mUnknownPeers;
std::map<RsPgpId, std::list<RsGxsId> > mAllowedPeers;
std::set<RsGxsId> mAllowedAnonPeers;
std::map<RsPgpId, std::set<RsGxsId> > mAllowedSignedPeers;
};
class RsGxsCircles: public RsGxsIfaceHelper

View file

@ -1334,7 +1334,7 @@ int RsServer::StartupRetroShare()
RsGxsNetService* gxsid_ns = new RsGxsNetService(
RS_SERVICE_GXS_TYPE_GXSID, gxsid_ds, nxsMgr,
mGxsIdService, mGxsIdService->getServiceInfo(),
mGxsIdService, mGxsCircles,
mGxsIdService, mGxsCircles,mGxsIdService,
pgpAuxUtils,
false,false); // don't synchronise group automatic (need explicit group request)
// don't sync messages at all.
@ -1353,8 +1353,12 @@ int RsServer::StartupRetroShare()
RsGxsNetService* gxscircles_ns = new RsGxsNetService(
RS_SERVICE_GXS_TYPE_GXSCIRCLE, gxscircles_ds, nxsMgr,
mGxsCircles, mGxsCircles->getServiceInfo(),
mGxsIdService, mGxsCircles,
pgpAuxUtils);
mGxsIdService, mGxsCircles,mGxsIdService,
pgpAuxUtils,
true,false); // synchronise group automatic
// don't sync messages at all.
mGxsCircles->setNetworkExchangeService(gxscircles_ns) ;
/**** Posted GXS service ****/
@ -1370,7 +1374,7 @@ int RsServer::StartupRetroShare()
RsGxsNetService* posted_ns = new RsGxsNetService(
RS_SERVICE_GXS_TYPE_POSTED, posted_ds, nxsMgr,
mPosted, mPosted->getServiceInfo(),
mGxsIdService, mGxsCircles,
mGxsIdService, mGxsCircles,mGxsIdService,
pgpAuxUtils);
mPosted->setNetworkExchangeService(posted_ns) ;
@ -1410,7 +1414,7 @@ int RsServer::StartupRetroShare()
RsGxsNetService* gxsforums_ns = new RsGxsNetService(
RS_SERVICE_GXS_TYPE_FORUMS, gxsforums_ds, nxsMgr,
mGxsForums, mGxsForums->getServiceInfo(),
mGxsIdService, mGxsCircles,
mGxsIdService, mGxsCircles,mGxsIdService,
pgpAuxUtils);
mGxsForums->setNetworkExchangeService(gxsforums_ns) ;
@ -1426,7 +1430,7 @@ int RsServer::StartupRetroShare()
RsGxsNetService* gxschannels_ns = new RsGxsNetService(
RS_SERVICE_GXS_TYPE_CHANNELS, gxschannels_ds, nxsMgr,
mGxsChannels, mGxsChannels->getServiceInfo(),
mGxsIdService, mGxsCircles,
mGxsIdService, mGxsCircles,mGxsIdService,
pgpAuxUtils);
mGxsChannels->setNetworkExchangeService(gxschannels_ns) ;
@ -1443,7 +1447,7 @@ int RsServer::StartupRetroShare()
RsGxsNetService* photo_ns = new RsGxsNetService(
RS_SERVICE_GXS_TYPE_PHOTO, photo_ds, nxsMgr,
mPhoto, mPhoto->getServiceInfo(),
mGxsIdService, mGxsCircles,
mGxsIdService, mGxsCircles,mGxsIdService,
pgpAuxUtils);
#endif
@ -1459,7 +1463,7 @@ int RsServer::StartupRetroShare()
RsGxsNetService* wire_ns = new RsGxsNetService(
RS_SERVICE_GXS_TYPE_WIRE, wire_ds, nxsMgr,
mWire, mWire->getServiceInfo(),
mGxsIdService, mGxsCircles,
mGxsIdService, mGxsCircles,mGxsIdService,
pgpAuxUtils);
#endif
// now add to p3service

View file

@ -29,8 +29,7 @@
#include "serialiser/rstlvbase.h"
#include "serialiser/rsbaseserial.h"
#define CIRCLE_DEBUG 1
//#define CIRCLE_DEBUG 1
uint32_t RsGxsCircleSerialiser::size(RsItem *item)
{

File diff suppressed because it is too large Load diff

View file

@ -28,6 +28,7 @@
#include <map>
#include <openssl/ssl.h>
#include "serialiser/rsserviceids.h"
#include "serialiser/rsserial.h"
@ -38,16 +39,17 @@
// These items have "flag type" numbers, but this is not used.
const uint8_t RS_PKT_SUBTYPE_NXS_SYNC_GRP = 0x01;
const uint8_t RS_PKT_SUBTYPE_NXS_SYNC_GRP_REQ_ITEM = 0x01;
const uint8_t RS_PKT_SUBTYPE_NXS_SYNC_GRP_ITEM = 0x02;
const uint8_t RS_PKT_SUBTYPE_NXS_SYNC_GRP_STATS = 0x03;
const uint8_t RS_PKT_SUBTYPE_NXS_GRP = 0x04;
const uint8_t RS_PKT_SUBTYPE_NXS_SYNC_GRP_STATS_ITEM = 0x03;
const uint8_t RS_PKT_SUBTYPE_NXS_GRP_ITEM = 0x04;
const uint8_t RS_PKT_SUBTYPE_NXS_ENCRYPTED_DATA_ITEM = 0x05;
const uint8_t RS_PKT_SUBTYPE_NXS_SESSION_KEY_ITEM = 0x06;
const uint8_t RS_PKT_SUBTYPE_NXS_SYNC_MSG_ITEM = 0x08;
const uint8_t RS_PKT_SUBTYPE_NXS_SYNC_MSG = 0x10;
const uint8_t RS_PKT_SUBTYPE_NXS_MSG = 0x20;
const uint8_t RS_PKT_SUBTYPE_NXS_TRANS = 0x40;
const uint8_t RS_PKT_SUBTYPE_NXS_GRP_PUBLISH_KEY = 0x80;
const uint8_t RS_PKT_SUBTYPE_NXS_SYNC_MSG_REQ_ITEM = 0x10;
const uint8_t RS_PKT_SUBTYPE_NXS_MSG_ITEM = 0x20;
const uint8_t RS_PKT_SUBTYPE_NXS_TRANSAC_ITEM = 0x40;
const uint8_t RS_PKT_SUBTYPE_NXS_GRP_PUBLISH_KEY_ITEM = 0x80;
// possibility create second service to deal with this functionality
@ -75,11 +77,15 @@ public:
setPriorityLevel(QOS_PRIORITY_RS_GXS_NET);
return;
}
virtual ~RsNxsItem(){ return; }
virtual ~RsNxsItem(){}
virtual bool serialise(void *data,uint32_t& size) const = 0 ;
virtual uint32_t serial_size() const = 0 ;
virtual void clear() = 0;
virtual std::ostream &print(std::ostream &out, uint16_t indent = 0) = 0;
bool serialise_header(void *data,uint32_t& pktsize,uint32_t& tlvsize, uint32_t& offset) const;
uint32_t transactionNumber; // set to zero if this is not a transaction item
};
@ -89,38 +95,42 @@ public:
* Server may advise client peer to use sync file
* while serving his request. This results
*/
class RsNxsSyncGrp : public RsNxsItem {
class RsNxsSyncGrpReqItem : public RsNxsItem
{
public:
static const uint8_t FLAG_USE_SYNC_HASH;
static const uint8_t FLAG_ONLY_CURRENT; // only send most current version of grps / ignores sync hash
RsNxsSyncGrp(uint16_t servtype) : RsNxsItem(servtype, RS_PKT_SUBTYPE_NXS_SYNC_GRP) { clear(); return;}
RsNxsSyncGrpReqItem(uint16_t servtype) : RsNxsItem(servtype, RS_PKT_SUBTYPE_NXS_SYNC_GRP_REQ_ITEM) { clear(); return;}
virtual void clear();
virtual std::ostream &print(std::ostream &out, uint16_t indent);
virtual bool serialise(void *data,uint32_t& size) const;
virtual uint32_t serial_size() const ;
uint8_t flag; // advises whether to use sync hash
uint32_t createdSince; // how far back to sync data
uint32_t updateTS; // time of last group update
std::string syncHash; // use to determine if changes that have occured since last hash
};
/*!
* Use to request statistics about a particular group
*/
class RsNxsSyncGrpStats : public RsNxsItem
class RsNxsSyncGrpStatsItem : public RsNxsItem
{
public:
RsNxsSyncGrpStats(uint16_t servtype) : RsNxsItem(servtype, RS_PKT_SUBTYPE_NXS_SYNC_GRP_STATS) {}
RsNxsSyncGrpStatsItem(uint16_t servtype) : RsNxsItem(servtype, RS_PKT_SUBTYPE_NXS_SYNC_GRP_STATS_ITEM) {}
virtual void clear() {}
virtual std::ostream &print(std::ostream &out, uint16_t indent);
virtual bool serialise(void *data,uint32_t& size) const;
virtual uint32_t serial_size() const ;
static const uint8_t GROUP_INFO_TYPE_REQUEST = 0x01;
static const uint8_t GROUP_INFO_TYPE_RESPONSE = 0x02;
@ -138,11 +148,14 @@ public:
class RsNxsGroupPublishKeyItem : public RsNxsItem
{
public:
RsNxsGroupPublishKeyItem(uint16_t servtype) : RsNxsItem(servtype, RS_PKT_SUBTYPE_NXS_GRP_PUBLISH_KEY) { clear(); return;}
RsNxsGroupPublishKeyItem(uint16_t servtype) : RsNxsItem(servtype, RS_PKT_SUBTYPE_NXS_GRP_PUBLISH_KEY_ITEM) { clear(); return;}
virtual void clear();
virtual std::ostream &print(std::ostream &out, uint16_t indent);
virtual bool serialise(void *data,uint32_t& size) const;
virtual uint32_t serial_size() const;
RsGxsGroupId grpId ;
RsTlvSecurityKey key ;
};
@ -154,7 +167,7 @@ public:
* in order to guaranttee a collection of item have been
* received
*/
class RsNxsTransac : public RsNxsItem {
class RsNxsTransacItem: public RsNxsItem {
public:
@ -178,9 +191,13 @@ public:
static const uint16_t FLAG_TYPE_MSG_LIST_REQ;
static const uint16_t FLAG_TYPE_GRPS;
static const uint16_t FLAG_TYPE_MSGS;
static const uint16_t FLAG_TYPE_ENCRYPTED_DATA;
RsNxsTransac(uint16_t servtype) : RsNxsItem(servtype, RS_PKT_SUBTYPE_NXS_TRANS) { clear(); return; }
virtual ~RsNxsTransac() { return ; }
RsNxsTransacItem(uint16_t servtype) : RsNxsItem(servtype, RS_PKT_SUBTYPE_NXS_TRANSAC_ITEM) { clear(); return; }
virtual ~RsNxsTransacItem() { return ; }
virtual bool serialise(void *data,uint32_t& size) const;
virtual uint32_t serial_size() const ;
virtual void clear();
virtual std::ostream &print(std::ostream &out, uint16_t indent);
@ -209,6 +226,9 @@ public:
RsNxsSyncGrpItem(uint16_t servtype) : RsNxsItem(servtype, RS_PKT_SUBTYPE_NXS_SYNC_GRP_ITEM) { clear(); return ; }
virtual ~RsNxsSyncGrpItem() { return; }
virtual bool serialise(void *data,uint32_t& size) const;
virtual uint32_t serial_size() const;
virtual void clear();
virtual std::ostream &print(std::ostream &out, uint16_t indent);
@ -223,6 +243,57 @@ public:
};
/*!
* Use to send to peer list of grps
* held by server peer
*/
class RsNxsSessionKeyItem : public RsNxsItem
{
public:
RsNxsSessionKeyItem(uint16_t servtype) : RsNxsItem(servtype, RS_PKT_SUBTYPE_NXS_SESSION_KEY_ITEM) { clear(); }
virtual ~RsNxsSessionKeyItem() {}
virtual bool serialise(void *data,uint32_t& size) const;
virtual uint32_t serial_size() const;
virtual void clear();
virtual std::ostream &print(std::ostream &out, uint16_t indent);
/// Session key encrypted for the whole group
///
uint8_t iv[EVP_MAX_IV_LENGTH] ; // initialisation vector
std::map<RsGxsId, RsTlvBinaryData> encrypted_session_keys; // encrypted session keys
};
/*!
* Use to send to peer list of grps
* held by server peer
*/
class RsNxsEncryptedDataItem : public RsNxsItem
{
public:
RsNxsEncryptedDataItem(uint16_t servtype) : RsNxsItem(servtype, RS_PKT_SUBTYPE_NXS_ENCRYPTED_DATA_ITEM),encrypted_data(servtype)
{
encrypted_data.tlvtype = TLV_TYPE_BIN_ENCRYPTED ;
clear();
}
virtual ~RsNxsEncryptedDataItem() {}
virtual bool serialise(void *data,uint32_t& size) const;
virtual uint32_t serial_size() const;
virtual void clear();
virtual std::ostream &print(std::ostream &out, uint16_t indent);
/// grpId of grp held by sending peer
///
RsTlvBinaryData encrypted_data ;
};
/*!
* Contains serialised group items
* Each item corresponds to a group which needs to be
@ -233,7 +304,7 @@ class RsNxsGrp : public RsNxsItem
public:
RsNxsGrp(uint16_t servtype) : RsNxsItem(servtype, RS_PKT_SUBTYPE_NXS_GRP), grp(servtype), meta(servtype),
RsNxsGrp(uint16_t servtype) : RsNxsItem(servtype, RS_PKT_SUBTYPE_NXS_GRP_ITEM), grp(servtype), meta(servtype),
metaData(NULL) { clear();
//std::cout << "\nGrp refcount++ : " << ++refcount << std::endl;
return; }
@ -243,6 +314,9 @@ public:
RsNxsGrp* clone() const;
virtual bool serialise(void *data,uint32_t& size) const;
virtual uint32_t serial_size() const;
virtual void clear();
virtual std::ostream &print(std::ostream &out, uint16_t indent);
@ -266,14 +340,19 @@ public:
* Use to request list of msg held by peer
* for a given group
*/
class RsNxsSyncMsg : public RsNxsItem
class RsNxsSyncMsgReqItem : public RsNxsItem
{
public:
#ifdef UNUSED_CODE
static const uint8_t FLAG_USE_SYNC_HASH;
#endif
RsNxsSyncMsg(uint16_t servtype) : RsNxsItem(servtype, RS_PKT_SUBTYPE_NXS_SYNC_MSG) { clear(); return; }
RsNxsSyncMsgReqItem(uint16_t servtype) : RsNxsItem(servtype, RS_PKT_SUBTYPE_NXS_SYNC_MSG_REQ_ITEM) { clear(); return; }
virtual bool serialise(void *data,uint32_t& size) const;
virtual uint32_t serial_size() const;
virtual void clear();
@ -299,6 +378,9 @@ public:
static const uint8_t FLAG_USE_SYNC_HASH;
RsNxsSyncMsgItem(uint16_t servtype) : RsNxsItem(servtype, RS_PKT_SUBTYPE_NXS_SYNC_MSG_ITEM) { clear(); return; }
virtual bool serialise(void *data,uint32_t& size) const;
virtual uint32_t serial_size() const;
virtual void clear();
virtual std::ostream &print(std::ostream &out, uint16_t indent);
@ -318,7 +400,7 @@ class RsNxsMsg : public RsNxsItem
{
public:
RsNxsMsg(uint16_t servtype) : RsNxsItem(servtype, RS_PKT_SUBTYPE_NXS_MSG), meta(servtype), msg(servtype),
RsNxsMsg(uint16_t servtype) : RsNxsItem(servtype, RS_PKT_SUBTYPE_NXS_MSG_ITEM), meta(servtype), msg(servtype),
metaData(NULL) {
// std::cout << "\nrefcount++ : " << ++refcount << std::endl;
clear(); return;
@ -332,6 +414,9 @@ public:
}
}
virtual bool serialise(void *data,uint32_t& size) const;
virtual uint32_t serial_size() const;
virtual void clear();
virtual std::ostream &print(std::ostream &out, uint16_t indent);
@ -360,12 +445,15 @@ public:
/*!
* Used to request a search of user data
*/
class RsNxsSearchReq : public RsNxsItem
class RsNxsSearchReqItem : public RsNxsItem
{
public:
RsNxsSearchReq(uint16_t servtype): RsNxsItem(servtype, RS_PKT_SUBTYPE_EXT_SEARCH_REQ), serviceSearchItem(servtype) { return; }
virtual ~RsNxsSearchReq() { return;}
RsNxsSearchReqItem(uint16_t servtype): RsNxsItem(servtype, RS_PKT_SUBTYPE_EXT_SEARCH_REQ), serviceSearchItem(servtype) { return; }
virtual ~RsNxsSearchReqItem() { return;}
virtual bool serialise(void *data,uint32_t& size) const;
virtual uint32_t serial_size() const;
virtual void clear() { return;}
virtual std::ostream &print(std::ostream &out, uint16_t /*indent*/) { return out; }
@ -381,11 +469,15 @@ public:
* Used to respond to a RsGrpSearchReq
* with grpId/MsgIds that satisfy search request
*/
class RsNxsSearchResultMsg
class RsNxsSearchResultMsgItem
{
public:
RsNxsSearchResultMsg() : context(0) { return;}
RsNxsSearchResultMsgItem() : context(0) { return;}
virtual bool serialise(void *data,uint32_t& size) const;
virtual uint32_t serial_size() const;
void clear() {}
std::ostream &print(std::ostream &out, uint16_t /*indent*/) { return out; }
@ -402,11 +494,15 @@ public:
* Used to respond to a RsGrpSearchReq
* with grpId/MsgIds that satisfy search request
*/
class RsNxsSearchResultGrp
class RsNxsSearchResultGrpItem
{
public:
RsNxsSearchResultGrp();
RsNxsSearchResultGrpItem();
virtual bool serialise(void *data,uint32_t& size) const;
virtual uint32_t serial_size() const;
void clear() {}
std::ostream &print(std::ostream &out, uint16_t /*indent*/) { return out; }
@ -421,6 +517,7 @@ public:
};
#ifndef UNUSED_CODE
class RsNxsDeleteMsg
{
public:
@ -443,7 +540,7 @@ public:
RsTlvKeySignature idSign;
RsTlvKeySignature deleteSign; // (grpId + grp data) sign // TODO: add warning not to place grpId in msg
};
#endif
class RsNxsSerialiser : public RsSerialType
@ -460,60 +557,19 @@ public:
virtual RsItem* deserialise(void *data, uint32_t *size);
private:
RsNxsSyncGrpReqItem *deserialNxsSyncGrpReqItem(void *data, uint32_t *size); /* RS_PKT_SUBTYPE_SYNC_GRP */
RsNxsSyncGrpItem *deserialNxsSyncGrpItem(void *data, uint32_t *size); /* RS_PKT_SUBTYPE_SYNC_GRP_ITEM */
RsNxsSyncMsgReqItem *deserialNxsSyncMsgReqItem(void *data, uint32_t *size); /* RS_PKT_SUBTYPE_SYNC_MSG */
RsNxsSyncMsgItem *deserialNxsSyncMsgItem(void *data, uint32_t *size); /* RS_PKT_SUBTYPE_SYNC_MSG_ITEM */
RsNxsGrp *deserialNxsGrpItem(void *data, uint32_t *size); /* RS_PKT_SUBTYPE_NXS_GRP */
RsNxsMsg *deserialNxsMsgItem(void *data, uint32_t *size); /* RS_PKT_SUBTYPE_NXS_MSG */
RsNxsTransacItem *deserialNxsTransacItem(void* data, uint32_t *size); /* RS_PKT_SUBTYPE_NXS_TRANS */
RsNxsGroupPublishKeyItem *deserialNxsGroupPublishKeyItem(void* data, uint32_t *size); /* RS_PKT_SUBTYPE_NXS_GRP_PUBLISH_KEY */
RsNxsSessionKeyItem *deserialNxsSessionKeyItem(void* data, uint32_t *size); /* RS_PKT_SUBTYPE_NXS_SESSION_KEY_ITEM */
RsNxsEncryptedDataItem *deserialNxsEncryptedDataItem(void* data, uint32_t *size); /* RS_PKT_SUBTYPE_NXS_ENCRYPTED_DATA_ITEM */
RsNxsSyncGrpStatsItem *deserialNxsSyncGrpStatsItem(void* data, uint32_t *size); /* RS_PKT_SUBTYPE_NXS_SYNC_GRP_STATS_ITEM */
/* for RS_PKT_SUBTYPE_SYNC_GRP */
virtual uint32_t sizeNxsSyncGrp(RsNxsSyncGrp* item);
virtual bool serialiseNxsSyncGrp(RsNxsSyncGrp *item, void *data, uint32_t *size);
virtual RsNxsSyncGrp* deserialNxsSyncGrp(void *data, uint32_t *size);
virtual uint32_t sizeNxsSyncGrpStats(RsNxsSyncGrpStats* item);
virtual bool serialiseNxsSyncGrpStats(RsNxsSyncGrpStats *item, void *data, uint32_t *size);
virtual RsNxsSyncGrpStats* deserialNxsSyncGrpStats(void *data, uint32_t *size);
/* for RS_PKT_SUBTYPE_SYNC_GRP_ITEM */
virtual uint32_t sizeNxsSyncGrpItem(RsNxsSyncGrpItem* item);
virtual bool serialiseNxsSyncGrpItem(RsNxsSyncGrpItem *item, void *data, uint32_t *size);
virtual RsNxsSyncGrpItem* deserialNxsSyncGrpItem(void *data, uint32_t *size);
/* for RS_PKT_SUBTYPE_NXS_GRP */
virtual uint32_t sizeNxsGrp(RsNxsGrp* item);
virtual bool serialiseNxsGrp(RsNxsGrp *item, void *data, uint32_t *size);
virtual RsNxsGrp* deserialNxsGrp(void *data, uint32_t *size);
/* for RS_PKT_SUBTYPE_SYNC_MSG */
virtual uint32_t sizeNxsSyncMsg(RsNxsSyncMsg* item);
virtual bool serialiseNxsSyncMsg(RsNxsSyncMsg *item, void *data, uint32_t *size);
virtual RsNxsSyncMsg* deserialNxsSyncMsg(void *data, uint32_t *size);
/* RS_PKT_SUBTYPE_SYNC_MSG_ITEM */
virtual uint32_t sizeNxsSyncMsgItem(RsNxsSyncMsgItem* item);
virtual bool serialiseNxsSynMsgItem(RsNxsSyncMsgItem* item, void *data, uint32_t* size);
virtual RsNxsSyncMsgItem* deserialNxsSyncMsgItem(void *data, uint32_t *size);
/* RS_PKT_SUBTYPE_NXS_MSG */
virtual uint32_t sizeNxsMsg(RsNxsMsg* item);
virtual bool serialiseNxsMsg(RsNxsMsg* item, void* data, uint32_t* size);
virtual RsNxsMsg* deserialNxsMsg(void *data, uint32_t *size);
/* RS_PKT_SUBTYPE_NXS_TRANS */
virtual uint32_t sizeNxsTrans(RsNxsTransac* item);
virtual bool serialiseNxsTrans(RsNxsTransac* item, void* data, uint32_t* size);
virtual RsNxsTransac* deserialNxsTrans(void* data, uint32_t *size);
/* RS_PKT_SUBTYPE_NXS_GRP_PUBLISH_KEY */
virtual uint32_t sizeNxsGroupPublishKeyItem(RsNxsGroupPublishKeyItem* item);
virtual bool serialiseNxsGroupPublishKeyItem(RsNxsGroupPublishKeyItem* item, void* data, uint32_t* size);
virtual RsNxsGroupPublishKeyItem* deserialNxsGroupPublishKeyItem(void* data, uint32_t *size);
private:
bool checkItemHeader(void *data, uint32_t *size, uint8_t subservice_type);
const uint16_t SERVICE_TYPE;
};

View file

@ -182,12 +182,10 @@ const uint16_t TLV_TYPE_KEY_PUB_RSA = 0x0112; /* not used yet */
const uint16_t TLV_TYPE_SIGN_RSA_SHA1 = 0x0120; /* Used (Distrib/Forums) */
const uint16_t TLV_TYPE_BIN_IMAGE = 0x0130; /* Used (Generic - Forums) */
const uint16_t TLV_TYPE_BIN_FILEDATA = 0x0140; /* Used - ACTIVE! */
const uint16_t TLV_TYPE_BIN_SERIALISE = 0x0150; /* Used (Generic - Distrib) */
const uint16_t TLV_TYPE_BIN_GENERIC = 0x0160; /* Used (DSDV Data) */
const uint16_t TLV_TYPE_BIN_ENCRYPTED = 0x0170; /* Encrypted data */
/**** Compound Types ****/

View file

@ -37,10 +37,14 @@
/*!********************************** RsTlvFileBinaryData **********************************/
RsTlvBinaryData::RsTlvBinaryData()
:tlvtype(0), bin_len(0), bin_data(NULL)
{
}
RsTlvBinaryData::RsTlvBinaryData(uint16_t t)
:tlvtype(t), bin_len(0), bin_data(NULL)
{
return;
}
RsTlvBinaryData::RsTlvBinaryData(const RsTlvBinaryData &b)

View file

@ -36,10 +36,13 @@
class RsTlvBinaryData: public RsTlvItem
{
public:
RsTlvBinaryData();
RsTlvBinaryData(uint16_t t);
RsTlvBinaryData(const RsTlvBinaryData& b); // as per rule of three
void operator=(const RsTlvBinaryData& b); // as per rule of three
virtual ~RsTlvBinaryData(); // as per rule of three
virtual uint32_t TlvSize() const;
virtual void TlvClear(); /*! Initialize fields to empty legal values ( "0", "", etc) */
virtual void TlvShallowClear(); /*! Don't delete the binary data */
@ -53,6 +56,7 @@ virtual bool SetTlv(void *data, uint32_t size, uint32_t *offset) const;
virtual bool GetTlv(void *data, uint32_t size, uint32_t *offset);
virtual std::ostream &print(std::ostream &out, uint16_t indent) const; /*! Error/Debug util function */
// mallocs the necessary size, and copies data into the allocated buffer in bin_data
bool setBinData(const void *data, uint32_t size);
uint16_t tlvtype; /// set/checked against TLV input

View file

@ -188,7 +188,7 @@ void p3GxsCircles::notifyChanges(std::vector<RsGxsNotify *> &changes)
if (msgChange && !msgChange->metaChange())
{
#ifdef DEBUG_CIRCLES
std::cerr << "p3GxsCircles::notifyChanges() Found Message Change Notification";
std::cerr << " Found Message Change Notification";
std::cerr << std::endl;
#endif
@ -197,7 +197,7 @@ void p3GxsCircles::notifyChanges(std::vector<RsGxsNotify *> &changes)
for(mit = msgChangeMap.begin(); mit != msgChangeMap.end(); ++mit)
{
#ifdef DEBUG_CIRCLES
std::cerr << "p3GxsCircles::notifyChanges() Msgs for Group: " << mit->first;
std::cerr << " Msgs for Group: " << mit->first;
std::cerr << std::endl;
#endif
}
@ -207,7 +207,7 @@ void p3GxsCircles::notifyChanges(std::vector<RsGxsNotify *> &changes)
if (groupChange && !groupChange->metaChange())
{
#ifdef DEBUG_CIRCLES
std::cerr << "p3GxsCircles::notifyChanges() Found Group Change Notification";
std::cerr << " Found Group Change Notification";
std::cerr << std::endl;
#endif
@ -216,8 +216,7 @@ void p3GxsCircles::notifyChanges(std::vector<RsGxsNotify *> &changes)
for(git = groupList.begin(); git != groupList.end(); ++git)
{
#ifdef DEBUG_CIRCLES
std::cerr << "p3GxsCircles::notifyChanges() Incoming Group: " << *git;
std::cerr << std::endl;
std::cerr << " Incoming Group: " << *git << ". Forcing cache load." << std::endl;
#endif
// for new circles we need to add them to the list.
@ -232,10 +231,17 @@ void p3GxsCircles::notifyChanges(std::vector<RsGxsNotify *> &changes)
}
}
}
if(groupChange)
for(std::list<RsGxsGroupId>::const_iterator git(groupChange->mGrpIdList.begin());git!=groupChange->mGrpIdList.end();++git)
{
#ifdef DEBUG_CIRCLES
std::cerr << " forcing cache loading for circle " << *git << " in order to trigger subscribe update." << std::endl;
#endif
force_cache_reload(RsGxsCircleId(*git)) ;
}
RsGxsIfaceHelper::receiveChanges(changes);
}
RsGxsIfaceHelper::receiveChanges(changes); // this clear up the vector and delete its elements
}
/********************************************************************************/
@ -263,8 +269,8 @@ bool p3GxsCircles:: getCircleDetails(const RsGxsCircleId &id, RsGxsCircleDetails
details.mCircleType = data.mCircleType;
details.mIsExternal = data.mIsExternal;
details.mUnknownPeers = data.mUnknownPeers;
details.mAllowedPeers = data.mAllowedPeers;
details.mAllowedAnonPeers = data.mAllowedAnonPeers;
details.mAllowedSignedPeers = data.mAllowedSignedPeers;
return true;
}
}
@ -341,16 +347,17 @@ bool p3GxsCircles::loadCircle(const RsGxsCircleId &circleId)
return cache_request_load(circleId);
}
int p3GxsCircles::canSend(const RsGxsCircleId &circleId, const RsPgpId &id)
int p3GxsCircles::canSend(const RsGxsCircleId &circleId, const RsPgpId &id, bool& should_encrypt)
{
RsStackMutex stack(mCircleMtx); /********** STACK LOCKED MTX ******/
if (mCircleCache.is_cached(circleId))
{
RsGxsCircleCache &data = mCircleCache.ref(circleId);
should_encrypt = (data.mCircleType == GXS_CIRCLE_TYPE_EXTERNAL);
if (data.isAllowedPeer(id))
{
return 1;
}
return 0;
}
return -1;
@ -383,6 +390,34 @@ bool p3GxsCircles::recipients(const RsGxsCircleId &circleId, std::list<RsPgpId>
return false;
}
bool p3GxsCircles::isRecipient(const RsGxsCircleId &circleId, const RsGxsId& id)
{
RsStackMutex stack(mCircleMtx); /********** STACK LOCKED MTX ******/
if (mCircleCache.is_cached(circleId))
{
const RsGxsCircleCache &data = mCircleCache.ref(circleId);
return data.isAllowedPeer(id);
}
return false;
}
bool p3GxsCircles::recipients(const RsGxsCircleId& circleId, std::list<RsGxsId>& gxs_ids)
{
RsGxsCircleDetails details ;
if(!getCircleDetails(circleId, details))
return false;
for(std::set<RsGxsId>::const_iterator it(details.mAllowedAnonPeers.begin());it!=details.mAllowedAnonPeers.end();++it)
gxs_ids.push_back(*it) ;
for(std::map<RsPgpId,std::set<RsGxsId> >::const_iterator it(details.mAllowedSignedPeers.begin());it!=details.mAllowedSignedPeers.end();++it)
for(std::set<RsGxsId>::const_iterator it2(it->second.begin());it2!=it->second.end();++it2)
gxs_ids.push_back(*it2) ;
return true;
}
/********************************************************************************/
/******************* Get/Set Data ******************************************/
/********************************************************************************/
@ -495,6 +530,7 @@ RsGxsCircleCache::RsGxsCircleCache()
mIsExternal = true;
mUpdateTime = 0;
mGroupStatus = 0;
mGroupSubscribeFlags = 0;
return;
}
@ -506,11 +542,12 @@ bool RsGxsCircleCache::loadBaseCircle(const RsGxsCircleGroup &circle)
mCircleId = RsGxsCircleId(circle.mMeta.mGroupId);
mCircleName = circle.mMeta.mGroupName;
mUpdateTime = time(NULL);
mProcessedCircles.insert(mCircleId);
// mProcessedCircles.insert(mCircleId);
mCircleType = circle.mMeta.mCircleType;
mIsExternal = (mCircleType != GXS_CIRCLE_TYPE_LOCAL);
mGroupStatus = circle.mMeta.mGroupStatus;
mGroupSubscribeFlags = circle.mMeta.mSubscribeFlags;
#ifdef DEBUG_CIRCLES
std::cerr << "RsGxsCircleCache::loadBaseCircle(" << mCircleId << ")";
@ -534,20 +571,35 @@ bool RsGxsCircleCache::loadSubCircle(const RsGxsCircleCache &subcircle)
return true;
}
bool RsGxsCircleCache::getAllowedPeersList(std::list<RsPgpId> &friendlist)
bool RsGxsCircleCache::getAllowedPeersList(std::list<RsPgpId> &friendlist) const
{
std::map<RsPgpId, std::list<RsGxsId> >::iterator it;
for(it = mAllowedPeers.begin(); it != mAllowedPeers.end(); ++it)
std::map<RsPgpId, std::set<RsGxsId> >::const_iterator it;
for(it = mAllowedSignedPeers.begin(); it != mAllowedSignedPeers.end(); ++it)
{
friendlist.push_back(it->first);
}
return true;
}
bool RsGxsCircleCache::isAllowedPeer(const RsPgpId &id)
bool RsGxsCircleCache::isAllowedPeer(const RsGxsId &id) const
{
std::map<RsPgpId, std::list<RsGxsId> >::iterator it = mAllowedPeers.find(id);
if (it != mAllowedPeers.end())
if(mUnprocessedPeers.find(id) != mUnprocessedPeers.end())
return true ;
if(mAllowedAnonPeers.find(id) != mAllowedAnonPeers.end())
return true ;
for(std::map<RsPgpId,std::set<RsGxsId> >::const_iterator it = mAllowedSignedPeers.begin();it!=mAllowedSignedPeers.end();++it)
if(it->second.find(id) != it->second.end())
return true ;
return false ;
}
bool RsGxsCircleCache::isAllowedPeer(const RsPgpId &id) const
{
std::map<RsPgpId, std::set<RsGxsId> >::const_iterator it = mAllowedSignedPeers.find(id);
if (it != mAllowedSignedPeers.end())
{
return true;
}
@ -557,8 +609,7 @@ bool RsGxsCircleCache::isAllowedPeer(const RsPgpId &id)
bool RsGxsCircleCache::addAllowedPeer(const RsPgpId &pgpId, const RsGxsId &gxsId)
{
/* created if doesn't exist */
std::list<RsGxsId> &gxsList = mAllowedPeers[pgpId];
gxsList.push_back(gxsId);
mAllowedSignedPeers[pgpId].insert(gxsId);
return true;
}
@ -566,7 +617,7 @@ bool RsGxsCircleCache::addAllowedPeer(const RsPgpId &pgpId, const RsGxsId &gxsId
bool RsGxsCircleCache::addLocalFriend(const RsPgpId &pgpId)
{
/* empty list as no GxsID associated */
std::list<RsGxsId> &gxsList = mAllowedPeers[pgpId];
mAllowedSignedPeers.insert(std::make_pair(pgpId,std::set<RsGxsId>()));
return true;
}
@ -753,6 +804,33 @@ bool p3GxsCircles::cachetest_handlerequest(uint32_t token)
/************************************************************************************/
// Complicated deal of loading Circles.
bool p3GxsCircles::force_cache_reload(const RsGxsCircleId& id)
{
#ifdef DEBUG_CIRCLES
std::cerr << "p3GxsCircles::force_cache_reload(): Forcing cache reload of Circle ID " << id << std::endl;
#endif
{
RsStackMutex stack(mCircleMtx); /********** STACK LOCKED MTX ******/
#ifdef DEBUG_CIRCLES
std::cerr << " clearing from existing cache entries..." << std::endl;
#endif
std::map<RsGxsCircleId, RsGxsCircleCache>::iterator it = mLoadingCache.find(id);
if (it != mLoadingCache.end())
{
mLoadingCache.erase(it) ;
#ifdef DEBUG_CIRCLES
std::cerr << " removed item from currently loading cache entries..." << std::endl;
#endif
}
mCircleCache.erase(id) ;
}
cache_request_load(id) ;
return true ;
}
bool p3GxsCircles::cache_request_load(const RsGxsCircleId &id)
{
@ -946,7 +1024,7 @@ bool p3GxsCircles::cache_load_for_token(uint32_t token)
std::cerr << "p3GxsCircles::cache_load_for_token() Is Unknown -> UnknownPeer: " << *pit;
std::cerr << std::endl;
#endif
cache.mUnknownPeers.insert(*pit);
cache.mAllowedAnonPeers.insert(*pit);
}
}
else
@ -1104,9 +1182,7 @@ bool p3GxsCircles::cache_reloadids(const RsGxsCircleId &circleId)
RsGxsCircleCache &cache = it->second;
/* try reload Ids */
std::set<RsGxsId>::const_iterator pit;
for(pit = cache.mUnprocessedPeers.begin();
pit != cache.mUnprocessedPeers.end(); ++pit)
for(std::set<RsGxsId>::const_iterator pit = cache.mUnprocessedPeers.begin(); pit != cache.mUnprocessedPeers.end(); ++pit)
{
/* check cache */
if (mIdentities->haveKey(*pit))
@ -1127,7 +1203,7 @@ bool p3GxsCircles::cache_reloadids(const RsGxsCircleId &circleId)
}
else
{
cache.mUnknownPeers.insert(*pit);
cache.mAllowedAnonPeers.insert(*pit);
#ifdef DEBUG_CIRCLES
std::cerr << "p3GxsCircles::cache_reloadids() UnknownPeer: ";
@ -1157,8 +1233,10 @@ bool p3GxsCircles::cache_reloadids(const RsGxsCircleId &circleId)
cache.mUnprocessedPeers.clear();
// If sub-circles are complete too.
#ifdef SUBSCIRCLES
if (cache.mUnprocessedCircles.empty())
{
#endif
#ifdef DEBUG_CIRCLES
std::cerr << "p3GxsCircles::cache_reloadids() Adding to cache Id: ";
std::cerr << circleId;
@ -1173,6 +1251,7 @@ bool p3GxsCircles::cache_reloadids(const RsGxsCircleId &circleId)
/* remove from loading queue */
mLoadingCache.erase(it);
#ifdef SUBSCIRCLES
}
else
{
@ -1180,6 +1259,7 @@ bool p3GxsCircles::cache_reloadids(const RsGxsCircleId &circleId)
std::cerr << circleId;
std::cerr << std::endl;
}
#endif
return true;
}
@ -1189,17 +1269,14 @@ bool p3GxsCircles::cache_reloadids(const RsGxsCircleId &circleId)
bool p3GxsCircles::checkCircleCacheForAutoSubscribe(RsGxsCircleCache &cache)
{
#ifdef DEBUG_CIRCLES
std::cerr << "p3GxsCircles::checkCircleCacheForAutoSubscribe() : ";
std::cerr << cache.mCircleId;
std::cerr << std::endl;
std::cerr << "p3GxsCircles::checkCircleCacheForAutoSubscribe() : "<< cache.mCircleId << std::endl;
#endif
/* if processed already - ignore */
if (!(cache.mGroupStatus & GXS_SERV::GXS_GRP_STATUS_UNPROCESSED))
{
#ifdef DEBUG_CIRCLES
std::cerr << "p3GxsCircles::checkCircleCacheForAutoSubscribe() : Already Processed";
std::cerr << std::endl;
std::cerr << " Already Processed" << std::endl;
#endif
return false;
@ -1209,50 +1286,90 @@ bool p3GxsCircles::checkCircleCacheForAutoSubscribe(RsGxsCircleCache &cache)
if (!cache.mIsExternal)
{
#ifdef DEBUG_CIRCLES
std::cerr << "p3GxsCircles::checkCircleCacheForAutoSubscribe() : Personal Circle";
std::cerr << std::endl;
std::cerr << " Personal Circle. Nothing to do." << std::endl;
#endif
return false;
}
/* if we appear in the group - then autosubscribe, and mark as processed */
const RsPgpId& ownId = mPgpUtils->getPGPOwnId();
std::map<RsPgpId, std::list<RsGxsId> >::iterator it = cache.mAllowedPeers.find(ownId);
if (it != cache.mAllowedPeers.end())
std::map<RsPgpId, std::set<RsGxsId> >::iterator it = cache.mAllowedSignedPeers.find(ownId);
bool am_I_allowed = it != cache.mAllowedSignedPeers.end() ;
if(!am_I_allowed)
{
// also check if there's an unknown anonymous identity in the list that would belong to us
std::list<RsGxsId> own_gxs_ids ;
rsIdentity->getOwnIds(own_gxs_ids) ;
for(std::list<RsGxsId>::const_iterator it(own_gxs_ids.begin());it!=own_gxs_ids.end();++it)
if(cache.mAllowedAnonPeers.end() != cache.mAllowedAnonPeers.find(*it))
{
am_I_allowed = true ;
#ifdef DEBUG_CIRCLES
std::cerr << " found own GxsId " << *it << " as being in the circle" << std::endl;
#endif
break ;
}
}
#ifdef DEBUG_CIRCLES
else
std::cerr << " found own PGP id as signed to one of the circle's GxsIds" << std::endl;
#endif
if(am_I_allowed)
{
uint32_t token, token2;
if(! (cache.mGroupSubscribeFlags & GXS_SERV::GROUP_SUBSCRIBE_SUBSCRIBED))
{
#ifdef DEBUG_CIRCLES
/* we are part of this group - subscribe, clear unprocessed flag */
std::cerr << "p3GxsCircles::checkCircleCacheForAutoSubscribe() Found OwnId -> AutoSubscribe!";
std::cerr << std::endl;
std::cerr << " I'm allowed in this circle => AutoSubscribing!" << std::endl;
#endif
RsGenExchange::subscribeToGroup(token, RsGxsGroupId(cache.mCircleId), true);
}
#ifdef DEBUG_CIRCLES
else
std::cerr << " I'm allowed in this circle, and already subscribed." << std::endl;
#endif
RsGenExchange::setGroupStatusFlags(token2, RsGxsGroupId(cache.mCircleId), 0, GXS_SERV::GXS_GRP_STATUS_UNPROCESSED);
uint32_t token, token2;
RsGenExchange::subscribeToGroup(token, RsGxsGroupId(cache.mCircleId.toStdString()), true);
RsGenExchange::setGroupStatusFlags(token2, RsGxsGroupId(cache.mCircleId.toStdString()), 0, GXS_SERV::GXS_GRP_STATUS_UNPROCESSED);
cache.mGroupStatus ^= GXS_SERV::GXS_GRP_STATUS_UNPROCESSED;
return true;
}
else if (cache.mUnknownPeers.empty())
else if (cache.mUnprocessedPeers.empty())
{
/* we know all the peers - we are not part - we can flag as PROCESSED. */
uint32_t token,token2;
RsGenExchange::setGroupStatusFlags(token, RsGxsGroupId(cache.mCircleId.toStdString()), 0, GXS_SERV::GXS_GRP_STATUS_UNPROCESSED);
if(cache.mGroupSubscribeFlags & GXS_SERV::GROUP_SUBSCRIBE_SUBSCRIBED)
{
RsGenExchange::subscribeToGroup(token2, RsGxsGroupId(cache.mCircleId), false);
#ifdef DEBUG_CIRCLES
std::cerr << "p3GxsCircles::checkCircleCacheForAutoSubscribe() Know All Peers -> Processed";
std::cerr << std::endl;
std::cerr << " Not part of the group! Let's unsubscribe this circle of unfriendly Napoleons!" << std::endl;
#endif
}
#ifdef DEBUG_CIRCLES
else
std::cerr << " Not part of the group, and not subscribed either." << std::endl;
#endif
/* we know all the peers - we are not part - we can flag as PROCESSED. */
uint32_t token;
RsGenExchange::setGroupStatusFlags(token, RsGxsGroupId(cache.mCircleId.toStdString()), 0, GXS_SERV::GXS_GRP_STATUS_UNPROCESSED);
cache.mGroupStatus ^= GXS_SERV::GXS_GRP_STATUS_UNPROCESSED;
return true ;
}
else
{
#ifdef DEBUG_CIRCLES
std::cerr << "p3GxsCircles::checkCircleCacheForAutoSubscribe() Leaving Unprocessed";
std::cerr << std::endl;
std::cerr << " Leaving Unprocessed" << std::endl;
#endif
// Don't clear UNPROCESSED - as we might not know all the peers.
// TODO - work out when we flag as PROCESSED.
}

View file

@ -132,8 +132,9 @@ class RsGxsCircleCache
bool loadBaseCircle(const RsGxsCircleGroup &circle);
bool loadSubCircle(const RsGxsCircleCache &subcircle);
bool getAllowedPeersList(std::list<RsPgpId> &friendlist);
bool isAllowedPeer(const RsPgpId &id);
bool getAllowedPeersList(std::list<RsPgpId> &friendlist) const;
bool isAllowedPeer(const RsPgpId &id) const;
bool isAllowedPeer(const RsGxsId &id) const;
bool addAllowedPeer(const RsPgpId &pgpid, const RsGxsId &gxsId);
bool addLocalFriend(const RsPgpId &pgpid);
@ -144,14 +145,17 @@ class RsGxsCircleCache
bool mIsExternal;
uint32_t mGroupStatus;
uint32_t mGroupSubscribeFlags;
time_t mUpdateTime;
#ifdef SUBSCIRCLES
std::set<RsGxsCircleId> mUnprocessedCircles;
std::set<RsGxsCircleId> mProcessedCircles;
#endif
std::set<RsGxsId> mUnprocessedPeers;
std::set<RsGxsCircleId> mProcessedCircles;
std::set<RsGxsId> mUnknownPeers;
std::map<RsPgpId, std::list<RsGxsId> > mAllowedPeers;
std::set<RsGxsId> mAllowedAnonPeers;
std::map<RsPgpId, std::set<RsGxsId> > mAllowedSignedPeers;
};
@ -175,9 +179,11 @@ virtual RsServiceInfo getServiceInfo();
virtual bool isLoaded(const RsGxsCircleId &circleId);
virtual bool loadCircle(const RsGxsCircleId &circleId);
virtual int canSend(const RsGxsCircleId &circleId, const RsPgpId &id);
virtual int canSend(const RsGxsCircleId &circleId, const RsPgpId &id, bool &should_encrypt);
virtual int canReceive(const RsGxsCircleId &circleId, const RsPgpId &id);
virtual bool recipients(const RsGxsCircleId &circleId, std::list<RsPgpId> &friendlist) ;
virtual bool recipients(const RsGxsCircleId &circleId, std::list<RsGxsId> &gxs_ids) ;
virtual bool isRecipient(const RsGxsCircleId &circleId, const RsGxsId& id) ;
virtual bool getGroupData(const uint32_t &token, std::vector<RsGxsCircleGroup> &groups);
@ -219,6 +225,7 @@ virtual RsServiceInfo getServiceInfo();
bool cache_request_load(const RsGxsCircleId &id);
bool cache_start_load();
bool force_cache_reload(const RsGxsCircleId& id);
bool cache_load_for_token(uint32_t token);
bool cache_reloadids(const RsGxsCircleId &circleId);

View file

@ -36,6 +36,7 @@
#define CIRCLEGROUP_CIRCLE_COL_GROUPNAME 0
#define CIRCLEGROUP_CIRCLE_COL_GROUPID 1
#define CIRCLEGROUP_CIRCLE_COL_GROUPFLAGS 2
#define CIRCLEGROUP_FRIEND_COL_NAME 0
#define CIRCLEGROUP_FRIEND_COL_ID 1
@ -62,8 +63,8 @@ CirclesDialog::CirclesDialog(QWidget *parent)
mStateHelper->addWidget(CIRCLESDIALOG_GROUPMETA, ui.pushButton_editCircle);
mStateHelper->addWidget(CIRCLESDIALOG_GROUPMETA, ui.treeWidget_membership, UISTATE_ACTIVE_ENABLED);
mStateHelper->addWidget(CIRCLESDIALOG_GROUPMETA, ui.treeWidget_friends, UISTATE_ACTIVE_ENABLED);
mStateHelper->addWidget(CIRCLESDIALOG_GROUPMETA, ui.treeWidget_category, UISTATE_ACTIVE_ENABLED);
// mStateHelper->addWidget(CIRCLESDIALOG_GROUPMETA, ui.treeWidget_friends, UISTATE_ACTIVE_ENABLED);
// mStateHelper->addWidget(CIRCLESDIALOG_GROUPMETA, ui.treeWidget_category, UISTATE_ACTIVE_ENABLED);
mStateHelper->setWidgetEnabled(ui.pushButton_editCircle, false);
@ -74,8 +75,8 @@ CirclesDialog::CirclesDialog(QWidget *parent)
connect(ui.todoPushButton, SIGNAL(clicked()), this, SLOT(todo()));
connect(ui.treeWidget_membership, SIGNAL(itemSelectionChanged()), this, SLOT(circle_selected()));
connect(ui.treeWidget_friends, SIGNAL(itemSelectionChanged()), this, SLOT(friend_selected()));
connect(ui.treeWidget_category, SIGNAL(itemSelectionChanged()), this, SLOT(category_selected()));
// connect(ui.treeWidget_friends, SIGNAL(itemSelectionChanged()), this, SLOT(friend_selected()));
// connect(ui.treeWidget_category, SIGNAL(itemSelectionChanged()), this, SLOT(category_selected()));
/* Setup TokenQueue */
mCircleQueue = new TokenQueue(rsGxsCircles->getTokenService(), this);
@ -84,8 +85,8 @@ CirclesDialog::CirclesDialog(QWidget *parent)
QHeaderView * membership_header = ui.treeWidget_membership->header () ;
membership_header->resizeSection ( CIRCLEGROUP_CIRCLE_COL_GROUPNAME, 200 );
QHeaderView * friends_header = ui.treeWidget_friends->header () ;
friends_header->resizeSection ( CIRCLEGROUP_FRIEND_COL_NAME, 200 );
// QHeaderView * friends_header = ui.treeWidget_friends->header () ;
// friends_header->resizeSection ( CIRCLEGROUP_FRIEND_COL_NAME, 200 );
}
@ -135,8 +136,10 @@ void CirclesDialog::editExistingCircle()
QString coltext = item->text(CIRCLEGROUP_CIRCLE_COL_GROUPID);
RsGxsGroupId id ( coltext.toStdString());
uint32_t subscribe_flags = item->data(CIRCLEGROUP_CIRCLE_COL_GROUPFLAGS, Qt::UserRole).toUInt();
CreateCircleDialog dlg;
dlg.editExistingId(id);
dlg.editExistingId(id,true,!!(subscribe_flags & GXS_SERV::GROUP_SUBSCRIBE_ADMIN)) ;
dlg.exec();
}
@ -154,6 +157,7 @@ void CirclesDialog::reloadAll()
rsPeers->getGPGAcceptedList(friend_pgpIds);
rsPeers->getGPGAllList(all_pgpIds);
#ifdef SUSPENDED_CODE
/* clear tree */
ui.treeWidget_friends->clear();
@ -198,6 +202,7 @@ void CirclesDialog::reloadAll()
fofItem->addChild(item);
}
}
#endif
}
void set_item_background(QTreeWidgetItem *item, uint32_t type)
@ -310,7 +315,7 @@ void mark_circle_item(QTreeWidgetItem *item, const std::set<RsPgpId> &names)
std::set<RsPgpId>::iterator it;
for(it = names.begin(); it != names.end(); ++it)
{
if (details.mAllowedPeers.end() != details.mAllowedPeers.find(*it))
if (details.mAllowedSignedPeers.end() != details.mAllowedSignedPeers.find(*it))
{
set_item_background(item, GREEN_BACKGROUND);
std::cerr << "CirclesDialog mark_circle_item: found match: " << id;
@ -383,8 +388,7 @@ void CirclesDialog::circle_selected()
{
/* now mark all the members */
std::set<RsPgpId> members;
std::map<RsPgpId, std::list<RsGxsId> >::iterator it;
for(it = details.mAllowedPeers.begin(); it != details.mAllowedPeers.end(); ++it)
for( std::map<RsPgpId, std::set<RsGxsId> >::iterator it = details.mAllowedSignedPeers.begin(); it != details.mAllowedSignedPeers.end(); ++it)
{
members.insert(it->first);
std::cerr << "Circle member: " << it->first;

View file

@ -6,7 +6,7 @@
<rect>
<x>0</x>
<y>0</y>
<width>746</width>
<width>920</width>
<height>568</height>
</rect>
</property>
@ -14,16 +14,7 @@
<string/>
</property>
<layout class="QVBoxLayout" name="verticalLayout_4">
<property name="leftMargin">
<number>0</number>
</property>
<property name="topMargin">
<number>0</number>
</property>
<property name="rightMargin">
<number>0</number>
</property>
<property name="bottomMargin">
<property name="margin">
<number>0</number>
</property>
<item>
@ -35,16 +26,7 @@
<enum>QFrame::Sunken</enum>
</property>
<layout class="QHBoxLayout" name="horizontalLayout_3">
<property name="leftMargin">
<number>2</number>
</property>
<property name="topMargin">
<number>2</number>
</property>
<property name="rightMargin">
<number>2</number>
</property>
<property name="bottomMargin">
<property name="margin">
<number>2</number>
</property>
<item>

View file

@ -22,9 +22,11 @@
*/
#include <QMessageBox>
#include <QMenu>
#include <algorithm>
#include "gui/Circles/CreateCircleDialog.h"
#include "gui/gxs/GxsIdDetails.h"
#include <retroshare/rspeers.h>
#include <retroshare/rsidentity.h>
@ -33,6 +35,8 @@
#include <algorithm>
//#define DEBUG_CREATE_CIRCLE_DIALOG 1
#define CREATECIRCLEDIALOG_CIRCLEINFO 2
#define CREATECIRCLEDIALOG_IDINFO 3
@ -51,10 +55,6 @@ CreateCircleDialog::CreateCircleDialog()
mCircleQueue = new TokenQueue(rsGxsCircles->getTokenService(), this);
mIdQueue = new TokenQueue(rsIdentity->getTokenService(), this);
//QString text = pId.empty() ? tr("Start New Thread") : tr("Post Forum Message");
//setWindowTitle(text);
//Settings->loadWidgetInformation(this);
ui.headerFrame->setHeaderImage(QPixmap(":/images/circles/circles_64.png"));
// connect up the buttons.
@ -67,6 +67,9 @@ CreateCircleDialog::CreateCircleDialog()
connect(ui.treeWidget_membership, SIGNAL(currentItemChanged(QTreeWidgetItem*,QTreeWidgetItem*)), this, SLOT(selectedMember(QTreeWidgetItem*, QTreeWidgetItem*)));
connect(ui.treeWidget_IdList, SIGNAL(currentItemChanged(QTreeWidgetItem*,QTreeWidgetItem*)), this, SLOT(selectedId(QTreeWidgetItem*, QTreeWidgetItem*)));
connect(ui.treeWidget_IdList, SIGNAL(customContextMenuRequested(QPoint)), this, SLOT(IdListCustomPopupMenu(QPoint)));
connect(ui.treeWidget_membership, SIGNAL(customContextMenuRequested(QPoint)), this, SLOT(MembershipListCustomPopupMenu(QPoint)));
connect(ui.IdFilter, SIGNAL(textChanged(QString)), this, SLOT(filterChanged(QString)));
//connect(ui.toolButton_NewId, SIGNAL(clicked()), this, SLOT(createNewGxsId()));
@ -82,15 +85,21 @@ CreateCircleDialog::CreateCircleDialog()
ui.addButton->setEnabled(false);
ui.radioButton_ListAll->setChecked(true);
QObject::connect(ui.radioButton_ListAll, SIGNAL(toggled(bool)), this, SLOT(updateCircleGUI())) ;
QObject::connect(ui.radioButton_ListAllPGP, SIGNAL(toggled(bool)), this, SLOT(updateCircleGUI())) ;
QObject::connect(ui.radioButton_ListKnownPGP, SIGNAL(toggled(bool)), this, SLOT(updateCircleGUI())) ;
QObject::connect(ui.radioButton_ListAll, SIGNAL(toggled(bool)), this, SLOT(idTypeChanged())) ;
QObject::connect(ui.radioButton_ListAllPGP, SIGNAL(toggled(bool)), this, SLOT(idTypeChanged())) ;
QObject::connect(ui.radioButton_ListKnownPGP, SIGNAL(toggled(bool)), this, SLOT(idTypeChanged())) ;
QObject::connect(ui.radioButton_Public, SIGNAL(toggled(bool)), this, SLOT(updateCircleType(bool))) ;
QObject::connect(ui.radioButton_Self, SIGNAL(toggled(bool)), this, SLOT(updateCircleType(bool))) ;
QObject::connect(ui.radioButton_Restricted, SIGNAL(toggled(bool)), this, SLOT(updateCircleType(bool))) ;
ui.radioButton_Public->setChecked(true) ;
mIsExistingCircle = false;
mIsExternalCircle = true;
mClearList = true;
ui.idChooser->loadIds(0,RsGxsId());
//ui.idChooser->loadIds(0,RsGxsId());
ui.circleComboBox->loadCircles(GXS_CIRCLE_CHOOSER_EXTERNAL, RsGxsCircleId());
}
@ -100,16 +109,49 @@ CreateCircleDialog::~CreateCircleDialog()
delete(mIdQueue);
}
void CreateCircleDialog::editExistingId(const RsGxsGroupId &circleId, const bool &clearList /*= true*/)
void CreateCircleDialog::editExistingId(const RsGxsGroupId &circleId, const bool &clearList /*= true*/,bool readonly)
{
/* load this circle */
mIsExistingCircle = true;
mReadOnly=readonly;
mClearList = clearList;
requestCircle(circleId);
if(readonly)
ui.headerFrame->setHeaderText(tr("Circle Details"));
else
ui.headerFrame->setHeaderText(tr("Edit Circle"));
ui.radioButton_Public->setEnabled(!readonly) ;
ui.radioButton_Self->setEnabled(!readonly) ;
ui.radioButton_Restricted->setEnabled(!readonly) ;
ui.circleName->setReadOnly(readonly) ;
if(readonly)
{
ui.circleAdminLabel->setVisible(true) ;
ui.idChooser->setVisible(false) ;
}
else
{
ui.circleAdminLabel->setVisible(false) ;
ui.idChooser->setVisible(true) ;
}
ui.buttonBox->button(QDialogButtonBox::Ok)->setText(tr("Update"));
ui.addButton->setEnabled(!readonly) ;
ui.removeButton->setEnabled(!readonly) ;
if(readonly)
{
ui.buttonBox->setStandardButtons(QDialogButtonBox::Cancel);
ui.buttonBox->button(QDialogButtonBox::Cancel)->setText(tr("Close"));
ui.peersSelection_GB->hide() ;
ui.addButton->hide() ;
ui.removeButton->hide() ;
}
requestCircle(circleId);
}
@ -117,36 +159,61 @@ void CreateCircleDialog::editNewId(bool isExternal)
{
/* load this circle */
mIsExistingCircle = false;
mReadOnly = false ;
/* setup personal or external circle */
if (isExternal)
{
setupForExternalCircle();
ui.headerFrame->setHeaderText(tr("Create New External Circle"));
ui.headerFrame->setHeaderText(tr("Create New Circle"));
ui.buttonBox->button(QDialogButtonBox::Ok)->setText(tr("Create"));
}
else
{
setupForPersonalCircle();
ui.headerFrame->setHeaderText(tr("Create New Personal Circle"));
ui.headerFrame->setHeaderText(tr("Create New Circle"));
}
/* enable stuff that might be locked */
}
void CreateCircleDialog::updateCircleType(bool b)
{
if(!b)
return ; // no need to change when b<-false
//if(ui.radioButton_Self->isChecked())
// setupForPersonalCircle() ;
//else
setupForExternalCircle() ;
if(ui.radioButton_Restricted->isChecked())
{
ui.circleComboBox->setEnabled(true) ;
ui.circleComboBox->show() ;
}
else
{
ui.circleComboBox->setEnabled(false) ;
ui.circleComboBox->hide() ;
}
}
void CreateCircleDialog::setupForPersonalCircle()
{
mIsExternalCircle = false;
/* hide distribution line */
ui.groupBox_title->setTitle(tr("Personal Circle Details"));
ui.groupBox_title->setTitle(tr("Circle Details"));
ui.frame_PgpTypes->hide();
ui.frame_Distribution->hide();
//ui.frame_Distribution->hide();
ui.idChooserLabel->hide();
ui.circleAdminLabel->hide();
ui.idChooser->hide();
//ui.toolButton_NewId->hide();
getPgpIdentities();
//getPgpIdentities();
}
void CreateCircleDialog::setupForExternalCircle()
@ -154,10 +221,12 @@ void CreateCircleDialog::setupForExternalCircle()
mIsExternalCircle = true;
/* show distribution line */
ui.groupBox_title->setTitle(tr("External Circle Details"));
ui.groupBox_title->setTitle(tr("Circle Details"));
ui.frame_PgpTypes->show();
ui.frame_Distribution->show();
ui.idChooserLabel->show();
ui.circleAdminLabel->show();
ui.idChooser->show();
//ui.toolButton_NewId->show();
@ -210,8 +279,10 @@ void CreateCircleDialog::addMember(const QString& keyId, const QString& idtype,
for(int i = 0; i < count; ++i){
QTreeWidgetItem *item = tree->topLevelItem(i);
if (keyId == item->text(RSCIRCLEID_COL_KEYID)) {
#ifdef DEBUG_CREATE_CIRCLE_DIALOG
std::cerr << "CreateCircleDialog::addMember() Already is a Member: " << keyId.toStdString();
std::cerr << std::endl;
#endif
return;
}//if (keyId == item->text(RSCIRCLEID_COL_KEYID))
}//for(int i = 0; i < count; ++i)
@ -220,6 +291,7 @@ void CreateCircleDialog::addMember(const QString& keyId, const QString& idtype,
member->setText(RSCIRCLEID_COL_NICKNAME, nickname);
member->setText(RSCIRCLEID_COL_KEYID, keyId);
member->setText(RSCIRCLEID_COL_IDTYPE, idtype);
//member->setIcon(RSCIRCLEID_COL_NICKNAME, pixmap);
tree->addTopLevelItem(member);
}
@ -228,8 +300,8 @@ void CreateCircleDialog::addMember(const QString& keyId, const QString& idtype,
void CreateCircleDialog::addCircle(const RsGxsCircleDetails &cirDetails)
{
typedef std::set<RsGxsId>::iterator itUnknownPeers;
for (itUnknownPeers it = cirDetails.mUnknownPeers.begin()
; it != cirDetails.mUnknownPeers.end()
for (itUnknownPeers it = cirDetails.mAllowedAnonPeers.begin()
; it != cirDetails.mAllowedAnonPeers.end()
; ++it) {
RsGxsId gxs_id = *it;
RsIdentityDetails gxs_details ;
@ -244,10 +316,9 @@ void CreateCircleDialog::addCircle(const RsGxsCircleDetails &cirDetails)
}//if(!gxs_id.isNull() && rsIdentity->getIdDetails(gxs_id,gxs_details))
}//for (itUnknownPeers it = cirDetails.mUnknownPeers.begin()
typedef std::map<RsPgpId, std::list<RsGxsId> >::const_iterator itAllowedPeers;
for (itAllowedPeers it = cirDetails.mAllowedPeers.begin()
; it != cirDetails.mAllowedPeers.end()
; ++it ) {
typedef std::map<RsPgpId, std::set<RsGxsId> >::const_iterator itAllowedPeers;
for (itAllowedPeers it = cirDetails.mAllowedSignedPeers.begin() ; it != cirDetails.mAllowedSignedPeers.end() ; ++it )
{
RsPgpId gpg_id = it->first;
RsPeerDetails details ;
if(!gpg_id.isNull() && rsPeers->getGPGDetails(gpg_id,details)) {
@ -273,8 +344,16 @@ void CreateCircleDialog::removeMember()
void CreateCircleDialog::createCircle()
{
if(mReadOnly)
{
close() ;
return ;
}
#ifdef DEBUG_CREATE_CIRCLE_DIALOG
std::cerr << "CreateCircleDialog::createCircle()";
std::cerr << std::endl;
#endif
QString name = ui.circleName->text();
@ -285,155 +364,239 @@ void CreateCircleDialog::createCircle()
return; //Don't add a empty Subject!!
}//if(name.isEmpty())
RsGxsCircleGroup circle;
RsGxsCircleGroup circle = mCircleGroup; // init with loaded group
circle.mMeta.mGroupName = std::string(name.toUtf8());
circle.mInvitedMembers.clear() ;
circle.mLocalFriends.clear() ;
RsGxsId authorId;
switch (ui.idChooser->getChosenId(authorId)) {
switch (ui.idChooser->getChosenId(authorId))
{
case GxsIdChooser::KnowId:
case GxsIdChooser::UnKnowId:
circle.mMeta.mAuthorId = authorId;
#ifdef DEBUG_CREATE_CIRCLE_DIALOG
std::cerr << "CreateCircleDialog::createCircle() AuthorId: " << authorId;
std::cerr << std::endl;
#endif
break;
case GxsIdChooser::NoId:
case GxsIdChooser::None:
default:
default: ;
#ifdef DEBUG_CREATE_CIRCLE_DIALOG
std::cerr << "CreateCircleDialog::createCircle() No AuthorId Chosen!";
std::cerr << std::endl;
}//switch (ui.idChooser->getChosenId(authorId))
#endif
}
/* copy Ids from GUI */
QTreeWidget *tree = ui.treeWidget_membership;
int count = tree->topLevelItemCount();
for(int i = 0; i < count; ++i) {
for(int i = 0; i < count; ++i)
{
QTreeWidgetItem *item = tree->topLevelItem(i);
QString keyId = item->text(RSCIRCLEID_COL_KEYID);
/* insert into circle */
if (mIsExternalCircle) {
circle.mInvitedMembers.push_back(RsGxsId(keyId.toStdString()));
if (mIsExternalCircle)
{
RsGxsId key_id_gxs(keyId.toStdString()) ;
if(key_id_gxs.isNull())
{
std::cerr << "Error: Not a proper keyID: " << keyId.toStdString() << std::endl;
continue ;
}
circle.mInvitedMembers.insert(key_id_gxs) ;
#ifdef DEBUG_CREATE_CIRCLE_DIALOG
std::cerr << "CreateCircleDialog::createCircle() Inserting Member: " << keyId.toStdString();
std::cerr << std::endl;
} else {//if (mIsExternalCircle)
circle.mLocalFriends.push_back(RsPgpId(keyId.toStdString()));
#endif
}
else
{
RsPgpId key_id_pgp(keyId.toStdString()) ;
if(key_id_pgp.isNull())
{
std::cerr << "Error: Not a proper PGP keyID: " << keyId.toStdString() << std::endl;
continue ;
}
circle.mLocalFriends.insert(key_id_pgp) ;
#ifdef DEBUG_CREATE_CIRCLE_DIALOG
std::cerr << "CreateCircleDialog::createCircle() Inserting Friend: " << keyId.toStdString();
std::cerr << std::endl;
}//else (mIsExternalCircle)
#endif
}
}//for(int i = 0; i < count; ++i)
}
if (mIsExistingCircle) {
std::cerr << "CreateCircleDialog::createCircle() Existing Circle TODO";
std::cerr << std::endl;
// if (mIsExistingCircle)
// {
// std::cerr << "CreateCircleDialog::createCircle() Existing Circle TODO";
// std::cerr << std::endl;
//
// // cannot edit these yet.
// QMessageBox::warning(this, tr("RetroShare"),tr("Cannot Edit Existing Circles Yet"), QMessageBox::Ok, QMessageBox::Ok);
// return;
// }
// cannot edit these yet.
QMessageBox::warning(this, tr("RetroShare"),tr("Cannot Edit Existing Circles Yet"), QMessageBox::Ok, QMessageBox::Ok);
return;
}//if (mIsExistingCircle)
if (mIsExternalCircle) {
if (mIsExternalCircle)
{
#ifdef DEBUG_CREATE_CIRCLE_DIALOG
std::cerr << "CreateCircleDialog::createCircle() External Circle";
std::cerr << std::endl;
#endif
// set distribution from GUI.
circle.mMeta.mCircleId.clear() ;
if (ui.radioButton_Public->isChecked()) {
#ifdef DEBUG_CREATE_CIRCLE_DIALOG
std::cerr << "CreateCircleDialog::createCircle() Public Circle";
std::cerr << std::endl;
#endif
circle.mMeta.mCircleType = GXS_CIRCLE_TYPE_PUBLIC;
} else if (ui.radioButton_Self->isChecked()) {
#ifdef DEBUG_CREATE_CIRCLE_DIALOG
std::cerr << "CreateCircleDialog::createCircle() ExtSelfRef Circle";
std::cerr << std::endl;
#endif
circle.mMeta.mCircleType = GXS_CIRCLE_TYPE_EXT_SELF;
} else if (ui.radioButton_Restricted->isChecked()) {
#ifdef DEBUG_CREATE_CIRCLE_DIALOG
std::cerr << "CreateCircleDialog::createCircle() External (Other) Circle";
std::cerr << std::endl;
#endif
circle.mMeta.mCircleType = GXS_CIRCLE_TYPE_EXTERNAL;
/* grab circle ID from chooser */
RsGxsCircleId chosenId;
if (ui.circleComboBox->getChosenCircle(chosenId)) {
#ifdef DEBUG_CREATE_CIRCLE_DIALOG
std::cerr << "CreateCircleDialog::createCircle() ChosenId: " << chosenId;
std::cerr << std::endl;
#endif
circle.mMeta.mCircleId = chosenId;
} else {//if (ui.circleComboBox->getChosenCircle(chosenId))
#ifdef DEBUG_CREATE_CIRCLE_DIALOG
std::cerr << "CreateCircleDialog::createCircle() Error no Id Chosen";
std::cerr << std::endl;
#endif
QMessageBox::warning(this, tr("RetroShare"),tr("No Restriction Circle Selected"), QMessageBox::Ok, QMessageBox::Ok);
return;
}//else (ui.circleComboBox->getChosenCircle(chosenId))
} else { //if (ui.radioButton_Public->isChecked())
}
else
{ //if (ui.radioButton_Public->isChecked())
QMessageBox::warning(this, tr("RetroShare"),tr("No Circle Limitations Selected"), QMessageBox::Ok, QMessageBox::Ok);
return;
}//else (ui.radioButton_Public->isChecked())
} else {//if (mIsExternalCircle)
}
else
{//if (mIsExternalCircle)
#ifdef DEBUG_CREATE_CIRCLE_DIALOG
std::cerr << "CreateCircleDialog::createCircle() Personal Circle";
std::cerr << std::endl;
#endif
// set personal distribution
circle.mMeta.mCircleId.clear() ;
circle.mMeta.mCircleType = GXS_CIRCLE_TYPE_LOCAL;
}//else (mIsExternalCircle)
std::cerr << "CreateCircleDialog::createCircle() : mCircleType: " << circle.mMeta.mCircleType;
std::cerr << std::endl;
std::cerr << "CreateCircleDialog::createCircle() : mCircleId: " << circle.mMeta.mCircleId;
std::cerr << std::endl;
std::cerr << "CreateCircleDialog::createCircle() Checks and Balances Okay - calling service proper..";
std::cerr << std::endl;
uint32_t token;
if(mIsExistingCircle)
{
#ifdef DEBUG_CREATE_CIRCLE_DIALOG
std::cerr << "CreateCircleDialog::updateCircle() : mCircleType: " << circle.mMeta.mCircleType << std::endl;
std::cerr << "CreateCircleDialog::updateCircle() : mCircleId: " << circle.mMeta.mCircleId << std::endl;
std::cerr << "CreateCircleDialog::updateCircle() : mGroupId: " << circle.mMeta.mGroupId << std::endl;
std::cerr << "CreateCircleDialog::updateCircle() Checks and Balances Okay - calling service proper.."<< std::endl;
#endif
rsGxsCircles->updateGroup(token, circle);
}
else
{
#ifdef DEBUG_CREATE_CIRCLE_DIALOG
std::cerr << "CreateCircleDialog::createCircle() : mCircleType: " << circle.mMeta.mCircleType << std::endl;
std::cerr << "CreateCircleDialog::createCircle() : mCircleId: " << circle.mMeta.mCircleId << std::endl;
std::cerr << "CreateCircleDialog::createCircle() Checks and Balances Okay - calling service proper.."<< std::endl;
#endif
rsGxsCircles->createGroup(token, circle);
}
close();
}
void CreateCircleDialog::updateCircleGUI()
{
#ifdef DEBUG_CREATE_CIRCLE_DIALOG
std::cerr << "CreateCircleDialog::updateCircleGUI()";
std::cerr << std::endl;
#endif
ui.circleName->setText(QString::fromUtf8(mCircleGroup.mMeta.mGroupName.c_str()));
bool isExternal = true;
#ifdef DEBUG_CREATE_CIRCLE_DIALOG
std::cerr << "CreateCircleDialog::updateCircleGUI() : CIRCLETYPE: " << mCircleGroup.mMeta.mCircleType;
std::cerr << std::endl;
#endif
switch(mCircleGroup.mMeta.mCircleType) {
ui.radioButton_Public->setChecked(false);
ui.radioButton_Self->setChecked(false);
ui.radioButton_Restricted->setChecked(false);
switch(mCircleGroup.mMeta.mCircleType)
{
case GXS_CIRCLE_TYPE_LOCAL:
#ifdef DEBUG_CREATE_CIRCLE_DIALOG
std::cerr << "CreateCircleDialog::updateCircleGUI() : LOCAL CIRCLETYPE";
std::cerr << std::endl;
#endif
isExternal = false;
break;
case GXS_CIRCLE_TYPE_PUBLIC:
#ifdef DEBUG_CREATE_CIRCLE_DIALOG
std::cerr << "CreateCircleDialog::updateCircleGUI() : PUBLIC CIRCLETYPE";
std::cerr << std::endl;
#endif
ui.radioButton_Public->setChecked(true);
break;
case GXS_CIRCLE_TYPE_EXT_SELF:
std::cerr << "CreateCircleDialog::updateCircleGUI() : EXT_SELF CIRCLE (fallthrough)";
std::cerr << std::endl;
#ifdef DEBUG_CREATE_CIRCLE_DIALOG
std::cerr << "CreateCircleDialog::updateCircleGUI() : EXT_SELF CIRCLE (fallthrough)"<< std::endl;
#endif
case GXS_CIRCLE_TYPE_EXTERNAL:
std::cerr << "CreateCircleDialog::updateCircleGUI() : EXTERNAL CIRCLETYPE";
std::cerr << std::endl;
if (mCircleGroup.mMeta.mCircleId.toStdString() == mCircleGroup.mMeta.mGroupId.toStdString()) {
#ifdef DEBUG_CREATE_CIRCLE_DIALOG
std::cerr << "CreateCircleDialog::updateCircleGUI() : EXTERNAL CIRCLETYPE"<< std::endl;
#endif
if (RsGxsGroupId(mCircleGroup.mMeta.mCircleId) == mCircleGroup.mMeta.mGroupId)
ui.radioButton_Self->setChecked(true);
else
ui.radioButton_Restricted->setChecked(true);
}//if (mCircleGroup.mMeta.mCircleId.toStdString() == mCircleGroup.mMeta.mGroupId.toStdString())
ui.circleComboBox->loadCircles(GXS_CIRCLE_CHOOSER_EXTERNAL, mCircleGroup.mMeta.mCircleId);
@ -442,17 +605,33 @@ void CreateCircleDialog::updateCircleGUI()
default:
std::cerr << "CreateCircleDialog::updateCircleGUI() INVALID mCircleType";
std::cerr << std::endl;
}//switch(mCircleGroup.mMeta.mCircleType)
// set preferredId.
ui.idChooser->loadIds(0,mCircleGroup.mMeta.mAuthorId);
}
/* setup personal or external circle */
if (isExternal) {
if (isExternal)
setupForExternalCircle();
} else {//if (isExternal)
else
setupForPersonalCircle();
}//else (isExternal)
// set preferredId.
std::cerr << "LoadCircle: setting author id to be " << mCircleGroup.mMeta.mAuthorId << std::endl;
//ui.idChooser->loadIds(0,mCircleGroup.mMeta.mAuthorId);
if(mReadOnly)
{
ui.circleAdminLabel->setId(mCircleGroup.mMeta.mAuthorId) ;
ui.idChooser->setVisible(false) ;
}
else
{
std::set<RsGxsId> ids ;
ids.insert(mCircleGroup.mMeta.mAuthorId) ;
ui.idChooser->setDefaultId(mCircleGroup.mMeta.mAuthorId) ;
ui.idChooser->setChosenId(mCircleGroup.mMeta.mAuthorId) ;
ui.idChooser->setIdConstraintSet(ids) ;
ui.idChooser->setFlags(IDCHOOSER_ID_REQUIRED | IDCHOOSER_NO_CREATE) ;
ui.circleAdminLabel->setVisible(false) ;
}
}
void CreateCircleDialog::requestCircle(const RsGxsGroupId &groupId)
@ -463,8 +642,10 @@ void CreateCircleDialog::requestCircle(const RsGxsGroupId &groupId)
std::list<RsGxsGroupId> groupIds;
groupIds.push_back(groupId);
#ifdef DEBUG_CREATE_CIRCLE_DIALOG
std::cerr << "CreateCircleDialog::requestCircle() Requesting Group Summary(" << groupId << ")";
std::cerr << std::endl;
#endif
uint32_t token;
mCircleQueue->requestGroupInfo(token, RS_TOKREQ_ANSTYPE_DATA, opts, groupIds, CREATECIRCLEDIALOG_CIRCLEINFO);
@ -472,8 +653,10 @@ void CreateCircleDialog::requestCircle(const RsGxsGroupId &groupId)
void CreateCircleDialog::loadCircle(uint32_t token)
{
#ifdef DEBUG_CREATE_CIRCLE_DIALOG
std::cerr << "CreateCircleDialog::loadCircle(" << token << ")";
std::cerr << std::endl;
#endif
QTreeWidget *tree = ui.treeWidget_membership;
@ -484,22 +667,23 @@ void CreateCircleDialog::loadCircle(uint32_t token)
std::cerr << "CreateCircleDialog::loadCircle() Error getting GroupData";
std::cerr << std::endl;
return;
}//if (!rsGxsCircles->getGroupData(token, groups))
}
if (groups.size() != 1) {
std::cerr << "CreateCircleDialog::loadCircle() Error Group.size() != 1";
std::cerr << std::endl;
return;
}//if (groups.size() != 1)
std::cerr << "CreateCircleDialog::loadCircle() LoadedGroup.meta: " << mCircleGroup.mMeta;
std::cerr << std::endl;
}
mCircleGroup = groups[0];
#ifdef DEBUG_CREATE_CIRCLE_DIALOG
std::cerr << "CreateCircleDialog::loadCircle() LoadedGroup.meta: " << mCircleGroup.mMeta << std::endl;
#endif
updateCircleGUI();
}
void CreateCircleDialog::getPgpIdentities()
/*void CreateCircleDialog::getPgpIdentities()
{
std::cerr << "CreateCircleDialog::getPgpIdentities()";
std::cerr << std::endl;
@ -527,19 +711,13 @@ void CreateCircleDialog::getPgpIdentities()
tree->addTopLevelItem(item);
// Local Circle.
if (mIsExistingCircle) {
// check if its in the circle.
std::list<RsPgpId>::const_iterator it;
it = std::find(mCircleGroup.mLocalFriends.begin(), mCircleGroup.mLocalFriends.end(), details.gpg_id);
if (it != mCircleGroup.mLocalFriends.end()) {
/* found it */
if (mIsExistingCircle)
if ( mCircleGroup.mLocalFriends.find(details.gpg_id) != mCircleGroup.mLocalFriends.end()) // check if its in the circle.
addMember(keyId, idtype, nickname);
}//if (it != mCircleGroup.mLocalFriends.end())
}//if (mIsExistingCircle)
}//for(it = ids.begin(); it != ids.end(); ++it)
}
filterIds();
}
}*/
void CreateCircleDialog::requestGxsIdentities()
@ -547,8 +725,10 @@ void CreateCircleDialog::requestGxsIdentities()
RsTokReqOptions opts;
opts.mReqType = GXS_REQUEST_TYPE_GROUP_DATA;
#ifdef DEBUG_CREATE_CIRCLE_DIALOG
std::cerr << "CreateCircleDialog::requestIdentities()";
std::cerr << std::endl;
#endif
uint32_t token;
mIdQueue->requestGroupInfo(token, RS_TOKREQ_ANSTYPE_DATA, opts, CREATECIRCLEDIALOG_IDINFO);
@ -556,8 +736,10 @@ void CreateCircleDialog::requestGxsIdentities()
void CreateCircleDialog::loadIdentities(uint32_t token)
{
#ifdef DEBUG_CREATE_CIRCLE_DIALOG
std::cerr << "CreateCircleDialog::loadIdentities(" << token << ")";
std::cerr << std::endl;
#endif
QTreeWidget *tree = ui.treeWidget_IdList;
@ -574,68 +756,77 @@ void CreateCircleDialog::loadIdentities(uint32_t token)
std::cerr << "CreateCircleDialog::insertIdentities() Error getting GroupData";
std::cerr << std::endl;
return;
}//if (!rsIdentity->getGroupData(token, datavector))
}
for(vit = datavector.begin(); vit != datavector.end(); ++vit) {
for(vit = datavector.begin(); vit != datavector.end(); ++vit)
{
data = (*vit);
/* do filtering */
bool ok = false;
if (acceptAnonymous) {
if (acceptAnonymous)
ok = true;
} else if (acceptAllPGP) {
else if (acceptAllPGP)
ok = data.mMeta.mGroupFlags & RSGXSID_GROUPFLAG_REALID ;
} else if (data.mPgpKnown) {
else if (data.mPgpKnown)
ok = data.mMeta.mGroupFlags & RSGXSID_GROUPFLAG_REALID ;
}//else if (data.mPgpKnown)
if (!ok) {
#ifdef DEBUG_CREATE_CIRCLE_DIALOG
std::cerr << "CreateCircleDialog::insertIdentities() Skipping ID: " << data.mMeta.mGroupId;
std::cerr << std::endl;
#endif
continue;
}//if (!ok)
}
QString keyId = QString::fromStdString(data.mMeta.mGroupId.toStdString());
QString nickname = QString::fromUtf8(data.mMeta.mGroupName.c_str());
QString idtype = tr("Anon Id");
if (data.mMeta.mGroupFlags & RSGXSID_GROUPFLAG_REALID) {
QPixmap pixmap ;
if(data.mImage.mSize == 0 || !pixmap.loadFromData(data.mImage.mData, data.mImage.mSize, "PNG"))
pixmap = QPixmap::fromImage(GxsIdDetails::makeDefaultIcon(RsGxsId(data.mMeta.mGroupId))) ;
if (data.mMeta.mGroupFlags & RSGXSID_GROUPFLAG_REALID)
{
if (data.mPgpKnown) {
RsPeerDetails details;
rsPeers->getGPGDetails(data.mPgpId, details);
idtype = QString::fromUtf8(details.name.c_str());
} else {
}
else
idtype = tr("PGP Linked Id");
}//else (data.mPgpKnown)
}//if (data.mMeta.mGroupFlags & RSGXSID_GROUPFLAG_REALID)
}
QTreeWidgetItem *item = new QTreeWidgetItem();
item->setText(RSCIRCLEID_COL_NICKNAME, nickname);
item->setIcon(RSCIRCLEID_COL_NICKNAME, QIcon(pixmap));
item->setText(RSCIRCLEID_COL_KEYID, keyId);
item->setText(RSCIRCLEID_COL_IDTYPE, idtype);
tree->addTopLevelItem(item);
// External Circle.
if (mIsExistingCircle) {
if (mIsExistingCircle)
{
// check if its in the circle.
std::list<RsGxsId>::const_iterator it;
// We use an explicit cast
//
it = std::find(mCircleGroup.mInvitedMembers.begin(), mCircleGroup.mInvitedMembers.end(), RsGxsId(data.mMeta.mGroupId));
if (it != mCircleGroup.mInvitedMembers.end()) {
/* found it */
if ( mCircleGroup.mInvitedMembers.find(RsGxsId(data.mMeta.mGroupId)) != mCircleGroup.mInvitedMembers.end()) /* found it */
addMember(keyId, idtype, nickname);
}//if (it != mCircleGroup.mInvitedMembers.end())
}//if (mIsExistingCircle)
}//for(vit = datavector.begin(); vit != datavector.end(); ++vit)
}
}
}
void CreateCircleDialog::loadRequest(const TokenQueue *queue, const TokenRequest &req)
{
#ifdef DEBUG_CREATE_CIRCLE_DIALOG
std::cerr << "CreateCircleDialog::loadRequest() UserType: " << req.mUserType;
std::cerr << std::endl;
#endif
if (queue == mCircleQueue) {
/* now switch on req */
@ -647,8 +838,8 @@ void CreateCircleDialog::loadRequest(const TokenQueue *queue, const TokenRequest
default:
std::cerr << "CreateCircleDialog::loadRequest() UNKNOWN UserType ";
std::cerr << std::endl;
}//switch(req.mUserType)
}//if (queue == mCircleQueue)
}
}
if (queue == mIdQueue) {
/* now switch on req */
@ -660,10 +851,14 @@ void CreateCircleDialog::loadRequest(const TokenQueue *queue, const TokenRequest
default:
std::cerr << "CreateCircleDialog::loadRequest() UNKNOWN UserType ";
std::cerr << std::endl;
}//switch(req.mUserType)
}//if (queue == mIdQueue)
}
}
}
void CreateCircleDialog::idTypeChanged()
{
requestGxsIdentities();
}
void CreateCircleDialog::filterChanged(const QString &text)
{
Q_UNUSED(text);
@ -683,5 +878,31 @@ void CreateCircleDialog::createNewGxsId()
IdEditDialog dlg(this);
dlg.setupNewId(false);
dlg.exec();
ui.idChooser->setDefaultId(dlg.getLastIdName());
//ui.idChooser->setDefaultId(dlg.getLastIdName());
}
void CreateCircleDialog::IdListCustomPopupMenu( QPoint )
{
QMenu contextMnu( this );
QTreeWidgetItem *item = ui.treeWidget_IdList->currentItem();
if (item) {
contextMnu.addAction(QIcon(":/images/edit_add24.png"), tr("Add Member"), this, SLOT(addMember()));
}
contextMnu.exec(QCursor::pos());
}
void CreateCircleDialog::MembershipListCustomPopupMenu( QPoint )
{
QMenu contextMnu( this );
QTreeWidgetItem *item = ui.treeWidget_membership->currentItem();
if (item && !mReadOnly)
contextMnu.addAction(QIcon(":/images/delete.png"), tr("Remove Member"), this, SLOT(removeMember()));
contextMnu.exec(QCursor::pos());
}

View file

@ -40,7 +40,7 @@ public:
~CreateCircleDialog();
void editNewId(bool isExternal);
void editExistingId(const RsGxsGroupId &circleId, const bool &clearList = true);
void editExistingId(const RsGxsGroupId &circleId, const bool &clearList = true, bool readonly=true);
void addMember(const QString &keyId, const QString &idtype, const QString &nickname);
void addMember(const RsGxsIdGroup &idGroup);
void addCircle(const RsGxsCircleDetails &cirDetails);
@ -51,12 +51,18 @@ private slots:
void addMember();
void removeMember();
void updateCircleType(bool b);
void selectedId(QTreeWidgetItem*, QTreeWidgetItem*);
void selectedMember(QTreeWidgetItem*, QTreeWidgetItem*);
void createCircle();
void filterChanged(const QString &text);
void createNewGxsId();
void idTypeChanged();
/** Create the context popup menu and it's submenus */
void IdListCustomPopupMenu( QPoint point );
void MembershipListCustomPopupMenu( QPoint point);
private:
@ -67,13 +73,14 @@ private:
bool mIsExistingCircle;
bool mIsExternalCircle;
bool mReadOnly;
void loadCircle(uint32_t token);
void loadIdentities(uint32_t token);
void requestCircle(const RsGxsGroupId &groupId);
void requestGxsIdentities();
void getPgpIdentities();
//void getPgpIdentities();
void filterIds();

View file

@ -6,7 +6,7 @@
<rect>
<x>0</x>
<y>0</y>
<width>681</width>
<width>881</width>
<height>515</height>
</rect>
</property>
@ -44,11 +44,14 @@
<item>
<widget class="QGroupBox" name="groupBox_2">
<property name="title">
<string>Circle Membership</string>
<string>Circle Members</string>
</property>
<layout class="QVBoxLayout" name="verticalLayout_2">
<item>
<widget class="QTreeWidget" name="treeWidget_membership">
<property name="contextMenuPolicy">
<enum>Qt::CustomContextMenu</enum>
</property>
<property name="sortingEnabled">
<bool>true</bool>
</property>
@ -126,9 +129,9 @@
</layout>
</item>
<item>
<widget class="QGroupBox" name="groupBox_4">
<widget class="QGroupBox" name="peersSelection_GB">
<property name="title">
<string>Known Identities</string>
<string>Known People</string>
</property>
<layout class="QVBoxLayout" name="verticalLayout">
<item>
@ -186,6 +189,9 @@
</item>
<item>
<widget class="RSTreeWidget" name="treeWidget_IdList">
<property name="contextMenuPolicy">
<enum>Qt::CustomContextMenu</enum>
</property>
<property name="sortingEnabled">
<bool>true</bool>
</property>
@ -240,7 +246,11 @@
</widget>
</item>
<item>
<widget class="QLineEdit" name="circleName"/>
<widget class="QLineEdit" name="circleName">
<property name="placeholderText">
<string>Circle name</string>
</property>
</widget>
</item>
<item>
<widget class="QLabel" name="idChooserLabel">
@ -251,12 +261,23 @@
</font>
</property>
<property name="text">
<string>Creator</string>
<string>Creator:</string>
</property>
</widget>
</item>
<item>
<widget class="GxsIdChooser" name="idChooser"/>
<widget class="GxsIdLabel" name="circleAdminLabel">
<property name="text">
<string>[Circle Admin]</string>
</property>
</widget>
</item>
<item>
<widget class="GxsIdChooser" name="idChooser">
<property name="toolTip">
<string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;The creator of a circle does not need to be known. It is however useful for public circles so that people know to whom to send a request for membership.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
</property>
</widget>
</item>
</layout>
</item>
@ -290,6 +311,9 @@
</item>
<item>
<widget class="QRadioButton" name="radioButton_Public">
<property name="toolTip">
<string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Publicly distributed circles are visible to your friends, which will get to know the circle data (Creator, members, etc)&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
</property>
<property name="text">
<string>Public</string>
</property>
@ -297,6 +321,9 @@
</item>
<item>
<widget class="QRadioButton" name="radioButton_Self">
<property name="toolTip">
<string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Self-restricted circles (the very existance of the circle, and its actual content) are only visible to the members of these circles. In practice the circle uses itself to limit its own distribution. &lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
</property>
<property name="text">
<string>Self-Restricted</string>
</property>
@ -304,6 +331,9 @@
</item>
<item>
<widget class="QRadioButton" name="radioButton_Restricted">
<property name="toolTip">
<string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Circles can be restricted to the members of another circle. Only the members of that second circle will be allowed to see the new circle and its content (list of members, etc).&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
</property>
<property name="text">
<string>Restricted to:</string>
</property>
@ -363,6 +393,11 @@
<extends>QComboBox</extends>
<header>gui/gxs/GxsCircleChooser.h</header>
</customwidget>
<customwidget>
<class>GxsIdLabel</class>
<extends>QLabel</extends>
<header>gui/gxs/GxsIdLabel.h</header>
</customwidget>
</customwidgets>
<resources>
<include location="../images.qrc"/>

View file

@ -21,6 +21,8 @@
*
*/
#include <unistd.h>
#include <QMessageBox>
#include <QMenu>
@ -28,10 +30,12 @@
#include "ui_IdDialog.h"
#include "IdEditDialog.h"
#include "gui/gxs/GxsIdDetails.h"
#include "gui/gxs/RsGxsUpdateBroadcastBase.h"
#include "gui/common/UIStateHelper.h"
#include "gui/chat/ChatDialog.h"
#include "gui/settings/rsharesettings.h"
#include "gui/msgs/MessageComposer.h"
#include "gui/Circles/CreateCircleDialog.h"
#include "gui/RetroShareLink.h"
#include "util/QtVersion.h"
@ -52,6 +56,22 @@
#define IDDIALOG_REPLIST 3
#define IDDIALOG_REFRESH 4
#define CIRCLEGROUP_CIRCLE_COL_GROUPNAME 0
#define CIRCLEGROUP_CIRCLE_COL_GROUPID 1
#define CIRCLEGROUP_CIRCLE_COL_GROUPFLAGS 2
#define CIRCLEGROUP_FRIEND_COL_NAME 0
#define CIRCLEGROUP_FRIEND_COL_ID 1
#define CLEAR_BACKGROUND 0
#define GREEN_BACKGROUND 1
#define BLUE_BACKGROUND 2
#define RED_BACKGROUND 3
#define GRAY_BACKGROUND 4
#define CIRCLESDIALOG_GROUPMETA 1
#define CIRCLESDIALOG_GROUPDATA 2
/****************************************************************
*/
@ -102,12 +122,21 @@ IdDialog::IdDialog(QWidget *parent) :
mIdQueue = NULL;
// This is used to grab the broadcast of changes from p3GxsCircles, which is discarded by the current dialog, since it expects data for p3Identity only.
mCirclesBroadcastBase = new RsGxsUpdateBroadcastBase(rsGxsCircles, this);
connect(mCirclesBroadcastBase, SIGNAL(fillDisplay(bool)), this, SLOT(updateCirclesDisplay(bool)));
allItem = new QTreeWidgetItem();
allItem->setText(0, tr("All"));
contactsItem = new QTreeWidgetItem();
contactsItem->setText(0, tr("Contacts"));
ui->treeWidget_membership->clear();
mExternalOtherCircleItem = NULL ;
mExternalSubCircleItem = NULL ;
mExternalAdminCircleItem = NULL ;
/* Setup UI helper */
mStateHelper = new UIStateHelper(this);
@ -164,7 +193,9 @@ IdDialog::IdDialog(QWidget *parent) :
connect(ui->inviteButton, SIGNAL(clicked()), this, SLOT(sendInvite()));
ui->avlabel->setPixmap(QPixmap(":/images/user/friends64.png"));
ui->headerTextLabel->setText(tr("People"));
/* Initialize splitter */
@ -177,8 +208,8 @@ IdDialog::IdDialog(QWidget *parent) :
/* Add filter types */
ui->filterComboBox->addItem(tr("All"), RSID_FILTER_ALL);
ui->filterComboBox->addItem(tr("Owned by you"), RSID_FILTER_OWNED_BY_YOU);
ui->filterComboBox->addItem(tr("Linked to your node"), RSID_FILTER_YOURSELF);
ui->filterComboBox->addItem(tr("Owned by myself"), RSID_FILTER_OWNED_BY_YOU);
ui->filterComboBox->addItem(tr("Linked to my node"), RSID_FILTER_YOURSELF);
ui->filterComboBox->addItem(tr("Linked to neighbor nodes"), RSID_FILTER_FRIENDS);
ui->filterComboBox->addItem(tr("Linked to distant nodes"), RSID_FILTER_OTHERS);
ui->filterComboBox->addItem(tr("Anonymous"), RSID_FILTER_PSEUDONYMS);
@ -188,6 +219,11 @@ IdDialog::IdDialog(QWidget *parent) :
QTreeWidgetItem *headerItem = ui->idTreeWidget->headerItem();
QString headerText = headerItem->text(RSID_COL_NICKNAME);
ui->filterLineEdit->addFilter(QIcon(), headerText, RSID_COL_NICKNAME, QString("%1 %2").arg(tr("Search"), headerText));
/* Set initial section sizes */
QHeaderView * circlesheader = ui->treeWidget_membership->header () ;
circlesheader->resizeSection (CIRCLEGROUP_CIRCLE_COL_GROUPNAME, 280);
ui->filterLineEdit->addFilter(QIcon(), tr("ID"), RSID_COL_KEYID, tr("Search ID"));
/* Setup tree */
@ -195,6 +231,7 @@ IdDialog::IdDialog(QWidget *parent) :
ui->idTreeWidget->enableColumnCustomize(true);
ui->idTreeWidget->setColumnCustomizable(RSID_COL_NICKNAME, false);
ui->idTreeWidget->setColumnHidden(RSID_COL_IDTYPE, true);
ui->idTreeWidget->setColumnHidden(RSID_COL_KEYID, true);
@ -212,29 +249,449 @@ IdDialog::IdDialog(QWidget *parent) :
mStateHelper->setActive(IDDIALOG_IDDETAILS, false);
mStateHelper->setActive(IDDIALOG_REPLIST, false);
QString hlp_str = tr(
" <h1><img width=\"32\" src=\":/icons/help_64.png\">&nbsp;&nbsp;Identities</h1> \
<p>In this tab you can create/edit pseudo-anonymous identities. \
</p> \
<p>In this tab you can create/edit pseudo-anonymous identities.</p> \
<p>Identities are used to securely identify your data: sign forum and channel posts,\
and receive feedback using Retroshare built-in email system, post comments \
after channel posts, etc.</p> \
<p> \
Identities can optionally be signed by your Retroshare node's certificate. \
Signed identities are easier to trust but are easily linked to your node's IP address. \
</p> \
<p> \
Anonymous identities allow you to anonymously interact with other users. They cannot be \
spoofed, but noone can prove who really owns a given identity. \
</p> \
") ;
<p>Identities can optionally be signed by your Retroshare node's certificate. \
Signed identities are easier to trust but are easily linked to your node's IP address.</p> \
<p> Anonymous identities allow you to anonymously interact with other users. They cannot be \
spoofed, but noone can prove who really owns a given identity.</p>") ;
registerHelpButton(ui->helpButton, hlp_str) ;
// load settings
processSettings(true);
// circles stuff
connect(ui->pushButton_extCircle, SIGNAL(clicked()), this, SLOT(createExternalCircle()));
connect(ui->pushButton_editCircle, SIGNAL(clicked()), this, SLOT(showEditExistingCircle()));
connect(ui->treeWidget_membership, SIGNAL(itemSelectionChanged()), this, SLOT(circle_selected()));
connect(ui->treeWidget_membership, SIGNAL(customContextMenuRequested(QPoint)), this, SLOT(CircleListCustomPopupMenu(QPoint)));
/* Setup TokenQueue */
mCircleQueue = new TokenQueue(rsGxsCircles->getTokenService(), this);
requestCircleGroupMeta();
}
void IdDialog::updateCirclesDisplay(bool)
{
#ifdef ID_DEBUG
std::cerr << "!!Updating circles display!" << std::endl;
#endif
requestCircleGroupMeta() ;
}
/************************** Request / Response *************************/
/*** Loading Main Index ***/
void IdDialog::requestCircleGroupMeta()
{
mStateHelper->setLoading(CIRCLESDIALOG_GROUPMETA, true);
#ifdef ID_DEBUG
std::cerr << "CirclesDialog::requestGroupMeta()";
std::cerr << std::endl;
#endif
mCircleQueue->cancelActiveRequestTokens(CIRCLESDIALOG_GROUPMETA);
RsTokReqOptions opts;
opts.mReqType = GXS_REQUEST_TYPE_GROUP_META;
uint32_t token;
mCircleQueue->requestGroupInfo(token, RS_TOKREQ_ANSTYPE_SUMMARY, opts, CIRCLESDIALOG_GROUPMETA);
}
void IdDialog::requestCircleGroupData(const RsGxsCircleId& circle_id)
{
mStateHelper->setLoading(CIRCLESDIALOG_GROUPDATA, true);
#ifdef ID_DEBUG
std::cerr << "CirclesDialog::requestGroupData()";
std::cerr << std::endl;
#endif
mCircleQueue->cancelActiveRequestTokens(CIRCLESDIALOG_GROUPDATA);
RsTokReqOptions opts;
opts.mReqType = GXS_REQUEST_TYPE_GROUP_DATA;
std::list<RsGxsGroupId> grps ;
grps.push_back(RsGxsGroupId(circle_id));
uint32_t token;
mCircleQueue->requestGroupInfo(token, RS_TOKREQ_ANSTYPE_DATA, opts, grps, CIRCLESDIALOG_GROUPDATA);
}
void IdDialog::loadCircleGroupMeta(const uint32_t &token)
{
mStateHelper->setLoading(CIRCLESDIALOG_GROUPMETA, false);
#ifdef ID_DEBUG
std::cerr << "CirclesDialog::loadCircleGroupMeta()";
std::cerr << std::endl;
#endif
std::list<RsGroupMetaData> groupInfo;
std::list<RsGroupMetaData>::iterator vit;
if (!rsGxsCircles->getGroupSummary(token,groupInfo))
{
std::cerr << "CirclesDialog::loadCircleGroupMeta() Error getting GroupMeta";
std::cerr << std::endl;
mStateHelper->setActive(CIRCLESDIALOG_GROUPMETA, false);
return;
}
mStateHelper->setActive(CIRCLESDIALOG_GROUPMETA, true);
/* add the top level item */
//QTreeWidgetItem *personalCirclesItem = new QTreeWidgetItem();
//personalCirclesItem->setText(0, tr("Personal Circles"));
//ui->treeWidget_membership->addTopLevelItem(personalCirclesItem);
if(!mExternalOtherCircleItem)
{
mExternalOtherCircleItem = new QTreeWidgetItem();
mExternalOtherCircleItem->setText(0, tr("Other visible circles"));
ui->treeWidget_membership->addTopLevelItem(mExternalOtherCircleItem);
}
if(!mExternalSubCircleItem )
{
mExternalSubCircleItem = new QTreeWidgetItem();
mExternalSubCircleItem->setText(0, tr("Circles I belong to"));
ui->treeWidget_membership->addTopLevelItem(mExternalSubCircleItem);
}
if(!mExternalAdminCircleItem)
{
mExternalAdminCircleItem = new QTreeWidgetItem();
mExternalAdminCircleItem->setText(0, tr("Circles I admin"));
ui->treeWidget_membership->addTopLevelItem(mExternalAdminCircleItem);
}
for(vit = groupInfo.begin(); vit != groupInfo.end();)
{
#ifdef ID_DEBUG
std::cerr << "CirclesDialog::loadCircleGroupMeta() GroupId: " << vit->mGroupId << " Group: " << vit->mGroupName << std::endl;
#endif
QList<QTreeWidgetItem*> clist = ui->treeWidget_membership->findItems( QString::fromStdString(vit->mGroupId.toStdString()), Qt::MatchExactly|Qt::MatchRecursive, CIRCLEGROUP_CIRCLE_COL_GROUPID);
if(clist.empty())
{
++vit ;
#ifdef ID_DEBUG
std::cerr << " group not already in list." << std::endl;
#endif
continue ;
}
if(clist.size() > 1)
{
std::cerr << " (EE) found " << clist.size() << " items in tree for group id " << vit->mGroupId << ": this is unexpected." << std::endl;
vit = groupInfo.erase(vit) ;
continue ;
}
QTreeWidgetItem *item = clist.front() ;
bool subscribed = vit->mSubscribeFlags & GXS_SERV::GROUP_SUBSCRIBE_SUBSCRIBED ;
bool admin = vit->mSubscribeFlags & GXS_SERV::GROUP_SUBSCRIBE_ADMIN ;
if(admin && item->parent() != mExternalAdminCircleItem)
{
std::cerr << " (EE) weird. Existing group is not in admin sub-items although it is admin." << std::endl;
delete item ;
++vit ;
continue ;
}
if(subscribed && !admin && item->parent() != mExternalSubCircleItem)
{
#ifdef ID_DEBUG
std::cerr << " Existing group is not in subscribed items although it is subscribed. Removing." << std::endl;
#endif
delete item ;
++vit ;
continue ;
}
if(!subscribed && !admin && item->parent() != mExternalOtherCircleItem)
{
#ifdef ID_DEBUG
std::cerr << " Existing group is not in subscribed items although it is subscribed. Removing." << std::endl;
#endif
delete item ;
++vit ;
continue ;
}
if(item->text(CIRCLEGROUP_CIRCLE_COL_GROUPNAME) != QString::fromUtf8(vit->mGroupName.c_str()))
{
#ifdef ID_DEBUG
std::cerr << " Existing group has a new name. Updating it in the tree." << std::endl;
#endif
item->setText(CIRCLEGROUP_CIRCLE_COL_GROUPNAME, QString::fromUtf8(vit->mGroupName.c_str()));
}
// the item is at the right place. Just remove it from the list of items to add.
#ifdef ID_DEBUG
std::cerr << " item already in place. Removing from list." << std::endl;
#endif
vit = groupInfo.erase(vit) ;
}
for(vit = groupInfo.begin(); vit != groupInfo.end(); ++vit)
{
if (vit->mCircleType == GXS_CIRCLE_TYPE_LOCAL)
{
std::cerr << "(WW) Local circle not added to tree widget. Needs to be implmeented." << std::endl;
continue ;
}
/* Add Widget, and request Pages */
QTreeWidgetItem *groupItem = new QTreeWidgetItem();
groupItem->setText(CIRCLEGROUP_CIRCLE_COL_GROUPNAME, QString::fromUtf8(vit->mGroupName.c_str()));
groupItem->setText(CIRCLEGROUP_CIRCLE_COL_GROUPID, QString::fromStdString(vit->mGroupId.toStdString()));
groupItem->setData(CIRCLEGROUP_CIRCLE_COL_GROUPFLAGS, Qt::UserRole, QVariant(vit->mSubscribeFlags));
if (vit->mSubscribeFlags & GXS_SERV::GROUP_SUBSCRIBE_ADMIN)
{
#ifdef ID_DEBUG
std::cerr << " adding item for group " << vit->mGroupId << " to admin"<< std::endl;
#endif
mExternalAdminCircleItem->addChild(groupItem);
}
else if (vit->mSubscribeFlags & GXS_SERV::GROUP_SUBSCRIBE_SUBSCRIBED)
{
#ifdef ID_DEBUG
std::cerr << " adding item for group " << vit->mGroupId << " to subscribed"<< std::endl;
#endif
mExternalSubCircleItem->addChild(groupItem);
}
else
{
#ifdef ID_DEBUG
std::cerr << " adding item for group " << vit->mGroupId << " to others"<< std::endl;
#endif
mExternalOtherCircleItem->addChild(groupItem);
}
}
}
static void mark_matching_tree(QTreeWidget *w, const std::set<RsGxsId>& members, int col)
{
w->selectionModel()->clearSelection() ;
for(std::set<RsGxsId>::const_iterator it(members.begin());it!=members.end();++it)
{
QList<QTreeWidgetItem*> clist = w->findItems( QString::fromStdString((*it).toStdString()), Qt::MatchExactly|Qt::MatchRecursive, col);
foreach(QTreeWidgetItem* item, clist)
item->setSelected(true) ;
}
}
void IdDialog::loadCircleGroupData(const uint32_t& token)
{
#ifdef ID_DEBUG
std::cerr << "Loading circle info" << std::endl;
#endif
std::vector<RsGxsCircleGroup> circle_grp_v ;
rsGxsCircles->getGroupData(token, circle_grp_v);
if (circle_grp_v.empty())
{
std::cerr << "(EE) unexpected empty result from getGroupData. Cannot process circle now!" << std::endl;
return ;
}
if (circle_grp_v.size() != 1)
{
std::cerr << "(EE) very weird result from getGroupData. Should get exactly one circle" << std::endl;
return ;
}
RsGxsCircleGroup cg = circle_grp_v.front();
RsGxsCircleId requested_cid(cg.mMeta.mGroupId) ;
QTreeWidgetItem *item = ui->treeWidget_membership->currentItem();
if ((!item) || (!item->parent()))
return;
QString coltext = item->text(CIRCLEGROUP_CIRCLE_COL_GROUPID);
RsGxsCircleId id ( coltext.toStdString()) ;
if(requested_cid != id)
{
std::cerr << "(WW) not the same circle. Dropping request." << std::endl;
return ;
}
/* now mark all the members */
std::set<RsGxsId> members = cg.mInvitedMembers;
mark_matching_tree(ui->idTreeWidget, members, RSID_COL_KEYID) ;
mStateHelper->setLoading(CIRCLESDIALOG_GROUPDATA, false);
}
void IdDialog::createExternalCircle()
{
CreateCircleDialog dlg;
dlg.editNewId(true);
dlg.exec();
requestCircleGroupMeta(); // update GUI
}
void IdDialog::showEditExistingCircle()
{
QTreeWidgetItem *item = ui->treeWidget_membership->currentItem();
if ((!item) || (!item->parent()))
{
return;
}
uint32_t subscribe_flags = item->data(CIRCLEGROUP_CIRCLE_COL_GROUPFLAGS, Qt::UserRole).toUInt();
QString coltext = item->text(CIRCLEGROUP_CIRCLE_COL_GROUPID);
RsGxsGroupId id ( coltext.toStdString());
CreateCircleDialog dlg;
dlg.editExistingId(id,true,!(subscribe_flags & GXS_SERV::GROUP_SUBSCRIBE_ADMIN)) ;
dlg.exec();
requestCircleGroupMeta(); // update GUI
}
void IdDialog::CircleListCustomPopupMenu( QPoint )
{
// (cyril) Removed this because we have a edit button already.
#ifdef SUSPENDED
QMenu contextMnu( this );
QTreeWidgetItem *item = ui->treeWidget_membership->currentItem();
if (item) {
contextMnu.addAction(QIcon(IMAGE_EDIT), tr("Edit Circle"), this, SLOT(editExistingCircle()));
}
contextMnu.exec(QCursor::pos());
#endif
}
static void set_item_background(QTreeWidgetItem *item, uint32_t type)
{
QBrush brush;
switch(type)
{
default:
case CLEAR_BACKGROUND:
brush = QBrush(Qt::white);
break;
case GREEN_BACKGROUND:
brush = QBrush(Qt::green);
break;
case BLUE_BACKGROUND:
brush = QBrush(Qt::blue);
break;
case RED_BACKGROUND:
brush = QBrush(Qt::red);
break;
case GRAY_BACKGROUND:
brush = QBrush(Qt::gray);
break;
}
item->setBackground (0, brush);
}
static void update_children_background(QTreeWidgetItem *item, uint32_t type)
{
int count = item->childCount();
for(int i = 0; i < count; ++i)
{
QTreeWidgetItem *child = item->child(i);
if (child->childCount() > 0)
{
update_children_background(child, type);
}
set_item_background(child, type);
}
}
#ifdef SUSPENDED
static void set_tree_background(QTreeWidget *tree, uint32_t type)
{
std::cerr << "CirclesDialog set_tree_background()";
std::cerr << std::endl;
/* grab all toplevel */
int count = tree->topLevelItemCount();
for(int i = 0; i < count; ++i)
{
QTreeWidgetItem *item = tree->topLevelItem(i);
/* resursively clear child backgrounds */
update_children_background(item, type);
set_item_background(item, type);
}
}
static void check_mark_item(QTreeWidgetItem *item, const std::set<RsPgpId> &names, uint32_t col, uint32_t type)
{
QString coltext = item->text(col);
RsPgpId colstr ( coltext.toStdString());
if (names.end() != names.find(colstr))
{
set_item_background(item, type);
std::cerr << "CirclesDialog check_mark_item: found match: " << colstr;
std::cerr << std::endl;
}
}
#endif
void IdDialog::circle_selected()
{
QTreeWidgetItem *item = ui->treeWidget_membership->currentItem();
#ifdef ID_DEBUG
std::cerr << "CirclesDialog::circle_selected() valid circle chosen";
std::cerr << std::endl;
#endif
if ((!item) || (!item->parent()))
{
mStateHelper->setWidgetEnabled(ui->pushButton_editCircle, false);
ui->pushButton_editCircle->setText(tr("Show details")) ;
ui->pushButton_editCircle->setEnabled(false) ;
mark_matching_tree(ui->idTreeWidget, std::set<RsGxsId>(), RSID_COL_KEYID) ;
return;
}
uint32_t subscribe_flags = item->data(CIRCLEGROUP_CIRCLE_COL_GROUPFLAGS, Qt::UserRole).toUInt();
ui->pushButton_editCircle->setEnabled(true) ;
if(subscribe_flags & GXS_SERV::GROUP_SUBSCRIBE_ADMIN)
ui->pushButton_editCircle->setText(tr("Edit circle")) ;
else
ui->pushButton_editCircle->setText(tr("Show details")) ;
//set_item_background(item, BLUE_BACKGROUND);
QString coltext = item->text(CIRCLEGROUP_CIRCLE_COL_GROUPID);
RsGxsCircleId id ( coltext.toStdString()) ;
requestCircleGroupData(id) ;
}
IdDialog::~IdDialog()
@ -246,6 +703,24 @@ IdDialog::~IdDialog()
delete(mIdQueue);
}
static QString getHumanReadableDuration(uint32_t seconds)
{
if(seconds < 60)
return QString(QObject::tr("%1 seconds ago")).arg(seconds) ;
else if(seconds < 120)
return QString(QObject::tr("%1 minute ago")).arg(seconds/60) ;
else if(seconds < 3600)
return QString(QObject::tr("%1 minutes ago")).arg(seconds/60) ;
else if(seconds < 7200)
return QString(QObject::tr("%1 hour ago")).arg(seconds/3600) ;
else if(seconds < 24*3600)
return QString(QObject::tr("%1 hours ago")).arg(seconds/3600) ;
else if(seconds < 2*24*3600)
return QString(QObject::tr("%1 day ago")).arg(seconds/86400) ;
else
return QString(QObject::tr("%1 days ago")).arg(seconds/86400) ;
}
void IdDialog::processSettings(bool load)
{
Settings->beginGroup("IdDialog");
@ -304,24 +779,6 @@ void IdDialog::updateSelection()
}
}
static QString getHumanReadableDuration(uint32_t seconds)
{
if(seconds < 60)
return QString(QObject::tr("%1 seconds ago")).arg(seconds) ;
else if(seconds < 120)
return QString(QObject::tr("%1 minute ago")).arg(seconds/60) ;
else if(seconds < 3600)
return QString(QObject::tr("%1 minutes ago")).arg(seconds/60) ;
else if(seconds < 7200)
return QString(QObject::tr("%1 hour ago")).arg(seconds/3600) ;
else if(seconds < 24*3600)
return QString(QObject::tr("%1 hours ago")).arg(seconds/3600) ;
else if(seconds < 2*24*3600)
return QString(QObject::tr("%1 day ago")).arg(seconds/86400) ;
else
return QString(QObject::tr("%1 days ago")).arg(seconds/86400) ;
}
void IdDialog::requestIdList()
{
//Disable by default, will be enable by insertIdDetails()
@ -395,6 +852,9 @@ bool IdDialog::fillIdListItem(const RsGxsIdGroup& data, QTreeWidgetItem *&item,
item->setText(RSID_COL_NICKNAME, QString::fromUtf8(data.mMeta.mGroupName.c_str()).left(RSID_MAXIMUM_NICKNAME_SIZE));
item->setText(RSID_COL_KEYID, QString::fromStdString(data.mMeta.mGroupId.toStdString()));
//time_t now = time(NULL) ;
//item->setText(RSID_COL_LASTUSED, getHumanReadableDuration(now - data.mLastUsageTS)) ;
item->setData(RSID_COL_KEYID, Qt::UserRole,QVariant(item_flags)) ;
item->setTextAlignment(RSID_COL_VOTES, Qt::AlignRight);
@ -579,7 +1039,6 @@ void IdDialog::requestIdDetails()
mIdQueue->requestGroupInfo(token, RS_TOKREQ_ANSTYPE_DATA, opts, groupIds, IDDIALOG_IDDETAILS);
}
void IdDialog::insertIdDetails(uint32_t token)
{
mStateHelper->setLoading(IDDIALOG_IDDETAILS, false);
@ -635,7 +1094,9 @@ void IdDialog::insertIdDetails(uint32_t token)
#ifdef ID_DEBUG
std::cerr << "Setting header frame image : " << pix.width() << " x " << pix.height() << std::endl;
#endif
ui->avlabel->setPixmap(pixmap);
ui->avatarLabel->setPixmap(pixmap);
if (data.mPgpKnown)
@ -816,6 +1277,7 @@ void IdDialog::updateDisplay(bool complete)
return;
}
requestCircleGroupMeta();
std::list<RsGxsGroupId> grpIds;
getAllGrpIds(grpIds);
@ -915,13 +1377,15 @@ void IdDialog::insertRepList(uint32_t token)
mStateHelper->setActive(IDDIALOG_REPLIST, true);
}
void IdDialog::loadRequest(const TokenQueue * /*queue*/, const TokenRequest &req)
void IdDialog::loadRequest(const TokenQueue * queue, const TokenRequest &req)
{
#ifdef ID_DEBUG
std::cerr << "IdDialog::loadRequest() UserType: " << req.mUserType;
std::cerr << std::endl;
#endif
if(queue == mIdQueue)
{
switch(req.mUserType)
{
case IDDIALOG_IDLIST:
@ -947,6 +1411,32 @@ void IdDialog::loadRequest(const TokenQueue * /*queue*/, const TokenRequest &req
}
}
if(queue == mCircleQueue)
{
#ifdef ID_DEBUG
std::cerr << "CirclesDialog::loadRequest() UserType: " << req.mUserType;
std::cerr << std::endl;
#endif
/* now switch on req */
switch(req.mUserType)
{
case CIRCLESDIALOG_GROUPMETA:
loadCircleGroupMeta(req.mToken);
break;
case CIRCLESDIALOG_GROUPDATA:
loadCircleGroupData(req.mToken);
break;
default:
std::cerr << "CirclesDialog::loadRequest() ERROR: INVALID TYPE";
std::cerr << std::endl;
break;
}
}
}
void IdDialog::IdListCustomPopupMenu( QPoint )
{
QMenu contextMnu( this );
@ -981,7 +1471,9 @@ void IdDialog::IdListCustomPopupMenu( QPoint )
if(item_flags & RSID_FILTER_OWNED_BY_YOU)
one_item_owned_by_you = true ;
#ifdef ID_DEBUG
std::cerr << " item flags = " << item_flags << std::endl;
#endif
RsGxsId keyId((*it)->text(RSID_COL_KEYID).toStdString());
RsReputations::ReputationInfo info ;

View file

@ -56,7 +56,17 @@ public:
protected:
virtual void updateDisplay(bool complete);
void loadCircleGroupMeta(const uint32_t &token);
void loadCircleGroupData(const uint32_t &token);
void requestCircleGroupMeta();
void requestCircleGroupData(const RsGxsCircleId& circle_id);
private slots:
void createExternalCircle();
void showEditExistingCircle();
void updateCirclesDisplay(bool);
void filterComboBoxChanged();
void filterChanged(const QString &text);
@ -74,6 +84,9 @@ private slots:
/** Create the context popup menu and it's submenus */
void IdListCustomPopupMenu( QPoint point );
void CircleListCustomPopupMenu(QPoint point) ;
void circle_selected() ;
void addtoContacts();
void removefromContacts();
@ -104,10 +117,16 @@ private:
private:
TokenQueue *mIdQueue;
TokenQueue *mCircleQueue;
UIStateHelper *mStateHelper;
QTreeWidgetItem *contactsItem;
QTreeWidgetItem *allItem;
QTreeWidgetItem *mExternalSubCircleItem;
QTreeWidgetItem *mExternalOtherCircleItem;
QTreeWidgetItem *mExternalAdminCircleItem;
RsGxsUpdateBroadcastBase *mCirclesBroadcastBase ;
RsGxsGroupId mId;

View file

@ -6,8 +6,8 @@
<rect>
<x>0</x>
<y>0</y>
<width>745</width>
<height>640</height>
<width>1475</width>
<height>1134</height>
</rect>
</property>
<property name="sizePolicy">
@ -19,14 +19,8 @@
<property name="windowTitle">
<string/>
</property>
<layout class="QGridLayout" name="gridLayout_5">
<property name="horizontalSpacing">
<number>0</number>
</property>
<property name="margin">
<number>0</number>
</property>
<item row="0" column="0">
<layout class="QVBoxLayout" name="verticalLayout_6">
<item>
<widget class="QFrame" name="titleBarFrame">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Maximum">
@ -62,7 +56,7 @@
<string/>
</property>
<property name="pixmap">
<pixmap resource="../images.qrc">:/images/user/friends24.png</pixmap>
<pixmap resource="../../../../../trunk/retroshare-gui/src/gui/images.qrc">:/images/user/friends24.png</pixmap>
</property>
<property name="scaledContents">
<bool>true</bool>
@ -102,7 +96,7 @@
<enum>Qt::NoFocus</enum>
</property>
<property name="icon">
<iconset resource="../images.qrc">
<iconset resource="../../../../../trunk/retroshare-gui/src/gui/images.qrc">
<normaloff>:/icons/help_64.png</normaloff>:/icons/help_64.png</iconset>
</property>
<property name="checkable">
@ -116,7 +110,7 @@
</layout>
</widget>
</item>
<item row="1" column="0">
<item>
<widget class="QSplitter" name="splitter">
<property name="orientation">
<enum>Qt::Horizontal</enum>
@ -159,7 +153,7 @@
<string>New ID</string>
</property>
<property name="icon">
<iconset resource="../images.qrc">
<iconset resource="../../../../../trunk/retroshare-gui/src/gui/images.qrc">
<normaloff>:/images/identity/identity_create_32.png</normaloff>:/images/identity/identity_create_32.png</iconset>
</property>
<property name="iconSize">
@ -235,7 +229,16 @@
</item>
</layout>
</widget>
<widget class="QWidget" name="layoutWidget">
<widget class="QTabWidget" name="tabWidget1">
<property name="currentIndex">
<number>0</number>
</property>
<widget class="QWidget" name="tab_2">
<attribute name="title">
<string>Person</string>
</attribute>
<layout class="QVBoxLayout" name="verticalLayout">
<item>
<layout class="QVBoxLayout" name="verticalLayout_4">
<item>
<widget class="QFrame" name="headerFrame">
@ -449,19 +452,6 @@
</item>
</layout>
</item>
<item row="1" column="0">
<spacer name="verticalSpacer_2">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
<height>40</height>
</size>
</property>
</spacer>
</item>
</layout>
</widget>
</item>
@ -527,7 +517,7 @@ p, li { white-space: pre-wrap; }
</property>
<property name="icon">
<iconset>
<normaloff>../icons/yellow_biohazard64.png</normaloff>../icons/yellow_biohazard64.png</iconset>
<normaloff>../../../../../trunk/retroshare-gui/src/gui/icons/yellow_biohazard64.png</normaloff>../../../../../trunk/retroshare-gui/src/gui/icons/yellow_biohazard64.png</iconset>
</property>
</item>
<item>
@ -587,13 +577,84 @@ p, li { white-space: pre-wrap; }
</spacer>
</item>
</layout>
</item>
</layout>
</widget>
<widget class="QWidget" name="tab">
<attribute name="title">
<string>Circles</string>
</attribute>
<layout class="QGridLayout" name="gridLayout_5">
<item row="0" column="0">
<layout class="QHBoxLayout" name="horizontalLayout_7">
<item>
<widget class="QPushButton" name="pushButton_extCircle">
<property name="text">
<string>Create Circle</string>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="pushButton_editCircle">
<property name="text">
<string>Edit Circle</string>
</property>
</widget>
</item>
<item>
<spacer name="horizontalSpacer">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
</layout>
</item>
<item row="1" column="0">
<widget class="QTreeWidget" name="treeWidget_membership">
<property name="contextMenuPolicy">
<enum>Qt::CustomContextMenu</enum>
</property>
<property name="sortingEnabled">
<bool>true</bool>
</property>
<column>
<property name="text">
<string>Name</string>
</property>
</column>
<column>
<property name="text">
<string>IDs</string>
</property>
</column>
<item>
<property name="text">
<string>Public Circles</string>
</property>
</item>
<item>
<property name="text">
<string>Personal Circles</string>
</property>
</item>
</widget>
</item>
</layout>
</widget>
</widget>
</widget>
</item>
</layout>
<action name="editIdentity">
<property name="icon">
<iconset resource="../images.qrc">
<iconset resource="../../../../../trunk/retroshare-gui/src/gui/images.qrc">
<normaloff>:/images/edit_16.png</normaloff>:/images/edit_16.png</iconset>
</property>
<property name="text">
@ -605,7 +666,7 @@ p, li { white-space: pre-wrap; }
</action>
<action name="removeIdentity">
<property name="icon">
<iconset resource="../images.qrc">
<iconset resource="../../../../../trunk/retroshare-gui/src/gui/images.qrc">
<normaloff>:/images/delete.png</normaloff>:/images/delete.png</iconset>
</property>
<property name="text">
@ -614,7 +675,7 @@ p, li { white-space: pre-wrap; }
</action>
<action name="chatIdentity">
<property name="icon">
<iconset resource="../images.qrc">
<iconset resource="../../../../../trunk/retroshare-gui/src/gui/images.qrc">
<normaloff>:/images/toaster/chat.png</normaloff>:/images/toaster/chat.png</iconset>
</property>
<property name="text">
@ -651,7 +712,7 @@ p, li { white-space: pre-wrap; }
<tabstop>idTreeWidget</tabstop>
</tabstops>
<resources>
<include location="../images.qrc"/>
<include location="../../../../../trunk/retroshare-gui/src/gui/images.qrc"/>
</resources>
<connections/>
</ui>

View file

@ -95,9 +95,9 @@
#include "gui/gxschannels/GxsChannelDialog.h"
#include "gui/gxsforums/GxsForumsDialog.h"
#include "gui/Identity/IdDialog.h"
#ifdef RS_USE_CIRCLES
#include "gui/Circles/CirclesDialog.h"
#endif
//#ifdef RS_USE_CIRCLES
//#include "gui/Circles/CirclesDialog.h"
//#endif
#ifdef RS_USE_WIKI
#include "gui/WikiPoos/WikiDialog.h"
#endif
@ -359,7 +359,7 @@ void MainWindow::initStackedPage()
addPage(newsFeed = new NewsFeed(ui->stackPages), grp, &notify);
addPage(friendsDialog = new FriendsDialog(ui->stackPages), grp, &notify);
#ifdef RS_USE_CIRCLES
#ifdef RS_USE_NEW_PEOPLE_DIALOG
PeopleDialog *peopleDialog = NULL;
addPage(peopleDialog = new PeopleDialog(ui->stackPages), grp, &notify);
#endif
@ -367,10 +367,10 @@ void MainWindow::initStackedPage()
IdDialog *idDialog = NULL;
addPage(idDialog = new IdDialog(ui->stackPages), grp, &notify);
#ifdef RS_USE_CIRCLES
CirclesDialog *circlesDialog = NULL;
addPage(circlesDialog = new CirclesDialog(ui->stackPages), grp, &notify);
#endif
//#ifdef RS_USE_CIRCLES
// CirclesDialog *circlesDialog = NULL;
// addPage(circlesDialog = new CirclesDialog(ui->stackPages), grp, &notify);
//#endif
addPage(transfersDialog = new TransfersDialog(ui->stackPages), grp, &notify);
addPage(chatLobbyDialog = new ChatLobbyWidget(ui->stackPages), grp, &notify);

View file

@ -54,8 +54,8 @@ void CircleWidget::updateData(const RsGroupMetaData& gxs_group_info
if (_circle_details != details) {
_circle_details=details;
typedef std::set<RsGxsId>::iterator itUnknownPeers;
for (itUnknownPeers it = _circle_details.mUnknownPeers.begin()
; it != _circle_details.mUnknownPeers.end()
for (itUnknownPeers it = _circle_details.mAllowedAnonPeers.begin()
; it != _circle_details.mAllowedAnonPeers.end()
; ++it) {
RsGxsId gxs_id = *it;
if(!gxs_id.isNull()) {
@ -63,15 +63,14 @@ void CircleWidget::updateData(const RsGroupMetaData& gxs_group_info
}//if(!gxs_id.isNull())
}//for (itUnknownPeers it = _circle_details.mUnknownPeers.begin()
typedef std::map<RsPgpId, std::list<RsGxsId> >::const_iterator itAllowedPeers;
for (itAllowedPeers it = _circle_details.mAllowedPeers.begin()
; it != _circle_details.mAllowedPeers.end()
; ++it ) {
typedef std::map<RsPgpId, std::set<RsGxsId> >::const_iterator itAllowedPeers;
for (itAllowedPeers it = _circle_details.mAllowedSignedPeers.begin() ; it != _circle_details.mAllowedSignedPeers.end() ; ++it )
{
RsPgpId pgp_id = it->first;
emit askForPGPIdentityWidget(pgp_id);
std::list<RsGxsId> gxs_id_list = it->second;
typedef std::list<RsGxsId>::const_iterator itGxsId;
std::set<RsGxsId> gxs_id_list = it->second;
typedef std::set<RsGxsId>::const_iterator itGxsId;
for (itGxsId curs=gxs_id_list.begin()
; curs != gxs_id_list.end()
; ++curs) {

View file

@ -85,7 +85,13 @@ void IdentityWidget::updateData(const RsGxsIdGroup &gxs_group_info)
ui->labelKeyId->setVisible(false);
/// (TODO) Get real ident icon
QImage image = GxsIdDetails::makeDefaultIcon(RsGxsId(_group_info.mMeta.mGroupId));
QImage image;
if(_group_info.mImage.mSize > 0 && image.loadFromData(_group_info.mImage.mData, _group_info.mImage.mSize, "PNG"))
image = image;
else
image = GxsIdDetails::makeDefaultIcon(RsGxsId(_group_info.mMeta.mGroupId));
if (_avatar != image) {
_avatar = image;
_scene->clear();
@ -122,13 +128,14 @@ void IdentityWidget::updateData(const RsPeerDetails &pgp_details)
ui->labelKeyId->setToolTip(tr("PGP id:").append(" "+_keyId));
QPixmap avatar;
AvatarDefs::getAvatarFromGpgId(_details.gpg_id.toStdString(), avatar);
/*AvatarDefs::getAvatarFromGpgId(_details.gpg_id, avatar);
if (_avatar != avatar.toImage()) {
_avatar = avatar.toImage();
_scene->clear();
_scene->addPixmap(avatar.scaled(ui->graphicsView->width(),ui->graphicsView->height()));
emit imageUpdated();
}//if (_avatar != avatar.toImage())
}*///if (_avatar != avatar.toImage())
//}//if (_details != gpg_details)
}
@ -200,3 +207,4 @@ void IdentityWidget::pbAdd_clicked()
{
emit addButtonClicked();
}

View file

@ -7,7 +7,7 @@
<x>0</x>
<y>0</y>
<width>102</width>
<height>158</height>
<height>170</height>
</rect>
</property>
<layout class="QVBoxLayout" name="verticalLayout">
@ -131,7 +131,6 @@
</item>
</layout>
</widget>
<resources/>
<customwidgets>
<customwidget>
<class>ElidedLabel</class>
@ -140,5 +139,8 @@
<container>1</container>
</customwidget>
</customwidgets>
<resources>
<include location="../images.qrc"/>
</resources>
<connections/>
</ui>

View file

@ -26,11 +26,16 @@
#include "gui/Circles/CreateCircleDialog.h"
#include "gui/common/FlowLayout.h"
#include "gui/settings/rsharesettings.h"
#include "gui/msgs/MessageComposer.h"
#include "gui/gxs/GxsIdDetails.h"
#include "gui/Identity/IdDetailsDialog.h"
#include "retroshare/rspeers.h"
#include "retroshare/rsidentity.h"
#include "retroshare/rsgxscircles.h"
#include "retroshare/rsgxsflags.h"
#include "retroshare/rsmsgs.h"
#include "retroshare/rsids.h"
#include <iostream>
#include <QMenu>
@ -56,6 +61,9 @@ PeopleDialog::PeopleDialog(QWidget *parent)
mIdentityQueue = new TokenQueue(rsIdentity->getTokenService(), this);
mCirclesQueue = new TokenQueue(rsGxsCircles->getTokenService(), this);
tabWidget->removeTab(1);
//need erase QtCreator Layout first(for Win)
delete idExternal->layout();
delete idInternal->layout();
@ -418,6 +426,45 @@ void PeopleDialog::iw_AddButtonClickedExt()
+ ";" + QString::fromStdString(dest->groupInfo().mMeta.mGroupId.toStdString()));
}//for( itCurs =_ext_circles_widgets.begin();
std::list<RsGxsId> own_identities ;
rsIdentity->getOwnIds(own_identities) ;
if(own_identities.size() <= 1)
{
QAction *action = contextMnu.addAction(QIcon(":/images/chat_24.png"), tr("Chat with this person"), this, SLOT(chatIdentity()));
if(own_identities.empty())
action->setEnabled(false) ;
else
action->setData(QString::fromStdString((own_identities.front()).toStdString()) + ";" + QString::fromStdString(dest->groupInfo().mMeta.mGroupId.toStdString())) ;
}
else
{
QMenu *mnu = contextMnu.addMenu(QIcon(":/images/chat_24.png"),tr("Chat with this person as...")) ;
for(std::list<RsGxsId>::const_iterator it=own_identities.begin();it!=own_identities.end();++it)
{
RsIdentityDetails idd ;
rsIdentity->getIdDetails(*it,idd) ;
QPixmap pixmap ;
if(idd.mAvatar.mSize == 0 || !pixmap.loadFromData(idd.mAvatar.mData, idd.mAvatar.mSize, "PNG"))
pixmap = QPixmap::fromImage(GxsIdDetails::makeDefaultIcon(*it)) ;
QAction *action = mnu->addAction(QIcon(pixmap), QString("%1 (%2)").arg(QString::fromUtf8(idd.mNickname.c_str()), QString::fromStdString((*it).toStdString())), this, SLOT(chatIdentity()));
action->setData(QString::fromStdString((*it).toStdString()) + ";" + QString::fromStdString(dest->groupInfo().mMeta.mGroupId.toStdString())) ;
}
}
QAction *actionsendmsg = contextMnu.addAction(QIcon(":/images/mail_new.png"), tr("Send message to this person"), this, SLOT(sendMessage()));
actionsendmsg->setData( QString::fromStdString(dest->groupInfo().mMeta.mGroupId.toStdString()));
contextMnu.addSeparator();
QAction *actionDetails = contextMnu.addAction(QIcon(":/images/info16.png"), tr("Person details"), this, SLOT(personDetails()));
actionDetails->setData( QString::fromStdString(dest->groupInfo().mMeta.mGroupId.toStdString()));
contextMnu.exec(QCursor::pos());
}//if (dest)
}
@ -469,7 +516,7 @@ void PeopleDialog::addToCircleExt()
dlg.addMember(idWidget->groupInfo());
}//if((itFound=_gxs_identity_widgets.find(gxs_id)) != _gxs_identity_widgets.end())
dlg.editExistingId(circle->groupInfo().mGroupId, false);
dlg.editExistingId(circle->groupInfo().mGroupId, false,false);
dlg.exec();
}//if((itFound=_ext_circles_widgets.find(groupId)) != _ext_circles_widgets.end())
}//if (action)
@ -498,12 +545,79 @@ void PeopleDialog::addToCircleInt()
dlg.addMember(idWidget->keyId(), idWidget->idtype(), idWidget->nickname());
}//if((itFound=_pgp_identity_widgets.find(pgp_id)) != _pgp_identity_widgets.end())
dlg.editExistingId(circle->groupInfo().mGroupId, false);
dlg.editExistingId(circle->groupInfo().mGroupId, false,false);
dlg.exec();
}//if((itFound=_ext_circles_widgets.find(groupId)) != _ext_circles_widgets.end())
}//if (action)
}
void PeopleDialog::chatIdentity()
{
QAction *action =
qobject_cast<QAction *>(QObject::sender());
if (action) {
QString data = action->data().toString();
QStringList idList = data.split(";");
RsGxsId from_gxs_id = RsGxsId(idList.at(0).toStdString());
RsGxsId gxs_id = RsGxsId(idList.at(1).toStdString());
uint32_t error_code ;
DistantChatPeerId dpid ;
if(!rsMsgs->initiateDistantChatConnexion(RsGxsId(gxs_id), from_gxs_id, dpid,error_code))
QMessageBox::information(NULL, tr("Distant chat cannot work"), QString("%1 %2: %3").arg(tr("Distant chat refused with this person.")).arg(tr("Error code")).arg(error_code)) ;
}
}
void PeopleDialog::sendMessage()
{
QAction *action =
qobject_cast<QAction *>(QObject::sender());
if (action) {
QString data = action->data().toString();
MessageComposer *nMsgDialog = MessageComposer::newMsg();
if (nMsgDialog == NULL) {
return;
}
RsGxsId gxs_id = RsGxsId(data.toStdString());;
nMsgDialog->addRecipient(MessageComposer::TO, RsGxsId(gxs_id));
nMsgDialog->show();
nMsgDialog->activateWindow();
/* window will destroy itself! */
}
}
void PeopleDialog::personDetails()
{
QAction *action =
qobject_cast<QAction *>(QObject::sender());
if (action) {
QString data = action->data().toString();
RsGxsId gxs_id = RsGxsId(data.toStdString());
if (RsGxsGroupId(gxs_id).isNull()) {
return;
}
IdDetailsDialog *dialog = new IdDetailsDialog(RsGxsGroupId(gxs_id));
dialog->show();
/* Dialog will destroy itself */
}
}
void PeopleDialog::cw_askForGXSIdentityWidget(RsGxsId gxs_id)
{
CircleWidget *dest =
@ -607,7 +721,7 @@ void PeopleDialog::fl_flowLayoutItemDroppedExt(QList<FlowLayoutItem *>flListItem
if (bCreateNewCircle){
dlg.editNewId(true);
} else {//if (bCreateNewCircle)
dlg.editExistingId(cirDest->groupInfo().mGroupId, false);
dlg.editExistingId(cirDest->groupInfo().mGroupId, false,false);
}//else (bCreateNewCircle)
dlg.exec();
@ -667,7 +781,7 @@ void PeopleDialog::fl_flowLayoutItemDroppedInt(QList<FlowLayoutItem *>flListItem
if (bCreateNewCircle){
dlg.editNewId(false);
} else {//if (bCreateNewCircle)
dlg.editExistingId(cirDest->groupInfo().mGroupId, false);
dlg.editExistingId(cirDest->groupInfo().mGroupId, false,false);
}//else (bCreateNewCircle)
dlg.exec();
@ -768,7 +882,7 @@ void PeopleDialog::pf_dropEventOccursExt(QDropEvent *event)
QWidget *wid =
qobject_cast<QWidget *>(event->source());//QT5 return QObject
FlowLayout *layout = NULL;
FlowLayout *layout;
if (wid) layout =
qobject_cast<FlowLayout *>(wid->layout());
if (layout) {
@ -808,7 +922,7 @@ void PeopleDialog::pf_dropEventOccursExt(QDropEvent *event)
if (bCreateNewCircle){
dlg.editNewId(true);
} else {//if (bCreateNewCircle)
dlg.editExistingId(cirDest->groupInfo().mGroupId, false);
dlg.editExistingId(cirDest->groupInfo().mGroupId, false,false);
}//else (bCreateNewCircle)
dlg.exec();
@ -858,7 +972,7 @@ void PeopleDialog::pf_dropEventOccursInt(QDropEvent *event)
QWidget *wid =
qobject_cast<QWidget *>(event->source());//QT5 return QObject
FlowLayout *layout = NULL;
FlowLayout *layout;
if (wid) layout =
qobject_cast<FlowLayout *>(wid->layout());
if (layout) {
@ -898,7 +1012,7 @@ void PeopleDialog::pf_dropEventOccursInt(QDropEvent *event)
if (bCreateNewCircle){
dlg.editNewId(false);
} else {//if (bCreateNewCircle)
dlg.editExistingId(cirDest->groupInfo().mGroupId, false);
dlg.editExistingId(cirDest->groupInfo().mGroupId, false,false);
}//else (bCreateNewCircle)
dlg.exec();

View file

@ -84,6 +84,10 @@ private slots:
void pf_dropEventOccursExt(QDropEvent *event);
void pf_dropEventOccursInt(QDropEvent *event);
void chatIdentity();
void sendMessage();
void personDetails();
private:
void reloadAll();
void populatePictureFlowExt();

View file

@ -20,16 +20,7 @@
<string/>
</property>
<layout class="QGridLayout" name="titleBarLayout">
<property name="leftMargin">
<number>0</number>
</property>
<property name="topMargin">
<number>0</number>
</property>
<property name="rightMargin">
<number>0</number>
</property>
<property name="bottomMargin">
<property name="margin">
<number>0</number>
</property>
<item row="0" column="0">
@ -94,8 +85,11 @@
</item>
<item row="1" column="0">
<widget class="QTabWidget" name="tabWidget">
<property name="enabled">
<bool>true</bool>
</property>
<property name="currentIndex">
<number>0</number>
<number>1</number>
</property>
<widget class="QWidget" name="tabExternal">
<property name="sizePolicy">
@ -105,7 +99,7 @@
</sizepolicy>
</property>
<attribute name="title">
<string>External</string>
<string>People</string>
</attribute>
<layout class="QVBoxLayout">
<item>
@ -128,7 +122,7 @@
<rect>
<x>0</x>
<y>0</y>
<width>685</width>
<width>701</width>
<height>248</height>
</rect>
</property>
@ -197,7 +191,7 @@
<rect>
<x>0</x>
<y>0</y>
<width>685</width>
<width>701</width>
<height>248</height>
</rect>
</property>

View file

@ -293,8 +293,9 @@ PictureFlowState::PictureFlowState():
PictureFlowState::~PictureFlowState()
{
for(int i = 0; i < (int)slideImages.count(); ++i)
for(uint i=0;i<slideImages.size();++i)
delete slideImages[i] ;
slideImages.clear() ;
}
// readjust the settings, call this when slide dimension is changed
@ -482,7 +483,7 @@ PictureFlowSoftwareRenderer::~PictureFlowSoftwareRenderer()
{
surfaceCache.clear();
buffer = QImage();
delete blankSurface;
if (blankSurface) delete blankSurface;
}
void PictureFlowSoftwareRenderer::paint()
@ -516,6 +517,7 @@ void PictureFlowSoftwareRenderer::init()
return;
surfaceCache.clear();
if (blankSurface) delete blankSurface;
blankSurface = 0;
size = widget->size();
@ -687,7 +689,7 @@ QImage* PictureFlowSoftwareRenderer::surface(int slideIndex)
bool empty = img ? img->isNull() : true;
if(empty) {
surfaceCache.remove(key);
imageHash.remove(slideIndex);
delete imageHash.take(slideIndex);
if(!blankSurface) {
int sw = state->slideWidth;
int sh = state->slideHeight;
@ -723,29 +725,28 @@ QImage* PictureFlowSoftwareRenderer::surface(int slideIndex)
return blankSurface;
}//if(empty)
#ifdef PICTUREFLOW_QT4
bool exist = imageHash.contains(slideIndex);
if(exist)
if(img == imageHash.find(slideIndex).value())
#ifdef PICTUREFLOW_QT2
if(img == imageHash[slideIndex])
#endif
#ifdef PICTUREFLOW_QT3
bool exist = imageHash.find(slideIndex) != imageHash.end();
if(exist)
if(img == imageHash.find(slideIndex).data())
#endif
#ifdef PICTUREFLOW_QT2
if(img == imageHash[slideIndex])
#ifdef PICTUREFLOW_QT4
bool exist = imageHash.contains(slideIndex);
if(exist)
if(img == imageHash.find(slideIndex).value())
#endif
if(surfaceCache.contains(key))
return surfaceCache[key];
QImage* sr = prepareSurface(img, state->slideWidth, state->slideHeight, bgcolor, state->reflectionEffect);
QImage *sr_copy = new QImage(*sr) ;
surfaceCache.insert(key, sr); // this takes ownership on sr. So we can't use it afterwards
surfaceCache.insert(key, sr); // QCache takes ownership on sr. And delete it when removed.
imageHash.insert(slideIndex, img);
return sr_copy;
return sr;
}
// Renders a slide to offscreen buffer. Returns a rect of the rendered area.
@ -756,7 +757,7 @@ QRect PictureFlowSoftwareRenderer::renderSlide(const SlideInfo &slide, int col1,
if(!blend)
return QRect();
QImage* src = surface(slide.slideIndex);
QImage* src = surface(slide.slideIndex); // src is owned by surfaceCache(QCache) don't delete it.
if(!src)
return QRect();
@ -788,10 +789,7 @@ QRect PictureFlowSoftwareRenderer::renderSlide(const SlideInfo &slide, int col1,
int xi = qMax((PFreal)0, ((w*PFREAL_ONE/2) + fdiv(xs*h, dist+ys)) >> PFREAL_SHIFT);
if(xi >= w)
{
delete src ;
return rect;
}
bool flag = false;
rect.setLeft(xi);
@ -861,7 +859,6 @@ QRect PictureFlowSoftwareRenderer::renderSlide(const SlideInfo &slide, int col1,
rect.setTop(0);
rect.setBottom(h-1);
delete src ;
return rect;
}
@ -1107,10 +1104,9 @@ void PictureFlow::setCenterIndex(int index)
void PictureFlow::clear()
{
int c = d->state->slideImages.count();
for(int i = 0; i < c; ++i)
for(uint i=0;i<d->state->slideImages.size();++i)
delete d->state->slideImages[i] ;
d->state->slideImages.resize(0);
d->state->slideImages.clear() ;
d->state->reset();
triggerRender();

View file

@ -103,7 +103,7 @@ void GxsGroupDialog::init()
connect(ui.addLogoButton, SIGNAL(clicked() ), this , SLOT(addGroupLogo()));
ui.typePublic->setChecked(true);
ui.typePublic_3->setChecked(true);
ui.distributionValueLabel->setText(tr("Public"));
updateCircleOptions();
connect(ui.typePublic, SIGNAL(clicked()), this , SLOT(updateCircleOptions()));
@ -218,23 +218,25 @@ void GxsGroupDialog::setupDefaults()
if (mDefaultsFlags & GXS_GROUP_DEFAULTS_DISTRIB_PUBLIC)
{
ui.typePublic->setChecked(true);
ui.typePublic_3->setChecked(true);
ui.distributionValueLabel->setText(tr("Public"));
ui.distributionCircleComboBox->setVisible(false) ;
}
else if (mDefaultsFlags & GXS_GROUP_DEFAULTS_DISTRIB_GROUP)
{
ui.typeGroup->setChecked(true);
ui.typeGroup_3->setChecked(true);
ui.distributionValueLabel->setText(tr("Restricted to circle:"));
ui.distributionCircleComboBox->setVisible(true) ;
}
else if (mDefaultsFlags & GXS_GROUP_DEFAULTS_DISTRIB_LOCAL)
{
ui.typeLocal->setChecked(true);
ui.typeLocal_3->setChecked(true);
ui.distributionValueLabel->setText(tr("Limited to your friends"));
ui.distributionCircleComboBox->setVisible(false) ;
}
else
{
// default
ui.typePublic->setChecked(true);
ui.typePublic_3->setChecked(true);
}
}
@ -285,31 +287,36 @@ void GxsGroupDialog::setupDefaults()
if (mDefaultsFlags & GXS_GROUP_DEFAULTS_COMMENTS_YES)
{
ui.comments_allowed->setChecked(true);
ui.comments_allowed_3->setChecked(true);
ui.commentsValueLabel->setText(tr("Allowed"));
}
else if (mDefaultsFlags & GXS_GROUP_DEFAULTS_COMMENTS_NO)
{
ui.comments_no->setChecked(true);
ui.comments_no_3->setChecked(true);
ui.commentsValueLabel->setText(tr("Disallowed"));
}
else
{
// default
ui.comments_no->setChecked(true);
ui.comments_no_3->setChecked(true);
ui.commentsValueLabel->setText(tr("Allowed"));
}
}
ui.antiSpam_trackMessages->setChecked((bool)(mDefaultsFlags & GXS_GROUP_DEFAULTS_ANTISPAM_TRACK));
ui.antiSpam_signedIds->setChecked((bool)(mDefaultsFlags & GXS_GROUP_DEFAULTS_ANTISPAM_FAVOR_PGP));
ui.antiSpam_trackMessages_2->setChecked((bool)(mDefaultsFlags & GXS_GROUP_DEFAULTS_ANTISPAM_TRACK));
ui.antiSpam_signedIds_2->setChecked((bool)(mDefaultsFlags & GXS_GROUP_DEFAULTS_ANTISPAM_FAVOR_PGP));
QString antispam_string ;
if(mDefaultsFlags & GXS_GROUP_DEFAULTS_ANTISPAM_TRACK) antispam_string += tr("Message tracking") ;
if(mDefaultsFlags & GXS_GROUP_DEFAULTS_ANTISPAM_FAVOR_PGP) antispam_string += (antispam_string.isNull()?"":" and ")+tr("PGP signature required") ;
ui.antiSpamValueLabel->setText(antispam_string) ;
#ifndef RS_USE_CIRCLES
ui.typeGroup->setEnabled(false);
ui.typeLocal->setEnabled(false);
ui.typeGroup_3->setEnabled(false);
ui.typeLocal_3->setEnabled(false);
#endif
ui.typeLocal->setEnabled(false); // for now, since local circles not fully tested.
ui.typeLocal->setToolTip(tr("This feature is not yet available, but it will be available very soon!")); // for now, since local circles not fully tested.
}
void GxsGroupDialog::setupVisibility()
@ -322,10 +329,12 @@ void GxsGroupDialog::setupVisibility()
ui.groupDesc->setVisible(mEnabledFlags & GXS_GROUP_FLAGS_DESCRIPTION);
ui.distribGroupBox->setVisible(mEnabledFlags & GXS_GROUP_FLAGS_DISTRIBUTION);
ui.distribGroupBox_2->setVisible(mEnabledFlags & GXS_GROUP_FLAGS_DISTRIBUTION);
ui.distributionLabel->setVisible(mEnabledFlags & GXS_GROUP_FLAGS_DISTRIBUTION);
ui.distributionValueLabel->setVisible(mEnabledFlags & GXS_GROUP_FLAGS_DISTRIBUTION);
ui.spamProtection_GB->setVisible(mEnabledFlags & GXS_GROUP_FLAGS_ANTI_SPAM);
ui.spamProtection_GB_2->setVisible(mEnabledFlags & GXS_GROUP_FLAGS_ANTI_SPAM);
ui.antiSpamLabel->setVisible(mEnabledFlags & GXS_GROUP_FLAGS_ANTI_SPAM);
ui.antiSpamValueLabel->setVisible(mEnabledFlags & GXS_GROUP_FLAGS_ANTI_SPAM);
ui.publishGroupBox->setVisible(mEnabledFlags & GXS_GROUP_FLAGS_PUBLISHSIGN);
@ -334,8 +343,9 @@ void GxsGroupDialog::setupVisibility()
ui.personalGroupBox->setVisible(mEnabledFlags & GXS_GROUP_FLAGS_PERSONALSIGN);
ui.commentGroupBox->setVisible(mEnabledFlags & GXS_GROUP_FLAGS_COMMENTS);
ui.commentGroupBox_2->setVisible(mEnabledFlags & GXS_GROUP_FLAGS_COMMENTS);
ui.commentslabel->setVisible(mEnabledFlags & GXS_GROUP_FLAGS_COMMENTS);
ui.commentsLabel->setVisible(mEnabledFlags & GXS_GROUP_FLAGS_COMMENTS);
ui.commentsValueLabel->setVisible(mEnabledFlags & GXS_GROUP_FLAGS_COMMENTS);
//ui.commentslabel->setVisible(mEnabledFlags & GXS_GROUP_FLAGS_COMMENTS);
ui.extraFrame->setVisible(mEnabledFlags & GXS_GROUP_FLAGS_EXTRA);
}
@ -363,10 +373,10 @@ void GxsGroupDialog::setupReadonly()
ui.idChooser->setEnabled(!(mReadonlyFlags & GXS_GROUP_FLAGS_PERSONALSIGN));
ui.distribGroupBox_2->setEnabled(!(mReadonlyFlags & GXS_GROUP_FLAGS_DISTRIBUTION));
ui.commentGroupBox_2->setEnabled(!(mReadonlyFlags & GXS_GROUP_FLAGS_COMMENTS));
//ui.distribGroupBox_2->setEnabled(!(mReadonlyFlags & GXS_GROUP_FLAGS_DISTRIBUTION));
//ui.commentGroupBox_2->setEnabled(!(mReadonlyFlags & GXS_GROUP_FLAGS_COMMENTS));
ui.spamProtection_GB->setEnabled(!(mReadonlyFlags & GXS_GROUP_FLAGS_ANTI_SPAM));
ui.spamProtection_GB_2->setEnabled(!(mReadonlyFlags & GXS_GROUP_FLAGS_ANTI_SPAM));
//ui.spamProtection_GB_2->setEnabled(!(mReadonlyFlags & GXS_GROUP_FLAGS_ANTI_SPAM));
ui.extraFrame->setEnabled(!(mReadonlyFlags & GXS_GROUP_FLAGS_EXTRA));
#ifndef UNFINISHED
@ -417,8 +427,7 @@ void GxsGroupDialog::updateFromExistingMeta(const QString &description)
break;
case MODE_SHOW:{
ui.headerFrame->setHeaderText(QString::fromUtf8(mGrpMeta.mGroupName.c_str()));
if (mPicture.isNull())
return;
if (!mPicture.isNull())
ui.headerFrame->setHeaderImage(mPicture);
}
break;
@ -428,21 +437,27 @@ void GxsGroupDialog::updateFromExistingMeta(const QString &description)
}
/* set description */
ui.groupDesc->setPlainText(description);
QString distribution_string = "[Unknown]";
switch(mGrpMeta.mCircleType)
{
case GXS_CIRCLE_TYPE_YOUREYESONLY:
ui.typeLocal->setChecked(true);
ui.typeLocal_3->setChecked(true);
distribution_string = tr("Your friends only") ;
ui.localComboBox->loadCircles(GXS_CIRCLE_CHOOSER_PERSONAL, mGrpMeta.mInternalCircle);
ui.distributionCircleComboBox->setVisible(true) ;
ui.distributionCircleComboBox->loadCircles(GXS_CIRCLE_CHOOSER_PERSONAL, mGrpMeta.mInternalCircle);
break;
case GXS_CIRCLE_TYPE_PUBLIC:
ui.typePublic->setChecked(true);
ui.typePublic_3->setChecked(true);
distribution_string = tr("Public") ;
ui.distributionCircleComboBox->setVisible(false) ;
break;
case GXS_CIRCLE_TYPE_EXTERNAL:
ui.typeGroup->setChecked(true);
ui.typeGroup_3->setChecked(true);
distribution_string = tr("Restricted to circle:") ;
ui.distributionCircleComboBox->setVisible(true) ;
ui.distributionCircleComboBox->loadCircles(GXS_CIRCLE_CHOOSER_EXTERNAL, mGrpMeta.mCircleId);
ui.circleComboBox->loadCircles(GXS_CIRCLE_CHOOSER_EXTERNAL, mGrpMeta.mCircleId);
break;
default:
@ -450,6 +465,7 @@ void GxsGroupDialog::updateFromExistingMeta(const QString &description)
std::cerr << std::endl;
break;
}
ui.distributionValueLabel->setText(distribution_string) ;
ui.idChooser->loadIds(0, mGrpMeta.mAuthorId);
@ -642,8 +658,14 @@ void GxsGroupDialog::setGroupSignFlags(uint32_t signFlags)
ui.antiSpam_trackMessages ->setChecked((bool)(signFlags & GXS_SERV::FLAG_AUTHOR_AUTHENTICATION_TRACK_MESSAGES) );
ui.antiSpam_signedIds ->setChecked((bool)(signFlags & GXS_SERV::FLAG_AUTHOR_AUTHENTICATION_GPG) );
ui.antiSpam_trackMessages_2->setChecked((bool)(signFlags & GXS_SERV::FLAG_AUTHOR_AUTHENTICATION_TRACK_MESSAGES) );
ui.antiSpam_signedIds_2 ->setChecked((bool)(signFlags & GXS_SERV::FLAG_AUTHOR_AUTHENTICATION_GPG) );
QString antispam_string ;
if(signFlags & GXS_SERV::FLAG_AUTHOR_AUTHENTICATION_TRACK_MESSAGES) antispam_string += tr("Message tracking") ;
if(signFlags & GXS_SERV::FLAG_AUTHOR_AUTHENTICATION_GPG) antispam_string += (antispam_string.isNull()?"":" and ")+tr("PGP signature required") ;
ui.antiSpamValueLabel->setText(antispam_string) ;
//ui.antiSpam_trackMessages_2->setChecked((bool)(signFlags & GXS_SERV::FLAG_AUTHOR_AUTHENTICATION_TRACK_MESSAGES) );
//ui.antiSpam_signedIds_2 ->setChecked((bool)(signFlags & GXS_SERV::FLAG_AUTHOR_AUTHENTICATION_GPG) );
//ui.SignEdIds->setChecked((bool)(signFlags & GXS_SERV::FLAG_AUTHOR_AUTHENTICATION_GPG) );
//ui.trackmessagesradioButton->setChecked((bool)(signFlags & GXS_SERV::FLAG_AUTHOR_AUTHENTICATION_TRACK_MESSAGES) );
@ -651,13 +673,15 @@ void GxsGroupDialog::setGroupSignFlags(uint32_t signFlags)
if ((signFlags & GXS_SERV::FLAG_GROUP_SIGN_PUBLISH_THREADHEAD) &&
(signFlags & GXS_SERV::FLAG_AUTHOR_AUTHENTICATION_IFNOPUBSIGN))
{
// (cyril) very weird piece of code. Need to clear this up.
ui.comments_allowed->setChecked(true);
ui.comments_allowed_3->setChecked(true);
ui.commentsValueLabel->setText("Allowed") ;
}
else
{
ui.comments_no->setChecked(true);
ui.comments_no_3->setChecked(true);
ui.commentsValueLabel->setText("Allowed") ;
}
}

View file

@ -7,31 +7,22 @@
<x>0</x>
<y>0</y>
<width>928</width>
<height>400</height>
<height>769</height>
</rect>
</property>
<property name="windowTitle">
<string notr="true">Create New</string>
</property>
<layout class="QGridLayout" name="gridLayout_5">
<property name="leftMargin">
<number>0</number>
</property>
<property name="topMargin">
<number>0</number>
</property>
<property name="rightMargin">
<number>0</number>
</property>
<property name="bottomMargin">
<number>0</number>
</property>
<property name="horizontalSpacing">
<number>6</number>
</property>
<property name="verticalSpacing">
<number>0</number>
</property>
<property name="margin">
<number>0</number>
</property>
<item row="0" column="0">
<widget class="HeaderFrame" name="headerFrame"/>
</item>
@ -44,7 +35,7 @@
<enum>QFrame::Raised</enum>
</property>
<property name="currentIndex">
<number>0</number>
<number>1</number>
</property>
<widget class="QWidget" name="createmode">
<layout class="QGridLayout" name="gridLayout">
@ -57,16 +48,7 @@
<property name="spacing">
<number>0</number>
</property>
<property name="leftMargin">
<number>4</number>
</property>
<property name="topMargin">
<number>4</number>
</property>
<property name="rightMargin">
<number>4</number>
</property>
<property name="bottomMargin">
<property name="margin">
<number>4</number>
</property>
<item>
@ -130,16 +112,7 @@
<property name="spacing">
<number>9</number>
</property>
<property name="leftMargin">
<number>3</number>
</property>
<property name="topMargin">
<number>3</number>
</property>
<property name="rightMargin">
<number>3</number>
</property>
<property name="bottomMargin">
<property name="margin">
<number>3</number>
</property>
<item>
@ -239,16 +212,7 @@
</property>
<widget class="QWidget" name="dockWidgetContents">
<layout class="QGridLayout" name="_2">
<property name="leftMargin">
<number>0</number>
</property>
<property name="topMargin">
<number>0</number>
</property>
<property name="rightMargin">
<number>0</number>
</property>
<property name="bottomMargin">
<property name="margin">
<number>0</number>
</property>
<property name="spacing">
@ -635,188 +599,12 @@
</widget>
<widget class="QWidget" name="showmode">
<layout class="QGridLayout" name="gridLayout_6">
<item row="1" column="0">
<widget class="QGroupBox" name="groupBox_3">
<property name="title">
<string>Description</string>
</property>
<layout class="QGridLayout" name="_4">
<item row="0" column="0">
<widget class="QTextEdit" name="descriptiontextEdit">
<property name="readOnly">
<bool>true</bool>
</property>
</widget>
</item>
</layout>
</widget>
</item>
<item row="0" column="0">
<widget class="QGroupBox" name="groupBox_2">
<property name="title">
<string>Info</string>
</property>
<layout class="QGridLayout" name="_3">
<item row="7" column="2">
<widget class="QGroupBox" name="distribGroupBox_2">
<property name="sizePolicy">
<sizepolicy hsizetype="Expanding" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="title">
<string/>
</property>
<layout class="QGridLayout" name="gridLayout_2">
<property name="leftMargin">
<number>6</number>
</property>
<property name="topMargin">
<number>6</number>
</property>
<property name="rightMargin">
<number>6</number>
</property>
<property name="bottomMargin">
<number>6</number>
</property>
<item row="0" column="1">
<widget class="QRadioButton" name="typeGroup_3">
<property name="sizePolicy">
<sizepolicy hsizetype="Minimum" vsizetype="Expanding">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="text">
<string>Restricted to Group</string>
</property>
<property name="icon">
<iconset resource="../images.qrc">
<normaloff>:/images/user/agt_forum24.png</normaloff>:/images/user/agt_forum24.png</iconset>
</property>
<property name="iconSize">
<size>
<width>16</width>
<height>16</height>
</size>
</property>
</widget>
</item>
<item row="0" column="0">
<widget class="QRadioButton" name="typePublic_3">
<property name="sizePolicy">
<sizepolicy hsizetype="Minimum" vsizetype="Expanding">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="text">
<string>Public</string>
</property>
<property name="icon">
<iconset resource="../images.qrc">
<normaloff>:/images/network.png</normaloff>:/images/network.png</iconset>
</property>
<property name="iconSize">
<size>
<width>16</width>
<height>16</height>
</size>
</property>
</widget>
</item>
<item row="0" column="2">
<widget class="QRadioButton" name="typeLocal_3">
<property name="sizePolicy">
<sizepolicy hsizetype="Minimum" vsizetype="Expanding">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="text">
<string>Only For Your Friends</string>
</property>
<property name="icon">
<iconset resource="../images.qrc">
<normaloff>:/images/user/friends24.png</normaloff>:/images/user/friends24.png</iconset>
</property>
<property name="iconSize">
<size>
<width>16</width>
<height>16</height>
</size>
</property>
</widget>
</item>
<item row="0" column="3">
<spacer name="horizontalSpacer_4">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
</layout>
</widget>
</item>
<item row="8" column="2">
<widget class="QGroupBox" name="commentGroupBox_2">
<property name="title">
<string/>
</property>
<layout class="QHBoxLayout" name="horizontalLayout_14">
<property name="spacing">
<number>6</number>
</property>
<property name="leftMargin">
<number>6</number>
</property>
<property name="topMargin">
<number>6</number>
</property>
<property name="rightMargin">
<number>6</number>
</property>
<property name="bottomMargin">
<number>6</number>
</property>
<item>
<widget class="QRadioButton" name="comments_allowed_3">
<property name="text">
<string>Comments allowed</string>
</property>
</widget>
</item>
<item>
<widget class="QRadioButton" name="comments_no_3">
<property name="text">
<string>Comments not allowed</string>
</property>
</widget>
</item>
<item>
<spacer name="horizontalSpacer_3">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
</layout>
</widget>
</item>
<item row="0" column="0">
<widget class="QLabel" name="label_3">
<property name="text">
@ -824,48 +612,13 @@
</property>
</widget>
</item>
<item row="0" column="2">
<item row="0" column="1">
<widget class="QLineEdit" name="nameline">
<property name="readOnly">
<bool>true</bool>
</property>
</widget>
</item>
<item row="1" column="2">
<widget class="QLineEdit" name="popline">
<property name="readOnly">
<bool>true</bool>
</property>
</widget>
</item>
<item row="5" column="2">
<widget class="QLineEdit" name="IDline">
<property name="readOnly">
<bool>true</bool>
</property>
</widget>
</item>
<item row="3" column="2">
<widget class="QLineEdit" name="lastpostline">
<property name="readOnly">
<bool>true</bool>
</property>
</widget>
</item>
<item row="5" column="0">
<widget class="QLabel" name="label_4">
<property name="text">
<string>ID</string>
</property>
</widget>
</item>
<item row="3" column="0">
<widget class="QLabel" name="label_11">
<property name="text">
<string>Last Post</string>
</property>
</widget>
</item>
<item row="1" column="0">
<widget class="QLabel" name="label_10">
<property name="text">
@ -873,11 +626,8 @@
</property>
</widget>
</item>
<item row="2" column="2">
<widget class="QLineEdit" name="postsline">
<property name="text">
<string/>
</property>
<item row="1" column="1">
<widget class="QLineEdit" name="popline">
<property name="readOnly">
<bool>true</bool>
</property>
@ -890,20 +640,27 @@
</property>
</widget>
</item>
<item row="8" column="0">
<widget class="QLabel" name="commentslabel">
<item row="2" column="1">
<widget class="QLineEdit" name="postsline">
<property name="text">
<string>Comments</string>
<string/>
</property>
<property name="readOnly">
<bool>true</bool>
</property>
</widget>
</item>
<item row="7" column="0">
<widget class="QLabel" name="label_5">
<item row="3" column="0">
<widget class="QLabel" name="label_11">
<property name="text">
<string>Type</string>
<string>Last Post</string>
</property>
<property name="alignment">
<set>Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter</set>
</widget>
</item>
<item row="3" column="1">
<widget class="QLineEdit" name="lastpostline">
<property name="readOnly">
<bool>true</bool>
</property>
</widget>
</item>
@ -914,66 +671,97 @@
</property>
</widget>
</item>
<item row="4" column="2">
<item row="4" column="1">
<widget class="GxsIdLabel" name="authorLabel">
<property name="text">
<string>GxsIdLabel</string>
</property>
</widget>
</item>
<item row="10" column="0">
<widget class="QLabel" name="label_8">
<item row="5" column="0">
<widget class="QLabel" name="label_4">
<property name="text">
<string>Anti spam</string>
<string>ID</string>
</property>
</widget>
</item>
<item row="10" column="2">
<widget class="QGroupBox" name="spamProtection_GB_2">
<property name="title">
<string/>
<item row="5" column="1">
<widget class="QLineEdit" name="IDline">
<property name="readOnly">
<bool>true</bool>
</property>
</widget>
</item>
<item row="6" column="0" rowspan="2">
<widget class="QLabel" name="commentsLabel">
<property name="text">
<string>Comments:</string>
</property>
</widget>
</item>
<item row="6" column="1">
<widget class="QLabel" name="commentsValueLabel">
<property name="text">
<string>TextLabel</string>
</property>
</widget>
</item>
<item row="7" column="1" rowspan="2">
<layout class="QHBoxLayout" name="horizontalLayout_10">
<property name="leftMargin">
<number>6</number>
</property>
<property name="topMargin">
<number>6</number>
</property>
<property name="rightMargin">
<number>6</number>
</property>
<property name="bottomMargin">
<number>6</number>
</property>
<item>
<widget class="QRadioButton" name="antiSpam_signedIds_2">
<widget class="QLabel" name="distributionValueLabel">
<property name="text">
<string>PGP-signed ids</string>
<string>TextLabel</string>
</property>
</widget>
</item>
<item>
<widget class="QRadioButton" name="antiSpam_trackMessages_2">
<property name="text">
<string>Track of Posts</string>
<widget class="GxsCircleChooser" name="distributionCircleComboBox">
<property name="sizePolicy">
<sizepolicy hsizetype="MinimumExpanding" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
</widget>
</item>
<item>
<spacer name="horizontalSpacer_9">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>718</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
</layout>
</item>
<item row="8" column="0">
<widget class="QLabel" name="distributionLabel">
<property name="text">
<string>Distribution:</string>
</property>
</widget>
</item>
<item row="9" column="0">
<widget class="QLabel" name="antiSpamLabel">
<property name="text">
<string>Anti Spam:</string>
</property>
</widget>
</item>
<item row="9" column="1">
<widget class="QLabel" name="antiSpamValueLabel">
<property name="text">
<string>TextLabel</string>
</property>
</widget>
</item>
</layout>
</widget>
</item>
<item row="1" column="0">
<widget class="QGroupBox" name="groupBox_3">
<property name="title">
<string>Description</string>
</property>
<layout class="QGridLayout" name="_4">
<item row="0" column="0">
<widget class="QTextEdit" name="descriptiontextEdit">
<property name="readOnly">
<bool>true</bool>
</property>
</widget>
</item>
</layout>

View file

@ -60,6 +60,7 @@ GxsIdChooser::GxsIdChooser(QWidget *parent)
setSizeAdjustPolicy(QComboBox::AdjustToContents);
mFirstLoad = true;
mAllowedCount = 0 ;
mDefaultId.clear() ;
@ -99,6 +100,13 @@ void GxsIdChooser::showEvent(QShowEvent *event)
QComboBox::showEvent(event);
}
void GxsIdChooser::setIdConstraintSet(const std::set<RsGxsId>& s)
{
mConstraintIdsSet = s ;
updateDisplay(true);
update(); // Qt flush
}
void GxsIdChooser::loadIds(uint32_t chooserFlags, const RsGxsId &defId)
{
mFlags = chooserFlags;
@ -119,6 +127,7 @@ static void loadPrivateIdsCallback(GxsIdDetailsType type, const RsIdentityDetail
return;
}
// this prevents the objects that depend on what's in the combo-box to activate and
// perform any change.Only user-changes should cause this.
chooser->blockSignals(true) ;
@ -167,30 +176,69 @@ static void loadPrivateIdsCallback(GxsIdDetailsType type, const RsIdentityDetail
//std::cerr << " - disabling ID - entry = " << index << std::endl;
chooser->setEntryEnabled(index,false) ;
}
std::cerr << std::endl;
if(!chooser->isInConstraintSet(details.mId))
chooser->setEntryEnabled(index,false) ;
chooser->model()->sort(0);
chooser->blockSignals(false) ;
}
bool GxsIdChooser::isInConstraintSet(const RsGxsId& id) const
{
if(mConstraintIdsSet.empty()) // special case: empty set means no constraint
return true ;
return mConstraintIdsSet.find(id) != mConstraintIdsSet.end() ;
}
void GxsIdChooser::setEntryEnabled(int indx,bool enabled)
{
bool disable = !enabled ;
removeItem(indx) ;
QSortFilterProxyModel* model = qobject_cast<QSortFilterProxyModel*>(QComboBox::model());
//QStandardItem* item = model->item(index);
#ifdef TO_REMOVE
// bool disable = !enabled ;
//
// QSortFilterProxyModel* model = qobject_cast<QSortFilterProxyModel*>(QComboBox::model());
// //QStandardItem* item = model->item(index);
//
// QModelIndex ii = model->index(indx,0);
//
// // visually disable by greying out - works only if combobox has been painted already and palette returns the wanted color
// //model->setFlags(ii,disable ? (model->flags(ii) & ~(Qt::ItemIsSelectable|Qt::ItemIsEnabled)) : (Qt::ItemIsSelectable|Qt::ItemIsEnabled));
//
// uint32_t v = enabled?(1|32):(0);
//
// std::cerr << "GxsIdChooser::setEnabledEntry: i=" << indx << ", v=" << v << std::endl;
//
// // clear item data in order to use default color
// //model->setData(ii,disable ? (QComboBox::palette().color(QPalette::Disabled, QPalette::Text)) : QVariant(), Qt::TextColorRole);
// model->setData(ii,QVariant(v),Qt::UserRole-1) ;
//
// std::cerr << "model data after operation: " << model->data(ii,Qt::UserRole-1).toUInt() << std::endl;
#endif
}
QModelIndex ii = model->index(indx,0);
uint32_t GxsIdChooser::countEnabledEntries() const
{
return count() ;
// visually disable by greying out - works only if combobox has been painted already and palette returns the wanted color
//model->setFlags(ii,disable ? (model->flags(ii) & ~(Qt::ItemIsSelectable|Qt::ItemIsEnabled)) : (Qt::ItemIsSelectable|Qt::ItemIsEnabled));
uint32_t v = enabled?(1|32):(0);
// clear item data in order to use default color
//model->setData(ii,disable ? (QComboBox::palette().color(QPalette::Disabled, QPalette::Text)) : QVariant(), Qt::TextColorRole);
model->setData(ii,QVariant(v),Qt::UserRole-1) ;
#ifdef TO_REMOVE
// uint32_t res = 0 ;
// QSortFilterProxyModel* model = qobject_cast<QSortFilterProxyModel*>(QComboBox::model());
//
// for(uint32_t i=0;i<model->rowCount();++i)
// {
// QModelIndex ii = model->index(i,0);
// uint32_t v = model->data(ii,Qt::UserRole-1).toUInt() ;
//
// std::cerr << "GxsIdChooser::countEnabledEntries(): i=" << i << ", v=" << v << std::endl;
// if(v > 0)
// ++res ;
// }
//
// return res ;
#endif
}
void GxsIdChooser::loadPrivateIds()
@ -238,8 +286,7 @@ void GxsIdChooser::loadPrivateIds()
}
for (std::list<RsGxsId>::iterator it = ids.begin(); it != ids.end(); ++it) {
/* add to Chooser */
GxsIdDetails::process(*it, loadPrivateIdsCallback, this);
GxsIdDetails::process(*it, loadPrivateIdsCallback, this); /* add to Chooser */
}
if (mFirstLoad) {

View file

@ -59,6 +59,11 @@ public:
ChosenId_Ret getChosenId(RsGxsId &gxsId);
void setEntryEnabled(int index, bool enabled);
void setIdConstraintSet(const std::set<RsGxsId>& s) ;
bool isInConstraintSet(const RsGxsId& id) const ;
uint32_t countEnabledEntries() const ;
signals:
// emitted after first load of own ids
void idsLoaded();
@ -79,7 +84,9 @@ private:
uint32_t mFlags;
RsGxsId mDefaultId;
bool mFirstLoad;
uint32_t mAllowedCount ;
std::set<RsGxsId> mConstraintIdsSet ; // leave empty if all allowed
RsGxsUpdateBroadcastBase *mBase;
};

View file

@ -28,6 +28,7 @@
#include <QPushButton>
#include <retroshare/rsgxsforums.h>
#include <retroshare/rsgxscircles.h>
#include "gui/settings/rsharesettings.h"
#include "gui/RetroShareLink.h"
@ -43,6 +44,7 @@
#define CREATEGXSFORUMMSG_FORUMINFO 1
#define CREATEGXSFORUMMSG_PARENTMSG 2
#define CREATEGXSFORUMMSG_CIRCLENFO 3
//#define ENABLE_GENERATE
@ -57,6 +59,7 @@ CreateGxsForumMsg::CreateGxsForumMsg(const RsGxsGroupId &fId, const RsGxsMessage
/* Setup Queue */
mForumQueue = new TokenQueue(rsGxsForums->getTokenService(), this);
mCirclesQueue = new TokenQueue(rsGxsCircles->getTokenService(), this);
/* Setup UI helper */
mStateHelper = new UIStateHelper(this);
@ -100,6 +103,7 @@ CreateGxsForumMsg::CreateGxsForumMsg(const RsGxsGroupId &fId, const RsGxsMessage
mParentMsgLoaded = false;
mForumMetaLoaded = false;
mForumCircleLoaded = false;
newMsg();
@ -112,6 +116,7 @@ CreateGxsForumMsg::CreateGxsForumMsg(const RsGxsGroupId &fId, const RsGxsMessage
CreateGxsForumMsg::~CreateGxsForumMsg()
{
delete(mForumQueue);
delete(mCirclesQueue);
}
void CreateGxsForumMsg::newMsg()
@ -121,7 +126,8 @@ void CreateGxsForumMsg::newMsg()
mForumMetaLoaded = false;
/* fill in the available OwnIds for signing */
std::cerr << "Initing ID chooser. Sign flags = " << std::hex << mForumMeta.mSignFlags << std::dec << std::endl;
//std::cerr << "Initing ID chooser. Sign flags = " << std::hex << mForumMeta.mSignFlags << std::dec << std::endl;
ui.idChooser->loadIds(IDCHOOSER_ID_REQUIRED, RsGxsId());
@ -143,8 +149,7 @@ void CreateGxsForumMsg::newMsg()
std::list<RsGxsGroupId> groupIds;
groupIds.push_back(mForumId);
std::cerr << "ForumsV2Dialog::newMsg() Requesting Group Summary(" << mForumId << ")";
std::cerr << std::endl;
//std::cerr << "ForumsV2Dialog::newMsg() Requesting Group Summary(" << mForumId << ")"<< std::endl;
uint32_t token;
mForumQueue->requestGroupInfo(token, RS_TOKREQ_ANSTYPE_SUMMARY, opts, groupIds, CREATEGXSFORUMMSG_FORUMINFO);
@ -163,8 +168,8 @@ void CreateGxsForumMsg::newMsg()
std::vector<RsGxsMessageId> &vect = msgIds[mForumId];
vect.push_back(mParentId);
std::cerr << "ForumsV2Dialog::newMsg() Requesting Parent Summary(" << mParentId << ")";
std::cerr << std::endl;
//std::cerr << "ForumsV2Dialog::newMsg() Requesting Parent Summary(" << mParentId << ")";
//std::cerr << std::endl;
uint32_t token;
mForumQueue->requestMsgInfo(token, RS_TOKREQ_ANSTYPE_DATA, opts, msgIds, CREATEGXSFORUMMSG_PARENTMSG);
@ -178,8 +183,8 @@ void CreateGxsForumMsg::loadFormInformation()
mStateHelper->setActive(CREATEGXSFORUMMSG_PARENTMSG, true);
mStateHelper->setLoading(CREATEGXSFORUMMSG_PARENTMSG, false);
} else {
std::cerr << "CreateGxsForumMsg::loadMsgInformation() ParentMsg not Loaded Yet";
std::cerr << std::endl;
//std::cerr << "CreateGxsForumMsg::loadMsgInformation() ParentMsg not Loaded Yet";
//std::cerr << std::endl;
mStateHelper->setActive(CREATEGXSFORUMMSG_PARENTMSG, false);
@ -194,18 +199,18 @@ void CreateGxsForumMsg::loadFormInformation()
mStateHelper->setActive(CREATEGXSFORUMMSG_FORUMINFO, true);
mStateHelper->setLoading(CREATEGXSFORUMMSG_FORUMINFO, false);
} else {
std::cerr << "CreateGxsForumMsg::loadMsgInformation() ForumMeta not Loaded Yet";
std::cerr << std::endl;
//std::cerr << "CreateGxsForumMsg::loadMsgInformation() ForumMeta not Loaded Yet";
//std::cerr << std::endl;
mStateHelper->setActive(CREATEGXSFORUMMSG_FORUMINFO, false);
return;
}
std::cerr << "CreateGxsForumMsg::loadMsgInformation() Data Available!";
std::cerr << std::endl;
//std::cerr << "CreateGxsForumMsg::loadMsgInformation() Data Available!";
//std::cerr << std::endl;
std::cerr << "CreateGxsForumMsg::loadMsgInformation() using signFlags=" << std::hex << mForumMeta.mSignFlags << std::dec << std::endl;
//std::cerr << "CreateGxsForumMsg::loadMsgInformation() using signFlags=" << std::hex << mForumMeta.mSignFlags << std::dec << std::endl;
if(mForumMeta.mSignFlags & GXS_SERV::FLAG_AUTHOR_AUTHENTICATION_GPG)
ui.idChooser->setFlags(IDCHOOSER_ID_REQUIRED | IDCHOOSER_NON_ANONYMOUS) ;
@ -300,8 +305,8 @@ void CreateGxsForumMsg::createMsg()
case GxsIdChooser::KnowId:
case GxsIdChooser::UnKnowId:
msg.mMeta.mAuthorId = authorId;
std::cerr << "CreateGxsForumMsg::createMsg() AuthorId: " << authorId;
std::cerr << std::endl;
//std::cerr << "CreateGxsForumMsg::createMsg() AuthorId: " << authorId;
//std::cerr << std::endl;
break;
case GxsIdChooser::None:
@ -328,8 +333,8 @@ void CreateGxsForumMsg::createMsg()
return;
}//switch (ui.idChooser->getChosenId(authorId))
} else {
std::cerr << "CreateGxsForumMsg::createMsg() No Signature (for now :)";
std::cerr << std::endl;
//std::cerr << "CreateGxsForumMsg::createMsg() No Signature (for now :)";
//std::cerr << std::endl;
QMessageBox::warning(this, tr("RetroShare"),tr("Please choose Signing Id, it is required"), QMessageBox::Ok, QMessageBox::Ok);
return;
}//if (ui.signBox->isChecked())
@ -408,7 +413,7 @@ void CreateGxsForumMsg::addFile()
void CreateGxsForumMsg::fileHashingFinished(QList<HashedFile> hashedFiles)
{
std::cerr << "CreateGxsForumMsg::fileHashingFinished() started." << std::endl;
//std::cerr << "CreateGxsForumMsg::fileHashingFinished() started." << std::endl;
QString mesgString;
@ -431,8 +436,8 @@ void CreateGxsForumMsg::fileHashingFinished(QList<HashedFile> hashedFiles)
void CreateGxsForumMsg::loadForumInfo(const uint32_t &token)
{
std::cerr << "CreateGxsForumMsg::loadForumInfo()";
std::cerr << std::endl;
//std::cerr << "CreateGxsForumMsg::loadForumInfo()";
//std::cerr << std::endl;
std::list<RsGroupMetaData> groupInfo;
rsGxsForums->getGroupSummary(token, groupInfo);
@ -444,6 +449,20 @@ void CreateGxsForumMsg::loadForumInfo(const uint32_t &token)
mForumMeta = fi;
mForumMetaLoaded = true;
if(!fi.mCircleId.isNull())
{
//std::cerr << "Circle ID is not null: " << fi.mCircleId << ": loading circle info to add constraint to the GXS ID chooser." << std::endl;
RsTokReqOptions opts;
opts.mReqType = GXS_REQUEST_TYPE_GROUP_DATA;
std::list<RsGxsGroupId> groupIds;
groupIds.push_back(RsGxsGroupId(fi.mCircleId));
uint32_t _token;
mCirclesQueue->requestGroupInfo(_token, RS_TOKREQ_ANSTYPE_DATA, opts, groupIds, CREATEGXSFORUMMSG_CIRCLENFO);
}
loadFormInformation();
}
else
@ -455,11 +474,50 @@ void CreateGxsForumMsg::loadForumInfo(const uint32_t &token)
mStateHelper->setLoading(CREATEGXSFORUMMSG_FORUMINFO, false);
}
}
void CreateGxsForumMsg::loadForumCircleInfo(const uint32_t& token)
{
//std::cerr << "Loading forum circle info" << std::endl;
std::vector<RsGxsCircleGroup> circle_grp_v ;
rsGxsCircles->getGroupData(token, circle_grp_v);
if (circle_grp_v.empty())
{
std::cerr << "(EE) unexpected empty result from getGroupData. Cannot process circle now!" << std::endl;
return ;
}
if (circle_grp_v.size() != 1)
{
std::cerr << "(EE) very weird result from getGroupData. Should get exactly one circle" << std::endl;
return ;
}
RsGxsCircleGroup cg = circle_grp_v.front();
mForumCircleData = cg;
mForumCircleLoaded = true;
//std::cerr << "Loaded content of circle " << cg.mMeta.mGroupId << std::endl;
//for(std::set<RsGxsId>::const_iterator it(cg.mInvitedMembers.begin());it!=cg.mInvitedMembers.end();++it)
// std::cerr << " added constraint to circle element " << *it << std::endl;
ui.idChooser->setIdConstraintSet(cg.mInvitedMembers) ;
ui.idChooser->setFlags(IDCHOOSER_NO_CREATE | ui.idChooser->flags()) ; // since there's a circle involved, no ID creation can be needed
RsGxsId tmpid ;
if(ui.idChooser->countEnabledEntries() == 0)
{
QMessageBox::information(NULL,tr("No compatible ID for this forum"),tr("None of your identities is allowed to post in this forum. This could be due to the forum being limited to a circle that contains none of your identities, or forum flags requiring a PGP-signed identity.")) ;
close() ;
}
}
void CreateGxsForumMsg::loadParentMsg(const uint32_t &token)
{
std::cerr << "CreateGxsForumMsg::loadParentMsg()";
std::cerr << std::endl;
//std::cerr << "CreateGxsForumMsg::loadParentMsg()";
//std::cerr << std::endl;
// Only grab one.... ignore more (shouldn't be any).
std::vector<RsGxsForumMsg> msgs;
@ -486,8 +544,8 @@ void CreateGxsForumMsg::loadParentMsg(const uint32_t &token)
void CreateGxsForumMsg::loadRequest(const TokenQueue *queue, const TokenRequest &req)
{
std::cerr << "CreateGxsForum::loadRequest() UserType: " << req.mUserType;
std::cerr << std::endl;
//std::cerr << "CreateGxsForum::loadRequest() UserType: " << req.mUserType;
//std::cerr << std::endl;
if (queue == mForumQueue)
{
@ -501,7 +559,20 @@ void CreateGxsForumMsg::loadRequest(const TokenQueue *queue, const TokenRequest
loadParentMsg(req.mToken);
break;
default:
std::cerr << "CreateGxsForum::loadRequest() UNKNOWN UserType ";
std::cerr << "CreateGxsForumMsg::loadRequest() UNKNOWN UserType " << req.mUserType << " for token request in mForumQueue";
std::cerr << std::endl;
}
}
if(queue == mCirclesQueue)
{
switch(req.mUserType)
{
case CREATEGXSFORUMMSG_CIRCLENFO:
loadForumCircleInfo(req.mToken) ;
break ;
default:
std::cerr << "CreateGxsForumMsg::loadRequest() UNKNOWN UserType " << req.mUserType << " for token request in mCirclesQueue";
std::cerr << std::endl;
}
}

View file

@ -27,6 +27,7 @@
#include "util/TokenQueue.h"
#include <retroshare/rsgxsforums.h>
#include <retroshare/rsgxscircles.h>
class UIStateHelper;
@ -60,16 +61,22 @@ private:
void loadForumInfo(const uint32_t &token);
void loadParentMsg(const uint32_t &token);
void loadForumCircleInfo(const uint32_t &token);
RsGxsGroupId mForumId;
RsGxsCircleId mCircleId ;
RsGxsMessageId mParentId;
bool mParentMsgLoaded;
bool mForumMetaLoaded;
bool mForumCircleLoaded ;
RsGxsForumMsg mParentMsg;
RsGroupMetaData mForumMeta;
RsGxsCircleGroup mForumCircleData ;
TokenQueue *mForumQueue;
TokenQueue *mCirclesQueue;
UIStateHelper *mStateHelper;
/** Qt Designer generated object */

View file

@ -31,6 +31,7 @@ CONFIG += gxsforums
CONFIG += gxschannels
CONFIG += posted
CONFIG += gxsgui
CONFIG += gxscircles
# Other Disabled Bits.
#CONFIG += framecatcher
@ -1175,6 +1176,7 @@ identities {
gxscircles {
DEFINES += RS_USE_CIRCLES
# DEFINES += RS_USE_NEW_PEOPLE_DIALOG
HEADERS += \
gui/Circles/CirclesDialog.h \

View file

@ -5,6 +5,8 @@
#include <retroshare/rsgxsifacehelper.h>
//#define DEBUG_GXS_BROADCAST 1
// previously gxs allowed only one event consumer to poll for changes
// this required a single broadcast instance per service
// now the update notify works through rsnotify and notifyqt
@ -43,8 +45,28 @@ RsGxsUpdateBroadcast *RsGxsUpdateBroadcast::get(RsGxsIfaceHelper *ifaceImpl)
void RsGxsUpdateBroadcast::onChangesReceived(const RsGxsChanges& changes)
{
#ifdef DEBUG_GXS_BROADCAST
std::cerr << "onChangesReceived()" << std::endl;
{
std::cerr << "Received changes for service " << (void*)changes.mService << ", expecting service " << (void*)mIfaceImpl->getTokenService() << std::endl;
std::cerr << " changes content: " << std::endl;
for(std::list<RsGxsGroupId>::const_iterator it(changes.mGrps.begin());it!=changes.mGrps.end();++it) std::cerr << " grp id: " << *it << std::endl;
for(std::list<RsGxsGroupId>::const_iterator it(changes.mGrpsMeta.begin());it!=changes.mGrpsMeta.end();++it) std::cerr << " grp meta: " << *it << std::endl;
for(std::map<RsGxsGroupId,std::vector<RsGxsMessageId> >::const_iterator it(changes.mMsgs.begin());it!=changes.mMsgs.end();++it)
for(uint32_t i=0;i<it->second.size();++i)
std::cerr << " grp id: " << it->first << ". Msg ID " << it->second[i] << std::endl;
for(std::map<RsGxsGroupId,std::vector<RsGxsMessageId> >::const_iterator it(changes.mMsgsMeta.begin());it!=changes.mMsgsMeta.end();++it)
for(uint32_t i=0;i<it->second.size();++i)
std::cerr << " grp id: " << it->first << ". Msg Meta " << it->second[i] << std::endl;
}
#endif
if(changes.mService != mIfaceImpl->getTokenService())
{
// std::cerr << "(EE) Incorrect service. Dropping." << std::endl;
return;
}
if (!changes.mMsgs.empty() || !changes.mMsgsMeta.empty())
{

View file

@ -176,21 +176,21 @@ RsSerialType* init_item(RsNxsMsg& nxm)
return new RsNxsSerialiser(RS_SERVICE_TYPE_PLUGIN_SIMPLE_FORUM);
}
RsSerialType* init_item(RsNxsSyncGrp& rsg)
RsSerialType* init_item(RsNxsSyncGrpReqItem& rsg)
{
rsg.clear();
rsg.flag = RsNxsSyncGrp::FLAG_USE_SYNC_HASH;
rsg.flag = RsNxsSyncGrpItem::FLAG_USE_SYNC_HASH;
rsg.createdSince = rand()%2423;
randString(3124,rsg.syncHash);
return new RsNxsSerialiser(RS_SERVICE_TYPE_PLUGIN_SIMPLE_FORUM);
}
RsSerialType* init_item(RsNxsSyncMsg& rsgm)
RsSerialType* init_item(RsNxsSyncMsgReqItem& rsgm)
{
rsgm.clear();
rsgm.flag = RsNxsSyncMsg::FLAG_USE_SYNC_HASH;
rsgm.flag = RsNxsSyncMsgItem::FLAG_USE_SYNC_HASH;
rsgm.createdSince = rand()%24232;
rsgm.transactionNumber = rand()%23;
init_random(rsgm.grpId) ;
@ -223,7 +223,7 @@ RsSerialType* init_item(RsNxsSyncMsgItem& rsgml)
return new RsNxsSerialiser(RS_SERVICE_TYPE_PLUGIN_SIMPLE_FORUM);
}
RsSerialType* init_item(RsNxsTransac& rstx){
RsSerialType* init_item(RsNxsTransacItem &rstx){
rstx.clear();
@ -236,7 +236,7 @@ RsSerialType* init_item(RsNxsTransac& rstx){
}
bool operator==(const RsNxsSyncGrp& l, const RsNxsSyncGrp& r)
bool operator==(const RsNxsSyncGrpReqItem& l, const RsNxsSyncGrpReqItem& r)
{
if(l.syncHash != r.syncHash) return false;
@ -247,7 +247,7 @@ bool operator==(const RsNxsSyncGrp& l, const RsNxsSyncGrp& r)
return true;
}
bool operator==(const RsNxsSyncMsg& l, const RsNxsSyncMsg& r)
bool operator==(const RsNxsSyncMsgReqItem& l, const RsNxsSyncMsgReqItem& r)
{
if(l.flag != r.flag) return false;
@ -279,7 +279,7 @@ bool operator==(const RsNxsSyncMsgItem& l, const RsNxsSyncMsgItem& r)
return true;
}
bool operator==(const RsNxsTransac& l, const RsNxsTransac& r){
bool operator==(const RsNxsTransacItem& l, const RsNxsTransacItem& r){
if(l.transactFlag != r.transactFlag) return false;
if(l.transactionNumber != r.transactionNumber) return false;

View file

@ -9,11 +9,11 @@ bool operator==(const RsNxsGrp&, const RsNxsGrp&);
bool operator==(const RsNxsMsg&, const RsNxsMsg&);
bool operator==(const RsGxsGrpMetaData& l, const RsGxsGrpMetaData& r);
bool operator==(const RsGxsMsgMetaData& l, const RsGxsMsgMetaData& r);
bool operator==(const RsNxsSyncGrp& l, const RsNxsSyncGrp& r);
bool operator==(const RsNxsSyncMsg& l, const RsNxsSyncMsg& r);
bool operator==(const RsNxsSyncGrpItem& l, const RsNxsSyncGrpItem& r);
bool operator==(const RsNxsSyncMsgItem& l, const RsNxsSyncMsgItem& r);
bool operator==(const RsNxsTransac& l, const RsNxsTransac& r);
bool operator==(const RsNxsSyncGrpItem& l, const RsNxsSyncGrpItem& r);
bool operator==(const RsNxsSyncMsgItem& l, const RsNxsSyncMsgItem& r);
bool operator==(const RsNxsTransacItem& l, const RsNxsTransacItem& r);
//void init_item(RsNxsGrp& nxg);
//void init_item(RsNxsMsg& nxm);
@ -23,11 +23,11 @@ void init_item(RsGxsMsgMetaData* metaMsg);
RsSerialType* init_item(RsNxsGrp& nxg);
RsSerialType* init_item(RsNxsMsg& nxm);
RsSerialType* init_item(RsNxsSyncGrp& rsg);
RsSerialType* init_item(RsNxsSyncMsg& rsgm);
RsSerialType* init_item(RsNxsSyncGrpReqItem &rsg);
RsSerialType* init_item(RsNxsSyncMsgReqItem &rsgm);
RsSerialType* init_item(RsNxsSyncGrpItem& rsgl);
RsSerialType* init_item(RsNxsSyncMsgItem& rsgml);
RsSerialType* init_item(RsNxsTransac& rstx);
RsSerialType* init_item(RsNxsTransacItem& rstx);
template<typename T>
void copy_all_but(T& ex, const std::list<T>& s, std::list<T>& d)

View file

@ -24,7 +24,7 @@ bool rs_nxs_test::RsNxsSimpleDummyCircles::loadCircle(
}
int rs_nxs_test::RsNxsSimpleDummyCircles::canSend(const RsGxsCircleId& circleId,
const RsPgpId& id) {
const RsPgpId& id, bool &should_encrypt) {
return true;
}
@ -33,11 +33,20 @@ int rs_nxs_test::RsNxsSimpleDummyCircles::canReceive(
return true;
}
bool rs_nxs_test::RsNxsSimpleDummyCircles::isRecipient(const RsGxsCircleId &circleId, const RsGxsId& id)
{
return true ;
}
bool rs_nxs_test::RsNxsSimpleDummyCircles::recipients(
const RsGxsCircleId& circleId, std::list<RsPgpId>& friendlist) {
return true;
}
bool rs_nxs_test::RsNxsSimpleDummyCircles::recipients(
const RsGxsCircleId& circleId, std::list<RsGxsId>& friendlist) {
return true;
}
rs_nxs_test::RsNxsSimpleDummyReputation::RsNxsSimpleDummyReputation(
RepMap& repMap, bool cached) {
}
@ -76,8 +85,7 @@ bool rs_nxs_test::RsNxsDelayedDummyCircles::loadCircle(
return allowed(circleId);
}
int rs_nxs_test::RsNxsDelayedDummyCircles::canSend(
const RsGxsCircleId& circleId, const RsPgpId& id) {
int rs_nxs_test::RsNxsDelayedDummyCircles::canSend(const RsGxsCircleId& circleId, const RsPgpId& id, bool &should_encrypt) {
return allowed(circleId);
}

View file

@ -39,10 +39,13 @@ namespace rs_nxs_test
bool isLoaded(const RsGxsCircleId &circleId);
bool loadCircle(const RsGxsCircleId &circleId);
int canSend(const RsGxsCircleId &circleId, const RsPgpId &id);
int canSend(const RsGxsCircleId &circleId, const RsPgpId &id,bool& should_encrypt);
int canReceive(const RsGxsCircleId &circleId, const RsPgpId &id);
bool recipients(const RsGxsCircleId &circleId, std::list<RsPgpId> &friendlist);
virtual bool recipients(const RsGxsCircleId &circleId, std::list<RsGxsId>& idlist) ;
virtual bool isRecipient(const RsGxsCircleId &circleId, const RsGxsId& id) ;
virtual bool getLocalCircleServerUpdateTS(const RsGxsCircleId& gid,time_t& grp_server_update_TS,time_t& msg_server_update_TS) { return true ; }
};
/*!
@ -66,10 +69,13 @@ namespace rs_nxs_test
bool isLoaded(const RsGxsCircleId &circleId);
bool loadCircle(const RsGxsCircleId &circleId);
int canSend(const RsGxsCircleId &circleId, const RsPgpId &id);
int canSend(const RsGxsCircleId &circleId, const RsPgpId &id,bool& should_encrypt);
int canReceive(const RsGxsCircleId &circleId, const RsPgpId &id);
bool recipients(const RsGxsCircleId &circleId, std::list<RsPgpId> &friendlist);
virtual bool recipients(const RsGxsCircleId &circleId, std::list<RsGxsId>& idlist) { return true ;}
virtual bool isRecipient(const RsGxsCircleId &circleId, const RsGxsId& id) { return allowed(circleId) ; }
virtual bool getLocalCircleServerUpdateTS(const RsGxsCircleId& gid,time_t& grp_server_update_TS,time_t& msg_server_update_TS) { return true ; }
private:
bool allowed(const RsGxsCircleId& circleId);

View file

@ -81,6 +81,7 @@ rs_nxs_test::NxsTestHub::NxsTestHub(NxsTestScenario::pointer testScenario)
mTestScenario->getServiceInfo(),
mTestScenario->getDummyReputations(*cit),
mTestScenario->getDummyCircles(*cit),
NULL,
mTestScenario->getDummyPgpUtils(),
true
)

View file

@ -12,9 +12,9 @@ TEST(libretroshare_serialiser, RsNxsItem)
{
test_RsItem<RsNxsGrp>(RS_SERVICE_TYPE_PLUGIN_SIMPLE_FORUM);
test_RsItem<RsNxsMsg>(RS_SERVICE_TYPE_PLUGIN_SIMPLE_FORUM);
test_RsItem<RsNxsSyncGrp>(RS_SERVICE_TYPE_PLUGIN_SIMPLE_FORUM);
test_RsItem<RsNxsSyncMsg>(RS_SERVICE_TYPE_PLUGIN_SIMPLE_FORUM);
test_RsItem<RsNxsSyncGrpItem>(RS_SERVICE_TYPE_PLUGIN_SIMPLE_FORUM);
test_RsItem<RsNxsSyncMsgItem>(RS_SERVICE_TYPE_PLUGIN_SIMPLE_FORUM);
test_RsItem<RsNxsTransac>(RS_SERVICE_TYPE_PLUGIN_SIMPLE_FORUM);
test_RsItem<RsNxsSyncGrpItem>(RS_SERVICE_TYPE_PLUGIN_SIMPLE_FORUM);
test_RsItem<RsNxsSyncMsgItem>(RS_SERVICE_TYPE_PLUGIN_SIMPLE_FORUM);
test_RsItem<RsNxsTransacItem>(RS_SERVICE_TYPE_PLUGIN_SIMPLE_FORUM);
}

View file

@ -67,7 +67,7 @@ GxsPeerNode::GxsPeerNode(const RsPeerId &ownId, const std::list<RsPeerId> &frien
mGxsIdNs = new RsGxsNetService(
RS_SERVICE_GXS_TYPE_GXSID, mGxsIdDs, nxsMgr,
mGxsIdService, mGxsIdService->getServiceInfo(),
mGxsIdService, mGxsCircles,
mGxsIdService, mGxsCircles,mGxsIdService,
mPgpAuxUtils,
false); // don't synchronise group automatic (need explicit group request)
@ -81,7 +81,7 @@ GxsPeerNode::GxsPeerNode(const RsPeerId &ownId, const std::list<RsPeerId> &frien
#endif
(RS_SERVICE_GXS_TYPE_GXSCIRCLE, mGxsCirclesDs, nxsMgr,
mGxsCircles, mGxsCircles->getServiceInfo(),
mGxsIdService, mGxsCircles,
mGxsIdService, mGxsCircles,NULL,
mPgpAuxUtils);
}
else
@ -107,7 +107,7 @@ GxsPeerNode::GxsPeerNode(const RsPeerId &ownId, const std::list<RsPeerId> &frien
#endif
(RS_SERVICE_GXS_TYPE_TEST, mTestDs, nxsMgr,
mTestService, mTestService->getServiceInfo(),
mGxsIdService, mGxsCircles,
mGxsIdService, mGxsCircles,mGxsIdService,
mPgpAuxUtils);
if (mUseIdentityService)

View file

@ -54,7 +54,7 @@ TEST(libretroshare_services, DISABLED_GXS_nxs_basic)
std::cerr << "Sending in SyncGrp";
std::cerr << std::endl;
RsNxsSyncGrp *syncGrp = new RsNxsSyncGrp(RS_SERVICE_GXS_TYPE_TEST);
RsNxsSyncGrpItem *syncGrp = new RsNxsSyncGrpItem(RS_SERVICE_GXS_TYPE_TEST);
syncGrp->flag = 0; //RsNxsSyncGrp::FLAG_USE_SYNC_HASH;
syncGrp->PeerId(friendId);
tester.sendPacket(syncGrp);
@ -69,7 +69,7 @@ TEST(libretroshare_services, DISABLED_GXS_nxs_basic)
std::cerr << "Recved in SyncGrp";
std::cerr << std::endl;
RsNxsSyncGrp *grp = dynamic_cast<RsNxsSyncGrp *>(item);
RsNxsSyncGrpItem *grp = dynamic_cast<RsNxsSyncGrpItem *>(item);
ASSERT_TRUE(grp);
delete grp;
@ -134,7 +134,7 @@ TEST(libretroshare_services, DISABLED_GXS_nxs_basic2)
std::cerr << "Created Groups.";
std::cerr << std::endl;
RsNxsSyncGrp *syncGrp = new RsNxsSyncGrp(RS_SERVICE_GXS_TYPE_TEST);
RsNxsSyncGrpItem *syncGrp= new RsNxsSyncGrpItem(RS_SERVICE_GXS_TYPE_TEST);
syncGrp->flag = 0; //RsNxsSyncGrp::FLAG_USE_SYNC_HASH;
syncGrp->PeerId(friendId);
tester.sendPacket(syncGrp);
@ -159,8 +159,8 @@ TEST(libretroshare_services, DISABLED_GXS_nxs_basic2)
item->print(std::cerr);
// ignore NxsSyncGrp.
RsNxsSyncGrp *grp = dynamic_cast<RsNxsSyncGrp *>(item);
RsNxsTransac *trans = dynamic_cast<RsNxsTransac *>(item);
RsNxsSyncGrpItem *grp = dynamic_cast<RsNxsSyncGrpItem *>(item);
RsNxsTransacItem *trans = dynamic_cast<RsNxsTransacItem *>(item);
if (grp)
{
std::cerr << "Recved in SyncGrp - ignoring";

View file

@ -41,7 +41,7 @@ TEST(libretroshare_services, DISABLED_GxsNxsPairExchange1)
dropFilter.setUseSource(true);
dropFilter.addSource(p2);
{
RsNxsSyncGrp *syncGrp = new RsNxsSyncGrp(RS_SERVICE_GXS_TYPE_TEST);
RsNxsSyncGrpItem *syncGrp = new RsNxsSyncGrpItem(RS_SERVICE_GXS_TYPE_TEST);
dropFilter.setUseFullTypes(true);
dropFilter.addFullType(syncGrp->PacketId());
}
@ -111,7 +111,7 @@ TEST(libretroshare_services, DISABLED_GxsNxsPairExchange2)
dropFilter.setUseSource(true);
dropFilter.addSource(p2);
{
RsNxsSyncGrp *syncGrp = new RsNxsSyncGrp(RS_SERVICE_GXS_TYPE_TEST);
RsNxsSyncGrpItem *syncGrp = new RsNxsSyncGrpItem(RS_SERVICE_GXS_TYPE_TEST);
dropFilter.setUseFullTypes(true);
dropFilter.addFullType(syncGrp->PacketId());
}