Merge branch 'master'

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

47
TODO.circles.txt Normal file
View File

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

View File

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

View File

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

View File

@ -63,7 +63,8 @@ class GxsSecurity
*@param in
*@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 )
@ -74,7 +75,8 @@ class GxsSecurity
* @param inlen
* @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

View File

@ -92,9 +92,9 @@ public:
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<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

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

View File

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

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 decryptData(const uint8_t *encrypted_data,uint32_t encrypted_data_size,uint8_t *& clear_data,uint32_t& clear_data_size,const RsGxsId& encryption_key_id,uint32_t& encryption_error) = 0 ;
// virtual bool getPublicKey(const RsGxsId &id, RsTlvSecurityKey &key) = 0;
virtual bool getOwnIds(std::list<RsGxsId>& ids) = 0;
virtual bool isOwnId(const RsGxsId& key_id) = 0 ;
virtual void timeStampKey(const RsGxsId& key_id) = 0 ;
// virtual void networkRequestPublicKey(const RsGxsId& key_id,const std::list<RsPeerId>& peer_ids) = 0 ;
// Key related interface - used for validating msgs and groups.
// Key related interface - used for validating msgs and groups.
/*!
* Use to query a whether given key is available by its key reference
* @param keyref the keyref of key that is being checked for
@ -147,8 +143,8 @@ public:
*/
virtual bool havePrivateKey(const RsGxsId &id) = 0;
// 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.
// 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.
/*!
* Use to request a given key reference
* @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 getPrivateKey(const RsGxsId &id, RsTlvSecurityKey &key) = 0; // For signing outgoing messages.
virtual bool getIdDetails(const RsGxsId& id, RsIdentityDetails& details) = 0 ; // Proxy function so that we get p3Identity info from Gxs
#ifdef SUSPENDED
#endif
};
class GixsReputation
@ -218,9 +211,13 @@ class RsGcxs
virtual bool isLoaded(const RsGxsCircleId &circleId) = 0;
virtual bool loadCircle(const RsGxsCircleId &circleId) = 0;
virtual int canSend(const RsGxsCircleId &circleId, const RsPgpId &id) = 0;
virtual int canReceive(const RsGxsCircleId &circleId, const RsPgpId &id) = 0;
virtual bool recipients(const RsGxsCircleId &circleId, std::list<RsPgpId> &friendlist) = 0;
virtual int canSend(const RsGxsCircleId &circleId, const RsPgpId &id,bool& should_encrypt) = 0;
virtual int canReceive(const RsGxsCircleId &circleId, const RsPgpId &id) = 0;
virtual bool recipients(const RsGxsCircleId &circleId, std::list<RsPgpId>& friendlist) = 0;
virtual bool recipients(const RsGxsCircleId &circleId, std::list<RsGxsId>& idlist) = 0;
virtual bool isRecipient(const RsGxsCircleId &circleId, const RsGxsId& id) = 0;
virtual bool getLocalCircleServerUpdateTS(const RsGxsCircleId& gid,time_t& grp_server_update_TS,time_t& msg_server_update_TS) =0;
};
@ -231,8 +228,12 @@ public:
RsGxsCircleExchange(RsGeneralDataService* gds, RsNetworkExchangeService* ns, RsSerialType* serviceSerialiser,
uint16_t mServType, RsGixs* gixs, uint32_t authenPolicy)
: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,
RsNxsObserver *nxsObs, // used to be = NULL.
const RsServiceInfo serviceInfo,
RsGixsReputation* reputations = NULL, RsGcxs* circles = NULL,
RsGixsReputation* reputations = NULL, RsGcxs* circles = NULL, RsGixs *gixs=NULL,
PgpAuxUtils *pgpUtils = NULL,
bool grpAutoSync = true, bool msgAutoSync = true);
@ -154,6 +154,8 @@ public:
virtual void rejectMessage(const RsGxsMessageId& msg_id) ;
virtual bool getGroupServerUpdateTS(const RsGxsGroupId& gid,time_t& grp_server_update_TS,time_t& msg_server_update_TS) ;
/* p3Config methods */
public:
@ -215,7 +217,7 @@ private:
* @param item the transaction item to process
* @return false ownership of item left with callee
*/
bool locked_processTransac(RsNxsTransac* item);
bool locked_processTransac(RsNxsTransacItem* item);
/*!
* This adds a transaction
@ -318,19 +320,19 @@ private:
* of groups held by user
* @param item contains grp sync info
*/
void handleRecvSyncGroup(RsNxsSyncGrp* item);
void handleRecvSyncGroup(RsNxsSyncGrpReqItem* item);
/*!
* Handles an nxs item for group statistics
* @param item contaims update time stamp and number of messages
*/
void handleRecvSyncGrpStatistics(RsNxsSyncGrpStats *grs);
void handleRecvSyncGrpStatistics(RsNxsSyncGrpStatsItem *grs);
/*!
* Handles an nxs item for msgs synchronisation
* @param item contaims msg sync info
*/
void handleRecvSyncMessage(RsNxsSyncMsg* item);
void handleRecvSyncMessage(RsNxsSyncMsgReqItem* item);
/*!
* Handles an nxs item for group publish key
@ -349,22 +351,21 @@ private:
* @param toVet groupid/peer to vet are stored here if their circle id is not cached
* @return false, if you cannot send to this peer, true otherwise
*/
bool canSendGrpId(const RsPeerId& sslId, RsGxsGrpMetaData& grpMeta, std::vector<GrpIdCircleVet>& toVet);
bool canSendMsgIds(const std::vector<RsGxsMsgMetaData*>& msgMetas, const RsGxsGrpMetaData&, const RsPeerId& sslId);
bool canSendGrpId(const RsPeerId& sslId, RsGxsGrpMetaData& grpMeta, std::vector<GrpIdCircleVet>& toVet, bool &should_encrypt);
bool canSendMsgIds(std::vector<RsGxsMsgMetaData*>& msgMetas, const RsGxsGrpMetaData&, const RsPeerId& sslId, RsGxsCircleId &should_encrypt_id);
bool checkCanRecvMsgFromPeer(const RsPeerId& sslId, const RsGxsGrpMetaData& meta);
void locked_createTransactionFromPending(MsgRespPending* grpPend);
void locked_createTransactionFromPending(GrpRespPending* msgPend);
void locked_createTransactionFromPending(GrpCircleIdRequestVetting* grpPend);
void locked_createTransactionFromPending(MsgCircleIdsRequestVetting* grpPend);
bool locked_createTransactionFromPending(GrpCircleIdRequestVetting* grpPend) ;
bool locked_createTransactionFromPending(MsgCircleIdsRequestVetting* grpPend) ;
void locked_pushMsgTransactionFromList(std::list<RsNxsItem*>& reqList, const RsPeerId& peerId, const uint32_t& transN);
void locked_pushGrpTransactionFromList(std::list<RsNxsItem*>& reqList, const RsPeerId& peerId, const uint32_t& transN);
void locked_pushGrpTransactionFromList(std::list<RsNxsItem*>& reqList, const RsPeerId& peerId, const uint32_t& transN); // forms a grp list request
void locked_pushMsgTransactionFromList(std::list<RsNxsItem*>& reqList, const RsPeerId& peerId, const uint32_t& transN); // forms a msg list request
void locked_pushGrpRespFromList(std::list<RsNxsItem*>& respList, const RsPeerId& peer, const uint32_t& transN);
void locked_pushMsgRespFromList(std::list<RsNxsItem*>& itemL, const RsPeerId& sslId, const RsGxsGroupId &grp_id, const uint32_t& transN);
void syncWithPeers();
void syncGrpStatistics();
void addGroupItemToList(NxsTransaction*& tr,
@ -375,15 +376,15 @@ private:
void processExplicitGroupRequests();
void locked_doMsgUpdateWork(const RsNxsTransac* nxsTrans, const RsGxsGroupId& grpId);
void locked_doMsgUpdateWork(const RsNxsTransacItem* nxsTrans, const RsGxsGroupId& grpId);
void updateServerSyncTS();
#ifdef TO_REMOVE
void updateClientSyncTS();
#endif
bool locked_CanReceiveUpdate(const RsNxsSyncGrp* item);
bool locked_CanReceiveUpdate(const RsNxsSyncMsg* item);
bool locked_CanReceiveUpdate(const RsNxsSyncGrpReqItem *item);
bool locked_CanReceiveUpdate(const RsNxsSyncMsgReqItem* item);
private:
@ -450,8 +451,15 @@ private:
void locked_stampPeerGroupUpdateTime(const RsPeerId& pid,const RsGxsGroupId& grpId,time_t tm,uint32_t n_messages) ;
/*!
* encrypts/decrypts the transaction for the destination circle id.
*/
bool encryptSingleNxsItem(RsNxsItem *item, const RsGxsCircleId& destination_circle, RsNxsItem *& encrypted_item, uint32_t &status) ;
bool processTransactionForDecryption(NxsTransaction *tr); // return false when the keys are not loaded => need retry later
void cleanRejectedMessages();
void processObserverNotifications();
private:
@ -469,8 +477,8 @@ private:
/*** transactions ***/
/*** synchronisation ***/
std::list<RsNxsSyncGrp*> mSyncGrp;
std::list<RsNxsSyncMsg*> mSyncMsg;
std::list<RsNxsSyncGrpItem*> mSyncGrp;
std::list<RsNxsSyncMsgItem*> mSyncMsg;
/*** synchronisation ***/
RsNxsObserver* mObserver;
@ -496,6 +504,7 @@ private:
int mUpdateCounter ;
RsGcxs* mCircles;
RsGixs *mGixs;
RsGixsReputation* mReputations;
PgpAuxUtils *mPgpUtils;
bool mGrpAutoSync;
@ -516,7 +525,6 @@ public:
typedef std::map<RsPeerId, RsGxsMsgUpdateItem*> ClientMsgMap;
typedef std::map<RsGxsGroupId, RsGxsServerMsgUpdateItem*> ServerMsgMap;
typedef std::map<RsPeerId, RsGxsGrpUpdateItem*> ClientGrpMap;
private:
ClientMsgMap mClientMsgUpdateMap;

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

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_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_PUB_RSA = 0x0112; /* 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_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_SIGN_RSA_SHA1 = 0x0120; /* Used (Distrib/Forums) */
const uint16_t TLV_TYPE_BIN_IMAGE = 0x0130; /* Used (Generic - Forums) */
const uint16_t TLV_TYPE_BIN_FILEDATA = 0x0140; /* Used - ACTIVE! */
const uint16_t TLV_TYPE_BIN_SERIALISE = 0x0150; /* Used (Generic - Distrib) */
const uint16_t TLV_TYPE_BIN_GENERIC = 0x0160; /* Used (DSDV Data) */
const uint16_t TLV_TYPE_BIN_GENERIC = 0x0160; /* Used (DSDV Data) */
const uint16_t TLV_TYPE_BIN_ENCRYPTED = 0x0170; /* Encrypted data */
/**** Compound Types ****/

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -6,8 +6,8 @@
<rect>
<x>0</x>
<y>0</y>
<width>745</width>
<height>640</height>
<width>1475</width>
<height>1134</height>
</rect>
</property>
<property name="sizePolicy">
@ -19,14 +19,8 @@
<property name="windowTitle">
<string/>
</property>
<layout class="QGridLayout" name="gridLayout_5">
<property name="horizontalSpacing">
<number>0</number>
</property>
<property name="margin">
<number>0</number>
</property>
<item row="0" column="0">
<layout class="QVBoxLayout" name="verticalLayout_6">
<item>
<widget class="QFrame" name="titleBarFrame">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Maximum">
@ -62,7 +56,7 @@
<string/>
</property>
<property name="pixmap">
<pixmap resource="../images.qrc">:/images/user/friends24.png</pixmap>
<pixmap resource="../../../../../trunk/retroshare-gui/src/gui/images.qrc">:/images/user/friends24.png</pixmap>
</property>
<property name="scaledContents">
<bool>true</bool>
@ -102,7 +96,7 @@
<enum>Qt::NoFocus</enum>
</property>
<property name="icon">
<iconset resource="../images.qrc">
<iconset resource="../../../../../trunk/retroshare-gui/src/gui/images.qrc">
<normaloff>:/icons/help_64.png</normaloff>:/icons/help_64.png</iconset>
</property>
<property name="checkable">
@ -116,7 +110,7 @@
</layout>
</widget>
</item>
<item row="1" column="0">
<item>
<widget class="QSplitter" name="splitter">
<property name="orientation">
<enum>Qt::Horizontal</enum>
@ -159,7 +153,7 @@
<string>New ID</string>
</property>
<property name="icon">
<iconset resource="../images.qrc">
<iconset resource="../../../../../trunk/retroshare-gui/src/gui/images.qrc">
<normaloff>:/images/identity/identity_create_32.png</normaloff>:/images/identity/identity_create_32.png</iconset>
</property>
<property name="iconSize">
@ -235,225 +229,345 @@
</item>
</layout>
</widget>
<widget class="QWidget" name="layoutWidget">
<layout class="QVBoxLayout" name="verticalLayout_4">
<item>
<widget class="QFrame" name="headerFrame">
<property name="frameShape">
<enum>QFrame::StyledPanel</enum>
</property>
<property name="frameShadow">
<enum>QFrame::Raised</enum>
</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>
<widget class="QTabWidget" name="tabWidget1">
<property name="currentIndex">
<number>0</number>
</property>
<widget class="QWidget" name="tab_2">
<attribute name="title">
<string>Person</string>
</attribute>
<layout class="QVBoxLayout" name="verticalLayout">
<item>
<layout class="QVBoxLayout" name="verticalLayout_4">
<item>
<widget class="QFrame" name="headerFrame">
<property name="frameShape">
<enum>QFrame::StyledPanel</enum>
</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 name="frameShadow">
<enum>QFrame::Raised</enum>
</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>
</item>
<item row="0" column="1" rowspan="2" colspan="2">
<widget class="StyledElidedLabel" name="headerTextLabel">
<property name="text">
<string>People</string>
<item>
<widget class="QGroupBox" name="detailsGroupBox">
<property name="title">
<string>Identity info</string>
</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>
</item>
</layout>
</widget>
</item>
<item>
<widget class="QGroupBox" name="detailsGroupBox">
<property name="title">
<string>Identity info</string>
</property>
<layout class="QGridLayout" name="gridLayout_3">
<item row="0" column="0">
<layout class="QGridLayout" name="gridLayout">
<property name="margin">
<number>6</number>
<item>
<widget class="QGroupBox" name="reputationGroupBox">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="spacing">
<number>6</number>
<property name="title">
<string>Reputation</string>
</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>
<layout class="QVBoxLayout" name="verticalLayout_2">
<item>
<layout class="QGridLayout" name="gridLayout_2">
<property name="margin">
<number>6</number>
</property>
<item row="2" column="1">
<widget class="QLineEdit" name="neighborNodesOpinion_TF">
<property name="toolTip">
<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>
</property>
<property name="readOnly">
<bool>true</bool>
</property>
</widget>
</item>
<item row="1" column="0">
<widget class="QLabel" name="label_6">
<property name="text">
<string>Your opinion:</string>
</property>
</widget>
</item>
<item row="2" column="0">
<widget class="QLabel" name="label_5">
<property name="text">
<string>Neighbor nodes:</string>
</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>../../../../../trunk/retroshare-gui/src/gui/icons/yellow_biohazard64.png</normaloff>../../../../../trunk/retroshare-gui/src/gui/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>
</layout>
</widget>
</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>
<item row="1" column="0">
<spacer name="verticalSpacer_2">
<item>
<spacer name="verticalSpacer">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<property name="sizeType">
<enum>QSizePolicy::Expanding</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
@ -463,137 +577,84 @@
</spacer>
</item>
</layout>
</widget>
</item>
<item>
<widget class="QGroupBox" name="reputationGroupBox">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="title">
<string>Reputation</string>
</property>
<layout class="QVBoxLayout" name="verticalLayout_2">
</item>
</layout>
</widget>
<widget class="QWidget" name="tab">
<attribute name="title">
<string>Circles</string>
</attribute>
<layout class="QGridLayout" name="gridLayout_5">
<item row="0" column="0">
<layout class="QHBoxLayout" name="horizontalLayout_7">
<item>
<layout class="QGridLayout" name="gridLayout_2">
<property name="margin">
<number>6</number>
<widget class="QPushButton" name="pushButton_extCircle">
<property name="text">
<string>Create Circle</string>
</property>
<item row="2" column="1">
<widget class="QLineEdit" name="neighborNodesOpinion_TF">
<property name="toolTip">
<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>
</property>
<property name="readOnly">
<bool>true</bool>
</property>
</widget>
</item>
<item row="1" column="0">
<widget class="QLabel" name="label_6">
<property name="text">
<string>Your opinion:</string>
</property>
</widget>
</item>
<item row="2" column="0">
<widget class="QLabel" name="label_5">
<property name="text">
<string>Neighbor nodes:</string>
</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>
</widget>
</item>
<item>
<widget class="QPushButton" name="pushButton_editCircle">
<property name="text">
<string>Edit Circle</string>
</property>
</widget>
</item>
<item>
<spacer name="horizontalSpacer">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
</layout>
</widget>
</item>
<item>
<spacer name="verticalSpacer">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<property name="sizeType">
<enum>QSizePolicy::Expanding</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
<height>40</height>
</size>
</property>
</spacer>
</item>
</layout>
</item>
<item row="1" column="0">
<widget class="QTreeWidget" name="treeWidget_membership">
<property name="contextMenuPolicy">
<enum>Qt::CustomContextMenu</enum>
</property>
<property name="sortingEnabled">
<bool>true</bool>
</property>
<column>
<property name="text">
<string>Name</string>
</property>
</column>
<column>
<property name="text">
<string>IDs</string>
</property>
</column>
<item>
<property name="text">
<string>Public Circles</string>
</property>
</item>
<item>
<property name="text">
<string>Personal Circles</string>
</property>
</item>
</widget>
</item>
</layout>
</widget>
</widget>
</widget>
</item>
</layout>
<action name="editIdentity">
<property name="icon">
<iconset resource="../images.qrc">
<iconset resource="../../../../../trunk/retroshare-gui/src/gui/images.qrc">
<normaloff>:/images/edit_16.png</normaloff>:/images/edit_16.png</iconset>
</property>
<property name="text">
@ -605,7 +666,7 @@ p, li { white-space: pre-wrap; }
</action>
<action name="removeIdentity">
<property name="icon">
<iconset resource="../images.qrc">
<iconset resource="../../../../../trunk/retroshare-gui/src/gui/images.qrc">
<normaloff>:/images/delete.png</normaloff>:/images/delete.png</iconset>
</property>
<property name="text">
@ -614,7 +675,7 @@ p, li { white-space: pre-wrap; }
</action>
<action name="chatIdentity">
<property name="icon">
<iconset resource="../images.qrc">
<iconset resource="../../../../../trunk/retroshare-gui/src/gui/images.qrc">
<normaloff>:/images/toaster/chat.png</normaloff>:/images/toaster/chat.png</iconset>
</property>
<property name="text">
@ -651,7 +712,7 @@ p, li { white-space: pre-wrap; }
<tabstop>idTreeWidget</tabstop>
</tabstops>
<resources>
<include location="../images.qrc"/>
<include location="../../../../../trunk/retroshare-gui/src/gui/images.qrc"/>
</resources>
<connections/>
</ui>

View File

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

View File

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

View File

@ -1,202 +1,210 @@
#include "gui/People/IdentityWidget.h"
#include "ui_IdentityWidget.h"
#include "gui/common/AvatarDefs.h"
#include <gui/gxs/GxsIdDetails.h>
#include <QDrag>
#include <QMimeData>
#include <QGraphicsProxyWidget>
IdentityWidget::IdentityWidget(QString name/*=QString()*/, QWidget *parent/*=0*/) :
FlowLayoutItem(name, parent),
ui(new Ui::IdentityWidget)
{
ui->setupUi(this);
_haveGXSId = false;
_havePGPDetail = false;
m_myName = name;
ui->labelName->setText(m_myName);
ui->labelName->setToolTip(m_myName);
QFont font = ui->labelName->font();
font.setItalic(false);
ui->labelName->setFont(font);
_keyId="";
ui->labelKeyId->setText(_keyId);
ui->labelKeyId->setToolTip(_keyId);
ui->labelKeyId->setVisible(false);
ui->labelGXSId->setText(_keyId);
ui->labelGXSId->setToolTip(_keyId);
ui->labelGXSId->setVisible(false);
ui->pbAdd->setVisible(false);
QObject::connect(ui->pbAdd, SIGNAL(clicked()), this, SLOT(pbAdd_clicked()));
_scene = new QGraphicsScene(this);
ui->graphicsView->setScene(_scene);
//To grab events
ui->graphicsView->setEnabled(false);
ui->graphicsView->setAlignment(Qt::AlignLeft | Qt::AlignTop);
setIsCurrent(false);
setIsSelected(false);
setAcceptDrops(true);
}
IdentityWidget::~IdentityWidget()
{
delete _scene;
delete ui;
}
void IdentityWidget::updateData(const RsGxsIdGroup &gxs_group_info)
{
//if (_group_info != gxs_group_info) {
_group_info = gxs_group_info;
_haveGXSId = true;
m_myName = QString::fromUtf8(_group_info.mMeta.mGroupName.c_str());
ui->labelName->setText(m_myName);
if (_havePGPDetail) {
ui->labelName->setToolTip(tr("GXS name:").append(" "+m_myName).append("\n")
.append(tr("PGP name:").append(" "+_nickname)));
} else {//if (m_myName != _nickname)
ui->labelName->setToolTip(tr("GXS name:").append(" "+m_myName));
}//else (m_myName != _nickname)
_gxsId = QString::fromStdString(_group_info.mMeta.mGroupId.toStdString());
ui->labelGXSId->setText(_gxsId);
ui->labelGXSId->setToolTip(tr("GXS id:").append(" "+_gxsId));
if (!_havePGPDetail) {
QFont font = ui->labelName->font();
font.setItalic(false);
ui->labelName->setFont(font);
_keyId=QString::fromStdString(_group_info.mMeta.mGroupId.toStdString());
ui->labelKeyId->setText(_keyId);
ui->labelKeyId->setToolTip(tr("GXS id:").append(" "+_keyId));
ui->labelKeyId->setVisible(false);
/// (TODO) Get real ident icon
QImage image = GxsIdDetails::makeDefaultIcon(RsGxsId(_group_info.mMeta.mGroupId));
if (_avatar != image) {
_avatar = image;
_scene->clear();
_scene->addPixmap(QPixmap::fromImage(image.scaled(ui->graphicsView->width(),ui->graphicsView->height())));
emit imageUpdated();
}//if (_avatar != image)
}//if (!_havePGPDetail)
//}//if (_group_info != gxs_group_info)
}
void IdentityWidget::updateData(const RsPeerDetails &pgp_details)
{
//if (_details != pgp_details) {
_details = pgp_details;
_havePGPDetail = true;
_nickname = QString::fromUtf8(_details.name.c_str());
if (!_haveGXSId) m_myName = _nickname;
ui->labelName->setText(m_myName);
if (_haveGXSId) {
ui->labelName->setToolTip(tr("GXS name:").append(" "+m_myName).append("\n")
.append(tr("PGP name:").append(" "+_nickname)));
} else {//if (m_myName != _nickname)
ui->labelName->setToolTip(tr("PGP name:").append(" "+_nickname));
}//else (m_myName != _nickname)
QFont font = ui->labelName->font();
font.setItalic(true);
ui->labelName->setFont(font);
_keyId = QString::fromStdString(_details.gpg_id.toStdString());
ui->labelKeyId->setText(_keyId);
ui->labelKeyId->setToolTip(tr("PGP id:").append(" "+_keyId));
QPixmap avatar;
AvatarDefs::getAvatarFromGpgId(_details.gpg_id.toStdString(), avatar);
if (_avatar != avatar.toImage()) {
_avatar = avatar.toImage();
_scene->clear();
_scene->addPixmap(avatar.scaled(ui->graphicsView->width(),ui->graphicsView->height()));
emit imageUpdated();
}//if (_avatar != avatar.toImage())
//}//if (_details != gpg_details)
}
void IdentityWidget::updateData(const RsGxsIdGroup &gxs_group_info, const RsPeerDetails &pgp_details)
{
updateData(gxs_group_info);
updateData(pgp_details);
}
QSize IdentityWidget::sizeHint()
{
QSize size;
size.setHeight(ui->graphicsView->size().height() + ui->labelName->size().height());
size.setWidth(ui->graphicsView->size().width() > ui->labelName->size().width()
?ui->graphicsView->size().width() : ui->labelName->size().width());
return size;
}
const QPixmap IdentityWidget::getImage()
{
#if QT_VERSION >= QT_VERSION_CHECK (5, 0, 0)
return ui->graphicsView->grab();
//return this->grab(); //QT5
#else
return QPixmap::grabWidget(ui->graphicsView);
//return QPixmap::grabWidget(this);
#endif
}
const QPixmap IdentityWidget::getDragImage()
{
#if QT_VERSION >= QT_VERSION_CHECK (5, 0, 0)
return ui->graphicsView->grab();
//return this->grab(); //QT5
#else
return QPixmap::grabWidget(ui->graphicsView);
//return QPixmap::grabWidget(this);
#endif
}
void IdentityWidget::setIsSelected(bool value)
{
m_isSelected=value;
QFont font=ui->labelName->font();
font.setBold(value);
ui->labelName->setFont(font);
}
/*
bool IdentityWidget::isSelected()
{
return m_isSelected;
}*/
void IdentityWidget::setIsCurrent(bool value)
{
m_isCurrent=value;
ui->labelKeyId->setVisible(value);
ui->labelGXSId->setVisible(value && (_haveGXSId && _havePGPDetail));
ui->pbAdd->setVisible(value);
}
/*
bool IdentityWidget::isCurrent()
{
return m_isCurrent;
}*/
void IdentityWidget::pbAdd_clicked()
{
emit addButtonClicked();
}
#include "gui/People/IdentityWidget.h"
#include "ui_IdentityWidget.h"
#include "gui/common/AvatarDefs.h"
#include <gui/gxs/GxsIdDetails.h>
#include <QDrag>
#include <QMimeData>
#include <QGraphicsProxyWidget>
IdentityWidget::IdentityWidget(QString name/*=QString()*/, QWidget *parent/*=0*/) :
FlowLayoutItem(name, parent),
ui(new Ui::IdentityWidget)
{
ui->setupUi(this);
_haveGXSId = false;
_havePGPDetail = false;
m_myName = name;
ui->labelName->setText(m_myName);
ui->labelName->setToolTip(m_myName);
QFont font = ui->labelName->font();
font.setItalic(false);
ui->labelName->setFont(font);
_keyId="";
ui->labelKeyId->setText(_keyId);
ui->labelKeyId->setToolTip(_keyId);
ui->labelKeyId->setVisible(false);
ui->labelGXSId->setText(_keyId);
ui->labelGXSId->setToolTip(_keyId);
ui->labelGXSId->setVisible(false);
ui->pbAdd->setVisible(false);
QObject::connect(ui->pbAdd, SIGNAL(clicked()), this, SLOT(pbAdd_clicked()));
_scene = new QGraphicsScene(this);
ui->graphicsView->setScene(_scene);
//To grab events
ui->graphicsView->setEnabled(false);
ui->graphicsView->setAlignment(Qt::AlignLeft | Qt::AlignTop);
setIsCurrent(false);
setIsSelected(false);
setAcceptDrops(true);
}
IdentityWidget::~IdentityWidget()
{
delete _scene;
delete ui;
}
void IdentityWidget::updateData(const RsGxsIdGroup &gxs_group_info)
{
//if (_group_info != gxs_group_info) {
_group_info = gxs_group_info;
_haveGXSId = true;
m_myName = QString::fromUtf8(_group_info.mMeta.mGroupName.c_str());
ui->labelName->setText(m_myName);
if (_havePGPDetail) {
ui->labelName->setToolTip(tr("GXS name:").append(" "+m_myName).append("\n")
.append(tr("PGP name:").append(" "+_nickname)));
} else {//if (m_myName != _nickname)
ui->labelName->setToolTip(tr("GXS name:").append(" "+m_myName));
}//else (m_myName != _nickname)
_gxsId = QString::fromStdString(_group_info.mMeta.mGroupId.toStdString());
ui->labelGXSId->setText(_gxsId);
ui->labelGXSId->setToolTip(tr("GXS id:").append(" "+_gxsId));
if (!_havePGPDetail) {
QFont font = ui->labelName->font();
font.setItalic(false);
ui->labelName->setFont(font);
_keyId=QString::fromStdString(_group_info.mMeta.mGroupId.toStdString());
ui->labelKeyId->setText(_keyId);
ui->labelKeyId->setToolTip(tr("GXS id:").append(" "+_keyId));
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));
if (_avatar != image) {
_avatar = image;
_scene->clear();
_scene->addPixmap(QPixmap::fromImage(image.scaled(ui->graphicsView->width(),ui->graphicsView->height())));
emit imageUpdated();
}//if (_avatar != image)
}//if (!_havePGPDetail)
//}//if (_group_info != gxs_group_info)
}
void IdentityWidget::updateData(const RsPeerDetails &pgp_details)
{
//if (_details != pgp_details) {
_details = pgp_details;
_havePGPDetail = true;
_nickname = QString::fromUtf8(_details.name.c_str());
if (!_haveGXSId) m_myName = _nickname;
ui->labelName->setText(m_myName);
if (_haveGXSId) {
ui->labelName->setToolTip(tr("GXS name:").append(" "+m_myName).append("\n")
.append(tr("PGP name:").append(" "+_nickname)));
} else {//if (m_myName != _nickname)
ui->labelName->setToolTip(tr("PGP name:").append(" "+_nickname));
}//else (m_myName != _nickname)
QFont font = ui->labelName->font();
font.setItalic(true);
ui->labelName->setFont(font);
_keyId = QString::fromStdString(_details.gpg_id.toStdString());
ui->labelKeyId->setText(_keyId);
ui->labelKeyId->setToolTip(tr("PGP id:").append(" "+_keyId));
QPixmap avatar;
/*AvatarDefs::getAvatarFromGpgId(_details.gpg_id, avatar);
if (_avatar != avatar.toImage()) {
_avatar = avatar.toImage();
_scene->clear();
_scene->addPixmap(avatar.scaled(ui->graphicsView->width(),ui->graphicsView->height()));
emit imageUpdated();
}*///if (_avatar != avatar.toImage())
//}//if (_details != gpg_details)
}
void IdentityWidget::updateData(const RsGxsIdGroup &gxs_group_info, const RsPeerDetails &pgp_details)
{
updateData(gxs_group_info);
updateData(pgp_details);
}
QSize IdentityWidget::sizeHint()
{
QSize size;
size.setHeight(ui->graphicsView->size().height() + ui->labelName->size().height());
size.setWidth(ui->graphicsView->size().width() > ui->labelName->size().width()
?ui->graphicsView->size().width() : ui->labelName->size().width());
return size;
}
const QPixmap IdentityWidget::getImage()
{
#if QT_VERSION >= QT_VERSION_CHECK (5, 0, 0)
return ui->graphicsView->grab();
//return this->grab(); //QT5
#else
return QPixmap::grabWidget(ui->graphicsView);
//return QPixmap::grabWidget(this);
#endif
}
const QPixmap IdentityWidget::getDragImage()
{
#if QT_VERSION >= QT_VERSION_CHECK (5, 0, 0)
return ui->graphicsView->grab();
//return this->grab(); //QT5
#else
return QPixmap::grabWidget(ui->graphicsView);
//return QPixmap::grabWidget(this);
#endif
}
void IdentityWidget::setIsSelected(bool value)
{
m_isSelected=value;
QFont font=ui->labelName->font();
font.setBold(value);
ui->labelName->setFont(font);
}
/*
bool IdentityWidget::isSelected()
{
return m_isSelected;
}*/
void IdentityWidget::setIsCurrent(bool value)
{
m_isCurrent=value;
ui->labelKeyId->setVisible(value);
ui->labelGXSId->setVisible(value && (_haveGXSId && _havePGPDetail));
ui->pbAdd->setVisible(value);
}
/*
bool IdentityWidget::isCurrent()
{
return m_isCurrent;
}*/
void IdentityWidget::pbAdd_clicked()
{
emit addButtonClicked();
}

