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 << "!!!!!! 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 << " message ID = " << received_id << std::endl;
std::cerr << " data status = " << data_status << 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: // This function is mandatory. It should do two things:

View file

@ -34,6 +34,11 @@
* #define GXS_SECURITY_DEBUG 1 * #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) static RsGxsId getRsaKeyFingerprint(RSA *pubkey)
{ {
int lenn = BN_num_bytes(pubkey -> n); 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) bool GxsSecurity::checkPrivateKey(const RsTlvSecurityKey& key)
{ {
#ifdef GXS_SECURITY_DEBUG
std::cerr << "Checking private key " << key.keyId << " ..." << std::endl; std::cerr << "Checking private key " << key.keyId << " ..." << std::endl;
#endif
if( (key.keyFlags & RSTLV_KEY_TYPE_MASK) != RSTLV_KEY_TYPE_FULL) 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) bool GxsSecurity::checkPublicKey(const RsTlvSecurityKey& key)
{ {
#ifdef GXS_SECURITY_DEBUG
std::cerr << "Checking public key " << key.keyId << " ..." << std::endl; std::cerr << "Checking public key " << key.keyId << " ..." << std::endl;
#endif
if( (key.keyFlags & RSTLV_KEY_TYPE_MASK) != RSTLV_KEY_TYPE_PUBLIC_ONLY) 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 << std::endl;
std::cerr << "WARNING: GXS ID key pair " << private_key.keyId << " has inconsistent fingerprint. This is an old key " << 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; std::cerr << std::endl;
public_key.keyId = private_key.keyId ; public_key.keyId = private_key.keyId ;
@ -410,10 +419,15 @@ bool GxsSecurity::encrypt(uint8_t *& out, uint32_t &outlen, const uint8_t *in, u
#ifdef DISTRIB_DEBUG #ifdef DISTRIB_DEBUG
std::cerr << "GxsSecurity::encrypt() " << std::endl; std::cerr << "GxsSecurity::encrypt() " << std::endl;
#endif #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 *tmpkey = ::extractPublicKey(key) ;
RSA *rsa_publish_pub = RSAPublicKey_dup(tmpkey) ; RSA *rsa_publish_pub = RSAPublicKey_dup(tmpkey) ;
RSA_free(tmpkey) ; RSA_free(tmpkey) ;
EVP_PKEY *public_key = NULL; EVP_PKEY *public_key = NULL;
@ -430,7 +444,7 @@ bool GxsSecurity::encrypt(uint8_t *& out, uint32_t &outlen, const uint8_t *in, u
{ {
#ifdef DISTRIB_DEBUG #ifdef DISTRIB_DEBUG
std::cerr << "GxsSecurity(): Could not generate publish key " << grpId std::cerr << "GxsSecurity(): Could not generate publish key " << grpId
<< std::endl; << std::endl;
#endif #endif
return false; return false;
} }
@ -477,7 +491,7 @@ bool GxsSecurity::encrypt(uint8_t *& out, uint32_t &outlen, const uint8_t *in, u
// now encrypt actual data // now encrypt actual data
if(!EVP_SealUpdate(&ctx, (unsigned char*) out + out_offset, &out_currOffset, (unsigned char*) in, inlen)) if(!EVP_SealUpdate(&ctx, (unsigned char*) out + out_offset, &out_currOffset, (unsigned char*) in, inlen))
{ {
free(out) ; free(out) ;
out = NULL ; out = NULL ;
return false; return false;
} }
@ -488,7 +502,7 @@ bool GxsSecurity::encrypt(uint8_t *& out, uint32_t &outlen, const uint8_t *in, u
// add padding // add padding
if(!EVP_SealFinal(&ctx, (unsigned char*) out + out_offset, &out_currOffset)) if(!EVP_SealFinal(&ctx, (unsigned char*) out + out_offset, &out_currOffset))
{ {
free(out) ; free(out) ;
out = NULL ; out = NULL ;
return false; return false;
} }
@ -499,7 +513,7 @@ bool GxsSecurity::encrypt(uint8_t *& out, uint32_t &outlen, const uint8_t *in, u
// make sure offset has not gone passed valid memory bounds // make sure offset has not gone passed valid memory bounds
if(out_offset > max_outlen) if(out_offset > max_outlen)
{ {
free(out) ; free(out) ;
out = NULL ; out = NULL ;
return false; return false;
} }
@ -511,14 +525,160 @@ bool GxsSecurity::encrypt(uint8_t *& out, uint32_t &outlen, const uint8_t *in, u
return true; 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) 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; std::cerr << "GxsSecurity::decrypt() " << std::endl;
#endif #endif
RSA *rsa_publish = extractPrivateKey(key) ; RSA *rsa_publish = extractPrivateKey(key) ;
EVP_PKEY *privateKey = NULL; EVP_PKEY *privateKey = NULL;
//RSA* rsa_publish = EVP_PKEY_get1_RSA(privateKey); //RSA* rsa_publish = EVP_PKEY_get1_RSA(privateKey);
@ -531,7 +691,7 @@ bool GxsSecurity::decrypt(uint8_t *& out, uint32_t & outlen, const uint8_t *in,
} }
else else
{ {
#ifdef DISTRIB_DEBUG #ifdef GXS_SECURITY_DEBUG
std::cerr << "GxsSecurity(): Could not generate publish key " << grpId std::cerr << "GxsSecurity(): Could not generate publish key " << grpId
<< std::endl; << std::endl;
#endif #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(); 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; std::cerr << "Severe error in " << __PRETTY_FUNCTION__ << ": cannot encrypt. " << std::endl;
return false ; return false ;
@ -606,7 +770,144 @@ bool GxsSecurity::decrypt(uint8_t *& out, uint32_t & outlen, const uint8_t *in,
return true; 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) bool GxsSecurity::validateNxsGrp(const RsNxsGrp& grp, const RsTlvKeySignature& sign, const RsTlvSecurityKey& key)
{ {
#ifdef GXS_SECURITY_DEBUG #ifdef GXS_SECURITY_DEBUG

View file

@ -63,7 +63,8 @@ class GxsSecurity
*@param in *@param in
*@param inlen *@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 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 ) * Decrypts data using evelope decryption (taken from open ssl's evp_sealinit )
@ -74,7 +75,8 @@ class GxsSecurity
* @param inlen * @param inlen
* @return false if encryption failed * @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 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 * uses grp signature to check if group has been

View file

@ -92,9 +92,9 @@ public:
uint32_t mMaxVisibleCount ; uint32_t mMaxVisibleCount ;
}; };
typedef std::map<RsGxsGroupId, std::vector<RsNxsMsg*> > NxsMsgDataResult; typedef std::map<RsGxsGroupId, std::vector<RsNxsMsg*> > NxsMsgDataResult;
typedef std::map<RsGxsGrpMsgIdPair, std::vector<RsNxsMsg*> > NxsMsgRelatedDataResult; typedef std::map<RsGxsGrpMsgIdPair, std::vector<RsNxsMsg*> > NxsMsgRelatedDataResult;
typedef std::map<RsGxsGroupId, std::vector<RsNxsMsg*> > GxsMsgResult; // <grpId, msgs> typedef std::map<RsGxsGroupId, std::vector<RsNxsMsg*> > GxsMsgResult; // <grpId, msgs>
/*! /*!
* The main role of GDS is the preparation and handing out of messages requested from * The main role of GDS is the preparation and handing out of messages requested from

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() void RsGenExchange::data_tick()
{ {
@ -170,7 +175,7 @@ void RsGenExchange::tick()
// Meta Changes should happen first. // Meta Changes should happen first.
// This is important, as services want to change Meta, then get results. // This is important, as services want to change Meta, then get results.
// Services shouldn't rely on this ordering - but some do. // Services shouldn't rely on this ordering - but some do.
processGrpMetaChanges(); processGrpMetaChanges();
processMsgMetaChanges(); processMsgMetaChanges();
mDataAccess->processRequests(); mDataAccess->processRequests();
@ -183,9 +188,9 @@ void RsGenExchange::tick()
processGroupDelete(); processGroupDelete();
processRecvdData(); processRecvdData();
processRoutingClues() ; processRoutingClues() ;
if(!mNotifications.empty()) if(!mNotifications.empty())
{ {
@ -234,6 +239,11 @@ void RsGenExchange::tick()
RsGxsGroupChange* gc = new RsGxsGroupChange(RsGxsNotify::TYPE_PROCESSED, false); RsGxsGroupChange* gc = new RsGxsGroupChange(RsGxsNotify::TYPE_PROCESSED, false);
gc->mGrpIdList = grpIds; 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); mNotifications.push_back(gc);
} }
@ -1137,8 +1147,13 @@ void RsGenExchange::receiveChanges(std::vector<RsGxsNotify*>& changes)
out.mGrps.splice(out.mGrps.end(), gc->mGrpIdList); out.mGrps.splice(out.mGrps.end(), gc->mGrpIdList);
} }
} }
else
std::cerr << "(EE) Unknown changes type!!" << std::endl;
delete n; delete n;
} }
changes.clear() ;
RsServer::notify()->notifyGxsChange(out); RsServer::notify()->notifyGxsChange(out);
} }
@ -1153,6 +1168,8 @@ bool RsGenExchange::subscribeToGroup(uint32_t& token, const RsGxsGroupId& grpId,
if(mNetService != NULL) if(mNetService != NULL)
mNetService->subscribeStatusChanged(grpId,subscribe) ; mNetService->subscribeStatusChanged(grpId,subscribe) ;
else
std::cerr << "(EE) No mNetService in RsGenExchange for service 0x" << std::hex << mServType << std::dec << std::endl;
return true; return true;
} }
@ -1814,6 +1831,11 @@ void RsGenExchange::processGrpMetaChanges()
RsGxsGroupChange* gc = new RsGxsGroupChange(RsGxsNotify::TYPE_PROCESSED, true); RsGxsGroupChange* gc = new RsGxsGroupChange(RsGxsNotify::TYPE_PROCESSED, true);
gc->mGrpIdList = grpChanged; gc->mGrpIdList = grpChanged;
mNotifications.push_back(gc); 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); RsGxsGroupChange* gc = new RsGxsGroupChange(RsGxsNotify::TYPE_PUBLISH, false);
gc->mGrpIdList = grpChanged; gc->mGrpIdList = grpChanged;
mNotifications.push_back(gc); 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
} }
} }
@ -2755,30 +2782,30 @@ void RsGenExchange::processRecvdMessages()
void RsGenExchange::processRecvdGroups() void RsGenExchange::processRecvdGroups()
{ {
RS_STACK_MUTEX(mGenMtx) ; RS_STACK_MUTEX(mGenMtx) ;
if(mReceivedGrps.empty()) if(mReceivedGrps.empty())
return; return;
NxsGrpPendValidVect::iterator vit = mReceivedGrps.begin(); NxsGrpPendValidVect::iterator vit = mReceivedGrps.begin();
std::vector<RsGxsGroupId> existingGrpIds; std::vector<RsGxsGroupId> existingGrpIds;
std::list<RsGxsGroupId> grpIds; std::list<RsGxsGroupId> grpIds;
std::map<RsNxsGrp*, RsGxsGrpMetaData*> grps; std::map<RsNxsGrp*, RsGxsGrpMetaData*> grps;
mDataStore->retrieveGroupIds(existingGrpIds); mDataStore->retrieveGroupIds(existingGrpIds);
while( vit != mReceivedGrps.end()) while( vit != mReceivedGrps.end())
{ {
GxsPendingItem<RsNxsGrp*, RsGxsGroupId>& gpsi = *vit; GxsPendingItem<RsNxsGrp*, RsGxsGroupId>& gpsi = *vit;
RsNxsGrp* grp = gpsi.mItem; RsNxsGrp* grp = gpsi.mItem;
RsGxsGrpMetaData* meta = new RsGxsGrpMetaData(); RsGxsGrpMetaData* meta = new RsGxsGrpMetaData();
bool deserialOk = false; bool deserialOk = false;
if(grp->meta.bin_len != 0) if(grp->meta.bin_len != 0)
deserialOk = meta->deserialise(grp->meta.bin_data, grp->meta.bin_len); deserialOk = meta->deserialise(grp->meta.bin_data, grp->meta.bin_len);
bool erase = true; bool erase = true;
if(deserialOk) if(deserialOk)
{ {
@ -2788,22 +2815,22 @@ void RsGenExchange::processRecvdGroups()
grp->metaData = meta; grp->metaData = meta;
uint8_t ret = validateGrp(grp); uint8_t ret = validateGrp(grp);
if(ret == VALIDATE_SUCCESS)
if(ret == VALIDATE_SUCCESS) {
{
meta->mGroupStatus = GXS_SERV::GXS_GRP_STATUS_UNPROCESSED | GXS_SERV::GXS_GRP_STATUS_UNREAD; 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); computeHash(grp->grp, meta->mHash);
// group has been validated. Let's notify the global router for the clue // group has been validated. Let's notify the global router for the clue
#ifdef GEN_EXCH_DEBUG
std::cerr << " Group routage info: Identity=" << meta->mAuthorId << " from " << grp->PeerId() << std::endl;
#endif
if(!meta->mAuthorId.isNull()) if(!meta->mAuthorId.isNull())
mRoutingClues[meta->mAuthorId].insert(grp->PeerId()) ; {
#ifdef GEN_EXCH_DEBUG
std::cerr << "Group routage info: Identity=" << meta->mAuthorId << " from " << grp->PeerId() << std::endl;
#endif
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 // 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. // of grp metadata arrive.
@ -2816,6 +2843,8 @@ void RsGenExchange::processRecvdGroups()
if(meta->mCircleType == GXS_CIRCLE_TYPE_YOUREYESONLY) if(meta->mCircleType == GXS_CIRCLE_TYPE_YOUREYESONLY)
meta->mOriginator = grp->PeerId(); meta->mOriginator = grp->PeerId();
meta->mSubscribeFlags = GXS_SERV::GROUP_SUBSCRIBE_NOT_SUBSCRIBED;
grps.insert(std::make_pair(grp, meta)); grps.insert(std::make_pair(grp, meta));
grpIds.push_back(grp->grpId); grpIds.push_back(grp->grpId);
} }
@ -2826,17 +2855,17 @@ void RsGenExchange::processRecvdGroups()
mGroupUpdates.push_back(update); mGroupUpdates.push_back(update);
} }
erase = true; erase = true;
} }
else if(ret == VALIDATE_FAIL) else if(ret == VALIDATE_FAIL)
{ {
#ifdef GEN_EXCH_DEBUG #ifdef GEN_EXCH_DEBUG
std::cerr << " failed to validate incoming meta, grpId: " << grp->grpId << ": wrong signature" << std::endl; std::cerr << " failed to validate incoming meta, grpId: " << grp->grpId << ": wrong signature" << std::endl;
#endif #endif
delete grp; delete grp;
erase = true; erase = true;
} }
else if(ret == VALIDATE_FAIL_TRY_LATER) else if(ret == VALIDATE_FAIL_TRY_LATER)
{ {
#ifdef GEN_EXCH_DEBUG #ifdef GEN_EXCH_DEBUG
std::cerr << " failed to validate incoming grp, trying again. grpId: " << grp->grpId << std::endl; std::cerr << " failed to validate incoming grp, trying again. grpId: " << grp->grpId << std::endl;
@ -2862,21 +2891,26 @@ void RsGenExchange::processRecvdGroups()
delete grp; delete grp;
delete meta; delete meta;
erase = true; erase = true;
} }
if(erase) if(erase)
vit = mReceivedGrps.erase(vit); vit = mReceivedGrps.erase(vit);
else else
++vit; ++vit;
} }
if(!grpIds.empty()) if(!grpIds.empty())
{ {
RsGxsGroupChange* c = new RsGxsGroupChange(RsGxsNotify::TYPE_RECEIVE, false); RsGxsGroupChange* c = new RsGxsGroupChange(RsGxsNotify::TYPE_RECEIVE, false);
c->mGrpIdList = grpIds; c->mGrpIdList = grpIds;
mNotifications.push_back(c); mNotifications.push_back(c);
mDataStore->storeGroup(grps); 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
}
} }
void RsGenExchange::performUpdateValidation() void RsGenExchange::performUpdateValidation()
@ -2936,22 +2970,35 @@ void RsGenExchange::performUpdateValidation()
else else
{ {
delete gu.newGrp; delete gu.newGrp;
gu.newGrp = NULL ;
} }
delete gu.oldGrpMeta; delete gu.oldGrpMeta;
gu.oldGrpMeta = NULL ;
} }
mDataStore->updateGroup(grps);
// notify the client // notify the client
RsGxsGroupChange* c = new RsGxsGroupChange(RsGxsNotify::TYPE_RECEIVE, true); RsGxsGroupChange* c = new RsGxsGroupChange(RsGxsNotify::TYPE_RECEIVE, true);
for(uint32_t i=0;i<mGroupUpdates.size();++i) 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); 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 // cleanup
mGroupUpdates.clear(); mGroupUpdates.clear();

View file

@ -616,6 +616,14 @@ public:
void shareGroupPublishKey(const RsGxsGroupId& grpId,const std::set<RsPeerId>& peers) ; 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: protected:
/** Notifications **/ /** Notifications **/

View file

@ -123,16 +123,12 @@ 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 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 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 getOwnIds(std::list<RsGxsId>& ids) = 0;
virtual bool isOwnId(const RsGxsId& key_id) = 0 ; virtual bool isOwnId(const RsGxsId& key_id) = 0 ;
virtual void timeStampKey(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.
// Key related interface - used for validating msgs and groups.
/*! /*!
* Use to query a whether given key is available by its key reference * Use to query a whether given key is available by its key reference
* @param keyref the keyref of key that is being checked for * @param keyref the keyref of key that is being checked for
@ -147,8 +143,8 @@ public:
*/ */
virtual bool havePrivateKey(const RsGxsId &id) = 0; virtual bool havePrivateKey(const RsGxsId &id) = 0;
// The fetchKey has an optional peerList.. this is people that had the msg with the signature. // The fetchKey has an optional peerList.. this is people that had the msg with the signature.
// These same people should have the identity - so we ask them first. // These same people should have the identity - so we ask them first.
/*! /*!
* Use to request a given key reference * Use to request a given key reference
* @param keyref the KeyRef of the key being requested * @param keyref the KeyRef of the key being requested
@ -167,9 +163,6 @@ public:
virtual bool getKey(const RsGxsId &id, RsTlvSecurityKey &key) = 0; virtual bool getKey(const RsGxsId &id, RsTlvSecurityKey &key) = 0;
virtual bool getPrivateKey(const RsGxsId &id, RsTlvSecurityKey &key) = 0; // For signing outgoing messages. 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 virtual bool getIdDetails(const RsGxsId& id, RsIdentityDetails& details) = 0 ; // Proxy function so that we get p3Identity info from Gxs
#ifdef SUSPENDED
#endif
}; };
class GixsReputation class GixsReputation
@ -218,9 +211,13 @@ class RsGcxs
virtual bool isLoaded(const RsGxsCircleId &circleId) = 0; virtual bool isLoaded(const RsGxsCircleId &circleId) = 0;
virtual bool loadCircle(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 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<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;
}; };
@ -231,8 +228,12 @@ public:
RsGxsCircleExchange(RsGeneralDataService* gds, RsNetworkExchangeService* ns, RsSerialType* serviceSerialiser, RsGxsCircleExchange(RsGeneralDataService* gds, RsNetworkExchangeService* ns, RsSerialType* serviceSerialiser,
uint16_t mServType, RsGixs* gixs, uint32_t authenPolicy) uint16_t mServType, RsGixs* gixs, uint32_t authenPolicy)
:RsGenExchange(gds,ns,serviceSerialiser,mServType, gixs, authenPolicy) { return; } :RsGenExchange(gds,ns,serviceSerialiser,mServType, gixs, authenPolicy) { return; }
virtual ~RsGxsCircleExchange() { 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, RsNxsNetMgr *netMgr,
RsNxsObserver *nxsObs, // used to be = NULL. RsNxsObserver *nxsObs, // used to be = NULL.
const RsServiceInfo serviceInfo, const RsServiceInfo serviceInfo,
RsGixsReputation* reputations = NULL, RsGcxs* circles = NULL, RsGixsReputation* reputations = NULL, RsGcxs* circles = NULL, RsGixs *gixs=NULL,
PgpAuxUtils *pgpUtils = NULL, PgpAuxUtils *pgpUtils = NULL,
bool grpAutoSync = true, bool msgAutoSync = true); bool grpAutoSync = true, bool msgAutoSync = true);
@ -154,6 +154,8 @@ public:
virtual void rejectMessage(const RsGxsMessageId& msg_id) ; 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 */ /* p3Config methods */
public: public:
@ -215,7 +217,7 @@ private:
* @param item the transaction item to process * @param item the transaction item to process
* @return false ownership of item left with callee * @return false ownership of item left with callee
*/ */
bool locked_processTransac(RsNxsTransac* item); bool locked_processTransac(RsNxsTransacItem* item);
/*! /*!
* This adds a transaction * This adds a transaction
@ -318,19 +320,19 @@ private:
* of groups held by user * of groups held by user
* @param item contains grp sync info * @param item contains grp sync info
*/ */
void handleRecvSyncGroup(RsNxsSyncGrp* item); void handleRecvSyncGroup(RsNxsSyncGrpReqItem* item);
/*! /*!
* Handles an nxs item for group statistics * Handles an nxs item for group statistics
* @param item contaims update time stamp and number of messages * @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 * Handles an nxs item for msgs synchronisation
* @param item contaims msg sync info * @param item contaims msg sync info
*/ */
void handleRecvSyncMessage(RsNxsSyncMsg* item); void handleRecvSyncMessage(RsNxsSyncMsgReqItem* item);
/*! /*!
* Handles an nxs item for group publish key * 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 * @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 * @return false, if you cannot send to this peer, true otherwise
*/ */
bool canSendGrpId(const RsPeerId& sslId, RsGxsGrpMetaData& grpMeta, std::vector<GrpIdCircleVet>& toVet); 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 canSendMsgIds(const std::vector<RsGxsMsgMetaData*>& msgMetas, const RsGxsGrpMetaData&, const RsPeerId& sslId);
bool checkCanRecvMsgFromPeer(const RsPeerId& sslId, const RsGxsGrpMetaData& meta); bool checkCanRecvMsgFromPeer(const RsPeerId& sslId, const RsGxsGrpMetaData& meta);
void locked_createTransactionFromPending(MsgRespPending* grpPend); void locked_createTransactionFromPending(MsgRespPending* grpPend);
void locked_createTransactionFromPending(GrpRespPending* msgPend); void locked_createTransactionFromPending(GrpRespPending* msgPend);
void locked_createTransactionFromPending(GrpCircleIdRequestVetting* grpPend); bool locked_createTransactionFromPending(GrpCircleIdRequestVetting* grpPend) ;
void locked_createTransactionFromPending(MsgCircleIdsRequestVetting* 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); // forms a grp list request
void locked_pushGrpTransactionFromList(std::list<RsNxsItem*>& reqList, const RsPeerId& peerId, const uint32_t& transN); 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_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 locked_pushMsgRespFromList(std::list<RsNxsItem*>& itemL, const RsPeerId& sslId, const RsGxsGroupId &grp_id, const uint32_t& transN);
void syncWithPeers(); void syncWithPeers();
void syncGrpStatistics(); void syncGrpStatistics();
void addGroupItemToList(NxsTransaction*& tr, void addGroupItemToList(NxsTransaction*& tr,
@ -375,15 +376,15 @@ private:
void processExplicitGroupRequests(); void processExplicitGroupRequests();
void locked_doMsgUpdateWork(const RsNxsTransac* nxsTrans, const RsGxsGroupId& grpId); void locked_doMsgUpdateWork(const RsNxsTransacItem* nxsTrans, const RsGxsGroupId& grpId);
void updateServerSyncTS(); void updateServerSyncTS();
#ifdef TO_REMOVE #ifdef TO_REMOVE
void updateClientSyncTS(); void updateClientSyncTS();
#endif #endif
bool locked_CanReceiveUpdate(const RsNxsSyncGrp* item); bool locked_CanReceiveUpdate(const RsNxsSyncGrpReqItem *item);
bool locked_CanReceiveUpdate(const RsNxsSyncMsg* item); bool locked_CanReceiveUpdate(const RsNxsSyncMsgReqItem* item);
private: private:
@ -450,8 +451,15 @@ private:
void locked_stampPeerGroupUpdateTime(const RsPeerId& pid,const RsGxsGroupId& grpId,time_t tm,uint32_t n_messages) ; 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 cleanRejectedMessages();
void processObserverNotifications(); void processObserverNotifications();
private: private:
@ -469,8 +477,8 @@ private:
/*** transactions ***/ /*** transactions ***/
/*** synchronisation ***/ /*** synchronisation ***/
std::list<RsNxsSyncGrp*> mSyncGrp; std::list<RsNxsSyncGrpItem*> mSyncGrp;
std::list<RsNxsSyncMsg*> mSyncMsg; std::list<RsNxsSyncMsgItem*> mSyncMsg;
/*** synchronisation ***/ /*** synchronisation ***/
RsNxsObserver* mObserver; RsNxsObserver* mObserver;
@ -496,6 +504,7 @@ private:
int mUpdateCounter ; int mUpdateCounter ;
RsGcxs* mCircles; RsGcxs* mCircles;
RsGixs *mGixs;
RsGixsReputation* mReputations; RsGixsReputation* mReputations;
PgpAuxUtils *mPgpUtils; PgpAuxUtils *mPgpUtils;
bool mGrpAutoSync; bool mGrpAutoSync;
@ -516,7 +525,6 @@ public:
typedef std::map<RsPeerId, RsGxsMsgUpdateItem*> ClientMsgMap; typedef std::map<RsPeerId, RsGxsMsgUpdateItem*> ClientMsgMap;
typedef std::map<RsGxsGroupId, RsGxsServerMsgUpdateItem*> ServerMsgMap; typedef std::map<RsGxsGroupId, RsGxsServerMsgUpdateItem*> ServerMsgMap;
typedef std::map<RsPeerId, RsGxsGrpUpdateItem*> ClientGrpMap; typedef std::map<RsPeerId, RsGxsGrpUpdateItem*> ClientGrpMap;
private: private:
ClientMsgMap mClientMsgUpdateMap; ClientMsgMap mClientMsgUpdateMap;

View file

@ -222,12 +222,12 @@ bool GrpCircleVetting::expired()
{ {
return time(NULL) > (mTimeStamp + EXPIRY_PERIOD_OFFSET); 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)) if(mCircles->isLoaded(circleId))
{ {
const RsPgpId& pgpId = mPgpUtils->getPGPId(peerId); const RsPgpId& pgpId = mPgpUtils->getPGPId(peerId);
return mCircles->canSend(circleId, pgpId); return mCircles->canSend(circleId, pgpId,should_encrypt);
} }
mCircles->loadCircle(circleId); mCircles->loadCircle(circleId);
@ -250,7 +250,7 @@ bool GrpCircleIdRequestVetting::cleared()
if(!gic.mCleared) if(!gic.mCleared)
{ {
if(canSend(mPeerId, gic.mCircleId)) if(canSend(mPeerId, gic.mCircleId,gic.mShouldEncrypt))
{ {
gic.mCleared = true; gic.mCleared = true;
count++; count++;
@ -284,9 +284,30 @@ MsgCircleIdsRequestVetting::MsgCircleIdsRequestVetting(RsGcxs* const circles,
bool MsgCircleIdsRequestVetting::cleared() 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 int MsgCircleIdsRequestVetting::getType() const

View file

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

View file

@ -134,6 +134,16 @@ public:
* \param msgId * \param msgId
*/ */
virtual void rejectMessage(const RsGxsMessageId& msgId) =0; 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 #endif // RSGNP_H

View file

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

View file

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

View file

@ -29,8 +29,7 @@
#include "serialiser/rstlvbase.h" #include "serialiser/rstlvbase.h"
#include "serialiser/rsbaseserial.h" #include "serialiser/rsbaseserial.h"
#define CIRCLE_DEBUG 1 //#define CIRCLE_DEBUG 1
uint32_t RsGxsCircleSerialiser::size(RsItem *item) 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 <map>
#include <openssl/ssl.h>
#include "serialiser/rsserviceids.h" #include "serialiser/rsserviceids.h"
#include "serialiser/rsserial.h" #include "serialiser/rsserial.h"
@ -38,16 +39,17 @@
// These items have "flag type" numbers, but this is not used. // 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_ITEM = 0x02;
const uint8_t RS_PKT_SUBTYPE_NXS_SYNC_GRP_STATS = 0x03; const uint8_t RS_PKT_SUBTYPE_NXS_SYNC_GRP_STATS_ITEM = 0x03;
const uint8_t RS_PKT_SUBTYPE_NXS_GRP = 0x04; 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_ITEM = 0x08;
const uint8_t RS_PKT_SUBTYPE_NXS_SYNC_MSG = 0x10; const uint8_t RS_PKT_SUBTYPE_NXS_SYNC_MSG_REQ_ITEM = 0x10;
const uint8_t RS_PKT_SUBTYPE_NXS_MSG = 0x20; const uint8_t RS_PKT_SUBTYPE_NXS_MSG_ITEM = 0x20;
const uint8_t RS_PKT_SUBTYPE_NXS_TRANS = 0x40; const uint8_t RS_PKT_SUBTYPE_NXS_TRANSAC_ITEM = 0x40;
const uint8_t RS_PKT_SUBTYPE_NXS_GRP_PUBLISH_KEY = 0x80; const uint8_t RS_PKT_SUBTYPE_NXS_GRP_PUBLISH_KEY_ITEM = 0x80;
// possibility create second service to deal with this functionality // possibility create second service to deal with this functionality
@ -75,11 +77,15 @@ public:
setPriorityLevel(QOS_PRIORITY_RS_GXS_NET); setPriorityLevel(QOS_PRIORITY_RS_GXS_NET);
return; 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 void clear() = 0;
virtual std::ostream &print(std::ostream &out, uint16_t indent = 0) = 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 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 * Server may advise client peer to use sync file
* while serving his request. This results * while serving his request. This results
*/ */
class RsNxsSyncGrp : public RsNxsItem { class RsNxsSyncGrpReqItem : public RsNxsItem
{
public: public:
static const uint8_t FLAG_USE_SYNC_HASH; 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 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 void clear();
virtual std::ostream &print(std::ostream &out, uint16_t indent); virtual std::ostream &print(std::ostream &out, uint16_t indent);
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
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 * Use to request statistics about a particular group
*/ */
class RsNxsSyncGrpStats : public RsNxsItem class RsNxsSyncGrpStatsItem : public RsNxsItem
{ {
public: 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 void clear() {}
virtual std::ostream &print(std::ostream &out, uint16_t indent); 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_REQUEST = 0x01;
static const uint8_t GROUP_INFO_TYPE_RESPONSE = 0x02; static const uint8_t GROUP_INFO_TYPE_RESPONSE = 0x02;
@ -138,11 +148,14 @@ public:
class RsNxsGroupPublishKeyItem : public RsNxsItem class RsNxsGroupPublishKeyItem : public RsNxsItem
{ {
public: 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 void clear();
virtual std::ostream &print(std::ostream &out, uint16_t indent); 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 ; RsGxsGroupId grpId ;
RsTlvSecurityKey key ; RsTlvSecurityKey key ;
}; };
@ -154,7 +167,7 @@ public:
* in order to guaranttee a collection of item have been * in order to guaranttee a collection of item have been
* received * received
*/ */
class RsNxsTransac : public RsNxsItem { class RsNxsTransacItem: public RsNxsItem {
public: public:
@ -178,9 +191,13 @@ public:
static const uint16_t FLAG_TYPE_MSG_LIST_REQ; static const uint16_t FLAG_TYPE_MSG_LIST_REQ;
static const uint16_t FLAG_TYPE_GRPS; static const uint16_t FLAG_TYPE_GRPS;
static const uint16_t FLAG_TYPE_MSGS; 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; } RsNxsTransacItem(uint16_t servtype) : RsNxsItem(servtype, RS_PKT_SUBTYPE_NXS_TRANSAC_ITEM) { clear(); return; }
virtual ~RsNxsTransac() { return ; } virtual ~RsNxsTransacItem() { return ; }
virtual bool serialise(void *data,uint32_t& size) const;
virtual uint32_t serial_size() const ;
virtual void clear(); virtual void clear();
virtual std::ostream &print(std::ostream &out, uint16_t indent); virtual std::ostream &print(std::ostream &out, uint16_t indent);
@ -197,7 +214,7 @@ public:
* Use to send to peer list of grps * Use to send to peer list of grps
* held by server peer * held by server peer
*/ */
class RsNxsSyncGrpItem : public RsNxsItem class RsNxsSyncGrpItem: public RsNxsItem
{ {
public: public:
@ -209,6 +226,9 @@ public:
RsNxsSyncGrpItem(uint16_t servtype) : RsNxsItem(servtype, RS_PKT_SUBTYPE_NXS_SYNC_GRP_ITEM) { clear(); return ; } RsNxsSyncGrpItem(uint16_t servtype) : RsNxsItem(servtype, RS_PKT_SUBTYPE_NXS_SYNC_GRP_ITEM) { clear(); return ; }
virtual ~RsNxsSyncGrpItem() { return; } virtual ~RsNxsSyncGrpItem() { return; }
virtual bool serialise(void *data,uint32_t& size) const;
virtual uint32_t serial_size() const;
virtual void clear(); virtual void clear();
virtual std::ostream &print(std::ostream &out, uint16_t indent); 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 * Contains serialised group items
* Each item corresponds to a group which needs to be * Each item corresponds to a group which needs to be
@ -233,7 +304,7 @@ class RsNxsGrp : public RsNxsItem
public: 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(); metaData(NULL) { clear();
//std::cout << "\nGrp refcount++ : " << ++refcount << std::endl; //std::cout << "\nGrp refcount++ : " << ++refcount << std::endl;
return; } return; }
@ -243,6 +314,9 @@ public:
RsNxsGrp* clone() const; RsNxsGrp* clone() const;
virtual bool serialise(void *data,uint32_t& size) const;
virtual uint32_t serial_size() const;
virtual void clear(); virtual void clear();
virtual std::ostream &print(std::ostream &out, uint16_t indent); virtual std::ostream &print(std::ostream &out, uint16_t indent);
@ -266,14 +340,19 @@ public:
* Use to request list of msg held by peer * Use to request list of msg held by peer
* for a given group * for a given group
*/ */
class RsNxsSyncMsg : public RsNxsItem class RsNxsSyncMsgReqItem : public RsNxsItem
{ {
public: public:
#ifdef UNUSED_CODE
static const uint8_t FLAG_USE_SYNC_HASH; 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(); virtual void clear();
@ -299,6 +378,9 @@ public:
static const uint8_t FLAG_USE_SYNC_HASH; static const uint8_t FLAG_USE_SYNC_HASH;
RsNxsSyncMsgItem(uint16_t servtype) : RsNxsItem(servtype, RS_PKT_SUBTYPE_NXS_SYNC_MSG_ITEM) { clear(); return; } 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 void clear();
virtual std::ostream &print(std::ostream &out, uint16_t indent); virtual std::ostream &print(std::ostream &out, uint16_t indent);
@ -318,7 +400,7 @@ class RsNxsMsg : public RsNxsItem
{ {
public: 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) { metaData(NULL) {
// std::cout << "\nrefcount++ : " << ++refcount << std::endl; // std::cout << "\nrefcount++ : " << ++refcount << std::endl;
clear(); return; 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 void clear();
virtual std::ostream &print(std::ostream &out, uint16_t indent); virtual std::ostream &print(std::ostream &out, uint16_t indent);
@ -360,12 +445,15 @@ public:
/*! /*!
* Used to request a search of user data * Used to request a search of user data
*/ */
class RsNxsSearchReq : public RsNxsItem class RsNxsSearchReqItem : public RsNxsItem
{ {
public: public:
RsNxsSearchReq(uint16_t servtype): RsNxsItem(servtype, RS_PKT_SUBTYPE_EXT_SEARCH_REQ), serviceSearchItem(servtype) { return; } RsNxsSearchReqItem(uint16_t servtype): RsNxsItem(servtype, RS_PKT_SUBTYPE_EXT_SEARCH_REQ), serviceSearchItem(servtype) { return; }
virtual ~RsNxsSearchReq() { return;} virtual ~RsNxsSearchReqItem() { return;}
virtual bool serialise(void *data,uint32_t& size) const;
virtual uint32_t serial_size() const;
virtual void clear() { return;} virtual void clear() { return;}
virtual std::ostream &print(std::ostream &out, uint16_t /*indent*/) { return out; } virtual std::ostream &print(std::ostream &out, uint16_t /*indent*/) { return out; }
@ -381,11 +469,15 @@ public:
* Used to respond to a RsGrpSearchReq * Used to respond to a RsGrpSearchReq
* with grpId/MsgIds that satisfy search request * with grpId/MsgIds that satisfy search request
*/ */
class RsNxsSearchResultMsg class RsNxsSearchResultMsgItem
{ {
public: 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() {} void clear() {}
std::ostream &print(std::ostream &out, uint16_t /*indent*/) { return out; } std::ostream &print(std::ostream &out, uint16_t /*indent*/) { return out; }
@ -402,11 +494,15 @@ public:
* Used to respond to a RsGrpSearchReq * Used to respond to a RsGrpSearchReq
* with grpId/MsgIds that satisfy search request * with grpId/MsgIds that satisfy search request
*/ */
class RsNxsSearchResultGrp class RsNxsSearchResultGrpItem
{ {
public: public:
RsNxsSearchResultGrp(); RsNxsSearchResultGrpItem();
virtual bool serialise(void *data,uint32_t& size) const;
virtual uint32_t serial_size() const;
void clear() {} void clear() {}
std::ostream &print(std::ostream &out, uint16_t /*indent*/) { return out; } std::ostream &print(std::ostream &out, uint16_t /*indent*/) { return out; }
@ -421,6 +517,7 @@ public:
}; };
#ifndef UNUSED_CODE
class RsNxsDeleteMsg class RsNxsDeleteMsg
{ {
public: public:
@ -443,7 +540,7 @@ public:
RsTlvKeySignature idSign; RsTlvKeySignature idSign;
RsTlvKeySignature deleteSign; // (grpId + grp data) sign // TODO: add warning not to place grpId in msg RsTlvKeySignature deleteSign; // (grpId + grp data) sign // TODO: add warning not to place grpId in msg
}; };
#endif
class RsNxsSerialiser : public RsSerialType class RsNxsSerialiser : public RsSerialType
@ -460,60 +557,19 @@ public:
virtual RsItem* deserialise(void *data, uint32_t *size); virtual RsItem* deserialise(void *data, uint32_t *size);
private: 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 */
bool checkItemHeader(void *data, uint32_t *size, uint8_t subservice_type);
/* 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:
const uint16_t SERVICE_TYPE; const uint16_t SERVICE_TYPE;
}; };

View file

@ -176,18 +176,16 @@ const uint16_t TLV_TYPE_CERT_X509 = 0x0101;
const uint16_t TLV_TYPE_CERT_OPENPGP = 0x0102; const uint16_t TLV_TYPE_CERT_OPENPGP = 0x0102;
const uint16_t TLV_TYPE_KEY_EVP_PKEY = 0x0110; /* Used (Generic - Distrib) */ const uint16_t TLV_TYPE_KEY_EVP_PKEY = 0x0110; /* Used (Generic - Distrib) */
const uint16_t TLV_TYPE_KEY_PRIV_RSA = 0x0111; /* not used yet */ const uint16_t TLV_TYPE_KEY_PRIV_RSA = 0x0111; /* not used yet */
const uint16_t TLV_TYPE_KEY_PUB_RSA = 0x0112; /* not used yet */ 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_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_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_SERIALISE = 0x0150; /* Used (Generic - Distrib) */
const uint16_t TLV_TYPE_BIN_GENERIC = 0x0160; /* Used (DSDV Data) */
const uint16_t TLV_TYPE_BIN_GENERIC = 0x0160; /* Used (DSDV Data) */ const uint16_t TLV_TYPE_BIN_ENCRYPTED = 0x0170; /* Encrypted data */
/**** Compound Types ****/ /**** Compound Types ****/

View file

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

View file

@ -35,25 +35,29 @@
class RsTlvBinaryData: public RsTlvItem class RsTlvBinaryData: public RsTlvItem
{ {
public: public:
RsTlvBinaryData(uint16_t t); RsTlvBinaryData();
RsTlvBinaryData(const RsTlvBinaryData& b); // as per rule of three RsTlvBinaryData(uint16_t t);
void operator=(const RsTlvBinaryData& b); // as per rule of three RsTlvBinaryData(const RsTlvBinaryData& b); // as per rule of three
virtual ~RsTlvBinaryData(); // as per rule of three void operator=(const RsTlvBinaryData& b); // 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 */
/// Serialise. virtual ~RsTlvBinaryData(); // as per rule of three
/*! Serialise Tlv to buffer(*data) of 'size' bytes starting at *offset */
virtual bool SetTlv(void *data, uint32_t size, uint32_t *offset) const;
/// Deserialise. virtual uint32_t TlvSize() const;
/*! Deserialise Tlv buffer(*data) of 'size' bytes starting at *offset */ virtual void TlvClear(); /*! Initialize fields to empty legal values ( "0", "", etc) */
virtual bool GetTlv(void *data, uint32_t size, uint32_t *offset); virtual void TlvShallowClear(); /*! Don't delete the binary data */
virtual std::ostream &print(std::ostream &out, uint16_t indent) const; /*! Error/Debug util function */
bool setBinData(const void *data, uint32_t size); /// Serialise.
/*! Serialise Tlv to buffer(*data) of 'size' bytes starting at *offset */
virtual bool SetTlv(void *data, uint32_t size, uint32_t *offset) const;
/// Deserialise.
/*! Deserialise Tlv buffer(*data) of 'size' bytes starting at *offset */
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 uint16_t tlvtype; /// set/checked against TLV input
uint32_t bin_len; /// size of malloc'ed data (not serialised) uint32_t bin_len; /// size of malloc'ed data (not serialised)

View file

@ -176,66 +176,72 @@ void p3GxsCircles::service_tick()
void p3GxsCircles::notifyChanges(std::vector<RsGxsNotify *> &changes) void p3GxsCircles::notifyChanges(std::vector<RsGxsNotify *> &changes)
{ {
#ifdef DEBUG_CIRCLES #ifdef DEBUG_CIRCLES
std::cerr << "p3GxsCircles::notifyChanges()"; std::cerr << "p3GxsCircles::notifyChanges()";
std::cerr << std::endl; std::cerr << std::endl;
#endif #endif
std::vector<RsGxsNotify *>::iterator it; std::vector<RsGxsNotify *>::iterator it;
for(it = changes.begin(); it != changes.end(); ++it) for(it = changes.begin(); it != changes.end(); ++it)
{ {
RsGxsGroupChange *groupChange = dynamic_cast<RsGxsGroupChange *>(*it); RsGxsGroupChange *groupChange = dynamic_cast<RsGxsGroupChange *>(*it);
RsGxsMsgChange *msgChange = dynamic_cast<RsGxsMsgChange *>(*it); RsGxsMsgChange *msgChange = dynamic_cast<RsGxsMsgChange *>(*it);
if (msgChange && !msgChange->metaChange()) if (msgChange && !msgChange->metaChange())
{ {
#ifdef DEBUG_CIRCLES #ifdef DEBUG_CIRCLES
std::cerr << "p3GxsCircles::notifyChanges() Found Message Change Notification"; std::cerr << " Found Message Change Notification";
std::cerr << std::endl; std::cerr << std::endl;
#endif #endif
std::map<RsGxsGroupId, std::vector<RsGxsMessageId> > &msgChangeMap = msgChange->msgChangeMap; std::map<RsGxsGroupId, std::vector<RsGxsMessageId> > &msgChangeMap = msgChange->msgChangeMap;
std::map<RsGxsGroupId, std::vector<RsGxsMessageId> >::iterator mit; std::map<RsGxsGroupId, std::vector<RsGxsMessageId> >::iterator mit;
for(mit = msgChangeMap.begin(); mit != msgChangeMap.end(); ++mit) for(mit = msgChangeMap.begin(); mit != msgChangeMap.end(); ++mit)
{ {
#ifdef DEBUG_CIRCLES #ifdef DEBUG_CIRCLES
std::cerr << "p3GxsCircles::notifyChanges() Msgs for Group: " << mit->first; std::cerr << " Msgs for Group: " << mit->first;
std::cerr << std::endl; std::cerr << std::endl;
#endif #endif
} }
} }
/* add groups to ExternalIdList (Might get Personal Circles here until NetChecks in place) */ /* add groups to ExternalIdList (Might get Personal Circles here until NetChecks in place) */
if (groupChange && !groupChange->metaChange()) if (groupChange && !groupChange->metaChange())
{ {
#ifdef DEBUG_CIRCLES #ifdef DEBUG_CIRCLES
std::cerr << "p3GxsCircles::notifyChanges() Found Group Change Notification"; std::cerr << " Found Group Change Notification";
std::cerr << std::endl; std::cerr << std::endl;
#endif #endif
std::list<RsGxsGroupId> &groupList = groupChange->mGrpIdList; std::list<RsGxsGroupId> &groupList = groupChange->mGrpIdList;
std::list<RsGxsGroupId>::iterator git; std::list<RsGxsGroupId>::iterator git;
for(git = groupList.begin(); git != groupList.end(); ++git) for(git = groupList.begin(); git != groupList.end(); ++git)
{ {
#ifdef DEBUG_CIRCLES #ifdef DEBUG_CIRCLES
std::cerr << "p3GxsCircles::notifyChanges() Incoming Group: " << *git; std::cerr << " Incoming Group: " << *git << ". Forcing cache load." << std::endl;
std::cerr << std::endl;
#endif #endif
// for new circles we need to add them to the list. // for new circles we need to add them to the list.
// we don't know the type of this circle here // we don't know the type of this circle here
// original behavior was to add all ids to the external ids list // original behavior was to add all ids to the external ids list
addCircleIdToList(RsGxsCircleId(*git), 0); addCircleIdToList(RsGxsCircleId(*git), 0);
// reset the cached circle data for this id
{
RsStackMutex stack(mCircleMtx); /********** STACK LOCKED MTX ******/
mCircleCache.erase(RsGxsCircleId(*git));
}
}
}
}
RsGxsIfaceHelper::receiveChanges(changes);
// reset the cached circle data for this id
{
RsStackMutex stack(mCircleMtx); /********** STACK LOCKED MTX ******/
mCircleCache.erase(RsGxsCircleId(*git));
}
}
}
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); // 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.mCircleType = data.mCircleType;
details.mIsExternal = data.mIsExternal; details.mIsExternal = data.mIsExternal;
details.mUnknownPeers = data.mUnknownPeers; details.mAllowedAnonPeers = data.mAllowedAnonPeers;
details.mAllowedPeers = data.mAllowedPeers; details.mAllowedSignedPeers = data.mAllowedSignedPeers;
return true; return true;
} }
} }
@ -341,16 +347,17 @@ bool p3GxsCircles::loadCircle(const RsGxsCircleId &circleId)
return cache_request_load(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 ******/ RsStackMutex stack(mCircleMtx); /********** STACK LOCKED MTX ******/
if (mCircleCache.is_cached(circleId)) if (mCircleCache.is_cached(circleId))
{ {
RsGxsCircleCache &data = mCircleCache.ref(circleId); RsGxsCircleCache &data = mCircleCache.ref(circleId);
should_encrypt = (data.mCircleType == GXS_CIRCLE_TYPE_EXTERNAL);
if (data.isAllowedPeer(id)) if (data.isAllowedPeer(id))
{
return 1; return 1;
}
return 0; return 0;
} }
return -1; return -1;
@ -371,7 +378,7 @@ int p3GxsCircles::canReceive(const RsGxsCircleId &circleId, const RsPgpId &id)
return -1; return -1;
} }
bool p3GxsCircles::recipients(const RsGxsCircleId &circleId, std::list<RsPgpId> &friendlist) bool p3GxsCircles::recipients(const RsGxsCircleId &circleId, std::list<RsPgpId>& friendlist)
{ {
RsStackMutex stack(mCircleMtx); /********** STACK LOCKED MTX ******/ RsStackMutex stack(mCircleMtx); /********** STACK LOCKED MTX ******/
if (mCircleCache.is_cached(circleId)) if (mCircleCache.is_cached(circleId))
@ -383,6 +390,34 @@ bool p3GxsCircles::recipients(const RsGxsCircleId &circleId, std::list<RsPgpId>
return false; 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 ******************************************/ /******************* Get/Set Data ******************************************/
/********************************************************************************/ /********************************************************************************/
@ -495,6 +530,7 @@ RsGxsCircleCache::RsGxsCircleCache()
mIsExternal = true; mIsExternal = true;
mUpdateTime = 0; mUpdateTime = 0;
mGroupStatus = 0; mGroupStatus = 0;
mGroupSubscribeFlags = 0;
return; return;
} }
@ -506,11 +542,12 @@ bool RsGxsCircleCache::loadBaseCircle(const RsGxsCircleGroup &circle)
mCircleId = RsGxsCircleId(circle.mMeta.mGroupId); mCircleId = RsGxsCircleId(circle.mMeta.mGroupId);
mCircleName = circle.mMeta.mGroupName; mCircleName = circle.mMeta.mGroupName;
mUpdateTime = time(NULL); mUpdateTime = time(NULL);
mProcessedCircles.insert(mCircleId); // mProcessedCircles.insert(mCircleId);
mCircleType = circle.mMeta.mCircleType; mCircleType = circle.mMeta.mCircleType;
mIsExternal = (mCircleType != GXS_CIRCLE_TYPE_LOCAL); mIsExternal = (mCircleType != GXS_CIRCLE_TYPE_LOCAL);
mGroupStatus = circle.mMeta.mGroupStatus; mGroupStatus = circle.mMeta.mGroupStatus;
mGroupSubscribeFlags = circle.mMeta.mSubscribeFlags;
#ifdef DEBUG_CIRCLES #ifdef DEBUG_CIRCLES
std::cerr << "RsGxsCircleCache::loadBaseCircle(" << mCircleId << ")"; std::cerr << "RsGxsCircleCache::loadBaseCircle(" << mCircleId << ")";
@ -534,20 +571,35 @@ bool RsGxsCircleCache::loadSubCircle(const RsGxsCircleCache &subcircle)
return true; 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; std::map<RsPgpId, std::set<RsGxsId> >::const_iterator it;
for(it = mAllowedPeers.begin(); it != mAllowedPeers.end(); ++it) for(it = mAllowedSignedPeers.begin(); it != mAllowedSignedPeers.end(); ++it)
{ {
friendlist.push_back(it->first); friendlist.push_back(it->first);
} }
return true; 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(mUnprocessedPeers.find(id) != mUnprocessedPeers.end())
if (it != mAllowedPeers.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; return true;
} }
@ -557,8 +609,7 @@ bool RsGxsCircleCache::isAllowedPeer(const RsPgpId &id)
bool RsGxsCircleCache::addAllowedPeer(const RsPgpId &pgpId, const RsGxsId &gxsId) bool RsGxsCircleCache::addAllowedPeer(const RsPgpId &pgpId, const RsGxsId &gxsId)
{ {
/* created if doesn't exist */ /* created if doesn't exist */
std::list<RsGxsId> &gxsList = mAllowedPeers[pgpId]; mAllowedSignedPeers[pgpId].insert(gxsId);
gxsList.push_back(gxsId);
return true; return true;
} }
@ -566,7 +617,7 @@ bool RsGxsCircleCache::addAllowedPeer(const RsPgpId &pgpId, const RsGxsId &gxsId
bool RsGxsCircleCache::addLocalFriend(const RsPgpId &pgpId) bool RsGxsCircleCache::addLocalFriend(const RsPgpId &pgpId)
{ {
/* empty list as no GxsID associated */ /* empty list as no GxsID associated */
std::list<RsGxsId> &gxsList = mAllowedPeers[pgpId]; mAllowedSignedPeers.insert(std::make_pair(pgpId,std::set<RsGxsId>()));
return true; return true;
} }
@ -753,6 +804,33 @@ bool p3GxsCircles::cachetest_handlerequest(uint32_t token)
/************************************************************************************/ /************************************************************************************/
// Complicated deal of loading Circles. // 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) 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 << "p3GxsCircles::cache_load_for_token() Is Unknown -> UnknownPeer: " << *pit;
std::cerr << std::endl; std::cerr << std::endl;
#endif #endif
cache.mUnknownPeers.insert(*pit); cache.mAllowedAnonPeers.insert(*pit);
} }
} }
else else
@ -1104,9 +1182,7 @@ bool p3GxsCircles::cache_reloadids(const RsGxsCircleId &circleId)
RsGxsCircleCache &cache = it->second; RsGxsCircleCache &cache = it->second;
/* try reload Ids */ /* try reload Ids */
std::set<RsGxsId>::const_iterator pit; for(std::set<RsGxsId>::const_iterator pit = cache.mUnprocessedPeers.begin(); pit != cache.mUnprocessedPeers.end(); ++pit)
for(pit = cache.mUnprocessedPeers.begin();
pit != cache.mUnprocessedPeers.end(); ++pit)
{ {
/* check cache */ /* check cache */
if (mIdentities->haveKey(*pit)) if (mIdentities->haveKey(*pit))
@ -1127,7 +1203,7 @@ bool p3GxsCircles::cache_reloadids(const RsGxsCircleId &circleId)
} }
else else
{ {
cache.mUnknownPeers.insert(*pit); cache.mAllowedAnonPeers.insert(*pit);
#ifdef DEBUG_CIRCLES #ifdef DEBUG_CIRCLES
std::cerr << "p3GxsCircles::cache_reloadids() UnknownPeer: "; std::cerr << "p3GxsCircles::cache_reloadids() UnknownPeer: ";
@ -1157,8 +1233,10 @@ bool p3GxsCircles::cache_reloadids(const RsGxsCircleId &circleId)
cache.mUnprocessedPeers.clear(); cache.mUnprocessedPeers.clear();
// If sub-circles are complete too. // If sub-circles are complete too.
#ifdef SUBSCIRCLES
if (cache.mUnprocessedCircles.empty()) if (cache.mUnprocessedCircles.empty())
{ {
#endif
#ifdef DEBUG_CIRCLES #ifdef DEBUG_CIRCLES
std::cerr << "p3GxsCircles::cache_reloadids() Adding to cache Id: "; std::cerr << "p3GxsCircles::cache_reloadids() Adding to cache Id: ";
std::cerr << circleId; std::cerr << circleId;
@ -1173,6 +1251,7 @@ bool p3GxsCircles::cache_reloadids(const RsGxsCircleId &circleId)
/* remove from loading queue */ /* remove from loading queue */
mLoadingCache.erase(it); mLoadingCache.erase(it);
#ifdef SUBSCIRCLES
} }
else else
{ {
@ -1180,6 +1259,7 @@ bool p3GxsCircles::cache_reloadids(const RsGxsCircleId &circleId)
std::cerr << circleId; std::cerr << circleId;
std::cerr << std::endl; std::cerr << std::endl;
} }
#endif
return true; return true;
} }
@ -1189,17 +1269,14 @@ bool p3GxsCircles::cache_reloadids(const RsGxsCircleId &circleId)
bool p3GxsCircles::checkCircleCacheForAutoSubscribe(RsGxsCircleCache &cache) bool p3GxsCircles::checkCircleCacheForAutoSubscribe(RsGxsCircleCache &cache)
{ {
#ifdef DEBUG_CIRCLES #ifdef DEBUG_CIRCLES
std::cerr << "p3GxsCircles::checkCircleCacheForAutoSubscribe() : "; std::cerr << "p3GxsCircles::checkCircleCacheForAutoSubscribe() : "<< cache.mCircleId << std::endl;
std::cerr << cache.mCircleId;
std::cerr << std::endl;
#endif #endif
/* if processed already - ignore */ /* if processed already - ignore */
if (!(cache.mGroupStatus & GXS_SERV::GXS_GRP_STATUS_UNPROCESSED)) if (!(cache.mGroupStatus & GXS_SERV::GXS_GRP_STATUS_UNPROCESSED))
{ {
#ifdef DEBUG_CIRCLES #ifdef DEBUG_CIRCLES
std::cerr << "p3GxsCircles::checkCircleCacheForAutoSubscribe() : Already Processed"; std::cerr << " Already Processed" << std::endl;
std::cerr << std::endl;
#endif #endif
return false; return false;
@ -1209,50 +1286,90 @@ bool p3GxsCircles::checkCircleCacheForAutoSubscribe(RsGxsCircleCache &cache)
if (!cache.mIsExternal) if (!cache.mIsExternal)
{ {
#ifdef DEBUG_CIRCLES #ifdef DEBUG_CIRCLES
std::cerr << "p3GxsCircles::checkCircleCacheForAutoSubscribe() : Personal Circle"; std::cerr << " Personal Circle. Nothing to do." << std::endl;
std::cerr << std::endl;
#endif #endif
return false; return false;
} }
/* if we appear in the group - then autosubscribe, and mark as processed */ /* if we appear in the group - then autosubscribe, and mark as processed */
const RsPgpId& ownId = mPgpUtils->getPGPOwnId(); 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 #ifdef DEBUG_CIRCLES
/* we are part of this group - subscribe, clear unprocessed flag */ std::cerr << " found own GxsId " << *it << " as being in the circle" << std::endl;
std::cerr << "p3GxsCircles::checkCircleCacheForAutoSubscribe() Found OwnId -> AutoSubscribe!"; #endif
std::cerr << std::endl; break ;
}
}
#ifdef DEBUG_CIRCLES
else
std::cerr << " found own PGP id as signed to one of the circle's GxsIds" << std::endl;
#endif #endif
if(am_I_allowed)
{
uint32_t token, token2; 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); if(! (cache.mGroupSubscribeFlags & GXS_SERV::GROUP_SUBSCRIBE_SUBSCRIBED))
{
#ifdef DEBUG_CIRCLES
/* we are part of this group - subscribe, clear unprocessed flag */
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);
cache.mGroupStatus ^= GXS_SERV::GXS_GRP_STATUS_UNPROCESSED; cache.mGroupStatus ^= GXS_SERV::GXS_GRP_STATUS_UNPROCESSED;
return true; 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 #ifdef DEBUG_CIRCLES
std::cerr << "p3GxsCircles::checkCircleCacheForAutoSubscribe() Know All Peers -> Processed"; std::cerr << " Not part of the group! Let's unsubscribe this circle of unfriendly Napoleons!" << std::endl;
std::cerr << std::endl; #endif
}
#ifdef DEBUG_CIRCLES
else
std::cerr << " Not part of the group, and not subscribed either." << std::endl;
#endif #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; cache.mGroupStatus ^= GXS_SERV::GXS_GRP_STATUS_UNPROCESSED;
return true ;
} }
else else
{ {
#ifdef DEBUG_CIRCLES #ifdef DEBUG_CIRCLES
std::cerr << "p3GxsCircles::checkCircleCacheForAutoSubscribe() Leaving Unprocessed"; std::cerr << " Leaving Unprocessed" << std::endl;
std::cerr << std::endl;
#endif #endif
// Don't clear UNPROCESSED - as we might not know all the peers. // Don't clear UNPROCESSED - as we might not know all the peers.
// TODO - work out when we flag as PROCESSED. // TODO - work out when we flag as PROCESSED.
} }

View file

@ -132,8 +132,9 @@ class RsGxsCircleCache
bool loadBaseCircle(const RsGxsCircleGroup &circle); bool loadBaseCircle(const RsGxsCircleGroup &circle);
bool loadSubCircle(const RsGxsCircleCache &subcircle); bool loadSubCircle(const RsGxsCircleCache &subcircle);
bool getAllowedPeersList(std::list<RsPgpId> &friendlist); bool getAllowedPeersList(std::list<RsPgpId> &friendlist) const;
bool isAllowedPeer(const RsPgpId &id); bool isAllowedPeer(const RsPgpId &id) const;
bool isAllowedPeer(const RsGxsId &id) const;
bool addAllowedPeer(const RsPgpId &pgpid, const RsGxsId &gxsId); bool addAllowedPeer(const RsPgpId &pgpid, const RsGxsId &gxsId);
bool addLocalFriend(const RsPgpId &pgpid); bool addLocalFriend(const RsPgpId &pgpid);
@ -144,14 +145,17 @@ class RsGxsCircleCache
bool mIsExternal; bool mIsExternal;
uint32_t mGroupStatus; uint32_t mGroupStatus;
uint32_t mGroupSubscribeFlags;
time_t mUpdateTime; time_t mUpdateTime;
#ifdef SUBSCIRCLES
std::set<RsGxsCircleId> mUnprocessedCircles; std::set<RsGxsCircleId> mUnprocessedCircles;
std::set<RsGxsCircleId> mProcessedCircles;
#endif
std::set<RsGxsId> mUnprocessedPeers; std::set<RsGxsId> mUnprocessedPeers;
std::set<RsGxsCircleId> mProcessedCircles; std::set<RsGxsId> mAllowedAnonPeers;
std::set<RsGxsId> mUnknownPeers; std::map<RsPgpId, std::set<RsGxsId> > mAllowedSignedPeers;
std::map<RsPgpId, std::list<RsGxsId> > mAllowedPeers;
}; };
@ -175,9 +179,11 @@ virtual RsServiceInfo getServiceInfo();
virtual bool isLoaded(const RsGxsCircleId &circleId); virtual bool isLoaded(const RsGxsCircleId &circleId);
virtual bool loadCircle(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 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<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); 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_request_load(const RsGxsCircleId &id);
bool cache_start_load(); bool cache_start_load();
bool force_cache_reload(const RsGxsCircleId& id);
bool cache_load_for_token(uint32_t token); bool cache_load_for_token(uint32_t token);
bool cache_reloadids(const RsGxsCircleId &circleId); bool cache_reloadids(const RsGxsCircleId &circleId);

View file

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

View file

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

View file

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

View file

@ -6,7 +6,7 @@
<rect> <rect>
<x>0</x> <x>0</x>
<y>0</y> <y>0</y>
<width>681</width> <width>881</width>
<height>515</height> <height>515</height>
</rect> </rect>
</property> </property>
@ -44,11 +44,14 @@
<item> <item>
<widget class="QGroupBox" name="groupBox_2"> <widget class="QGroupBox" name="groupBox_2">
<property name="title"> <property name="title">
<string>Circle Membership</string> <string>Circle Members</string>
</property> </property>
<layout class="QVBoxLayout" name="verticalLayout_2"> <layout class="QVBoxLayout" name="verticalLayout_2">
<item> <item>
<widget class="QTreeWidget" name="treeWidget_membership"> <widget class="QTreeWidget" name="treeWidget_membership">
<property name="contextMenuPolicy">
<enum>Qt::CustomContextMenu</enum>
</property>
<property name="sortingEnabled"> <property name="sortingEnabled">
<bool>true</bool> <bool>true</bool>
</property> </property>
@ -126,9 +129,9 @@
</layout> </layout>
</item> </item>
<item> <item>
<widget class="QGroupBox" name="groupBox_4"> <widget class="QGroupBox" name="peersSelection_GB">
<property name="title"> <property name="title">
<string>Known Identities</string> <string>Known People</string>
</property> </property>
<layout class="QVBoxLayout" name="verticalLayout"> <layout class="QVBoxLayout" name="verticalLayout">
<item> <item>
@ -186,6 +189,9 @@
</item> </item>
<item> <item>
<widget class="RSTreeWidget" name="treeWidget_IdList"> <widget class="RSTreeWidget" name="treeWidget_IdList">
<property name="contextMenuPolicy">
<enum>Qt::CustomContextMenu</enum>
</property>
<property name="sortingEnabled"> <property name="sortingEnabled">
<bool>true</bool> <bool>true</bool>
</property> </property>
@ -240,7 +246,11 @@
</widget> </widget>
</item> </item>
<item> <item>
<widget class="QLineEdit" name="circleName"/> <widget class="QLineEdit" name="circleName">
<property name="placeholderText">
<string>Circle name</string>
</property>
</widget>
</item> </item>
<item> <item>
<widget class="QLabel" name="idChooserLabel"> <widget class="QLabel" name="idChooserLabel">
@ -251,12 +261,23 @@
</font> </font>
</property> </property>
<property name="text"> <property name="text">
<string>Creator</string> <string>Creator:</string>
</property> </property>
</widget> </widget>
</item> </item>
<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> </item>
</layout> </layout>
</item> </item>
@ -290,6 +311,9 @@
</item> </item>
<item> <item>
<widget class="QRadioButton" name="radioButton_Public"> <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"> <property name="text">
<string>Public</string> <string>Public</string>
</property> </property>
@ -297,6 +321,9 @@
</item> </item>
<item> <item>
<widget class="QRadioButton" name="radioButton_Self"> <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"> <property name="text">
<string>Self-Restricted</string> <string>Self-Restricted</string>
</property> </property>
@ -304,6 +331,9 @@
</item> </item>
<item> <item>
<widget class="QRadioButton" name="radioButton_Restricted"> <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"> <property name="text">
<string>Restricted to:</string> <string>Restricted to:</string>
</property> </property>
@ -363,6 +393,11 @@
<extends>QComboBox</extends> <extends>QComboBox</extends>
<header>gui/gxs/GxsCircleChooser.h</header> <header>gui/gxs/GxsCircleChooser.h</header>
</customwidget> </customwidget>
<customwidget>
<class>GxsIdLabel</class>
<extends>QLabel</extends>
<header>gui/gxs/GxsIdLabel.h</header>
</customwidget>
</customwidgets> </customwidgets>
<resources> <resources>
<include location="../images.qrc"/> <include location="../images.qrc"/>

View file

@ -21,6 +21,8 @@
* *
*/ */
#include <unistd.h>
#include <QMessageBox> #include <QMessageBox>
#include <QMenu> #include <QMenu>
@ -28,10 +30,12 @@
#include "ui_IdDialog.h" #include "ui_IdDialog.h"
#include "IdEditDialog.h" #include "IdEditDialog.h"
#include "gui/gxs/GxsIdDetails.h" #include "gui/gxs/GxsIdDetails.h"
#include "gui/gxs/RsGxsUpdateBroadcastBase.h"
#include "gui/common/UIStateHelper.h" #include "gui/common/UIStateHelper.h"
#include "gui/chat/ChatDialog.h" #include "gui/chat/ChatDialog.h"
#include "gui/settings/rsharesettings.h" #include "gui/settings/rsharesettings.h"
#include "gui/msgs/MessageComposer.h" #include "gui/msgs/MessageComposer.h"
#include "gui/Circles/CreateCircleDialog.h"
#include "gui/RetroShareLink.h" #include "gui/RetroShareLink.h"
#include "util/QtVersion.h" #include "util/QtVersion.h"
@ -52,6 +56,22 @@
#define IDDIALOG_REPLIST 3 #define IDDIALOG_REPLIST 3
#define IDDIALOG_REFRESH 4 #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; 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 = new QTreeWidgetItem();
allItem->setText(0, tr("All")); allItem->setText(0, tr("All"));
contactsItem = new QTreeWidgetItem(); contactsItem = new QTreeWidgetItem();
contactsItem->setText(0, tr("Contacts")); contactsItem->setText(0, tr("Contacts"));
ui->treeWidget_membership->clear();
mExternalOtherCircleItem = NULL ;
mExternalSubCircleItem = NULL ;
mExternalAdminCircleItem = NULL ;
/* Setup UI helper */ /* Setup UI helper */
mStateHelper = new UIStateHelper(this); mStateHelper = new UIStateHelper(this);
@ -164,7 +193,9 @@ IdDialog::IdDialog(QWidget *parent) :
connect(ui->inviteButton, SIGNAL(clicked()), this, SLOT(sendInvite())); connect(ui->inviteButton, SIGNAL(clicked()), this, SLOT(sendInvite()));
ui->avlabel->setPixmap(QPixmap(":/images/user/friends64.png")); ui->avlabel->setPixmap(QPixmap(":/images/user/friends64.png"));
ui->headerTextLabel->setText(tr("People")); ui->headerTextLabel->setText(tr("People"));
/* Initialize splitter */ /* Initialize splitter */
@ -177,8 +208,8 @@ IdDialog::IdDialog(QWidget *parent) :
/* Add filter types */ /* Add filter types */
ui->filterComboBox->addItem(tr("All"), RSID_FILTER_ALL); ui->filterComboBox->addItem(tr("All"), RSID_FILTER_ALL);
ui->filterComboBox->addItem(tr("Owned by you"), RSID_FILTER_OWNED_BY_YOU); ui->filterComboBox->addItem(tr("Owned by myself"), RSID_FILTER_OWNED_BY_YOU);
ui->filterComboBox->addItem(tr("Linked to your node"), RSID_FILTER_YOURSELF); 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 neighbor nodes"), RSID_FILTER_FRIENDS);
ui->filterComboBox->addItem(tr("Linked to distant nodes"), RSID_FILTER_OTHERS); ui->filterComboBox->addItem(tr("Linked to distant nodes"), RSID_FILTER_OTHERS);
ui->filterComboBox->addItem(tr("Anonymous"), RSID_FILTER_PSEUDONYMS); ui->filterComboBox->addItem(tr("Anonymous"), RSID_FILTER_PSEUDONYMS);
@ -188,6 +219,11 @@ IdDialog::IdDialog(QWidget *parent) :
QTreeWidgetItem *headerItem = ui->idTreeWidget->headerItem(); QTreeWidgetItem *headerItem = ui->idTreeWidget->headerItem();
QString headerText = headerItem->text(RSID_COL_NICKNAME); QString headerText = headerItem->text(RSID_COL_NICKNAME);
ui->filterLineEdit->addFilter(QIcon(), headerText, RSID_COL_NICKNAME, QString("%1 %2").arg(tr("Search"), headerText)); 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")); ui->filterLineEdit->addFilter(QIcon(), tr("ID"), RSID_COL_KEYID, tr("Search ID"));
/* Setup tree */ /* Setup tree */
@ -195,6 +231,7 @@ IdDialog::IdDialog(QWidget *parent) :
ui->idTreeWidget->enableColumnCustomize(true); ui->idTreeWidget->enableColumnCustomize(true);
ui->idTreeWidget->setColumnCustomizable(RSID_COL_NICKNAME, false); ui->idTreeWidget->setColumnCustomizable(RSID_COL_NICKNAME, false);
ui->idTreeWidget->setColumnHidden(RSID_COL_IDTYPE, true); ui->idTreeWidget->setColumnHidden(RSID_COL_IDTYPE, true);
ui->idTreeWidget->setColumnHidden(RSID_COL_KEYID, true); ui->idTreeWidget->setColumnHidden(RSID_COL_KEYID, true);
@ -212,29 +249,449 @@ IdDialog::IdDialog(QWidget *parent) :
mStateHelper->setActive(IDDIALOG_IDDETAILS, false); mStateHelper->setActive(IDDIALOG_IDDETAILS, false);
mStateHelper->setActive(IDDIALOG_REPLIST, false); mStateHelper->setActive(IDDIALOG_REPLIST, false);
QString hlp_str = tr( QString hlp_str = tr(
" <h1><img width=\"32\" src=\":/icons/help_64.png\">&nbsp;&nbsp;Identities</h1> \ " <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>In this tab you can create/edit pseudo-anonymous identities.</p> \
</p> \
<p>Identities are used to securely identify your data: sign forum and channel posts,\ <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 \ and receive feedback using Retroshare built-in email system, post comments \
after channel posts, etc.</p> \ after channel posts, etc.</p> \
<p> \ <p>Identities can optionally be signed by your Retroshare node's certificate. \
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> \
Signed identities are easier to trust but are easily linked to your node's IP address. \ <p> Anonymous identities allow you to anonymously interact with other users. They cannot be \
</p> \ spoofed, but noone can prove who really owns a given identity.</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) ; registerHelpButton(ui->helpButton, hlp_str) ;
// load settings // load settings
processSettings(true); 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() IdDialog::~IdDialog()
@ -246,6 +703,24 @@ IdDialog::~IdDialog()
delete(mIdQueue); 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) void IdDialog::processSettings(bool load)
{ {
Settings->beginGroup("IdDialog"); 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() void IdDialog::requestIdList()
{ {
//Disable by default, will be enable by insertIdDetails() //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_NICKNAME, QString::fromUtf8(data.mMeta.mGroupName.c_str()).left(RSID_MAXIMUM_NICKNAME_SIZE));
item->setText(RSID_COL_KEYID, QString::fromStdString(data.mMeta.mGroupId.toStdString())); 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->setData(RSID_COL_KEYID, Qt::UserRole,QVariant(item_flags)) ;
item->setTextAlignment(RSID_COL_VOTES, Qt::AlignRight); 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); mIdQueue->requestGroupInfo(token, RS_TOKREQ_ANSTYPE_DATA, opts, groupIds, IDDIALOG_IDDETAILS);
} }
void IdDialog::insertIdDetails(uint32_t token) void IdDialog::insertIdDetails(uint32_t token)
{ {
mStateHelper->setLoading(IDDIALOG_IDDETAILS, false); mStateHelper->setLoading(IDDIALOG_IDDETAILS, false);
@ -635,7 +1094,9 @@ void IdDialog::insertIdDetails(uint32_t token)
#ifdef ID_DEBUG #ifdef ID_DEBUG
std::cerr << "Setting header frame image : " << pix.width() << " x " << pix.height() << std::endl; std::cerr << "Setting header frame image : " << pix.width() << " x " << pix.height() << std::endl;
#endif #endif
ui->avlabel->setPixmap(pixmap); ui->avlabel->setPixmap(pixmap);
ui->avatarLabel->setPixmap(pixmap); ui->avatarLabel->setPixmap(pixmap);
if (data.mPgpKnown) if (data.mPgpKnown)
@ -816,6 +1277,7 @@ void IdDialog::updateDisplay(bool complete)
return; return;
} }
requestCircleGroupMeta();
std::list<RsGxsGroupId> grpIds; std::list<RsGxsGroupId> grpIds;
getAllGrpIds(grpIds); getAllGrpIds(grpIds);
@ -915,36 +1377,64 @@ void IdDialog::insertRepList(uint32_t token)
mStateHelper->setActive(IDDIALOG_REPLIST, true); 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 #ifdef ID_DEBUG
std::cerr << "IdDialog::loadRequest() UserType: " << req.mUserType; std::cerr << "IdDialog::loadRequest() UserType: " << req.mUserType;
std::cerr << std::endl; std::cerr << std::endl;
#endif #endif
switch(req.mUserType) if(queue == mIdQueue)
{ {
case IDDIALOG_IDLIST: switch(req.mUserType)
insertIdList(req.mToken); {
break; case IDDIALOG_IDLIST:
insertIdList(req.mToken);
break;
case IDDIALOG_IDDETAILS: case IDDIALOG_IDDETAILS:
insertIdDetails(req.mToken); insertIdDetails(req.mToken);
break; break;
case IDDIALOG_REPLIST: case IDDIALOG_REPLIST:
insertRepList(req.mToken); insertRepList(req.mToken);
break; break;
case IDDIALOG_REFRESH: case IDDIALOG_REFRESH:
// replaced by RsGxsUpdateBroadcastPage // replaced by RsGxsUpdateBroadcastPage
// updateDisplay(true); // updateDisplay(true);
break; break;
default: default:
std::cerr << "IdDialog::loadRequest() ERROR"; std::cerr << "IdDialog::loadRequest() ERROR";
std::cerr << std::endl; std::cerr << std::endl;
break; break;
} }
}
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 ) void IdDialog::IdListCustomPopupMenu( QPoint )
@ -981,7 +1471,9 @@ void IdDialog::IdListCustomPopupMenu( QPoint )
if(item_flags & RSID_FILTER_OWNED_BY_YOU) if(item_flags & RSID_FILTER_OWNED_BY_YOU)
one_item_owned_by_you = true ; one_item_owned_by_you = true ;
#ifdef ID_DEBUG
std::cerr << " item flags = " << item_flags << std::endl; std::cerr << " item flags = " << item_flags << std::endl;
#endif
RsGxsId keyId((*it)->text(RSID_COL_KEYID).toStdString()); RsGxsId keyId((*it)->text(RSID_COL_KEYID).toStdString());
RsReputations::ReputationInfo info ; RsReputations::ReputationInfo info ;

View file

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

View file

@ -6,8 +6,8 @@
<rect> <rect>
<x>0</x> <x>0</x>
<y>0</y> <y>0</y>
<width>745</width> <width>1475</width>
<height>640</height> <height>1134</height>
</rect> </rect>
</property> </property>
<property name="sizePolicy"> <property name="sizePolicy">
@ -19,14 +19,8 @@
<property name="windowTitle"> <property name="windowTitle">
<string/> <string/>
</property> </property>
<layout class="QGridLayout" name="gridLayout_5"> <layout class="QVBoxLayout" name="verticalLayout_6">
<property name="horizontalSpacing"> <item>
<number>0</number>
</property>
<property name="margin">
<number>0</number>
</property>
<item row="0" column="0">
<widget class="QFrame" name="titleBarFrame"> <widget class="QFrame" name="titleBarFrame">
<property name="sizePolicy"> <property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Maximum"> <sizepolicy hsizetype="Preferred" vsizetype="Maximum">
@ -62,7 +56,7 @@
<string/> <string/>
</property> </property>
<property name="pixmap"> <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>
<property name="scaledContents"> <property name="scaledContents">
<bool>true</bool> <bool>true</bool>
@ -102,7 +96,7 @@
<enum>Qt::NoFocus</enum> <enum>Qt::NoFocus</enum>
</property> </property>
<property name="icon"> <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> <normaloff>:/icons/help_64.png</normaloff>:/icons/help_64.png</iconset>
</property> </property>
<property name="checkable"> <property name="checkable">
@ -116,7 +110,7 @@
</layout> </layout>
</widget> </widget>
</item> </item>
<item row="1" column="0"> <item>
<widget class="QSplitter" name="splitter"> <widget class="QSplitter" name="splitter">
<property name="orientation"> <property name="orientation">
<enum>Qt::Horizontal</enum> <enum>Qt::Horizontal</enum>
@ -159,7 +153,7 @@
<string>New ID</string> <string>New ID</string>
</property> </property>
<property name="icon"> <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> <normaloff>:/images/identity/identity_create_32.png</normaloff>:/images/identity/identity_create_32.png</iconset>
</property> </property>
<property name="iconSize"> <property name="iconSize">
@ -235,225 +229,345 @@
</item> </item>
</layout> </layout>
</widget> </widget>
<widget class="QWidget" name="layoutWidget"> <widget class="QTabWidget" name="tabWidget1">
<layout class="QVBoxLayout" name="verticalLayout_4"> <property name="currentIndex">
<item> <number>0</number>
<widget class="QFrame" name="headerFrame"> </property>
<property name="frameShape"> <widget class="QWidget" name="tab_2">
<enum>QFrame::StyledPanel</enum> <attribute name="title">
</property> <string>Person</string>
<property name="frameShadow"> </attribute>
<enum>QFrame::Raised</enum> <layout class="QVBoxLayout" name="verticalLayout">
</property> <item>
<layout class="QGridLayout" name="gridLayout_4"> <layout class="QVBoxLayout" name="verticalLayout_4">
<property name="horizontalSpacing"> <item>
<number>12</number> <widget class="QFrame" name="headerFrame">
</property> <property name="frameShape">
<item row="0" column="0" rowspan="2"> <enum>QFrame::StyledPanel</enum>
<widget class="QLabel" name="avlabel">
<property name="minimumSize">
<size>
<width>64</width>
<height>64</height>
</size>
</property> </property>
<property name="maximumSize"> <property name="frameShadow">
<size> <enum>QFrame::Raised</enum>
<width>64</width>
<height>64</height>
</size>
</property>
<property name="styleSheet">
<string notr="true"/>
</property>
<property name="text">
<string/>
</property>
<property name="scaledContents">
<bool>true</bool>
</property> </property>
<layout class="QGridLayout" name="gridLayout_4">
<property name="horizontalSpacing">
<number>12</number>
</property>
<item row="0" column="0" rowspan="2">
<widget class="QLabel" name="avlabel">
<property name="minimumSize">
<size>
<width>64</width>
<height>64</height>
</size>
</property>
<property name="maximumSize">
<size>
<width>64</width>
<height>64</height>
</size>
</property>
<property name="styleSheet">
<string notr="true"/>
</property>
<property name="text">
<string/>
</property>
<property name="scaledContents">
<bool>true</bool>
</property>
</widget>
</item>
<item row="0" column="1" rowspan="2" colspan="2">
<widget class="StyledElidedLabel" name="headerTextLabel">
<property name="text">
<string>People</string>
</property>
</widget>
</item>
</layout>
</widget> </widget>
</item> </item>
<item row="0" column="1" rowspan="2" colspan="2"> <item>
<widget class="StyledElidedLabel" name="headerTextLabel"> <widget class="QGroupBox" name="detailsGroupBox">
<property name="text"> <property name="title">
<string>People</string> <string>Identity info</string>
</property> </property>
<layout class="QGridLayout" name="gridLayout_3">
<item row="0" column="0">
<layout class="QGridLayout" name="gridLayout">
<property name="margin">
<number>6</number>
</property>
<property name="spacing">
<number>6</number>
</property>
<item row="2" column="0">
<widget class="QLabel" name="label_4">
<property name="text">
<string>Identity ID :</string>
</property>
</widget>
</item>
<item row="1" column="0">
<widget class="QLabel" name="label">
<property name="text">
<string>Identity name :</string>
</property>
</widget>
</item>
<item row="4" column="0">
<widget class="QLabel" name="PgpId_LB">
<property name="text">
<string>Owner node ID :</string>
</property>
</widget>
</item>
<item row="1" column="1">
<widget class="QLineEdit" name="lineEdit_Nickname">
<property name="enabled">
<bool>true</bool>
</property>
<property name="readOnly">
<bool>true</bool>
</property>
</widget>
</item>
<item row="2" column="1">
<widget class="QLineEdit" name="lineEdit_KeyId">
<property name="enabled">
<bool>true</bool>
</property>
<property name="readOnly">
<bool>true</bool>
</property>
</widget>
</item>
<item row="4" column="1">
<widget class="QLineEdit" name="lineEdit_GpgId">
<property name="enabled">
<bool>true</bool>
</property>
<property name="readOnly">
<bool>true</bool>
</property>
</widget>
</item>
<item row="5" column="0">
<widget class="QLabel" name="PgpName_LB">
<property name="text">
<string>Owner node name :</string>
</property>
</widget>
</item>
<item row="5" column="1">
<widget class="QLineEdit" name="lineEdit_GpgName">
<property name="enabled">
<bool>true</bool>
</property>
<property name="readOnly">
<bool>true</bool>
</property>
</widget>
</item>
<item row="3" column="0">
<widget class="QLabel" name="label_3">
<property name="text">
<string>Type:</string>
</property>
</widget>
</item>
<item row="3" column="1">
<widget class="QLineEdit" name="lineEdit_Type"/>
</item>
<item row="6" column="0">
<widget class="QLabel" name="label_7">
<property name="text">
<string>Last used:</string>
</property>
</widget>
</item>
<item row="6" column="1">
<widget class="QLineEdit" name="lineEdit_LastUsed"/>
</item>
</layout>
</item>
<item row="0" column="1">
<layout class="QVBoxLayout" name="verticalLayout_3">
<item>
<widget class="QLabel" name="avatarLabel">
<property name="sizePolicy">
<sizepolicy hsizetype="Fixed" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="minimumSize">
<size>
<width>128</width>
<height>128</height>
</size>
</property>
<property name="maximumSize">
<size>
<width>128</width>
<height>128</height>
</size>
</property>
<property name="frameShape">
<enum>QFrame::Box</enum>
</property>
<property name="frameShadow">
<enum>QFrame::Sunken</enum>
</property>
<property name="text">
<string extracomment="Click here to change your avatar">Your Avatar</string>
</property>
<property name="scaledContents">
<bool>true</bool>
</property>
<property name="alignment">
<set>Qt::AlignCenter</set>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="inviteButton">
<property name="text">
<string>Send Invite</string>
</property>
</widget>
</item>
<item>
<spacer name="verticalSpacer_3">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
<height>2</height>
</size>
</property>
</spacer>
</item>
</layout>
</item>
</layout>
</widget> </widget>
</item> </item>
</layout> <item>
</widget> <widget class="QGroupBox" name="reputationGroupBox">
</item> <property name="sizePolicy">
<item> <sizepolicy hsizetype="Preferred" vsizetype="Preferred">
<widget class="QGroupBox" name="detailsGroupBox"> <horstretch>0</horstretch>
<property name="title"> <verstretch>0</verstretch>
<string>Identity info</string> </sizepolicy>
</property>
<layout class="QGridLayout" name="gridLayout_3">
<item row="0" column="0">
<layout class="QGridLayout" name="gridLayout">
<property name="margin">
<number>6</number>
</property> </property>
<property name="spacing"> <property name="title">
<number>6</number> <string>Reputation</string>
</property> </property>
<item row="2" column="0"> <layout class="QVBoxLayout" name="verticalLayout_2">
<widget class="QLabel" name="label_4"> <item>
<property name="text"> <layout class="QGridLayout" name="gridLayout_2">
<string>Identity ID :</string> <property name="margin">
</property> <number>6</number>
</widget> </property>
</item> <item row="2" column="1">
<item row="1" column="0"> <widget class="QLineEdit" name="neighborNodesOpinion_TF">
<widget class="QLabel" name="label"> <property name="toolTip">
<property name="text"> <string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Average opinion of neighbor nodes about this identity. Negative is bad,&lt;/p&gt;&lt;p&gt;positive is good. Zero is neutral.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
<string>Identity name :</string> </property>
</property> <property name="readOnly">
</widget> <bool>true</bool>
</item> </property>
<item row="4" column="0"> </widget>
<widget class="QLabel" name="PgpId_LB"> </item>
<property name="text"> <item row="1" column="0">
<string>Owner node ID :</string> <widget class="QLabel" name="label_6">
</property> <property name="text">
</widget> <string>Your opinion:</string>
</item> </property>
<item row="1" column="1"> </widget>
<widget class="QLineEdit" name="lineEdit_Nickname"> </item>
<property name="enabled"> <item row="2" column="0">
<bool>true</bool> <widget class="QLabel" name="label_5">
</property> <property name="text">
<property name="readOnly"> <string>Neighbor nodes:</string>
<bool>true</bool> </property>
</property> </widget>
</widget> </item>
</item> <item row="1" column="1">
<item row="2" column="1"> <widget class="QComboBox" name="ownOpinion_CB">
<widget class="QLineEdit" name="lineEdit_KeyId"> <property name="toolTip">
<property name="enabled"> <string>&lt;!DOCTYPE HTML PUBLIC &quot;-//W3C//DTD HTML 4.0//EN&quot; &quot;http://www.w3.org/TR/REC-html40/strict.dtd&quot;&gt;
<bool>true</bool> &lt;html&gt;&lt;head&gt;&lt;meta name=&quot;qrichtext&quot; content=&quot;1&quot; /&gt;&lt;style type=&quot;text/css&quot;&gt;
</property> p, li { white-space: pre-wrap; }
<property name="readOnly"> &lt;/style&gt;&lt;/head&gt;&lt;body style=&quot; font-family:'Sans'; font-size:9pt; font-weight:400; font-style:normal;&quot;&gt;
<bool>true</bool> &lt;p style=&quot; margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;Your own opinion about an identity rules the visibility of that identity for yourself and your friend nodes. Your own opinion is shared among friends and used to compute a reputation score: If your opinion about an identity is neutral, the reputation score is the average of your friend's opinions. If not, your own opinion gives the score.&lt;/p&gt;
</property> &lt;p style=&quot; margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;The overall score is used in chat lobbies, forums and channels to decide on the actions to take for each specific identity. When the overall score is lower than -0.6, the identity is banned, which prevents all messages and forums/channels authored by this identity to be forwarded, both ways. Some forums also have special anti-spam flags that require a higher reputation level, making them more sensitive to bad opinions. Banned identities gradually lose their activity and eventually disappear (after 30 days). &lt;/p&gt;
</widget> &lt;p style=&quot;-qt-paragraph-type:empty; margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;&lt;br /&gt;&lt;/p&gt;
</item> &lt;p style=&quot;-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
<item row="4" column="1"> </property>
<widget class="QLineEdit" name="lineEdit_GpgId"> <property name="currentIndex">
<property name="enabled"> <number>0</number>
<bool>true</bool> </property>
</property> <item>
<property name="readOnly"> <property name="text">
<bool>true</bool> <string>Negative</string>
</property> </property>
</widget> <property name="icon">
</item> <iconset>
<item row="5" column="0"> <normaloff>../../../../../trunk/retroshare-gui/src/gui/icons/yellow_biohazard64.png</normaloff>../../../../../trunk/retroshare-gui/src/gui/icons/yellow_biohazard64.png</iconset>
<widget class="QLabel" name="PgpName_LB"> </property>
<property name="text"> </item>
<string>Owner node name :</string> <item>
</property> <property name="text">
</widget> <string>Neutral</string>
</item> </property>
<item row="5" column="1"> </item>
<widget class="QLineEdit" name="lineEdit_GpgName"> <item>
<property name="enabled"> <property name="text">
<bool>true</bool> <string>Positive</string>
</property> </property>
<property name="readOnly"> </item>
<bool>true</bool> </widget>
</property> </item>
</widget> <item row="3" column="1">
</item> <widget class="QLineEdit" name="overallOpinion_TF">
<item row="3" column="0"> <property name="toolTip">
<widget class="QLabel" name="label_3"> <string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Overall reputation score, accounting for yours and your friends'.&lt;/p&gt;&lt;p&gt;Negative is bad, positive is good. Zero is neutral. If the score is too low,&lt;/p&gt;&lt;p&gt;the identity is flagged as bad, and will be filtered out in forums, chat lobbies,&lt;/p&gt;&lt;p&gt;channels, etc.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
<property name="text"> </property>
<string>Type:</string> <property name="readOnly">
</property> <bool>true</bool>
</widget> </property>
</item> </widget>
<item row="3" column="1"> </item>
<widget class="QLineEdit" name="lineEdit_Type"/> <item row="3" column="0">
</item> <widget class="QLabel" name="label_2">
<item row="6" column="0"> <property name="font">
<widget class="QLabel" name="label_7"> <font>
<property name="text"> <weight>75</weight>
<string>Last used:</string> <bold>true</bold>
</property> </font>
</widget> </property>
</item> <property name="text">
<item row="6" column="1"> <string>Overall:</string>
<widget class="QLineEdit" name="lineEdit_LastUsed"/> </property>
</item> </widget>
</layout> </item>
</layout>
</item>
</layout>
</widget>
</item> </item>
<item row="0" column="1"> <item>
<layout class="QVBoxLayout" name="verticalLayout_3"> <spacer name="verticalSpacer">
<item>
<widget class="QLabel" name="avatarLabel">
<property name="sizePolicy">
<sizepolicy hsizetype="Fixed" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="minimumSize">
<size>
<width>128</width>
<height>128</height>
</size>
</property>
<property name="maximumSize">
<size>
<width>128</width>
<height>128</height>
</size>
</property>
<property name="frameShape">
<enum>QFrame::Box</enum>
</property>
<property name="frameShadow">
<enum>QFrame::Sunken</enum>
</property>
<property name="text">
<string extracomment="Click here to change your avatar">Your Avatar</string>
</property>
<property name="scaledContents">
<bool>true</bool>
</property>
<property name="alignment">
<set>Qt::AlignCenter</set>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="inviteButton">
<property name="text">
<string>Send Invite</string>
</property>
</widget>
</item>
<item>
<spacer name="verticalSpacer_3">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
<height>2</height>
</size>
</property>
</spacer>
</item>
</layout>
</item>
<item row="1" column="0">
<spacer name="verticalSpacer_2">
<property name="orientation"> <property name="orientation">
<enum>Qt::Vertical</enum> <enum>Qt::Vertical</enum>
</property> </property>
<property name="sizeType">
<enum>QSizePolicy::Expanding</enum>
</property>
<property name="sizeHint" stdset="0"> <property name="sizeHint" stdset="0">
<size> <size>
<width>20</width> <width>20</width>
@ -463,137 +577,84 @@
</spacer> </spacer>
</item> </item>
</layout> </layout>
</widget> </item>
</item> </layout>
<item> </widget>
<widget class="QGroupBox" name="reputationGroupBox"> <widget class="QWidget" name="tab">
<property name="sizePolicy"> <attribute name="title">
<sizepolicy hsizetype="Preferred" vsizetype="Preferred"> <string>Circles</string>
<horstretch>0</horstretch> </attribute>
<verstretch>0</verstretch> <layout class="QGridLayout" name="gridLayout_5">
</sizepolicy> <item row="0" column="0">
</property> <layout class="QHBoxLayout" name="horizontalLayout_7">
<property name="title">
<string>Reputation</string>
</property>
<layout class="QVBoxLayout" name="verticalLayout_2">
<item> <item>
<layout class="QGridLayout" name="gridLayout_2"> <widget class="QPushButton" name="pushButton_extCircle">
<property name="margin"> <property name="text">
<number>6</number> <string>Create Circle</string>
</property> </property>
<item row="2" column="1"> </widget>
<widget class="QLineEdit" name="neighborNodesOpinion_TF"> </item>
<property name="toolTip"> <item>
<string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Average opinion of neighbor nodes about this identity. Negative is bad,&lt;/p&gt;&lt;p&gt;positive is good. Zero is neutral.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string> <widget class="QPushButton" name="pushButton_editCircle">
</property> <property name="text">
<property name="readOnly"> <string>Edit Circle</string>
<bool>true</bool> </property>
</property> </widget>
</widget> </item>
</item> <item>
<item row="1" column="0"> <spacer name="horizontalSpacer">
<widget class="QLabel" name="label_6"> <property name="orientation">
<property name="text"> <enum>Qt::Horizontal</enum>
<string>Your opinion:</string> </property>
</property> <property name="sizeHint" stdset="0">
</widget> <size>
</item> <width>40</width>
<item row="2" column="0"> <height>20</height>
<widget class="QLabel" name="label_5"> </size>
<property name="text"> </property>
<string>Neighbor nodes:</string> </spacer>
</property>
</widget>
</item>
<item row="1" column="1">
<widget class="QComboBox" name="ownOpinion_CB">
<property name="toolTip">
<string>&lt;!DOCTYPE HTML PUBLIC &quot;-//W3C//DTD HTML 4.0//EN&quot; &quot;http://www.w3.org/TR/REC-html40/strict.dtd&quot;&gt;
&lt;html&gt;&lt;head&gt;&lt;meta name=&quot;qrichtext&quot; content=&quot;1&quot; /&gt;&lt;style type=&quot;text/css&quot;&gt;
p, li { white-space: pre-wrap; }
&lt;/style&gt;&lt;/head&gt;&lt;body style=&quot; font-family:'Sans'; font-size:9pt; font-weight:400; font-style:normal;&quot;&gt;
&lt;p style=&quot; margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;Your own opinion about an identity rules the visibility of that identity for yourself and your friend nodes. Your own opinion is shared among friends and used to compute a reputation score: If your opinion about an identity is neutral, the reputation score is the average of your friend's opinions. If not, your own opinion gives the score.&lt;/p&gt;
&lt;p style=&quot; margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;The overall score is used in chat lobbies, forums and channels to decide on the actions to take for each specific identity. When the overall score is lower than -0.6, the identity is banned, which prevents all messages and forums/channels authored by this identity to be forwarded, both ways. Some forums also have special anti-spam flags that require a higher reputation level, making them more sensitive to bad opinions. Banned identities gradually lose their activity and eventually disappear (after 30 days). &lt;/p&gt;
&lt;p style=&quot;-qt-paragraph-type:empty; margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;&lt;br /&gt;&lt;/p&gt;
&lt;p style=&quot;-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
</property>
<property name="currentIndex">
<number>0</number>
</property>
<item>
<property name="text">
<string>Negative</string>
</property>
<property name="icon">
<iconset>
<normaloff>../icons/yellow_biohazard64.png</normaloff>../icons/yellow_biohazard64.png</iconset>
</property>
</item>
<item>
<property name="text">
<string>Neutral</string>
</property>
</item>
<item>
<property name="text">
<string>Positive</string>
</property>
</item>
</widget>
</item>
<item row="3" column="1">
<widget class="QLineEdit" name="overallOpinion_TF">
<property name="toolTip">
<string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Overall reputation score, accounting for yours and your friends'.&lt;/p&gt;&lt;p&gt;Negative is bad, positive is good. Zero is neutral. If the score is too low,&lt;/p&gt;&lt;p&gt;the identity is flagged as bad, and will be filtered out in forums, chat lobbies,&lt;/p&gt;&lt;p&gt;channels, etc.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
</property>
<property name="readOnly">
<bool>true</bool>
</property>
</widget>
</item>
<item row="3" column="0">
<widget class="QLabel" name="label_2">
<property name="font">
<font>
<weight>75</weight>
<bold>true</bold>
</font>
</property>
<property name="text">
<string>Overall:</string>
</property>
</widget>
</item>
</layout>
</item> </item>
</layout> </layout>
</widget> </item>
</item> <item row="1" column="0">
<item> <widget class="QTreeWidget" name="treeWidget_membership">
<spacer name="verticalSpacer"> <property name="contextMenuPolicy">
<property name="orientation"> <enum>Qt::CustomContextMenu</enum>
<enum>Qt::Vertical</enum> </property>
</property> <property name="sortingEnabled">
<property name="sizeType"> <bool>true</bool>
<enum>QSizePolicy::Expanding</enum> </property>
</property> <column>
<property name="sizeHint" stdset="0"> <property name="text">
<size> <string>Name</string>
<width>20</width> </property>
<height>40</height> </column>
</size> <column>
</property> <property name="text">
</spacer> <string>IDs</string>
</item> </property>
</layout> </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>
</widget> </widget>
</item> </item>
</layout> </layout>
<action name="editIdentity"> <action name="editIdentity">
<property name="icon"> <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> <normaloff>:/images/edit_16.png</normaloff>:/images/edit_16.png</iconset>
</property> </property>
<property name="text"> <property name="text">
@ -605,7 +666,7 @@ p, li { white-space: pre-wrap; }
</action> </action>
<action name="removeIdentity"> <action name="removeIdentity">
<property name="icon"> <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> <normaloff>:/images/delete.png</normaloff>:/images/delete.png</iconset>
</property> </property>
<property name="text"> <property name="text">
@ -614,7 +675,7 @@ p, li { white-space: pre-wrap; }
</action> </action>
<action name="chatIdentity"> <action name="chatIdentity">
<property name="icon"> <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> <normaloff>:/images/toaster/chat.png</normaloff>:/images/toaster/chat.png</iconset>
</property> </property>
<property name="text"> <property name="text">
@ -651,7 +712,7 @@ p, li { white-space: pre-wrap; }
<tabstop>idTreeWidget</tabstop> <tabstop>idTreeWidget</tabstop>
</tabstops> </tabstops>
<resources> <resources>
<include location="../images.qrc"/> <include location="../../../../../trunk/retroshare-gui/src/gui/images.qrc"/>
</resources> </resources>
<connections/> <connections/>
</ui> </ui>

View file

@ -95,9 +95,9 @@
#include "gui/gxschannels/GxsChannelDialog.h" #include "gui/gxschannels/GxsChannelDialog.h"
#include "gui/gxsforums/GxsForumsDialog.h" #include "gui/gxsforums/GxsForumsDialog.h"
#include "gui/Identity/IdDialog.h" #include "gui/Identity/IdDialog.h"
#ifdef RS_USE_CIRCLES //#ifdef RS_USE_CIRCLES
#include "gui/Circles/CirclesDialog.h" //#include "gui/Circles/CirclesDialog.h"
#endif //#endif
#ifdef RS_USE_WIKI #ifdef RS_USE_WIKI
#include "gui/WikiPoos/WikiDialog.h" #include "gui/WikiPoos/WikiDialog.h"
#endif #endif
@ -359,7 +359,7 @@ void MainWindow::initStackedPage()
addPage(newsFeed = new NewsFeed(ui->stackPages), grp, &notify); addPage(newsFeed = new NewsFeed(ui->stackPages), grp, &notify);
addPage(friendsDialog = new FriendsDialog(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; PeopleDialog *peopleDialog = NULL;
addPage(peopleDialog = new PeopleDialog(ui->stackPages), grp, &notify); addPage(peopleDialog = new PeopleDialog(ui->stackPages), grp, &notify);
#endif #endif
@ -367,10 +367,10 @@ void MainWindow::initStackedPage()
IdDialog *idDialog = NULL; IdDialog *idDialog = NULL;
addPage(idDialog = new IdDialog(ui->stackPages), grp, &notify); addPage(idDialog = new IdDialog(ui->stackPages), grp, &notify);
#ifdef RS_USE_CIRCLES //#ifdef RS_USE_CIRCLES
CirclesDialog *circlesDialog = NULL; // CirclesDialog *circlesDialog = NULL;
addPage(circlesDialog = new CirclesDialog(ui->stackPages), grp, &notify); // addPage(circlesDialog = new CirclesDialog(ui->stackPages), grp, &notify);
#endif //#endif
addPage(transfersDialog = new TransfersDialog(ui->stackPages), grp, &notify); addPage(transfersDialog = new TransfersDialog(ui->stackPages), grp, &notify);
addPage(chatLobbyDialog = new ChatLobbyWidget(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) { if (_circle_details != details) {
_circle_details=details; _circle_details=details;
typedef std::set<RsGxsId>::iterator itUnknownPeers; typedef std::set<RsGxsId>::iterator itUnknownPeers;
for (itUnknownPeers it = _circle_details.mUnknownPeers.begin() for (itUnknownPeers it = _circle_details.mAllowedAnonPeers.begin()
; it != _circle_details.mUnknownPeers.end() ; it != _circle_details.mAllowedAnonPeers.end()
; ++it) { ; ++it) {
RsGxsId gxs_id = *it; RsGxsId gxs_id = *it;
if(!gxs_id.isNull()) { if(!gxs_id.isNull()) {
@ -63,15 +63,14 @@ void CircleWidget::updateData(const RsGroupMetaData& gxs_group_info
}//if(!gxs_id.isNull()) }//if(!gxs_id.isNull())
}//for (itUnknownPeers it = _circle_details.mUnknownPeers.begin() }//for (itUnknownPeers it = _circle_details.mUnknownPeers.begin()
typedef std::map<RsPgpId, std::list<RsGxsId> >::const_iterator itAllowedPeers; typedef std::map<RsPgpId, std::set<RsGxsId> >::const_iterator itAllowedPeers;
for (itAllowedPeers it = _circle_details.mAllowedPeers.begin() for (itAllowedPeers it = _circle_details.mAllowedSignedPeers.begin() ; it != _circle_details.mAllowedSignedPeers.end() ; ++it )
; it != _circle_details.mAllowedPeers.end() {
; ++it ) {
RsPgpId pgp_id = it->first; RsPgpId pgp_id = it->first;
emit askForPGPIdentityWidget(pgp_id); emit askForPGPIdentityWidget(pgp_id);
std::list<RsGxsId> gxs_id_list = it->second; std::set<RsGxsId> gxs_id_list = it->second;
typedef std::list<RsGxsId>::const_iterator itGxsId; typedef std::set<RsGxsId>::const_iterator itGxsId;
for (itGxsId curs=gxs_id_list.begin() for (itGxsId curs=gxs_id_list.begin()
; curs != gxs_id_list.end() ; curs != gxs_id_list.end()
; ++curs) { ; ++curs) {

View file

@ -61,7 +61,7 @@ void IdentityWidget::updateData(const RsGxsIdGroup &gxs_group_info)
_haveGXSId = true; _haveGXSId = true;
m_myName = QString::fromUtf8(_group_info.mMeta.mGroupName.c_str()); m_myName = QString::fromUtf8(_group_info.mMeta.mGroupName.c_str());
ui->labelName->setText(m_myName); ui->labelName->setText(m_myName);
if (_havePGPDetail) { if (_havePGPDetail) {
ui->labelName->setToolTip(tr("GXS name:").append(" "+m_myName).append("\n") ui->labelName->setToolTip(tr("GXS name:").append(" "+m_myName).append("\n")
.append(tr("PGP name:").append(" "+_nickname))); .append(tr("PGP name:").append(" "+_nickname)));
@ -75,17 +75,23 @@ void IdentityWidget::updateData(const RsGxsIdGroup &gxs_group_info)
ui->labelGXSId->setToolTip(tr("GXS id:").append(" "+_gxsId)); ui->labelGXSId->setToolTip(tr("GXS id:").append(" "+_gxsId));
if (!_havePGPDetail) { if (!_havePGPDetail) {
QFont font = ui->labelName->font(); QFont font = ui->labelName->font();
font.setItalic(false); font.setItalic(false);
ui->labelName->setFont(font); ui->labelName->setFont(font);
_keyId=QString::fromStdString(_group_info.mMeta.mGroupId.toStdString()); _keyId=QString::fromStdString(_group_info.mMeta.mGroupId.toStdString());
ui->labelKeyId->setText(_keyId); ui->labelKeyId->setText(_keyId);
ui->labelKeyId->setToolTip(tr("GXS id:").append(" "+_keyId)); ui->labelKeyId->setToolTip(tr("GXS id:").append(" "+_keyId));
ui->labelKeyId->setVisible(false); ui->labelKeyId->setVisible(false);
/// (TODO) Get real ident icon
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));
/// (TODO) Get real ident icon
QImage image = GxsIdDetails::makeDefaultIcon(RsGxsId(_group_info.mMeta.mGroupId));
if (_avatar != image) { if (_avatar != image) {
_avatar = image; _avatar = image;
_scene->clear(); _scene->clear();
@ -122,13 +128,14 @@ void IdentityWidget::updateData(const RsPeerDetails &pgp_details)
ui->labelKeyId->setToolTip(tr("PGP id:").append(" "+_keyId)); ui->labelKeyId->setToolTip(tr("PGP id:").append(" "+_keyId));
QPixmap avatar; QPixmap avatar;
AvatarDefs::getAvatarFromGpgId(_details.gpg_id.toStdString(), avatar); /*AvatarDefs::getAvatarFromGpgId(_details.gpg_id, avatar);
if (_avatar != avatar.toImage()) { if (_avatar != avatar.toImage()) {
_avatar = avatar.toImage(); _avatar = avatar.toImage();
_scene->clear(); _scene->clear();
_scene->addPixmap(avatar.scaled(ui->graphicsView->width(),ui->graphicsView->height())); _scene->addPixmap(avatar.scaled(ui->graphicsView->width(),ui->graphicsView->height()));
emit imageUpdated(); emit imageUpdated();
}//if (_avatar != avatar.toImage()) }*///if (_avatar != avatar.toImage())
//}//if (_details != gpg_details) //}//if (_details != gpg_details)
} }
@ -200,3 +207,4 @@ void IdentityWidget::pbAdd_clicked()
{ {
emit addButtonClicked(); emit addButtonClicked();
} }

View file

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

View file

@ -26,11 +26,16 @@
#include "gui/Circles/CreateCircleDialog.h" #include "gui/Circles/CreateCircleDialog.h"
#include "gui/common/FlowLayout.h" #include "gui/common/FlowLayout.h"
#include "gui/settings/rsharesettings.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/rspeers.h"
#include "retroshare/rsidentity.h" #include "retroshare/rsidentity.h"
#include "retroshare/rsgxscircles.h" #include "retroshare/rsgxscircles.h"
#include "retroshare/rsgxsflags.h" #include "retroshare/rsgxsflags.h"
#include "retroshare/rsmsgs.h"
#include "retroshare/rsids.h"
#include <iostream> #include <iostream>
#include <QMenu> #include <QMenu>
@ -56,6 +61,9 @@ PeopleDialog::PeopleDialog(QWidget *parent)
mIdentityQueue = new TokenQueue(rsIdentity->getTokenService(), this); mIdentityQueue = new TokenQueue(rsIdentity->getTokenService(), this);
mCirclesQueue = new TokenQueue(rsGxsCircles->getTokenService(), this); mCirclesQueue = new TokenQueue(rsGxsCircles->getTokenService(), this);
tabWidget->removeTab(1);
//need erase QtCreator Layout first(for Win) //need erase QtCreator Layout first(for Win)
delete idExternal->layout(); delete idExternal->layout();
delete idInternal->layout(); delete idInternal->layout();
@ -74,11 +82,11 @@ PeopleDialog::PeopleDialog(QWidget *parent)
{//First Get Item created in Qt Designer for Internal {//First Get Item created in Qt Designer for Internal
int count = idInternal->children().count(); int count = idInternal->children().count();
for (int curs = 0; curs < count; ++curs){ for (int curs = 0; curs < count; ++curs){
QObject *obj = idInternal->children().at(curs); QObject *obj = idInternal->children().at(curs);
QWidget *wid = qobject_cast<QWidget *>(obj); QWidget *wid = qobject_cast<QWidget *>(obj);
if (wid) _flowLayoutInt->addWidget(wid); if (wid) _flowLayoutInt->addWidget(wid);
}//for (int curs = 0; curs < count; ++curs) }//for (int curs = 0; curs < count; ++curs)
}//End First Get Item created in Qt Designer for Internal }//End First Get Item created in Qt Designer for Internal
pictureFlowWidgetExternal->setAcceptDrops(true); pictureFlowWidgetExternal->setAcceptDrops(true);
@ -418,6 +426,45 @@ void PeopleDialog::iw_AddButtonClickedExt()
+ ";" + QString::fromStdString(dest->groupInfo().mMeta.mGroupId.toStdString())); + ";" + QString::fromStdString(dest->groupInfo().mMeta.mGroupId.toStdString()));
}//for( itCurs =_ext_circles_widgets.begin(); }//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()); contextMnu.exec(QCursor::pos());
}//if (dest) }//if (dest)
} }
@ -469,7 +516,7 @@ void PeopleDialog::addToCircleExt()
dlg.addMember(idWidget->groupInfo()); dlg.addMember(idWidget->groupInfo());
}//if((itFound=_gxs_identity_widgets.find(gxs_id)) != _gxs_identity_widgets.end()) }//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(); dlg.exec();
}//if((itFound=_ext_circles_widgets.find(groupId)) != _ext_circles_widgets.end()) }//if((itFound=_ext_circles_widgets.find(groupId)) != _ext_circles_widgets.end())
}//if (action) }//if (action)
@ -498,12 +545,79 @@ void PeopleDialog::addToCircleInt()
dlg.addMember(idWidget->keyId(), idWidget->idtype(), idWidget->nickname()); dlg.addMember(idWidget->keyId(), idWidget->idtype(), idWidget->nickname());
}//if((itFound=_pgp_identity_widgets.find(pgp_id)) != _pgp_identity_widgets.end()) }//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(); dlg.exec();
}//if((itFound=_ext_circles_widgets.find(groupId)) != _ext_circles_widgets.end()) }//if((itFound=_ext_circles_widgets.find(groupId)) != _ext_circles_widgets.end())
}//if (action) }//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) void PeopleDialog::cw_askForGXSIdentityWidget(RsGxsId gxs_id)
{ {
CircleWidget *dest = CircleWidget *dest =
@ -607,7 +721,7 @@ void PeopleDialog::fl_flowLayoutItemDroppedExt(QList<FlowLayoutItem *>flListItem
if (bCreateNewCircle){ if (bCreateNewCircle){
dlg.editNewId(true); dlg.editNewId(true);
} else {//if (bCreateNewCircle) } else {//if (bCreateNewCircle)
dlg.editExistingId(cirDest->groupInfo().mGroupId, false); dlg.editExistingId(cirDest->groupInfo().mGroupId, false,false);
}//else (bCreateNewCircle) }//else (bCreateNewCircle)
dlg.exec(); dlg.exec();
@ -667,7 +781,7 @@ void PeopleDialog::fl_flowLayoutItemDroppedInt(QList<FlowLayoutItem *>flListItem
if (bCreateNewCircle){ if (bCreateNewCircle){
dlg.editNewId(false); dlg.editNewId(false);
} else {//if (bCreateNewCircle) } else {//if (bCreateNewCircle)
dlg.editExistingId(cirDest->groupInfo().mGroupId, false); dlg.editExistingId(cirDest->groupInfo().mGroupId, false,false);
}//else (bCreateNewCircle) }//else (bCreateNewCircle)
dlg.exec(); dlg.exec();
@ -768,7 +882,7 @@ void PeopleDialog::pf_dropEventOccursExt(QDropEvent *event)
QWidget *wid = QWidget *wid =
qobject_cast<QWidget *>(event->source());//QT5 return QObject qobject_cast<QWidget *>(event->source());//QT5 return QObject
FlowLayout *layout = NULL; FlowLayout *layout;
if (wid) layout = if (wid) layout =
qobject_cast<FlowLayout *>(wid->layout()); qobject_cast<FlowLayout *>(wid->layout());
if (layout) { if (layout) {
@ -808,7 +922,7 @@ void PeopleDialog::pf_dropEventOccursExt(QDropEvent *event)
if (bCreateNewCircle){ if (bCreateNewCircle){
dlg.editNewId(true); dlg.editNewId(true);
} else {//if (bCreateNewCircle) } else {//if (bCreateNewCircle)
dlg.editExistingId(cirDest->groupInfo().mGroupId, false); dlg.editExistingId(cirDest->groupInfo().mGroupId, false,false);
}//else (bCreateNewCircle) }//else (bCreateNewCircle)
dlg.exec(); dlg.exec();
@ -858,7 +972,7 @@ void PeopleDialog::pf_dropEventOccursInt(QDropEvent *event)
QWidget *wid = QWidget *wid =
qobject_cast<QWidget *>(event->source());//QT5 return QObject qobject_cast<QWidget *>(event->source());//QT5 return QObject
FlowLayout *layout = NULL; FlowLayout *layout;
if (wid) layout = if (wid) layout =
qobject_cast<FlowLayout *>(wid->layout()); qobject_cast<FlowLayout *>(wid->layout());
if (layout) { if (layout) {
@ -898,7 +1012,7 @@ void PeopleDialog::pf_dropEventOccursInt(QDropEvent *event)
if (bCreateNewCircle){ if (bCreateNewCircle){
dlg.editNewId(false); dlg.editNewId(false);
} else {//if (bCreateNewCircle) } else {//if (bCreateNewCircle)
dlg.editExistingId(cirDest->groupInfo().mGroupId, false); dlg.editExistingId(cirDest->groupInfo().mGroupId, false,false);
}//else (bCreateNewCircle) }//else (bCreateNewCircle)
dlg.exec(); dlg.exec();

View file

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

View file

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

View file

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

View file

@ -103,7 +103,7 @@ void GxsGroupDialog::init()
connect(ui.addLogoButton, SIGNAL(clicked() ), this , SLOT(addGroupLogo())); connect(ui.addLogoButton, SIGNAL(clicked() ), this , SLOT(addGroupLogo()));
ui.typePublic->setChecked(true); ui.typePublic->setChecked(true);
ui.typePublic_3->setChecked(true); ui.distributionValueLabel->setText(tr("Public"));
updateCircleOptions(); updateCircleOptions();
connect(ui.typePublic, SIGNAL(clicked()), this , SLOT(updateCircleOptions())); connect(ui.typePublic, SIGNAL(clicked()), this , SLOT(updateCircleOptions()));
@ -218,23 +218,25 @@ void GxsGroupDialog::setupDefaults()
if (mDefaultsFlags & GXS_GROUP_DEFAULTS_DISTRIB_PUBLIC) if (mDefaultsFlags & GXS_GROUP_DEFAULTS_DISTRIB_PUBLIC)
{ {
ui.typePublic->setChecked(true); 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) else if (mDefaultsFlags & GXS_GROUP_DEFAULTS_DISTRIB_GROUP)
{ {
ui.typeGroup->setChecked(true); 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) else if (mDefaultsFlags & GXS_GROUP_DEFAULTS_DISTRIB_LOCAL)
{ {
ui.typeLocal->setChecked(true); ui.typeLocal->setChecked(true);
ui.typeLocal_3->setChecked(true); ui.distributionValueLabel->setText(tr("Limited to your friends"));
ui.distributionCircleComboBox->setVisible(false) ;
} }
else else
{ {
// default // default
ui.typePublic->setChecked(true); ui.typePublic->setChecked(true);
ui.typePublic_3->setChecked(true);
} }
} }
@ -285,31 +287,36 @@ void GxsGroupDialog::setupDefaults()
if (mDefaultsFlags & GXS_GROUP_DEFAULTS_COMMENTS_YES) if (mDefaultsFlags & GXS_GROUP_DEFAULTS_COMMENTS_YES)
{ {
ui.comments_allowed->setChecked(true); ui.comments_allowed->setChecked(true);
ui.comments_allowed_3->setChecked(true); ui.commentsValueLabel->setText(tr("Allowed"));
} }
else if (mDefaultsFlags & GXS_GROUP_DEFAULTS_COMMENTS_NO) else if (mDefaultsFlags & GXS_GROUP_DEFAULTS_COMMENTS_NO)
{ {
ui.comments_no->setChecked(true); ui.comments_no->setChecked(true);
ui.comments_no_3->setChecked(true); ui.commentsValueLabel->setText(tr("Disallowed"));
} }
else else
{ {
// default // default
ui.comments_no->setChecked(true); 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_trackMessages->setChecked((bool)(mDefaultsFlags & GXS_GROUP_DEFAULTS_ANTISPAM_TRACK));
ui.antiSpam_signedIds->setChecked((bool)(mDefaultsFlags & GXS_GROUP_DEFAULTS_ANTISPAM_FAVOR_PGP)); 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 #ifndef RS_USE_CIRCLES
ui.typeGroup->setEnabled(false); ui.typeGroup->setEnabled(false);
ui.typeLocal->setEnabled(false);
ui.typeGroup_3->setEnabled(false); ui.typeGroup_3->setEnabled(false);
ui.typeLocal_3->setEnabled(false); ui.typeLocal_3->setEnabled(false);
#endif #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() void GxsGroupDialog::setupVisibility()
@ -322,10 +329,12 @@ void GxsGroupDialog::setupVisibility()
ui.groupDesc->setVisible(mEnabledFlags & GXS_GROUP_FLAGS_DESCRIPTION); ui.groupDesc->setVisible(mEnabledFlags & GXS_GROUP_FLAGS_DESCRIPTION);
ui.distribGroupBox->setVisible(mEnabledFlags & GXS_GROUP_FLAGS_DISTRIBUTION); 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->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); ui.publishGroupBox->setVisible(mEnabledFlags & GXS_GROUP_FLAGS_PUBLISHSIGN);
@ -334,8 +343,9 @@ void GxsGroupDialog::setupVisibility()
ui.personalGroupBox->setVisible(mEnabledFlags & GXS_GROUP_FLAGS_PERSONALSIGN); ui.personalGroupBox->setVisible(mEnabledFlags & GXS_GROUP_FLAGS_PERSONALSIGN);
ui.commentGroupBox->setVisible(mEnabledFlags & GXS_GROUP_FLAGS_COMMENTS); 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); ui.extraFrame->setVisible(mEnabledFlags & GXS_GROUP_FLAGS_EXTRA);
} }
@ -363,10 +373,10 @@ void GxsGroupDialog::setupReadonly()
ui.idChooser->setEnabled(!(mReadonlyFlags & GXS_GROUP_FLAGS_PERSONALSIGN)); ui.idChooser->setEnabled(!(mReadonlyFlags & GXS_GROUP_FLAGS_PERSONALSIGN));
ui.distribGroupBox_2->setEnabled(!(mReadonlyFlags & GXS_GROUP_FLAGS_DISTRIBUTION)); //ui.distribGroupBox_2->setEnabled(!(mReadonlyFlags & GXS_GROUP_FLAGS_DISTRIBUTION));
ui.commentGroupBox_2->setEnabled(!(mReadonlyFlags & GXS_GROUP_FLAGS_COMMENTS)); //ui.commentGroupBox_2->setEnabled(!(mReadonlyFlags & GXS_GROUP_FLAGS_COMMENTS));
ui.spamProtection_GB->setEnabled(!(mReadonlyFlags & GXS_GROUP_FLAGS_ANTI_SPAM)); 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)); ui.extraFrame->setEnabled(!(mReadonlyFlags & GXS_GROUP_FLAGS_EXTRA));
#ifndef UNFINISHED #ifndef UNFINISHED
@ -417,9 +427,8 @@ void GxsGroupDialog::updateFromExistingMeta(const QString &description)
break; break;
case MODE_SHOW:{ case MODE_SHOW:{
ui.headerFrame->setHeaderText(QString::fromUtf8(mGrpMeta.mGroupName.c_str())); ui.headerFrame->setHeaderText(QString::fromUtf8(mGrpMeta.mGroupName.c_str()));
if (mPicture.isNull()) if (!mPicture.isNull())
return; ui.headerFrame->setHeaderImage(mPicture);
ui.headerFrame->setHeaderImage(mPicture);
} }
break; break;
case MODE_EDIT:{ case MODE_EDIT:{
@ -428,21 +437,27 @@ void GxsGroupDialog::updateFromExistingMeta(const QString &description)
} }
/* set description */ /* set description */
ui.groupDesc->setPlainText(description); ui.groupDesc->setPlainText(description);
QString distribution_string = "[Unknown]";
switch(mGrpMeta.mCircleType) switch(mGrpMeta.mCircleType)
{ {
case GXS_CIRCLE_TYPE_YOUREYESONLY: case GXS_CIRCLE_TYPE_YOUREYESONLY:
ui.typeLocal->setChecked(true); 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.localComboBox->loadCircles(GXS_CIRCLE_CHOOSER_PERSONAL, mGrpMeta.mInternalCircle);
ui.distributionCircleComboBox->setVisible(true) ;
ui.distributionCircleComboBox->loadCircles(GXS_CIRCLE_CHOOSER_PERSONAL, mGrpMeta.mInternalCircle);
break; break;
case GXS_CIRCLE_TYPE_PUBLIC: case GXS_CIRCLE_TYPE_PUBLIC:
ui.typePublic->setChecked(true); ui.typePublic->setChecked(true);
ui.typePublic_3->setChecked(true); distribution_string = tr("Public") ;
ui.distributionCircleComboBox->setVisible(false) ;
break; break;
case GXS_CIRCLE_TYPE_EXTERNAL: case GXS_CIRCLE_TYPE_EXTERNAL:
ui.typeGroup->setChecked(true); 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); ui.circleComboBox->loadCircles(GXS_CIRCLE_CHOOSER_EXTERNAL, mGrpMeta.mCircleId);
break; break;
default: default:
@ -450,6 +465,7 @@ void GxsGroupDialog::updateFromExistingMeta(const QString &description)
std::cerr << std::endl; std::cerr << std::endl;
break; break;
} }
ui.distributionValueLabel->setText(distribution_string) ;
ui.idChooser->loadIds(0, mGrpMeta.mAuthorId); 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_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_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.SignEdIds->setChecked((bool)(signFlags & GXS_SERV::FLAG_AUTHOR_AUTHENTICATION_GPG) );
//ui.trackmessagesradioButton->setChecked((bool)(signFlags & GXS_SERV::FLAG_AUTHOR_AUTHENTICATION_TRACK_MESSAGES) ); //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) && if ((signFlags & GXS_SERV::FLAG_GROUP_SIGN_PUBLISH_THREADHEAD) &&
(signFlags & GXS_SERV::FLAG_AUTHOR_AUTHENTICATION_IFNOPUBSIGN)) (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->setChecked(true);
ui.comments_allowed_3->setChecked(true); ui.commentsValueLabel->setText("Allowed") ;
} }
else else
{ {
ui.comments_no->setChecked(true); ui.comments_no->setChecked(true);
ui.comments_no_3->setChecked(true); ui.commentsValueLabel->setText("Allowed") ;
} }
} }

View file

@ -7,31 +7,22 @@
<x>0</x> <x>0</x>
<y>0</y> <y>0</y>
<width>928</width> <width>928</width>
<height>400</height> <height>769</height>
</rect> </rect>
</property> </property>
<property name="windowTitle"> <property name="windowTitle">
<string notr="true">Create New</string> <string notr="true">Create New</string>
</property> </property>
<layout class="QGridLayout" name="gridLayout_5"> <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"> <property name="horizontalSpacing">
<number>6</number> <number>6</number>
</property> </property>
<property name="verticalSpacing"> <property name="verticalSpacing">
<number>0</number> <number>0</number>
</property> </property>
<property name="margin">
<number>0</number>
</property>
<item row="0" column="0"> <item row="0" column="0">
<widget class="HeaderFrame" name="headerFrame"/> <widget class="HeaderFrame" name="headerFrame"/>
</item> </item>
@ -44,7 +35,7 @@
<enum>QFrame::Raised</enum> <enum>QFrame::Raised</enum>
</property> </property>
<property name="currentIndex"> <property name="currentIndex">
<number>0</number> <number>1</number>
</property> </property>
<widget class="QWidget" name="createmode"> <widget class="QWidget" name="createmode">
<layout class="QGridLayout" name="gridLayout"> <layout class="QGridLayout" name="gridLayout">
@ -57,16 +48,7 @@
<property name="spacing"> <property name="spacing">
<number>0</number> <number>0</number>
</property> </property>
<property name="leftMargin"> <property name="margin">
<number>4</number>
</property>
<property name="topMargin">
<number>4</number>
</property>
<property name="rightMargin">
<number>4</number>
</property>
<property name="bottomMargin">
<number>4</number> <number>4</number>
</property> </property>
<item> <item>
@ -130,16 +112,7 @@
<property name="spacing"> <property name="spacing">
<number>9</number> <number>9</number>
</property> </property>
<property name="leftMargin"> <property name="margin">
<number>3</number>
</property>
<property name="topMargin">
<number>3</number>
</property>
<property name="rightMargin">
<number>3</number>
</property>
<property name="bottomMargin">
<number>3</number> <number>3</number>
</property> </property>
<item> <item>
@ -239,16 +212,7 @@
</property> </property>
<widget class="QWidget" name="dockWidgetContents"> <widget class="QWidget" name="dockWidgetContents">
<layout class="QGridLayout" name="_2"> <layout class="QGridLayout" name="_2">
<property name="leftMargin"> <property name="margin">
<number>0</number>
</property>
<property name="topMargin">
<number>0</number>
</property>
<property name="rightMargin">
<number>0</number>
</property>
<property name="bottomMargin">
<number>0</number> <number>0</number>
</property> </property>
<property name="spacing"> <property name="spacing">
@ -635,188 +599,12 @@
</widget> </widget>
<widget class="QWidget" name="showmode"> <widget class="QWidget" name="showmode">
<layout class="QGridLayout" name="gridLayout_6"> <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"> <item row="0" column="0">
<widget class="QGroupBox" name="groupBox_2"> <widget class="QGroupBox" name="groupBox_2">
<property name="title"> <property name="title">
<string>Info</string> <string>Info</string>
</property> </property>
<layout class="QGridLayout" name="_3"> <layout class="QGridLayout" name="gridLayout_2">
<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"> <item row="0" column="0">
<widget class="QLabel" name="label_3"> <widget class="QLabel" name="label_3">
<property name="text"> <property name="text">
@ -824,48 +612,13 @@
</property> </property>
</widget> </widget>
</item> </item>
<item row="0" column="2"> <item row="0" column="1">
<widget class="QLineEdit" name="nameline"> <widget class="QLineEdit" name="nameline">
<property name="readOnly"> <property name="readOnly">
<bool>true</bool> <bool>true</bool>
</property> </property>
</widget> </widget>
</item> </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"> <item row="1" column="0">
<widget class="QLabel" name="label_10"> <widget class="QLabel" name="label_10">
<property name="text"> <property name="text">
@ -873,11 +626,8 @@
</property> </property>
</widget> </widget>
</item> </item>
<item row="2" column="2"> <item row="1" column="1">
<widget class="QLineEdit" name="postsline"> <widget class="QLineEdit" name="popline">
<property name="text">
<string/>
</property>
<property name="readOnly"> <property name="readOnly">
<bool>true</bool> <bool>true</bool>
</property> </property>
@ -890,20 +640,27 @@
</property> </property>
</widget> </widget>
</item> </item>
<item row="8" column="0"> <item row="2" column="1">
<widget class="QLabel" name="commentslabel"> <widget class="QLineEdit" name="postsline">
<property name="text"> <property name="text">
<string>Comments</string> <string/>
</property>
<property name="readOnly">
<bool>true</bool>
</property> </property>
</widget> </widget>
</item> </item>
<item row="7" column="0"> <item row="3" column="0">
<widget class="QLabel" name="label_5"> <widget class="QLabel" name="label_11">
<property name="text"> <property name="text">
<string>Type</string> <string>Last Post</string>
</property> </property>
<property name="alignment"> </widget>
<set>Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter</set> </item>
<item row="3" column="1">
<widget class="QLineEdit" name="lastpostline">
<property name="readOnly">
<bool>true</bool>
</property> </property>
</widget> </widget>
</item> </item>
@ -914,66 +671,97 @@
</property> </property>
</widget> </widget>
</item> </item>
<item row="4" column="2"> <item row="4" column="1">
<widget class="GxsIdLabel" name="authorLabel"> <widget class="GxsIdLabel" name="authorLabel">
<property name="text"> <property name="text">
<string>GxsIdLabel</string> <string>GxsIdLabel</string>
</property> </property>
</widget> </widget>
</item> </item>
<item row="10" column="0"> <item row="5" column="0">
<widget class="QLabel" name="label_8"> <widget class="QLabel" name="label_4">
<property name="text"> <property name="text">
<string>Anti spam</string> <string>ID</string>
</property> </property>
</widget> </widget>
</item> </item>
<item row="10" column="2"> <item row="5" column="1">
<widget class="QGroupBox" name="spamProtection_GB_2"> <widget class="QLineEdit" name="IDline">
<property name="title"> <property name="readOnly">
<string/> <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">
<item>
<widget class="QLabel" name="distributionValueLabel">
<property name="text">
<string>TextLabel</string>
</property>
</widget>
</item>
<item>
<widget class="GxsCircleChooser" name="distributionCircleComboBox">
<property name="sizePolicy">
<sizepolicy hsizetype="MinimumExpanding" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
</widget>
</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> </property>
<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">
<property name="text">
<string>PGP-signed ids</string>
</property>
</widget>
</item>
<item>
<widget class="QRadioButton" name="antiSpam_trackMessages_2">
<property name="text">
<string>Track of Posts</string>
</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>
</widget> </widget>
</item> </item>
</layout> </layout>

View file

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

View file

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

View file

@ -28,6 +28,7 @@
#include <QPushButton> #include <QPushButton>
#include <retroshare/rsgxsforums.h> #include <retroshare/rsgxsforums.h>
#include <retroshare/rsgxscircles.h>
#include "gui/settings/rsharesettings.h" #include "gui/settings/rsharesettings.h"
#include "gui/RetroShareLink.h" #include "gui/RetroShareLink.h"
@ -43,6 +44,7 @@
#define CREATEGXSFORUMMSG_FORUMINFO 1 #define CREATEGXSFORUMMSG_FORUMINFO 1
#define CREATEGXSFORUMMSG_PARENTMSG 2 #define CREATEGXSFORUMMSG_PARENTMSG 2
#define CREATEGXSFORUMMSG_CIRCLENFO 3
//#define ENABLE_GENERATE //#define ENABLE_GENERATE
@ -57,6 +59,7 @@ CreateGxsForumMsg::CreateGxsForumMsg(const RsGxsGroupId &fId, const RsGxsMessage
/* Setup Queue */ /* Setup Queue */
mForumQueue = new TokenQueue(rsGxsForums->getTokenService(), this); mForumQueue = new TokenQueue(rsGxsForums->getTokenService(), this);
mCirclesQueue = new TokenQueue(rsGxsCircles->getTokenService(), this);
/* Setup UI helper */ /* Setup UI helper */
mStateHelper = new UIStateHelper(this); mStateHelper = new UIStateHelper(this);
@ -100,6 +103,7 @@ CreateGxsForumMsg::CreateGxsForumMsg(const RsGxsGroupId &fId, const RsGxsMessage
mParentMsgLoaded = false; mParentMsgLoaded = false;
mForumMetaLoaded = false; mForumMetaLoaded = false;
mForumCircleLoaded = false;
newMsg(); newMsg();
@ -112,6 +116,7 @@ CreateGxsForumMsg::CreateGxsForumMsg(const RsGxsGroupId &fId, const RsGxsMessage
CreateGxsForumMsg::~CreateGxsForumMsg() CreateGxsForumMsg::~CreateGxsForumMsg()
{ {
delete(mForumQueue); delete(mForumQueue);
delete(mCirclesQueue);
} }
void CreateGxsForumMsg::newMsg() void CreateGxsForumMsg::newMsg()
@ -121,7 +126,8 @@ void CreateGxsForumMsg::newMsg()
mForumMetaLoaded = false; mForumMetaLoaded = false;
/* fill in the available OwnIds for signing */ /* 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()); ui.idChooser->loadIds(IDCHOOSER_ID_REQUIRED, RsGxsId());
@ -143,8 +149,7 @@ void CreateGxsForumMsg::newMsg()
std::list<RsGxsGroupId> groupIds; std::list<RsGxsGroupId> groupIds;
groupIds.push_back(mForumId); groupIds.push_back(mForumId);
std::cerr << "ForumsV2Dialog::newMsg() Requesting Group Summary(" << mForumId << ")"; //std::cerr << "ForumsV2Dialog::newMsg() Requesting Group Summary(" << mForumId << ")"<< std::endl;
std::cerr << std::endl;
uint32_t token; uint32_t token;
mForumQueue->requestGroupInfo(token, RS_TOKREQ_ANSTYPE_SUMMARY, opts, groupIds, CREATEGXSFORUMMSG_FORUMINFO); mForumQueue->requestGroupInfo(token, RS_TOKREQ_ANSTYPE_SUMMARY, opts, groupIds, CREATEGXSFORUMMSG_FORUMINFO);
@ -163,8 +168,8 @@ void CreateGxsForumMsg::newMsg()
std::vector<RsGxsMessageId> &vect = msgIds[mForumId]; std::vector<RsGxsMessageId> &vect = msgIds[mForumId];
vect.push_back(mParentId); vect.push_back(mParentId);
std::cerr << "ForumsV2Dialog::newMsg() Requesting Parent Summary(" << mParentId << ")"; //std::cerr << "ForumsV2Dialog::newMsg() Requesting Parent Summary(" << mParentId << ")";
std::cerr << std::endl; //std::cerr << std::endl;
uint32_t token; uint32_t token;
mForumQueue->requestMsgInfo(token, RS_TOKREQ_ANSTYPE_DATA, opts, msgIds, CREATEGXSFORUMMSG_PARENTMSG); mForumQueue->requestMsgInfo(token, RS_TOKREQ_ANSTYPE_DATA, opts, msgIds, CREATEGXSFORUMMSG_PARENTMSG);
@ -178,8 +183,8 @@ void CreateGxsForumMsg::loadFormInformation()
mStateHelper->setActive(CREATEGXSFORUMMSG_PARENTMSG, true); mStateHelper->setActive(CREATEGXSFORUMMSG_PARENTMSG, true);
mStateHelper->setLoading(CREATEGXSFORUMMSG_PARENTMSG, false); mStateHelper->setLoading(CREATEGXSFORUMMSG_PARENTMSG, false);
} else { } else {
std::cerr << "CreateGxsForumMsg::loadMsgInformation() ParentMsg not Loaded Yet"; //std::cerr << "CreateGxsForumMsg::loadMsgInformation() ParentMsg not Loaded Yet";
std::cerr << std::endl; //std::cerr << std::endl;
mStateHelper->setActive(CREATEGXSFORUMMSG_PARENTMSG, false); mStateHelper->setActive(CREATEGXSFORUMMSG_PARENTMSG, false);
@ -194,18 +199,18 @@ void CreateGxsForumMsg::loadFormInformation()
mStateHelper->setActive(CREATEGXSFORUMMSG_FORUMINFO, true); mStateHelper->setActive(CREATEGXSFORUMMSG_FORUMINFO, true);
mStateHelper->setLoading(CREATEGXSFORUMMSG_FORUMINFO, false); mStateHelper->setLoading(CREATEGXSFORUMMSG_FORUMINFO, false);
} else { } else {
std::cerr << "CreateGxsForumMsg::loadMsgInformation() ForumMeta not Loaded Yet"; //std::cerr << "CreateGxsForumMsg::loadMsgInformation() ForumMeta not Loaded Yet";
std::cerr << std::endl; //std::cerr << std::endl;
mStateHelper->setActive(CREATEGXSFORUMMSG_FORUMINFO, false); mStateHelper->setActive(CREATEGXSFORUMMSG_FORUMINFO, false);
return; return;
} }
std::cerr << "CreateGxsForumMsg::loadMsgInformation() Data Available!"; //std::cerr << "CreateGxsForumMsg::loadMsgInformation() Data Available!";
std::cerr << std::endl; //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) if(mForumMeta.mSignFlags & GXS_SERV::FLAG_AUTHOR_AUTHENTICATION_GPG)
ui.idChooser->setFlags(IDCHOOSER_ID_REQUIRED | IDCHOOSER_NON_ANONYMOUS) ; ui.idChooser->setFlags(IDCHOOSER_ID_REQUIRED | IDCHOOSER_NON_ANONYMOUS) ;
@ -297,39 +302,39 @@ void CreateGxsForumMsg::createMsg()
if (ui.signBox->isChecked()) { if (ui.signBox->isChecked()) {
RsGxsId authorId; RsGxsId authorId;
switch (ui.idChooser->getChosenId(authorId)) { switch (ui.idChooser->getChosenId(authorId)) {
case GxsIdChooser::KnowId: case GxsIdChooser::KnowId:
case GxsIdChooser::UnKnowId: case GxsIdChooser::UnKnowId:
msg.mMeta.mAuthorId = authorId; msg.mMeta.mAuthorId = authorId;
std::cerr << "CreateGxsForumMsg::createMsg() AuthorId: " << authorId; //std::cerr << "CreateGxsForumMsg::createMsg() AuthorId: " << authorId;
std::cerr << std::endl; //std::cerr << std::endl;
break; break;
case GxsIdChooser::None: case GxsIdChooser::None:
{ {
// This is ONLY for the case where no id exists yet // This is ONLY for the case where no id exists yet
// If an id exists, the chooser would not return None // If an id exists, the chooser would not return None
IdEditDialog dlg(this); IdEditDialog dlg(this);
dlg.setupNewId(false); dlg.setupNewId(false);
dlg.exec(); dlg.exec();
// fetch new id, we will then see if the identity creation was successful // fetch new id, we will then see if the identity creation was successful
std::list<RsGxsId> own_ids; std::list<RsGxsId> own_ids;
if(!rsIdentity->getOwnIds(own_ids) || own_ids.size() != 1) if(!rsIdentity->getOwnIds(own_ids) || own_ids.size() != 1)
return; return;
// we have only a single id, so we can use the first one // we have only a single id, so we can use the first one
authorId = own_ids.front(); authorId = own_ids.front();
break; break;
} }
case GxsIdChooser::NoId: case GxsIdChooser::NoId:
default: default:
std::cerr << "CreateGxsForumMsg::createMsg() ERROR GETTING AuthorId!"; std::cerr << "CreateGxsForumMsg::createMsg() ERROR GETTING AuthorId!";
std::cerr << std::endl; std::cerr << std::endl;
QMessageBox::warning(this, tr("RetroShare"),tr("Congrats, you found a bug!")+" "+QString(__FILE__)+":"+QString(__LINE__), QMessageBox::Ok, QMessageBox::Ok); QMessageBox::warning(this, tr("RetroShare"),tr("Congrats, you found a bug!")+" "+QString(__FILE__)+":"+QString(__LINE__), QMessageBox::Ok, QMessageBox::Ok);
return; return;
}//switch (ui.idChooser->getChosenId(authorId)) }//switch (ui.idChooser->getChosenId(authorId))
} else { } else {
std::cerr << "CreateGxsForumMsg::createMsg() No Signature (for now :)"; //std::cerr << "CreateGxsForumMsg::createMsg() No Signature (for now :)";
std::cerr << std::endl; //std::cerr << std::endl;
QMessageBox::warning(this, tr("RetroShare"),tr("Please choose Signing Id, it is required"), QMessageBox::Ok, QMessageBox::Ok); QMessageBox::warning(this, tr("RetroShare"),tr("Please choose Signing Id, it is required"), QMessageBox::Ok, QMessageBox::Ok);
return; return;
}//if (ui.signBox->isChecked()) }//if (ui.signBox->isChecked())
@ -408,7 +413,7 @@ void CreateGxsForumMsg::addFile()
void CreateGxsForumMsg::fileHashingFinished(QList<HashedFile> hashedFiles) void CreateGxsForumMsg::fileHashingFinished(QList<HashedFile> hashedFiles)
{ {
std::cerr << "CreateGxsForumMsg::fileHashingFinished() started." << std::endl; //std::cerr << "CreateGxsForumMsg::fileHashingFinished() started." << std::endl;
QString mesgString; QString mesgString;
@ -431,35 +436,88 @@ void CreateGxsForumMsg::fileHashingFinished(QList<HashedFile> hashedFiles)
void CreateGxsForumMsg::loadForumInfo(const uint32_t &token) void CreateGxsForumMsg::loadForumInfo(const uint32_t &token)
{ {
std::cerr << "CreateGxsForumMsg::loadForumInfo()"; //std::cerr << "CreateGxsForumMsg::loadForumInfo()";
std::cerr << std::endl; //std::cerr << std::endl;
std::list<RsGroupMetaData> groupInfo; std::list<RsGroupMetaData> groupInfo;
rsGxsForums->getGroupSummary(token, groupInfo); rsGxsForums->getGroupSummary(token, groupInfo);
if (groupInfo.size() == 1) if (groupInfo.size() == 1)
{ {
RsGroupMetaData fi = groupInfo.front(); RsGroupMetaData fi = groupInfo.front();
mForumMeta = fi; mForumMeta = fi;
mForumMetaLoaded = true; mForumMetaLoaded = true;
loadFormInformation(); if(!fi.mCircleId.isNull())
} {
else //std::cerr << "Circle ID is not null: " << fi.mCircleId << ": loading circle info to add constraint to the GXS ID chooser." << std::endl;
{
std::cerr << "CreateGxsForumMsg::loadForumInfo() ERROR INVALID Number of Forums";
std::cerr << std::endl;
mStateHelper->setActive(CREATEGXSFORUMMSG_FORUMINFO, false); RsTokReqOptions opts;
mStateHelper->setLoading(CREATEGXSFORUMMSG_FORUMINFO, false); 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
{
std::cerr << "CreateGxsForumMsg::loadForumInfo() ERROR INVALID Number of Forums";
std::cerr << std::endl;
mStateHelper->setActive(CREATEGXSFORUMMSG_FORUMINFO, false);
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) void CreateGxsForumMsg::loadParentMsg(const uint32_t &token)
{ {
std::cerr << "CreateGxsForumMsg::loadParentMsg()"; //std::cerr << "CreateGxsForumMsg::loadParentMsg()";
std::cerr << std::endl; //std::cerr << std::endl;
// Only grab one.... ignore more (shouldn't be any). // Only grab one.... ignore more (shouldn't be any).
std::vector<RsGxsForumMsg> msgs; std::vector<RsGxsForumMsg> msgs;
@ -486,8 +544,8 @@ void CreateGxsForumMsg::loadParentMsg(const uint32_t &token)
void CreateGxsForumMsg::loadRequest(const TokenQueue *queue, const TokenRequest &req) void CreateGxsForumMsg::loadRequest(const TokenQueue *queue, const TokenRequest &req)
{ {
std::cerr << "CreateGxsForum::loadRequest() UserType: " << req.mUserType; //std::cerr << "CreateGxsForum::loadRequest() UserType: " << req.mUserType;
std::cerr << std::endl; //std::cerr << std::endl;
if (queue == mForumQueue) if (queue == mForumQueue)
{ {
@ -501,10 +559,23 @@ void CreateGxsForumMsg::loadRequest(const TokenQueue *queue, const TokenRequest
loadParentMsg(req.mToken); loadParentMsg(req.mToken);
break; break;
default: default:
std::cerr << "CreateGxsForum::loadRequest() UNKNOWN UserType "; std::cerr << "CreateGxsForumMsg::loadRequest() UNKNOWN UserType " << req.mUserType << " for token request in mForumQueue";
std::cerr << std::endl; 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;
}
}
} }
void CreateGxsForumMsg::insertPastedText(QString msg) void CreateGxsForumMsg::insertPastedText(QString msg)

View file

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

View file

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

View file

@ -5,6 +5,8 @@
#include <retroshare/rsgxsifacehelper.h> #include <retroshare/rsgxsifacehelper.h>
//#define DEBUG_GXS_BROADCAST 1
// previously gxs allowed only one event consumer to poll for changes // previously gxs allowed only one event consumer to poll for changes
// this required a single broadcast instance per service // this required a single broadcast instance per service
// now the update notify works through rsnotify and notifyqt // now the update notify works through rsnotify and notifyqt
@ -43,8 +45,28 @@ RsGxsUpdateBroadcast *RsGxsUpdateBroadcast::get(RsGxsIfaceHelper *ifaceImpl)
void RsGxsUpdateBroadcast::onChangesReceived(const RsGxsChanges& changes) 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()) if(changes.mService != mIfaceImpl->getTokenService())
{
// std::cerr << "(EE) Incorrect service. Dropping." << std::endl;
return; return;
}
if (!changes.mMsgs.empty() || !changes.mMsgsMeta.empty()) 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); return new RsNxsSerialiser(RS_SERVICE_TYPE_PLUGIN_SIMPLE_FORUM);
} }
RsSerialType* init_item(RsNxsSyncGrp& rsg) RsSerialType* init_item(RsNxsSyncGrpReqItem& rsg)
{ {
rsg.clear(); rsg.clear();
rsg.flag = RsNxsSyncGrp::FLAG_USE_SYNC_HASH; rsg.flag = RsNxsSyncGrpItem::FLAG_USE_SYNC_HASH;
rsg.createdSince = rand()%2423; rsg.createdSince = rand()%2423;
randString(3124,rsg.syncHash); randString(3124,rsg.syncHash);
return new RsNxsSerialiser(RS_SERVICE_TYPE_PLUGIN_SIMPLE_FORUM); return new RsNxsSerialiser(RS_SERVICE_TYPE_PLUGIN_SIMPLE_FORUM);
} }
RsSerialType* init_item(RsNxsSyncMsg& rsgm) RsSerialType* init_item(RsNxsSyncMsgReqItem& rsgm)
{ {
rsgm.clear(); rsgm.clear();
rsgm.flag = RsNxsSyncMsg::FLAG_USE_SYNC_HASH; rsgm.flag = RsNxsSyncMsgItem::FLAG_USE_SYNC_HASH;
rsgm.createdSince = rand()%24232; rsgm.createdSince = rand()%24232;
rsgm.transactionNumber = rand()%23; rsgm.transactionNumber = rand()%23;
init_random(rsgm.grpId) ; init_random(rsgm.grpId) ;
@ -223,7 +223,7 @@ RsSerialType* init_item(RsNxsSyncMsgItem& rsgml)
return new RsNxsSerialiser(RS_SERVICE_TYPE_PLUGIN_SIMPLE_FORUM); return new RsNxsSerialiser(RS_SERVICE_TYPE_PLUGIN_SIMPLE_FORUM);
} }
RsSerialType* init_item(RsNxsTransac& rstx){ RsSerialType* init_item(RsNxsTransacItem &rstx){
rstx.clear(); 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; if(l.syncHash != r.syncHash) return false;
@ -247,7 +247,7 @@ bool operator==(const RsNxsSyncGrp& l, const RsNxsSyncGrp& r)
return true; 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; if(l.flag != r.flag) return false;
@ -279,7 +279,7 @@ bool operator==(const RsNxsSyncMsgItem& l, const RsNxsSyncMsgItem& r)
return true; 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.transactFlag != r.transactFlag) return false;
if(l.transactionNumber != r.transactionNumber) 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 RsNxsMsg&, const RsNxsMsg&);
bool operator==(const RsGxsGrpMetaData& l, const RsGxsGrpMetaData& r); bool operator==(const RsGxsGrpMetaData& l, const RsGxsGrpMetaData& r);
bool operator==(const RsGxsMsgMetaData& l, const RsGxsMsgMetaData& 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 RsNxsSyncGrpItem& l, const RsNxsSyncGrpItem& r);
bool operator==(const RsNxsSyncMsgItem& l, const RsNxsSyncMsgItem& 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(RsNxsGrp& nxg);
//void init_item(RsNxsMsg& nxm); //void init_item(RsNxsMsg& nxm);
@ -23,11 +23,11 @@ void init_item(RsGxsMsgMetaData* metaMsg);
RsSerialType* init_item(RsNxsGrp& nxg); RsSerialType* init_item(RsNxsGrp& nxg);
RsSerialType* init_item(RsNxsMsg& nxm); RsSerialType* init_item(RsNxsMsg& nxm);
RsSerialType* init_item(RsNxsSyncGrp& rsg); RsSerialType* init_item(RsNxsSyncGrpReqItem &rsg);
RsSerialType* init_item(RsNxsSyncMsg& rsgm); RsSerialType* init_item(RsNxsSyncMsgReqItem &rsgm);
RsSerialType* init_item(RsNxsSyncGrpItem& rsgl); RsSerialType* init_item(RsNxsSyncGrpItem& rsgl);
RsSerialType* init_item(RsNxsSyncMsgItem& rsgml); RsSerialType* init_item(RsNxsSyncMsgItem& rsgml);
RsSerialType* init_item(RsNxsTransac& rstx); RsSerialType* init_item(RsNxsTransacItem& rstx);
template<typename T> template<typename T>
void copy_all_but(T& ex, const std::list<T>& s, std::list<T>& d) 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, int rs_nxs_test::RsNxsSimpleDummyCircles::canSend(const RsGxsCircleId& circleId,
const RsPgpId& id) { const RsPgpId& id, bool &should_encrypt) {
return true; return true;
} }
@ -33,11 +33,20 @@ int rs_nxs_test::RsNxsSimpleDummyCircles::canReceive(
return true; return true;
} }
bool rs_nxs_test::RsNxsSimpleDummyCircles::isRecipient(const RsGxsCircleId &circleId, const RsGxsId& id)
{
return true ;
}
bool rs_nxs_test::RsNxsSimpleDummyCircles::recipients( bool rs_nxs_test::RsNxsSimpleDummyCircles::recipients(
const RsGxsCircleId& circleId, std::list<RsPgpId>& friendlist) { const RsGxsCircleId& circleId, std::list<RsPgpId>& friendlist) {
return true; return true;
} }
bool rs_nxs_test::RsNxsSimpleDummyCircles::recipients(
const RsGxsCircleId& circleId, std::list<RsGxsId>& friendlist) {
return true;
}
rs_nxs_test::RsNxsSimpleDummyReputation::RsNxsSimpleDummyReputation( rs_nxs_test::RsNxsSimpleDummyReputation::RsNxsSimpleDummyReputation(
RepMap& repMap, bool cached) { RepMap& repMap, bool cached) {
} }
@ -76,8 +85,7 @@ bool rs_nxs_test::RsNxsDelayedDummyCircles::loadCircle(
return allowed(circleId); return allowed(circleId);
} }
int rs_nxs_test::RsNxsDelayedDummyCircles::canSend( int rs_nxs_test::RsNxsDelayedDummyCircles::canSend(const RsGxsCircleId& circleId, const RsPgpId& id, bool &should_encrypt) {
const RsGxsCircleId& circleId, const RsPgpId& id) {
return allowed(circleId); return allowed(circleId);
} }

View file

@ -39,10 +39,13 @@ namespace rs_nxs_test
bool isLoaded(const RsGxsCircleId &circleId); bool isLoaded(const RsGxsCircleId &circleId);
bool loadCircle(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); int canReceive(const RsGxsCircleId &circleId, const RsPgpId &id);
bool recipients(const RsGxsCircleId &circleId, std::list<RsPgpId> &friendlist); 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 isLoaded(const RsGxsCircleId &circleId);
bool loadCircle(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); int canReceive(const RsGxsCircleId &circleId, const RsPgpId &id);
bool recipients(const RsGxsCircleId &circleId, std::list<RsPgpId> &friendlist); 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: private:
bool allowed(const RsGxsCircleId& circleId); bool allowed(const RsGxsCircleId& circleId);

View file

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

View file

@ -12,9 +12,9 @@ TEST(libretroshare_serialiser, RsNxsItem)
{ {
test_RsItem<RsNxsGrp>(RS_SERVICE_TYPE_PLUGIN_SIMPLE_FORUM); test_RsItem<RsNxsGrp>(RS_SERVICE_TYPE_PLUGIN_SIMPLE_FORUM);
test_RsItem<RsNxsMsg>(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<RsNxsSyncGrpItem>(RS_SERVICE_TYPE_PLUGIN_SIMPLE_FORUM);
test_RsItem<RsNxsSyncMsgItem>(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( mGxsIdNs = new RsGxsNetService(
RS_SERVICE_GXS_TYPE_GXSID, mGxsIdDs, nxsMgr, RS_SERVICE_GXS_TYPE_GXSID, mGxsIdDs, nxsMgr,
mGxsIdService, mGxsIdService->getServiceInfo(), mGxsIdService, mGxsIdService->getServiceInfo(),
mGxsIdService, mGxsCircles, mGxsIdService, mGxsCircles,mGxsIdService,
mPgpAuxUtils, mPgpAuxUtils,
false); // don't synchronise group automatic (need explicit group request) 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 #endif
(RS_SERVICE_GXS_TYPE_GXSCIRCLE, mGxsCirclesDs, nxsMgr, (RS_SERVICE_GXS_TYPE_GXSCIRCLE, mGxsCirclesDs, nxsMgr,
mGxsCircles, mGxsCircles->getServiceInfo(), mGxsCircles, mGxsCircles->getServiceInfo(),
mGxsIdService, mGxsCircles, mGxsIdService, mGxsCircles,NULL,
mPgpAuxUtils); mPgpAuxUtils);
} }
else else
@ -107,7 +107,7 @@ GxsPeerNode::GxsPeerNode(const RsPeerId &ownId, const std::list<RsPeerId> &frien
#endif #endif
(RS_SERVICE_GXS_TYPE_TEST, mTestDs, nxsMgr, (RS_SERVICE_GXS_TYPE_TEST, mTestDs, nxsMgr,
mTestService, mTestService->getServiceInfo(), mTestService, mTestService->getServiceInfo(),
mGxsIdService, mGxsCircles, mGxsIdService, mGxsCircles,mGxsIdService,
mPgpAuxUtils); mPgpAuxUtils);
if (mUseIdentityService) if (mUseIdentityService)

View file

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

View file

@ -41,7 +41,7 @@ TEST(libretroshare_services, DISABLED_GxsNxsPairExchange1)
dropFilter.setUseSource(true); dropFilter.setUseSource(true);
dropFilter.addSource(p2); 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.setUseFullTypes(true);
dropFilter.addFullType(syncGrp->PacketId()); dropFilter.addFullType(syncGrp->PacketId());
} }
@ -111,7 +111,7 @@ TEST(libretroshare_services, DISABLED_GxsNxsPairExchange2)
dropFilter.setUseSource(true); dropFilter.setUseSource(true);
dropFilter.addSource(p2); 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.setUseFullTypes(true);
dropFilter.addFullType(syncGrp->PacketId()); dropFilter.addFullType(syncGrp->PacketId());
} }