View File

@ -1,144 +1,146 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>IdentityWidget</class>
<widget class="QWidget" name="IdentityWidget">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>102</width>
<height>158</height>
</rect>
</property>
<layout class="QVBoxLayout" name="verticalLayout">
<property name="spacing">
<number>0</number>
</property>
<property name="margin">
<number>1</number>
</property>
<item>
<widget class="QGraphicsView" name="graphicsView">
<property name="minimumSize">
<size>
<width>100</width>
<height>100</height>
</size>
</property>
<property name="maximumSize">
<size>
<width>100</width>
<height>100</height>
</size>
</property>
<property name="frameShape">
<enum>QFrame::NoFrame</enum>
</property>
<property name="verticalScrollBarPolicy">
<enum>Qt::ScrollBarAlwaysOff</enum>
</property>
<property name="horizontalScrollBarPolicy">
<enum>Qt::ScrollBarAlwaysOff</enum>
</property>
<property name="sceneRect">
<rectf>
<x>0.000000000000000</x>
<y>0.000000000000000</y>
<width>100.000000000000000</width>
<height>100.000000000000000</height>
</rectf>
</property>
<property name="alignment">
<set>Qt::AlignLeading|Qt::AlignLeft|Qt::AlignTop</set>
</property>
</widget>
</item>
<item>
<widget class="ElidedLabel" name="labelName">
<property name="minimumSize">
<size>
<width>0</width>
<height>15</height>
</size>
</property>
<property name="maximumSize">
<size>
<width>100</width>
<height>16777215</height>
</size>
</property>
<property name="text">
<string>Name</string>
</property>
<property name="scaledContents">
<bool>true</bool>
</property>
<property name="alignment">
<set>Qt::AlignCenter</set>
</property>
</widget>
</item>
<item>
<widget class="ElidedLabel" name="labelKeyId">
<property name="minimumSize">
<size>
<width>0</width>
<height>15</height>
</size>
</property>
<property name="maximumSize">
<size>
<width>100</width>
<height>16777215</height>
</size>
</property>
<property name="text">
<string>KeyId</string>
</property>
<property name="alignment">
<set>Qt::AlignCenter</set>
</property>
</widget>
</item>
<item>
<widget class="ElidedLabel" name="labelGXSId">
<property name="minimumSize">
<size>
<width>0</width>
<height>15</height>
</size>
</property>
<property name="maximumSize">
<size>
<width>100</width>
<height>16777215</height>
</size>
</property>
<property name="text">
<string>GXSId</string>
</property>
<property name="alignment">
<set>Qt::AlignCenter</set>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="pbAdd">
<property name="text">
<string>Add</string>
</property>
</widget>
</item>
</layout>
</widget>
<resources/>
<customwidgets>
<customwidget>
<class>ElidedLabel</class>
<extends>QLabel</extends>
<header location="global">gui/common/ElidedLabel.h</header>
<container>1</container>
</customwidget>
</customwidgets>
<connections/>
</ui>
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>IdentityWidget</class>
<widget class="QWidget" name="IdentityWidget">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>102</width>
<height>170</height>
</rect>
</property>
<layout class="QVBoxLayout" name="verticalLayout">
<property name="spacing">
<number>0</number>
</property>
<property name="margin">
<number>1</number>
</property>
<item>
<widget class="QGraphicsView" name="graphicsView">
<property name="minimumSize">
<size>
<width>100</width>
<height>100</height>
</size>
</property>
<property name="maximumSize">
<size>
<width>100</width>
<height>100</height>
</size>
</property>
<property name="frameShape">
<enum>QFrame::NoFrame</enum>
</property>
<property name="verticalScrollBarPolicy">
<enum>Qt::ScrollBarAlwaysOff</enum>
</property>
<property name="horizontalScrollBarPolicy">
<enum>Qt::ScrollBarAlwaysOff</enum>
</property>
<property name="sceneRect">
<rectf>
<x>0.000000000000000</x>
<y>0.000000000000000</y>
<width>100.000000000000000</width>
<height>100.000000000000000</height>
</rectf>
</property>
<property name="alignment">
<set>Qt::AlignLeading|Qt::AlignLeft|Qt::AlignTop</set>
</property>
</widget>
</item>
<item>
<widget class="ElidedLabel" name="labelName">
<property name="minimumSize">
<size>
<width>0</width>
<height>15</height>
</size>
</property>
<property name="maximumSize">
<size>
<width>100</width>
<height>16777215</height>
</size>
</property>
<property name="text">
<string>Name</string>
</property>
<property name="scaledContents">
<bool>true</bool>
</property>
<property name="alignment">
<set>Qt::AlignCenter</set>
</property>
</widget>
</item>
<item>
<widget class="ElidedLabel" name="labelKeyId">
<property name="minimumSize">
<size>
<width>0</width>
<height>15</height>
</size>
</property>
<property name="maximumSize">
<size>
<width>100</width>
<height>16777215</height>
</size>
</property>
<property name="text">
<string>KeyId</string>
</property>
<property name="alignment">
<set>Qt::AlignCenter</set>
</property>
</widget>
</item>
<item>
<widget class="ElidedLabel" name="labelGXSId">
<property name="minimumSize">
<size>
<width>0</width>
<height>15</height>
</size>
</property>
<property name="maximumSize">
<size>
<width>100</width>
<height>16777215</height>
</size>
</property>
<property name="text">
<string>GXSId</string>
</property>
<property name="alignment">
<set>Qt::AlignCenter</set>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="pbAdd">
<property name="text">
<string>Add</string>
</property>
</widget>
</item>
</layout>
</widget>
<customwidgets>
<customwidget>
<class>ElidedLabel</class>
<extends>QLabel</extends>
<header location="global">gui/common/ElidedLabel.h</header>
<container>1</container>
</customwidget>
</customwidgets>
<resources>
<include location="../images.qrc"/>
</resources>
<connections/>
</ui>

View File

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

View File

@ -1,105 +1,109 @@
/*
* Retroshare Identity.
*
* Copyright 2012-2012 by Robert Fernie.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
* License Version 2.1 as published by the Free Software Foundation.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Library General Public License for more details.
*
* You should have received a copy of the GNU Library General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
* USA.
*
* Please report all bugs and problems to "retroshare@lunamutt.com".
*
*/
#pragma once
#include <map>
#include <retroshare/rsidentity.h>
#include "gui/People/CircleWidget.h"
#include "gui/People/IdentityWidget.h"
#include "gui/gxs/RsGxsUpdateBroadcastPage.h"
#include "util/TokenQueue.h"
#include "ui_PeopleDialog.h"
#define IMAGE_IDENTITY ":/icons/friends_128.png"
class PeopleDialog : public RsGxsUpdateBroadcastPage, public Ui::PeopleDialog, public TokenResponse
{
Q_OBJECT
public:
static const uint32_t PD_IDLIST ;
static const uint32_t PD_IDDETAILS ;
static const uint32_t PD_REFRESH ;
static const uint32_t PD_CIRCLES ;
PeopleDialog(QWidget *parent = 0);
~PeopleDialog();
virtual QIcon iconPixmap() const { return QIcon(IMAGE_IDENTITY) ; } //MainPage
virtual QString pageName() const { return tr("People") ; } //MainPage
virtual QString helpText() const { return ""; } //MainPage
void loadRequest(const TokenQueue * /*queue*/, const TokenRequest &req) ;
void requestIdList() ;
void requestCirclesList() ;
void insertIdList(uint32_t token) ;
void insertCircles(uint32_t token) ;
protected:
// Derives from RsGxsUpdateBroadcastPage
virtual void updateDisplay(bool complete);
//End RsGxsUpdateBroadcastPage
private slots:
void iw_AddButtonClickedExt();
void iw_AddButtonClickedInt();
void addToCircleExt();
void addToCircleInt();
void cw_askForGXSIdentityWidget(RsGxsId gxs_id);
void cw_askForPGPIdentityWidget(RsPgpId pgp_id);
void cw_imageUpdatedExt();
void cw_imageUpdatedInt();
void fl_flowLayoutItemDroppedExt(QList<FlowLayoutItem *> flListItem, bool &bAccept);
void fl_flowLayoutItemDroppedInt(QList<FlowLayoutItem *> flListItem, bool &bAccept);
void pf_centerIndexChanged(int index);
void pf_mouseMoveOverSlideEvent(QMouseEvent* event, int slideIndex);
void pf_dragEnterEventOccurs(QDragEnterEvent *event);
void pf_dragMoveEventOccurs(QDragMoveEvent *event);
void pf_dropEventOccursExt(QDropEvent *event);
void pf_dropEventOccursInt(QDropEvent *event);
private:
void reloadAll();
void populatePictureFlowExt();
void populatePictureFlowInt();
TokenQueue *mIdentityQueue;
TokenQueue *mCirclesQueue;
FlowLayout *_flowLayoutExt;
std::map<RsGxsId,IdentityWidget *> _gxs_identity_widgets ;
std::map<RsGxsGroupId,CircleWidget *> _ext_circles_widgets ;
QList<CircleWidget*> _extListCir;
FlowLayout *_flowLayoutInt;
std::map<RsPgpId,IdentityWidget *> _pgp_identity_widgets ;
std::map<RsGxsGroupId,CircleWidget *> _int_circles_widgets ;
QList<CircleWidget*> _intListCir;
};
/*
* Retroshare Identity.
*
* Copyright 2012-2012 by Robert Fernie.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
* License Version 2.1 as published by the Free Software Foundation.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Library General Public License for more details.
*
* You should have received a copy of the GNU Library General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
* USA.
*
* Please report all bugs and problems to "retroshare@lunamutt.com".
*
*/
#pragma once
#include <map>
#include <retroshare/rsidentity.h>
#include "gui/People/CircleWidget.h"
#include "gui/People/IdentityWidget.h"
#include "gui/gxs/RsGxsUpdateBroadcastPage.h"
#include "util/TokenQueue.h"
#include "ui_PeopleDialog.h"
#define IMAGE_IDENTITY ":/icons/friends_128.png"
class PeopleDialog : public RsGxsUpdateBroadcastPage, public Ui::PeopleDialog, public TokenResponse
{
Q_OBJECT
public:
static const uint32_t PD_IDLIST ;
static const uint32_t PD_IDDETAILS ;
static const uint32_t PD_REFRESH ;
static const uint32_t PD_CIRCLES ;
PeopleDialog(QWidget *parent = 0);
~PeopleDialog();
virtual QIcon iconPixmap() const { return QIcon(IMAGE_IDENTITY) ; } //MainPage
virtual QString pageName() const { return tr("People") ; } //MainPage
virtual QString helpText() const { return ""; } //MainPage
void loadRequest(const TokenQueue * /*queue*/, const TokenRequest &req) ;
void requestIdList() ;
void requestCirclesList() ;
void insertIdList(uint32_t token) ;
void insertCircles(uint32_t token) ;
protected:
// Derives from RsGxsUpdateBroadcastPage
virtual void updateDisplay(bool complete);
//End RsGxsUpdateBroadcastPage
private slots:
void iw_AddButtonClickedExt();
void iw_AddButtonClickedInt();
void addToCircleExt();
void addToCircleInt();
void cw_askForGXSIdentityWidget(RsGxsId gxs_id);
void cw_askForPGPIdentityWidget(RsPgpId pgp_id);
void cw_imageUpdatedExt();
void cw_imageUpdatedInt();
void fl_flowLayoutItemDroppedExt(QList<FlowLayoutItem *> flListItem, bool &bAccept);
void fl_flowLayoutItemDroppedInt(QList<FlowLayoutItem *> flListItem, bool &bAccept);
void pf_centerIndexChanged(int index);
void pf_mouseMoveOverSlideEvent(QMouseEvent* event, int slideIndex);
void pf_dragEnterEventOccurs(QDragEnterEvent *event);
void pf_dragMoveEventOccurs(QDragMoveEvent *event);
void pf_dropEventOccursExt(QDropEvent *event);
void pf_dropEventOccursInt(QDropEvent *event);
void chatIdentity();
void sendMessage();
void personDetails();
private:
void reloadAll();
void populatePictureFlowExt();
void populatePictureFlowInt();
TokenQueue *mIdentityQueue;
TokenQueue *mCirclesQueue;
FlowLayout *_flowLayoutExt;
std::map<RsGxsId,IdentityWidget *> _gxs_identity_widgets ;
std::map<RsGxsGroupId,CircleWidget *> _ext_circles_widgets ;
QList<CircleWidget*> _extListCir;
FlowLayout *_flowLayoutInt;
std::map<RsPgpId,IdentityWidget *> _pgp_identity_widgets ;
std::map<RsGxsGroupId,CircleWidget *> _int_circles_widgets ;
QList<CircleWidget*> _intListCir;
};

View File

@ -1,265 +1,259 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>PeopleDialog</class>
<widget class="QWidget" name="PeopleDialog">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>727</width>
<height>524</height>
</rect>
</property>
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="windowTitle">
<string/>
</property>
<layout class="QGridLayout" name="titleBarLayout">
<property name="leftMargin">
<number>0</number>
</property>
<property name="topMargin">
<number>0</number>
</property>
<property name="rightMargin">
<number>0</number>
</property>
<property name="bottomMargin">
<number>0</number>
</property>
<item row="0" column="0">
<widget class="QFrame" name="titleBarFrame">
<property name="frameShape">
<enum>QFrame::Box</enum>
</property>
<property name="frameShadow">
<enum>QFrame::Sunken</enum>
</property>
<layout class="QHBoxLayout">
<property name="margin">
<number>2</number>
</property>
<item>
<widget class="QLabel" name="titleBarPixmap">
<property name="minimumSize">
<size>
<width>0</width>
<height>0</height>
</size>
</property>
<property name="maximumSize">
<size>
<width>24</width>
<height>24</height>
</size>
</property>
<property name="text">
<string/>
</property>
<property name="pixmap">
<pixmap resource="../images.qrc">:/images/identity/identities_32.png</pixmap>
</property>
<property name="scaledContents">
<bool>true</bool>
</property>
</widget>
</item>
<item>
<widget class="StyledLabel" name="titleBarLabel">
<property name="text">
<string>People</string>
</property>
</widget>
</item>
<item>
<spacer name="titleBarSpacer">
<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="1" column="0">
<widget class="QTabWidget" name="tabWidget">
<property name="currentIndex">
<number>0</number>
</property>
<widget class="QWidget" name="tabExternal">
<property name="sizePolicy">
<sizepolicy hsizetype="Expanding" vsizetype="Expanding">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<attribute name="title">
<string>External</string>
</attribute>
<layout class="QVBoxLayout">
<item>
<widget class="QSplitter" name="splitterExternal">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<widget class="QScrollArea" name="scrollAreaExternal">
<property name="minimumSize">
<size>
<width>0</width>
<height>250</height>
</size>
</property>
<property name="widgetResizable">
<bool>true</bool>
</property>
<widget class="FlowLayoutWidget" name="idExternal">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>685</width>
<height>248</height>
</rect>
</property>
<layout class="QVBoxLayout"/>
</widget>
</widget>
<widget class="QWidget" name="widgetExternal">
<layout class="QGridLayout" name="layoutExternal">
<item row="0" column="0">
<widget class="QLabel" name="label_External">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="text">
<string>Drag your circles or people to each other.</string>
</property>
<property name="alignment">
<set>Qt::AlignCenter</set>
</property>
</widget>
</item>
<item row="1" column="0">
<widget class="PictureFlow" name="pictureFlowWidgetExternal" native="true">
<property name="widgetResizable" stdset="0">
<bool>true</bool>
</property>
</widget>
</item>
</layout>
</widget>
</widget>
</item>
</layout>
</widget>
<widget class="QWidget" name="tabInternal">
<property name="sizePolicy">
<sizepolicy hsizetype="Expanding" vsizetype="Expanding">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<attribute name="title">
<string>Internal</string>
</attribute>
<layout class="QVBoxLayout">
<item>
<widget class="QSplitter" name="splitterInternal">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<widget class="QScrollArea" name="scrollAreaInternal">
<property name="minimumSize">
<size>
<width>0</width>
<height>250</height>
</size>
</property>
<property name="widgetResizable">
<bool>true</bool>
</property>
<widget class="FlowLayoutWidget" name="idInternal">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>685</width>
<height>248</height>
</rect>
</property>
<layout class="QVBoxLayout"/>
</widget>
</widget>
<widget class="QWidget" name="widgetInternal">
<layout class="QGridLayout" name="layoutInternal">
<item row="0" column="0">
<widget class="QLabel" name="label_Internal">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="text">
<string>Drag your circles or people to each other.</string>
</property>
<property name="alignment">
<set>Qt::AlignCenter</set>
</property>
</widget>
</item>
<item row="1" column="0">
<widget class="PictureFlow" name="pictureFlowWidgetInternal" native="true">
<property name="widgetResizable" stdset="0">
<bool>true</bool>
</property>
</widget>
</item>
</layout>
</widget>
</widget>
</item>
</layout>
</widget>
</widget>
</item>
</layout>
</widget>
<customwidgets>
<customwidget>
<class>StyledLabel</class>
<extends>QLabel</extends>
<header>gui/common/StyledLabel.h</header>
</customwidget>
<customwidget>
<class>PictureFlow</class>
<extends>QWidget</extends>
<header location="global">gui/common/PictureFlow.h</header>
<container>1</container>
</customwidget>
<customwidget>
<class>FlowLayoutWidget</class>
<extends>QWidget</extends>
<header location="global">gui/common/FlowLayout.h</header>
<container>1</container>
</customwidget>
</customwidgets>
<resources>
<include location="../images.qrc"/>
</resources>
<connections/>
</ui>
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>PeopleDialog</class>
<widget class="QWidget" name="PeopleDialog">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>727</width>
<height>524</height>
</rect>
</property>
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="windowTitle">
<string/>
</property>
<layout class="QGridLayout" name="titleBarLayout">
<property name="margin">
<number>0</number>
</property>
<item row="0" column="0">
<widget class="QFrame" name="titleBarFrame">
<property name="frameShape">
<enum>QFrame::Box</enum>
</property>
<property name="frameShadow">
<enum>QFrame::Sunken</enum>
</property>
<layout class="QHBoxLayout">
<property name="margin">
<number>2</number>
</property>
<item>
<widget class="QLabel" name="titleBarPixmap">
<property name="minimumSize">
<size>
<width>0</width>
<height>0</height>
</size>
</property>
<property name="maximumSize">
<size>
<width>24</width>
<height>24</height>
</size>
</property>
<property name="text">
<string/>
</property>
<property name="pixmap">
<pixmap resource="../images.qrc">:/images/identity/identities_32.png</pixmap>
</property>
<property name="scaledContents">
<bool>true</bool>
</property>
</widget>
</item>
<item>
<widget class="StyledLabel" name="titleBarLabel">
<property name="text">
<string>People</string>
</property>
</widget>
</item>
<item>
<spacer name="titleBarSpacer">
<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="1" column="0">
<widget class="QTabWidget" name="tabWidget">
<property name="enabled">
<bool>true</bool>
</property>
<property name="currentIndex">
<number>1</number>
</property>
<widget class="QWidget" name="tabExternal">
<property name="sizePolicy">
<sizepolicy hsizetype="Expanding" vsizetype="Expanding">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<attribute name="title">
<string>People</string>
</attribute>
<layout class="QVBoxLayout">
<item>
<widget class="QSplitter" name="splitterExternal">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<widget class="QScrollArea" name="scrollAreaExternal">
<property name="minimumSize">
<size>
<width>0</width>
<height>250</height>
</size>
</property>
<property name="widgetResizable">
<bool>true</bool>
</property>
<widget class="FlowLayoutWidget" name="idExternal">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>701</width>
<height>248</height>
</rect>
</property>
<layout class="QVBoxLayout"/>
</widget>
</widget>
<widget class="QWidget" name="widgetExternal">
<layout class="QGridLayout" name="layoutExternal">
<item row="0" column="0">
<widget class="QLabel" name="label_External">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="text">
<string>Drag your circles or people to each other.</string>
</property>
<property name="alignment">
<set>Qt::AlignCenter</set>
</property>
</widget>
</item>
<item row="1" column="0">
<widget class="PictureFlow" name="pictureFlowWidgetExternal" native="true">
<property name="widgetResizable" stdset="0">
<bool>true</bool>
</property>
</widget>
</item>
</layout>
</widget>
</widget>
</item>
</layout>
</widget>
<widget class="QWidget" name="tabInternal">
<property name="sizePolicy">
<sizepolicy hsizetype="Expanding" vsizetype="Expanding">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<attribute name="title">
<string>Internal</string>
</attribute>
<layout class="QVBoxLayout">
<item>
<widget class="QSplitter" name="splitterInternal">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<widget class="QScrollArea" name="scrollAreaInternal">
<property name="minimumSize">
<size>
<width>0</width>
<height>250</height>
</size>
</property>
<property name="widgetResizable">
<bool>true</bool>
</property>
<widget class="FlowLayoutWidget" name="idInternal">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>701</width>
<height>248</height>
</rect>
</property>
<layout class="QVBoxLayout"/>
</widget>
</widget>
<widget class="QWidget" name="widgetInternal">
<layout class="QGridLayout" name="layoutInternal">
<item row="0" column="0">
<widget class="QLabel" name="label_Internal">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="text">
<string>Drag your circles or people to each other.</string>
</property>
<property name="alignment">
<set>Qt::AlignCenter</set>
</property>
</widget>
</item>
<item row="1" column="0">
<widget class="PictureFlow" name="pictureFlowWidgetInternal" native="true">
<property name="widgetResizable" stdset="0">
<bool>true</bool>
</property>
</widget>
</item>
</layout>
</widget>
</widget>
</item>
</layout>
</widget>
</widget>
</item>
</layout>
</widget>
<customwidgets>
<customwidget>
<class>StyledLabel</class>
<extends>QLabel</extends>
<header>gui/common/StyledLabel.h</header>
</customwidget>
<customwidget>
<class>PictureFlow</class>
<extends>QWidget</extends>
<header location="global">gui/common/PictureFlow.h</header>
<container>1</container>
</customwidget>
<customwidget>
<class>FlowLayoutWidget</class>
<extends>QWidget</extends>
<header location="global">gui/common/FlowLayout.h</header>
<container>1</container>
</customwidget>
</customwidgets>
<resources>
<include location="../images.qrc"/>
</resources>
<connections/>
</ui>

View File

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

View File

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

View File

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

View File

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

View File

@ -58,7 +58,12 @@ public:
bool setChosenId(const 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:
// emitted after first load of own ids
void idsLoaded();
@ -79,7 +84,9 @@ private:
uint32_t mFlags;
RsGxsId mDefaultId;
bool mFirstLoad;
uint32_t mAllowedCount ;
std::set<RsGxsId> mConstraintIdsSet ; // leave empty if all allowed
RsGxsUpdateBroadcastBase *mBase;
};

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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