merged upstream/master

This commit is contained in:
csoler 2017-02-08 20:40:47 +01:00
commit 6681985634
48 changed files with 1681 additions and 655 deletions

View File

@ -1,7 +1,7 @@
ZLIB_VERSION=1.2.3
BZIP2_VERSION=1.0.6
MINIUPNPC_VERSION=2.0
OPENSSL_VERSION=1.0.2h
OPENSSL_VERSION=1.0.2k
SPEEX_VERSION=1.2rc2
SPEEXDSP_VERSION=1.2rc3
OPENCV_VERSION=2.4.13

View File

@ -109,7 +109,7 @@ void ForumHandler::handleWildcard(Request &req, Response &resp)
//KeyValueReference<RsPgpId> pgp_id("pgp_id",grp.mPgpId );
// not very happy about this, i think the flags should stay hidden in rsidentities
bool own = (grp.mMeta.mSubscribeFlags & GXS_SERV::GROUP_SUBSCRIBE_ADMIN);
bool pgp_linked = (grp.mMeta.mGroupFlags & RSGXSID_GROUPFLAG_REALID);
bool pgp_linked = (grp.mMeta.mGroupFlags & RSGXSID_GROUPFLAG_REALID_kept_for_compatibility);
bool subscribed = IS_GROUP_SUBSCRIBED(grp.mMeta.mSubscribeFlags);
resp.mDataStream.getStreamToMember()
<< id

View File

@ -156,8 +156,8 @@ void IdentityHandler::handleWildcard(Request & /*req*/, Response &resp)
RsGxsIdGroup& grp = *vit;
//electron: not very happy about this, i think the flags should stay hidden in rsidentities
bool own = (grp.mMeta.mSubscribeFlags & GXS_SERV::GROUP_SUBSCRIBE_ADMIN);
bool pgp_linked = (grp.mMeta.mGroupFlags & RSGXSID_GROUPFLAG_REALID);
resp.mDataStream.getStreamToMember()
bool pgp_linked = (grp.mMeta.mGroupFlags & RSGXSID_GROUPFLAG_REALID_kept_for_compatibility ) ;
resp.mDataStream.getStreamToMember()
<< makeKeyValueReference("id", grp.mMeta.mGroupId) /// @deprecated using "id" as key can cause problems in some JS based languages like Qml @see gxs_id instead
<< makeKeyValueReference("gxs_id", grp.mMeta.mGroupId)
<< makeKeyValueReference("pgp_id",grp.mPgpId )

View File

@ -739,26 +739,29 @@ bool LocalDirectoryStorage::serialiseDirEntry(const EntryIndex& indx,RsTlvBinary
//
std::string virtual_dir_name = locked_getVirtualDirName(indx) ;
if(!FileListIO::writeField(section_data,section_size,section_offset,FILE_LIST_IO_TAG_DIR_NAME ,virtual_dir_name )) return false ;
if(!FileListIO::writeField(section_data,section_size,section_offset,FILE_LIST_IO_TAG_RECURS_MODIF_TS,(uint32_t)dir->dir_most_recent_time)) return false ;
if(!FileListIO::writeField(section_data,section_size,section_offset,FILE_LIST_IO_TAG_MODIF_TS ,(uint32_t)dir->dir_modtime )) return false ;
if(!FileListIO::writeField(section_data,section_size,section_offset,FILE_LIST_IO_TAG_DIR_NAME ,virtual_dir_name )) { free(section_data); return false ;}
if(!FileListIO::writeField(section_data,section_size,section_offset,FILE_LIST_IO_TAG_RECURS_MODIF_TS,(uint32_t)dir->dir_most_recent_time)) { free(section_data); return false ;}
if(!FileListIO::writeField(section_data,section_size,section_offset,FILE_LIST_IO_TAG_MODIF_TS ,(uint32_t)dir->dir_modtime )) { free(section_data); return false ;}
// serialise number of subdirs and number of subfiles
if(!FileListIO::writeField(section_data,section_size,section_offset,FILE_LIST_IO_TAG_RAW_NUMBER,(uint32_t)allowed_subdirs.size() )) return false ;
if(!FileListIO::writeField(section_data,section_size,section_offset,FILE_LIST_IO_TAG_RAW_NUMBER,(uint32_t)allowed_subfiles )) return false ;
if(!FileListIO::writeField(section_data,section_size,section_offset,FILE_LIST_IO_TAG_RAW_NUMBER,(uint32_t)allowed_subdirs.size() )) { free(section_data); return false ;}
if(!FileListIO::writeField(section_data,section_size,section_offset,FILE_LIST_IO_TAG_RAW_NUMBER,(uint32_t)allowed_subfiles )) { free(section_data); return false ;}
// serialise subdirs entry indexes
for(uint32_t i=0;i<allowed_subdirs.size();++i)
if(!FileListIO::writeField(section_data,section_size,section_offset,FILE_LIST_IO_TAG_ENTRY_INDEX ,allowed_subdirs[i] )) return false ;
if(!FileListIO::writeField(section_data,section_size,section_offset,FILE_LIST_IO_TAG_ENTRY_INDEX ,allowed_subdirs[i] )) { free(section_data); return false ;}
// serialise directory subfiles, with info for each of them
unsigned char *file_section_data = (unsigned char *)rs_malloc(FL_BASE_TMP_SECTION_SIZE) ;
if(!file_section_data)
{
free(section_data);
return false ;
}
uint32_t file_section_size = FL_BASE_TMP_SECTION_SIZE ;
@ -774,14 +777,14 @@ bool LocalDirectoryStorage::serialiseDirEntry(const EntryIndex& indx,RsTlvBinary
continue ;
}
if(!FileListIO::writeField(file_section_data,file_section_size,file_section_offset,FILE_LIST_IO_TAG_FILE_NAME ,file->file_name )) return false ;
if(!FileListIO::writeField(file_section_data,file_section_size,file_section_offset,FILE_LIST_IO_TAG_FILE_SIZE ,file->file_size )) return false ;
if(!FileListIO::writeField(file_section_data,file_section_size,file_section_offset,FILE_LIST_IO_TAG_FILE_SHA1_HASH,file->file_hash )) return false ;
if(!FileListIO::writeField(file_section_data,file_section_size,file_section_offset,FILE_LIST_IO_TAG_MODIF_TS ,(uint32_t)file->file_modtime)) return false ;
if(!FileListIO::writeField(file_section_data,file_section_size,file_section_offset,FILE_LIST_IO_TAG_FILE_NAME ,file->file_name )) { free(section_data);free(file_section_data);return false ;}
if(!FileListIO::writeField(file_section_data,file_section_size,file_section_offset,FILE_LIST_IO_TAG_FILE_SIZE ,file->file_size )) { free(section_data);free(file_section_data);return false ;}
if(!FileListIO::writeField(file_section_data,file_section_size,file_section_offset,FILE_LIST_IO_TAG_FILE_SHA1_HASH,file->file_hash )) { free(section_data);free(file_section_data);return false ;}
if(!FileListIO::writeField(file_section_data,file_section_size,file_section_offset,FILE_LIST_IO_TAG_MODIF_TS ,(uint32_t)file->file_modtime)) { free(section_data);free(file_section_data);return false ;}
// now write the whole string into a single section in the file
if(!FileListIO::writeField(section_data,section_size,section_offset,FILE_LIST_IO_TAG_REMOTE_FILE_ENTRY,file_section_data,file_section_offset)) return false ;
if(!FileListIO::writeField(section_data,section_size,section_offset,FILE_LIST_IO_TAG_REMOTE_FILE_ENTRY,file_section_data,file_section_offset)) { free(section_data); free(file_section_data);return false ;}
#ifdef DEBUG_LOCAL_DIRECTORY_STORAGE
std::cerr << " pushing subfile " << file->hash << ", array position=" << i << " indx=" << dir->subfiles[i] << std::endl;
@ -793,7 +796,7 @@ bool LocalDirectoryStorage::serialiseDirEntry(const EntryIndex& indx,RsTlvBinary
std::cerr << "Serialised dir entry to send for entry index " << (void*)(intptr_t)indx << ". Data size is " << section_size << " bytes" << std::endl;
#endif
bindata.bin_data = section_data ;
bindata.bin_data = realloc(section_data,section_offset) ; // This discards the possibly unused trailing bytes in the end of section_data
bindata.bin_len = section_offset ;
return true ;
@ -865,6 +868,9 @@ bool RemoteDirectoryStorage::deserialiseUpdateDirEntry(const EntryIndex& indx,co
// deserialise directory subfiles, with info for each of them
std::vector<InternalFileHierarchyStorage::FileEntry> subfiles_array ;
// Pre-allocate file_section_data, so that read_field does not need to do it many times.
unsigned char *file_section_data = (unsigned char *)rs_malloc(FL_BASE_TMP_SECTION_SIZE) ;
if(!file_section_data)
@ -876,17 +882,17 @@ bool RemoteDirectoryStorage::deserialiseUpdateDirEntry(const EntryIndex& indx,co
{
// Read the full data section for the file
if(!FileListIO::readField(section_data,section_size,section_offset,FILE_LIST_IO_TAG_REMOTE_FILE_ENTRY,file_section_data,file_section_size)) return false ;
if(!FileListIO::readField(section_data,section_size,section_offset,FILE_LIST_IO_TAG_REMOTE_FILE_ENTRY,file_section_data,file_section_size)) { free(file_section_data); return false ; }
uint32_t file_section_offset = 0 ;
InternalFileHierarchyStorage::FileEntry f;
uint32_t modtime =0;
if(!FileListIO::readField(file_section_data,file_section_size,file_section_offset,FILE_LIST_IO_TAG_FILE_NAME ,f.file_name )) return false ;
if(!FileListIO::readField(file_section_data,file_section_size,file_section_offset,FILE_LIST_IO_TAG_FILE_SIZE ,f.file_size )) return false ;
if(!FileListIO::readField(file_section_data,file_section_size,file_section_offset,FILE_LIST_IO_TAG_FILE_SHA1_HASH,f.file_hash )) return false ;
if(!FileListIO::readField(file_section_data,file_section_size,file_section_offset,FILE_LIST_IO_TAG_MODIF_TS ,modtime )) return false ;
if(!FileListIO::readField(file_section_data,file_section_size,file_section_offset,FILE_LIST_IO_TAG_FILE_NAME ,f.file_name )) { free(file_section_data); return false ; }
if(!FileListIO::readField(file_section_data,file_section_size,file_section_offset,FILE_LIST_IO_TAG_FILE_SIZE ,f.file_size )) { free(file_section_data); return false ; }
if(!FileListIO::readField(file_section_data,file_section_size,file_section_offset,FILE_LIST_IO_TAG_FILE_SHA1_HASH,f.file_hash )) { free(file_section_data); return false ; }
if(!FileListIO::readField(file_section_data,file_section_size,file_section_offset,FILE_LIST_IO_TAG_MODIF_TS ,modtime )) { free(file_section_data); return false ; }
f.file_modtime = modtime ;

View File

@ -59,16 +59,16 @@ bool FileListIO::writeField( unsigned char*&buff,uint32_t& buff_size,uint32
bool FileListIO::readField (const unsigned char *buff,uint32_t buff_size,uint32_t& offset,uint8_t check_section_tag, unsigned char *& val,uint32_t& size)
{
if(!readSectionHeader(buff,buff_size,offset,check_section_tag,size))
uint32_t local_size ;
if(!readSectionHeader(buff,buff_size,offset,check_section_tag,local_size))
return false;
val = (unsigned char *)rs_malloc(size) ;
if(!val)
if(!checkSectionSize(val,size,0,local_size)) // allocate val if needed to handle local_size bytes.
return false;
memcpy(val,&buff[offset],size);
offset += size ;
memcpy(val,&buff[offset],local_size);
offset += local_size ;
return true ;
}

View File

@ -365,13 +365,16 @@ bool HashStorage::readHashStorageInfo(const unsigned char *data,uint32_t total_s
// of a section because of some unknown field, etc.
if(!FileListIO::readField(data,total_size,offset,FILE_LIST_IO_TAG_HASH_STORAGE_ENTRY,section_data,section_size))
return false;
{
free(section_data);
return false;
}
if(!FileListIO::readField(section_data,section_size,section_offset,FILE_LIST_IO_TAG_FILE_NAME ,info.filename )) return false ;
if(!FileListIO::readField(section_data,section_size,section_offset,FILE_LIST_IO_TAG_FILE_SIZE ,info.size )) return false ;
if(!FileListIO::readField(section_data,section_size,section_offset,FILE_LIST_IO_TAG_UPDATE_TS ,info.time_stamp)) return false ;
if(!FileListIO::readField(section_data,section_size,section_offset,FILE_LIST_IO_TAG_MODIF_TS ,info.modf_stamp)) return false ;
if(!FileListIO::readField(section_data,section_size,section_offset,FILE_LIST_IO_TAG_FILE_SHA1_HASH,info.hash )) return false ;
if(!FileListIO::readField(section_data,section_size,section_offset,FILE_LIST_IO_TAG_FILE_NAME ,info.filename )) { free(section_data); return false ; }
if(!FileListIO::readField(section_data,section_size,section_offset,FILE_LIST_IO_TAG_FILE_SIZE ,info.size )) { free(section_data); return false ; }
if(!FileListIO::readField(section_data,section_size,section_offset,FILE_LIST_IO_TAG_UPDATE_TS ,info.time_stamp)) { free(section_data); return false ; }
if(!FileListIO::readField(section_data,section_size,section_offset,FILE_LIST_IO_TAG_MODIF_TS ,info.modf_stamp)) { free(section_data); return false ; }
if(!FileListIO::readField(section_data,section_size,section_offset,FILE_LIST_IO_TAG_FILE_SHA1_HASH,info.hash )) { free(section_data); return false ; }
free(section_data);
return true;
@ -387,11 +390,11 @@ bool HashStorage::writeHashStorageInfo(unsigned char *& data,uint32_t& total_si
uint32_t section_offset = 0 ;
uint32_t section_size = FL_BASE_TMP_SECTION_SIZE;
if(!FileListIO::writeField(section_data,section_size,section_offset,FILE_LIST_IO_TAG_FILE_NAME ,info.filename )) return false ;
if(!FileListIO::writeField(section_data,section_size,section_offset,FILE_LIST_IO_TAG_FILE_SIZE ,info.size )) return false ;
if(!FileListIO::writeField(section_data,section_size,section_offset,FILE_LIST_IO_TAG_UPDATE_TS ,info.time_stamp)) return false ;
if(!FileListIO::writeField(section_data,section_size,section_offset,FILE_LIST_IO_TAG_MODIF_TS ,info.modf_stamp)) return false ;
if(!FileListIO::writeField(section_data,section_size,section_offset,FILE_LIST_IO_TAG_FILE_SHA1_HASH,info.hash )) return false ;
if(!FileListIO::writeField(section_data,section_size,section_offset,FILE_LIST_IO_TAG_FILE_NAME ,info.filename )) { free(section_data); return false ; }
if(!FileListIO::writeField(section_data,section_size,section_offset,FILE_LIST_IO_TAG_FILE_SIZE ,info.size )) { free(section_data); return false ; }
if(!FileListIO::writeField(section_data,section_size,section_offset,FILE_LIST_IO_TAG_UPDATE_TS ,info.time_stamp)) { free(section_data); return false ; }
if(!FileListIO::writeField(section_data,section_size,section_offset,FILE_LIST_IO_TAG_MODIF_TS ,info.modf_stamp)) { free(section_data); return false ; }
if(!FileListIO::writeField(section_data,section_size,section_offset,FILE_LIST_IO_TAG_FILE_SHA1_HASH,info.hash )) { free(section_data); return false ; }
// now write the whole string into a single section in the file

View File

@ -876,7 +876,7 @@ bool ftController::FileRequest(const std::string& fname, const RsFileHash& hash
// if policy is STRICT
// - disable clear, enforce encryption
// else
// - if not specified, use clear
// - if not specified, use both
//
if(mDefaultEncryptionPolicy == RS_FILE_CTRL_ENCRYPTION_POLICY_STRICT)
{
@ -884,7 +884,10 @@ bool ftController::FileRequest(const std::string& fname, const RsFileHash& hash
flags &= ~RS_FILE_REQ_UNENCRYPTED ;
}
else if(!(flags & ( RS_FILE_REQ_ENCRYPTED | RS_FILE_REQ_UNENCRYPTED )))
flags |= RS_FILE_REQ_UNENCRYPTED ;
{
flags |= RS_FILE_REQ_ENCRYPTED ;
flags |= RS_FILE_REQ_UNENCRYPTED ;
}
if(size == 0) // we treat this special case because
{

View File

@ -1569,7 +1569,9 @@ bool RsGenExchange::checkGroupMetaConsistency(const RsGroupMetaData& meta)
return false;
}
if(meta.mGroupFlags != GXS_SERV::FLAG_PRIVACY_PUBLIC && meta.mGroupFlags != GXS_SERV::FLAG_PRIVACY_RESTRICTED && meta.mGroupFlags != GXS_SERV::FLAG_PRIVACY_PRIVATE)
uint32_t gf = meta.mGroupFlags & GXS_SERV::FLAG_PRIVACY_MASK ;
if(gf != GXS_SERV::FLAG_PRIVACY_PUBLIC && gf != GXS_SERV::FLAG_PRIVACY_RESTRICTED && gf != GXS_SERV::FLAG_PRIVACY_PRIVATE)
{
std::cerr << "(EE) mGroupFlags has incorrect value " << std::hex << meta.mGroupFlags << std::dec << ". A value among GXS_SERV::FLAG_PRIVACY_{PUBLIC,RESTRICTED,PRIVATE} is expected." << std::endl;
return false ;

View File

@ -177,7 +177,7 @@ class RsGixsReputation
{
public:
// get Reputation.
virtual RsReputations::ReputationLevel overallReputationLevel(const RsGxsId& id) = 0;
virtual RsReputations::ReputationLevel overallReputationLevel(const RsGxsId& id,uint32_t *identity_flags=NULL) = 0;
};
/*** This Class pulls all the GXS Interfaces together ****/

View File

@ -457,45 +457,6 @@ void RsGxsNetService::cleanRejectedMessages()
++it ;
}
// temporary holds a map of pointers to class T, and destroys all pointers on delete.
template<class T>
class RsGxsMetaDataTemporaryMap: public std::map<RsGxsGroupId,T*>
{
public:
virtual ~RsGxsMetaDataTemporaryMap()
{
clear() ;
}
virtual void clear()
{
for(typename RsGxsMetaDataTemporaryMap<T>::iterator it = this->begin();it!=this->end();++it)
if(it->second != NULL)
delete it->second ;
std::map<RsGxsGroupId,T*>::clear() ;
}
};
template<class T>
class RsGxsMetaDataTemporaryMapVector: public std::vector<T*>
{
public:
virtual ~RsGxsMetaDataTemporaryMapVector()
{
clear() ;
}
virtual void clear()
{
for(typename RsGxsMetaDataTemporaryMapVector<T>::iterator it = this->begin();it!=this->end();++it)
if(it->second != NULL)
delete it->second ;
std::vector<T*>::clear() ;
}
};
RsGxsGroupId RsGxsNetService::hashGrpId(const RsGxsGroupId& gid,const RsPeerId& pid)
{
static const uint32_t SIZE = RsGxsGroupId::SIZE_IN_BYTES + RsPeerId::SIZE_IN_BYTES ;
@ -2973,9 +2934,8 @@ void RsGxsNetService::locked_genReqGrpTransaction(NxsTransaction* tr)
GXSNETDEBUG_P_(tr->mTransaction->PeerId()) << "locked_genReqGrpTransaction(): " << std::endl;
#endif
RsGxsMetaDataTemporaryMap<RsGxsGrpMetaData> grpMetaMap;
std::list<RsNxsSyncGrpItem*> grpItemL;
RsGxsMetaDataTemporaryMap<RsGxsGrpMetaData> grpMetaMap;
for(std::list<RsNxsItem*>::iterator lit = tr->mItems.begin(); lit != tr->mItems.end(); ++lit)
{
@ -2993,7 +2953,23 @@ void RsGxsNetService::locked_genReqGrpTransaction(NxsTransaction* tr)
}
if (grpItemL.empty())
return;
{
// Normally the client grp updateTS is set after the transaction, but if no transaction is to happen, we have to set it here.
// Possible change: always do the update of the grpClientTS here. Needs to be tested...
RsGxsGrpUpdate& item (mClientGrpUpdateMap[tr->mTransaction->PeerId()]);
#ifdef NXS_NET_DEBUG_0
GXSNETDEBUG_P_(tr->mTransaction->PeerId()) << " reqList is empty, updating anyway ClientGrpUpdate TS for peer " << tr->mTransaction->PeerId() << " to: " << tr->mTransaction->updateTS << std::endl;
#endif
if(item.grpUpdateTS != tr->mTransaction->updateTS)
{
item.grpUpdateTS = tr->mTransaction->updateTS;
IndicateConfigChanged();
}
return;
}
mDataStore->retrieveGxsGrpMetaData(grpMetaMap);
@ -3038,16 +3014,23 @@ void RsGxsNetService::locked_genReqGrpTransaction(NxsTransaction* tr)
if(!reqList.empty())
locked_pushGrpTransactionFromList(reqList, tr->mTransaction->PeerId(), transN);
else
{
RsGxsGrpUpdate& item (mClientGrpUpdateMap[tr->mTransaction->PeerId()]);
{
// Normally the client grp updateTS is set after the transaction, but if no transaction is to happen, we have to set it here.
// Possible change: always do the update of the grpClientTS here. Needs to be tested...
RsGxsGrpUpdate& item (mClientGrpUpdateMap[tr->mTransaction->PeerId()]);
#ifdef NXS_NET_DEBUG_0
GXSNETDEBUG_P_(tr->mTransaction->PeerId()) << " reqList is empty, updating anyway ClientGrpUpdate TS for peer " << tr->mTransaction->PeerId() << " to: " << tr->mTransaction->updateTS << std::endl;
GXSNETDEBUG_P_(tr->mTransaction->PeerId()) << " reqList is empty, updating anyway ClientGrpUpdate TS for peer " << tr->mTransaction->PeerId() << " to: " << tr->mTransaction->updateTS << std::endl;
#endif
item.grpUpdateTS = tr->mTransaction->updateTS;
IndicateConfigChanged();
}
if(item.grpUpdateTS != tr->mTransaction->updateTS)
{
item.grpUpdateTS = tr->mTransaction->updateTS;
IndicateConfigChanged();
}
}
}
void RsGxsNetService::locked_genSendGrpsTransaction(NxsTransaction* tr)
@ -4196,6 +4179,7 @@ void RsGxsNetService::handleRecvSyncMessage(RsNxsSyncMsgReqItem *item,bool item_
delete *it ;
itemL.clear() ;
delete mItem ;
break ;
}
}
@ -4793,6 +4777,7 @@ bool RsGxsNetService::removeGroups(const std::list<RsGxsGroupId>& groups)
}
IndicateConfigChanged();
return true ;
}
bool RsGxsNetService::stampMsgServerUpdateTS(const RsGxsGroupId& gid)

View File

@ -49,6 +49,70 @@ void freeAndClearContainerResource(Container container)
container.clear();
}
// temporary holds a map of pointers to class T, and destroys all pointers on delete.
template<class T>
class RsGxsMetaDataTemporaryMap: public std::map<RsGxsGroupId,T*>
{
public:
virtual ~RsGxsMetaDataTemporaryMap()
{
clear() ;
}
virtual void clear()
{
for(typename RsGxsMetaDataTemporaryMap<T>::iterator it = this->begin();it!=this->end();++it)
if(it->second != NULL)
delete it->second ;
std::map<RsGxsGroupId,T*>::clear() ;
}
};
template<class T>
class RsGxsMetaDataTemporaryMapVector: public std::map<RsGxsGroupId,std::vector<T*> >
{
public:
virtual ~RsGxsMetaDataTemporaryMapVector()
{
clear() ;
}
virtual void clear()
{
for(typename RsGxsMetaDataTemporaryMapVector<T>::iterator it = this->begin();it!=this->end();++it)
{
for(uint32_t i=0;i<it->second.size();++i)
delete it->second[i] ;
it->second.clear();
}
std::map<RsGxsGroupId,std::vector<T*> >::clear() ;
}
};
#ifdef UNUSED
template<class T>
class RsGxsMetaDataTemporaryMapVector: public std::vector<T*>
{
public:
virtual ~RsGxsMetaDataTemporaryMapVector()
{
clear() ;
}
virtual void clear()
{
for(typename RsGxsMetaDataTemporaryMapVector<T>::iterator it = this->begin();it!=this->end();++it)
if(it->second != NULL)
delete it->second ;
std::vector<T*>::clear() ;
}
};
#endif
inline RsGxsGrpMsgIdPair getMsgIdPair(RsNxsMsg& msg)
{
return RsGxsGrpMsgIdPair(std::make_pair(msg.grpId, msg.msgId));

View File

@ -43,8 +43,12 @@ extern RsIdentity *rsIdentity;
// GroupFlags: Only one so far:
#warning THIS FLAG OVERLAPS THE FLAGS FOR mGroupFlags. This is an error that should be fixed.
#define RSGXSID_GROUPFLAG_REALID 0x0001
// The deprecated flag overlaps the privacy flags for mGroupFlags. This is an error that should be fixed. For the sake of keeping some
// backward compatibility, we need to make the change step by step.
#define RSGXSID_GROUPFLAG_REALID_kept_for_compatibility 0x0001
#define RSGXSID_GROUPFLAG_REALID 0x0100
// THESE ARE FLAGS FOR INTERFACE.
#define RSID_TYPE_MASK 0xff00

View File

@ -48,7 +48,7 @@ public:
struct ReputationInfo
{
ReputationInfo() : mOwnOpinion(OPINION_NEUTRAL), mFriendAverageScore(REPUTATION_THRESHOLD_DEFAULT),mOverallReputationLevel(REPUTATION_NEUTRAL){}
ReputationInfo() : mOwnOpinion(OPINION_NEUTRAL),mFriendsPositiveVotes(0),mFriendsNegativeVotes(0), mFriendAverageScore(REPUTATION_THRESHOLD_DEFAULT),mOverallReputationLevel(REPUTATION_NEUTRAL){}
RsReputations::Opinion mOwnOpinion ;
@ -63,7 +63,10 @@ public:
virtual bool setOwnOpinion(const RsGxsId& key_id, const Opinion& op) =0;
virtual bool getOwnOpinion(const RsGxsId& key_id, Opinion& op) =0;
virtual bool getReputationInfo(const RsGxsId& id, const RsPgpId &ownerNode, ReputationInfo& info,bool stamp=true) =0;
virtual ReputationLevel overallReputationLevel(const RsGxsId& id)=0;
// This returns the reputation level and also the flags of the identity service for that id. This is useful in order to get these flags without relying on the async method of p3Identity
virtual ReputationLevel overallReputationLevel(const RsGxsId& id,uint32_t *identity_flags=NULL)=0;
// parameters

View File

@ -1073,6 +1073,8 @@ std::string p3Peers::getPGPKey(const RsPgpId& pgp_id,bool include_signatures)
RsCertificate cert( Detail,mem_block,mem_block_size ) ;
delete[] mem_block ;
return cert.armouredPGPKey() ;
}
@ -1125,6 +1127,8 @@ std::string p3Peers::GetRetroshareInvite(const RsPeerId& ssl_id,bool include_sig
RsCertificate cert( Detail,mem_block,mem_block_size ) ;
delete[] mem_block ;
return cert.toStdString() ;
}

View File

@ -1602,7 +1602,7 @@ void p3GxsCircles::checkDummyIdData()
std::vector<RsGxsIdGroup>::iterator it;
for(it = ids.begin(); it != ids.end(); ++it)
{
if (it->mMeta.mGroupFlags & RSGXSID_GROUPFLAG_REALID)
if (it->mMeta.mGroupFlags & RSGXSID_GROUPFLAG_REALID_kept_for_compatibility)
{
#ifdef DEBUG_CIRCLES
std::cerr << "p3GxsCircles::checkDummyIdData() PgpLinkedId: " << it->mMeta.mGroupId;
@ -1978,7 +1978,7 @@ bool p3GxsCircles::processMembershipRequests(uint32_t token)
#ifdef DEBUG_CIRCLES
std::cerr << "Processing circle membership requests." << std::endl;
#endif
GxsMsgDataMap msgItems ;
RsGxsMetaDataTemporaryMapVector<RsGxsMsgItem> msgItems;
if(!RsGenExchange::getMsgData(token, msgItems))
{

View File

@ -451,24 +451,25 @@ void p3GxsReputation::cleanup()
++it ;
}
// update opinions based on flags and contact information
// Update opinions based on flags and contact information.
// Note: the call to rsIdentity->isARegularContact() is done off-mutex, in order to avoid a cross-deadlock, as
// normally, p3GxsReputation gets called by p3dentity and not te reverse. That explains the weird implementation
// of these two loops.
{
std::list<RsGxsId> should_set_to_positive ;
std::list<RsGxsId> should_set_to_positive_candidates ;
if(mAutoSetPositiveOptionToContacts)
{
RsStackMutex stack(mReputationMtx); /****** LOCKED MUTEX *******/
for(std::map<RsGxsId,Reputation>::iterator it(mReputations.begin());it!=mReputations.end();++it)
{
bool is_a_contact = rsIdentity->isARegularContact(it->first) ;
if(mAutoSetPositiveOptionToContacts && is_a_contact && it->second.mOwnOpinion == RsReputations::OPINION_NEUTRAL)
should_set_to_positive.push_back(it->first) ;
}
if(it->second.mOwnOpinion == RsReputations::OPINION_NEUTRAL)
should_set_to_positive_candidates.push_back(it->first) ;
}
for(std::list<RsGxsId>::const_iterator it(should_set_to_positive.begin());it!=should_set_to_positive.end();++it)
setOwnOpinion(*it,RsReputations::OPINION_POSITIVE) ;
for(std::list<RsGxsId>::const_iterator it(should_set_to_positive_candidates.begin());it!=should_set_to_positive_candidates.end();++it)
if(rsIdentity->isARegularContact(*it))
setOwnOpinion(*it,RsReputations::OPINION_POSITIVE) ;
}
}
@ -767,14 +768,45 @@ bool p3GxsReputation::updateLatestUpdate(RsPeerId peerid,time_t latest_update)
* Opinion
****/
RsReputations::ReputationLevel p3GxsReputation::overallReputationLevel(const RsGxsId& id)
RsReputations::ReputationLevel p3GxsReputation::overallReputationLevel(const RsGxsId& id,uint32_t *identity_flags)
{
ReputationInfo info ;
getReputationInfo(id,RsPgpId(),info) ;
RsPgpId owner_id ;
if(identity_flags)
getIdentityFlagsAndOwnerId(id,*identity_flags,owner_id);
return info.mOverallReputationLevel ;
}
bool p3GxsReputation::getIdentityFlagsAndOwnerId(const RsGxsId& gxsid, uint32_t& identity_flags,RsPgpId& owner_id)
{
if(gxsid.isNull())
return false ;
RsStackMutex stack(mReputationMtx); /****** LOCKED MUTEX *******/
std::map<RsGxsId,Reputation>::iterator it = mReputations.find(gxsid) ;
if(it == mReputations.end())
return false ;
if(!(it->second.mIdentityFlags & REPUTATION_IDENTITY_FLAG_UP_TO_DATE))
return false ;
if(it->second.mIdentityFlags & REPUTATION_IDENTITY_FLAG_PGP_LINKED)
identity_flags |= RS_IDENTITY_FLAGS_PGP_LINKED ;
if(it->second.mIdentityFlags & REPUTATION_IDENTITY_FLAG_PGP_KNOWN)
identity_flags |= RS_IDENTITY_FLAGS_PGP_KNOWN ;
owner_id = it->second.mOwnerNode ;
return true ;
}
bool p3GxsReputation::getReputationInfo(const RsGxsId& gxsid, const RsPgpId& ownerNode, RsReputations::ReputationInfo& info, bool stamp)
{
if(gxsid.isNull())

View File

@ -115,7 +115,7 @@ public:
virtual bool isNodeBanned(const RsPgpId& id);
virtual void banNode(const RsPgpId& id,bool b) ;
virtual ReputationLevel overallReputationLevel(const RsGxsId& id);
virtual ReputationLevel overallReputationLevel(const RsGxsId& id,uint32_t *identity_flags=NULL);
virtual void setNodeAutoPositiveOpinionForContacts(bool b) ;
virtual bool nodeAutoPositiveOpinionForContacts() ;
@ -143,6 +143,7 @@ public:
virtual bool loadList(std::list<RsItem*>& load) ;
private:
bool getIdentityFlagsAndOwnerId(const RsGxsId& gxsid, uint32_t& identity_flags, RsPgpId &owner_id);
bool processIncoming();

View File

@ -695,12 +695,26 @@ bool p3IdService::createIdentity(uint32_t& token, RsIdentityParameters &params)
if (params.isPgpLinked)
{
id.mMeta.mGroupFlags = RSGXSID_GROUPFLAG_REALID;
#warning Backward compatibility issue to fix here in v0.7.0
// This is a hack, because a bad decision led to having RSGXSID_GROUPFLAG_REALID be equal to GXS_SERV::FLAG_PRIVACY_PRIVATE.
// In order to keep backward compatibility, we'll also add the new value
// When the ID is not PGP linked, the group flag cannot be let empty, so we use PUBLIC.
//
// The correct combination of flags should be:
// PGP-linked: GXS_SERV::FLAGS_PRIVACY_PUBLIC | RSGXSID_GROUPFLAG_REALID
// Anonymous : GXS_SERV::FLAGS_PRIVACY_PUBLIC
id.mMeta.mGroupFlags |= GXS_SERV::FLAG_PRIVACY_PRIVATE; // this is also equal to RSGXSID_GROUPFLAG_REALID_deprecated
id.mMeta.mGroupFlags |= RSGXSID_GROUPFLAG_REALID;
// The current version should be able to produce new identities that old peers will accept as well.
// In the future, we need to:
// - set the current group flags here (see above)
// - replace all occurences of RSGXSID_GROUPFLAG_REALID_deprecated by RSGXSID_GROUPFLAG_REALID in the code.
}
else
{
id.mMeta.mGroupFlags = 0;
}
id.mMeta.mGroupFlags |= GXS_SERV::FLAG_PRIVACY_PUBLIC;
createGroup(token, id);
@ -1260,7 +1274,7 @@ bool p3IdService::opinion_handlerequest(uint32_t token)
}
// update IdScore too.
bool pgpId = (meta.mGroupFlags & RSGXSID_GROUPFLAG_REALID);
bool pgpId = (meta.mGroupFlags & RSGXSID_GROUPFLAG_REALID_kept_for_compatibility);
ssdata.score.rep.updateIdScore(pgpId, ssdata.pgp.validatedSignature);
ssdata.score.rep.update();
@ -1876,7 +1890,7 @@ void RsGxsIdCache::init(const RsGxsIdGroupItem *item, const RsTlvPublicRSAKey& i
details.mFlags = 0 ;
if(item->meta.mSubscribeFlags & GXS_SERV::GROUP_SUBSCRIBE_ADMIN) details.mFlags |= RS_IDENTITY_FLAGS_IS_OWN_ID;
if(item->meta.mGroupFlags & RSGXSID_GROUPFLAG_REALID) details.mFlags |= RS_IDENTITY_FLAGS_PGP_LINKED;
if(item->meta.mGroupFlags & RSGXSID_GROUPFLAG_REALID_kept_for_compatibility) details.mFlags |= RS_IDENTITY_FLAGS_PGP_LINKED;
// do some tests
if(details.mFlags & RS_IDENTITY_FLAGS_IS_OWN_ID)
@ -2830,7 +2844,7 @@ RsGenExchange::ServiceCreate_Return p3IdService::service_CreateGroup(RsGxsGrpIte
ServiceCreate_Return createStatus;
if (item->meta.mGroupFlags & RSGXSID_GROUPFLAG_REALID)
if (item->meta.mGroupFlags & RSGXSID_GROUPFLAG_REALID_kept_for_compatibility)
{
/* create the hash */
Sha1CheckSum hash;
@ -3033,7 +3047,7 @@ bool p3IdService::pgphash_handlerequest(uint32_t token)
#endif // DEBUG_IDS
/* Filter based on IdType */
if (!(vit->mMeta.mGroupFlags & RSGXSID_GROUPFLAG_REALID))
if (!(vit->mMeta.mGroupFlags & RSGXSID_GROUPFLAG_REALID_kept_for_compatibility))
{
#ifdef DEBUG_IDS
std::cerr << "p3IdService::pgphash_request() discarding AnonID";
@ -3609,7 +3623,7 @@ bool p3IdService::recogn_process()
ssdata.recogntags.publishTs = item->meta.mPublishTs;
// update IdScore too.
bool pgpId = (item->meta.mGroupFlags & RSGXSID_GROUPFLAG_REALID);
bool pgpId = (item->meta.mGroupFlags & RSGXSID_GROUPFLAG_REALID_kept_for_compatibility);
ssdata.score.rep.updateIdScore(pgpId, ssdata.pgp.validatedSignature);
ssdata.score.rep.update();
@ -3830,7 +3844,7 @@ void p3IdService::generateDummy_FriendPGP()
RsGxsIdGroup id;
id.mMeta.mGroupFlags = RSGXSID_GROUPFLAG_REALID;
id.mMeta.mGroupFlags = RSGXSID_GROUPFLAG_REALID_kept_for_compatibility;
int idx = RSRandom::random_f32() * (gpgids.size() - 1);
it = gpgids.begin();
@ -3867,7 +3881,7 @@ void p3IdService::generateDummy_UnknownPGP()
RsGxsIdGroup id;
// FAKE DATA.
id.mMeta.mGroupFlags = RSGXSID_GROUPFLAG_REALID;
id.mMeta.mGroupFlags = RSGXSID_GROUPFLAG_REALID_kept_for_compatibility;
id.mPgpIdHash = Sha1CheckSum::random() ;
id.mPgpIdSign = RSRandom::random_alphaNumericString(20) ;
id.mMeta.mGroupName = RSRandom::random_alphaNumericString(10) ;

View File

@ -795,9 +795,9 @@ void CreateCircleDialog::loadIdentities(uint32_t token)
if (acceptAnonymous)
ok = true;
else if (acceptAllPGP)
ok = idGroup.mMeta.mGroupFlags & RSGXSID_GROUPFLAG_REALID ;
ok = idGroup.mMeta.mGroupFlags & RSGXSID_GROUPFLAG_REALID_kept_for_compatibility ;
else if (idGroup.mPgpKnown)
ok = idGroup.mMeta.mGroupFlags & RSGXSID_GROUPFLAG_REALID ;
ok = idGroup.mMeta.mGroupFlags & RSGXSID_GROUPFLAG_REALID_kept_for_compatibility ;
if (!ok) {
#ifdef DEBUG_CREATE_CIRCLE_DIALOG
@ -816,7 +816,7 @@ void CreateCircleDialog::loadIdentities(uint32_t token)
if(idGroup.mImage.mSize == 0 || !pixmap.loadFromData(idGroup.mImage.mData, idGroup.mImage.mSize, "PNG"))
pixmap = QPixmap::fromImage(GxsIdDetails::makeDefaultIcon(RsGxsId(idGroup.mMeta.mGroupId))) ;
if (idGroup.mMeta.mGroupFlags & RSGXSID_GROUPFLAG_REALID)
if (idGroup.mMeta.mGroupFlags & RSGXSID_GROUPFLAG_REALID_kept_for_compatibility)
{
if (idGroup.mPgpKnown) {
RsPeerDetails details;

View File

@ -24,6 +24,8 @@
#include "gui/gxs/GxsIdDetails.h"
#include "gui/settings/rsharesettings.h"
#include "gui/common/UIStateHelper.h"
#include "gui/msgs/MessageComposer.h"
#include "gui/RetroShareLink.h"
#include <retroshare/rspeers.h>
@ -85,6 +87,9 @@ IdDetailsDialog::IdDetailsDialog(const RsGxsGroupId& id, QWidget *parent) :
//connect(ui.buttonBox, SIGNAL(accepted()), this, SLOT(changeGroup()));
connect(ui->buttonBox, SIGNAL(rejected()), this, SLOT(reject()));
connect(ui->ownOpinion_CB, SIGNAL(currentIndexChanged(int)), this, SLOT(modifyReputation()));
connect(ui->autoBanIdentities_CB, SIGNAL(toggled(bool)), this, SLOT(toggleAutoBanIdentities(bool)));
connect(ui->inviteButton, SIGNAL(clicked()), this, SLOT(sendInvite()));
requestIdDetails();
}
@ -98,6 +103,17 @@ IdDetailsDialog::~IdDetailsDialog()
delete(mIdQueue);
}
void IdDetailsDialog::toggleAutoBanIdentities(bool b)
{
RsPgpId id(ui->lineEdit_GpgId->text().left(16).toStdString());
if(!id.isNull())
{
rsReputations->banNode(id,b) ;
//requestIdList();
}
}
static QString getHumanReadableDuration(uint32_t seconds)
{
if(seconds < 60)
@ -155,8 +171,13 @@ void IdDetailsDialog::insertIdDetails(uint32_t token)
ui->lineEdit_Nickname->setText(QString::fromUtf8(data.mMeta.mGroupName.c_str()));
ui->lineEdit_KeyId->setText(QString::fromStdString(data.mMeta.mGroupId.toStdString()));
//ui->lineEdit_GpgHash->setText(QString::fromStdString(data.mPgpIdHash.toStdString()));
ui->lineEdit_GpgId->setText(QString::fromStdString(data.mPgpId.toStdString()));
if(data.mPgpKnown)
ui->lineEdit_GpgId->setText(QString::fromStdString(data.mPgpId.toStdString()));
else
ui->lineEdit_GpgId->setText(QString::fromStdString(data.mPgpId.toStdString()) + tr(" [unverified]"));
ui->autoBanIdentities_CB->setVisible(!data.mPgpId.isNull()) ;
ui->banoption_label->setVisible(!data.mPgpId.isNull()) ;
time_t now = time(NULL) ;
ui->lineEdit_LastUsed->setText(getHumanReadableDuration(now - data.mLastUsageTS)) ;
@ -183,7 +204,7 @@ void IdDetailsDialog::insertIdDetails(uint32_t token)
}
else
{
if (data.mMeta.mGroupFlags & RSGXSID_GROUPFLAG_REALID)
if(data.mMeta.mGroupFlags & RSGXSID_GROUPFLAG_REALID_kept_for_compatibility)
{
ui->lineEdit_GpgName->setText(tr("Unknown real name"));
}
@ -211,13 +232,15 @@ void IdDetailsDialog::insertIdDetails(uint32_t token)
bool isOwnId = (data.mPgpKnown && (data.mPgpId == ownPgpId)) || (data.mMeta.mSubscribeFlags & GXS_SERV::GROUP_SUBSCRIBE_ADMIN);
if (isOwnId)
{
if (data.mPgpKnown)
ui->lineEdit_Type->setText(tr("Identity owned by you, linked to your Retroshare node")) ;
else
ui->lineEdit_Type->setText(tr("Anonymous identity, owned by you")) ;
else if (data.mMeta.mGroupFlags & RSGXSID_GROUPFLAG_REALID)
}
else if (data.mMeta.mGroupFlags & RSGXSID_GROUPFLAG_REALID_kept_for_compatibility)
{
if (data.mPgpKnown)
if(data.mPgpKnown)
if (rsPeers->isGPGAccepted(data.mPgpId))
ui->lineEdit_Type->setText(tr("Owned by a friend Retroshare node")) ;
else
@ -238,6 +261,8 @@ void IdDetailsDialog::insertIdDetails(uint32_t token)
// No Reputation yet!
mStateHelper->setWidgetEnabled(ui->ownOpinion_CB, true);
}
ui->autoBanIdentities_CB->setChecked(rsReputations->isNodeBanned(data.mPgpId));
/* now fill in the reputation information */
@ -265,8 +290,28 @@ void IdDetailsDialog::insertIdDetails(uint32_t token)
rsReputations->getReputationInfo(RsGxsId(data.mMeta.mGroupId),data.mPgpId,info) ;
#warning (csoler) Do we need to do this? This code is apparently not used.
ui->neighborNodesOpinion_TF->setText(QString::number(info.mFriendAverageScore));
ui->overallOpinion_TF->setText(QString::number(info.mOverallReputationLevel));
QString frep_string ;
if(info.mFriendsPositiveVotes > 0) frep_string += QString::number(info.mFriendsPositiveVotes) + tr(" positive ") ;
if(info.mFriendsNegativeVotes > 0) frep_string += QString::number(info.mFriendsNegativeVotes) + tr(" negative ") ;
if(info.mFriendsPositiveVotes==0 && info.mFriendsNegativeVotes==0)
frep_string = tr("No votes from friends") ;
ui->neighborNodesOpinion_TF->setText(frep_string) ;
ui->label_positive->setText(QString::number(info.mFriendsPositiveVotes));
ui->label_negative->setText(QString::number(info.mFriendsNegativeVotes));
switch(info.mOverallReputationLevel)
{
case RsReputations::REPUTATION_LOCALLY_POSITIVE: ui->overallOpinion_TF->setText(tr("Positive")) ; break ;
case RsReputations::REPUTATION_LOCALLY_NEGATIVE: ui->overallOpinion_TF->setText(tr("Negative (Banned by you)")) ; break ;
case RsReputations::REPUTATION_REMOTELY_POSITIVE: ui->overallOpinion_TF->setText(tr("Positive (according to your friends)")) ; break ;
case RsReputations::REPUTATION_REMOTELY_NEGATIVE: ui->overallOpinion_TF->setText(tr("Negative (according to your friends)")) ; break ;
default:
case RsReputations::REPUTATION_NEUTRAL: ui->overallOpinion_TF->setText(tr("Neutral")) ; break ;
}
switch(info.mOwnOpinion)
{
@ -408,3 +453,34 @@ void IdDetailsDialog::loadRequest(const TokenQueue *queue, const TokenRequest &r
std::cerr << std::endl;
}
}
QString IdDetailsDialog::inviteMessage()
{
return tr("Hi,<br>I want to be friends with you on RetroShare.<br>");
}
void IdDetailsDialog::sendInvite()
{
/* create a message */
MessageComposer *composer = MessageComposer::newMsg();
composer->setTitleText(tr("You have a friend invite"));
RsPeerId ownId = rsPeers->getOwnId();
RetroShareLink link;
link.createCertificate(ownId);
RsGxsId keyId(ui->lineEdit_KeyId->text().toStdString());
QString sMsgText = inviteMessage();
sMsgText += "<br><br>";
sMsgText += tr("Respond now:") + "<br>";
sMsgText += link.toHtml() + "<br>";
sMsgText += "<br>";
sMsgText += tr("Thanks, <br>") + QString::fromUtf8(rsPeers->getGPGName(rsPeers->getGPGOwnId()).c_str());
composer->setMsgText(sMsgText);
composer->addRecipient(MessageComposer::TO, RsGxsId(keyId));
composer->show();
}

View File

@ -48,7 +48,10 @@ public:
private slots:
void modifyReputation();
void toggleAutoBanIdentities(bool b);
static QString inviteMessage();
void sendInvite();
private :
void requestIdDetails();
void insertIdDetails(uint32_t token);

View File

@ -6,8 +6,8 @@
<rect>
<x>0</x>
<y>0</y>
<width>698</width>
<height>472</height>
<width>688</width>
<height>475</height>
</rect>
</property>
<property name="windowTitle">
@ -18,7 +18,16 @@
<normaloff>:/images/logo/logo_32.png</normaloff>:/images/logo/logo_32.png</iconset>
</property>
<layout class="QGridLayout" name="gridLayout_4">
<property name="margin">
<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">
@ -53,9 +62,113 @@
<layout class="QGridLayout" name="gridLayout_3">
<item row="0" column="0" rowspan="2">
<layout class="QGridLayout" name="gridLayout">
<property name="margin">
<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="9" 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>
<item row="8" column="0">
<widget class="QLabel" name="label_5">
<property name="text">
<string>Friends votes:</string>
</property>
</widget>
</item>
<item row="7" column="0">
<widget class="QLabel" name="label_6">
<property name="text">
<string>Your opinion:</string>
</property>
</widget>
</item>
<item row="7" column="1" colspan="2">
<widget class="QComboBox" name="ownOpinion_CB">
<property name="sizePolicy">
<sizepolicy hsizetype="Expanding" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<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:'MS Shell Dlg 2'; font-size:8pt; font-weight:400; font-style:normal;&quot;&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;&lt;span style=&quot; font-family:'Sans'; font-size:9pt;&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;/span&gt;&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;&lt;span style=&quot; font-family:'Sans'; font-size:9pt;&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;/span&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 resource="../icons.qrc">
<normaloff>:/icons/png/thumbs-down.png</normaloff>:/icons/png/thumbs-down.png</iconset>
</property>
</item>
<item>
<property name="text">
<string>Neutral</string>
</property>
<property name="icon">
<iconset resource="../icons.qrc">
<normaloff>:/icons/png/thumbs-neutral.png</normaloff>:/icons/png/thumbs-neutral.png</iconset>
</property>
</item>
<item>
<property name="text">
<string>Positive</string>
</property>
<property name="icon">
<iconset resource="../icons.qrc">
<normaloff>:/icons/png/thumbs-up.png</normaloff>:/icons/png/thumbs-up.png</iconset>
</property>
</item>
</widget>
</item>
<item row="8" column="1" colspan="2">
<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="9" column="1" colspan="2">
<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="4" column="0">
<widget class="QLabel" name="PgpId_LB">
<property name="text">
@ -70,39 +183,6 @@
</property>
</widget>
</item>
<item row="3" column="1">
<widget class="QLineEdit" name="lineEdit_Type"/>
</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="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="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="5" column="0">
<widget class="QLabel" name="PgpName_LB">
<property name="text">
@ -110,16 +190,6 @@
</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="1" column="0">
<widget class="QLabel" name="label">
<property name="text">
@ -134,20 +204,28 @@
</property>
</widget>
</item>
<item row="8" column="0" colspan="2">
<spacer name="verticalSpacer_2">
<property name="orientation">
<enum>Qt::Vertical</enum>
<item row="6" column="0">
<widget class="QLabel" name="label_7">
<property name="text">
<string>Last used:</string>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
<height>40</height>
</size>
</property>
</spacer>
</widget>
</item>
<item row="6" column="1">
<item row="10" column="0">
<widget class="QLabel" name="banoption_label">
<property name="text">
<string>Ban-option:</string>
</property>
</widget>
</item>
<item row="10" column="1" colspan="2">
<widget class="QCheckBox" name="autoBanIdentities_CB">
<property name="text">
<string>Auto-Ban all identities signed by the same node</string>
</property>
</widget>
</item>
<item row="6" column="1" colspan="2">
<widget class="QLineEdit" name="lineEdit_LastUsed">
<property name="enabled">
<bool>true</bool>
@ -157,189 +235,227 @@
</property>
</widget>
</item>
<item row="6" column="0">
<widget class="QLabel" name="label_7">
<property name="text">
<string>Last used:</string>
<item row="5" column="1" colspan="2">
<widget class="QLineEdit" name="lineEdit_GpgName">
<property name="enabled">
<bool>true</bool>
</property>
<property name="readOnly">
<bool>true</bool>
</property>
</widget>
</item>
<item row="4" column="1" colspan="2">
<widget class="QLineEdit" name="lineEdit_GpgId">
<property name="enabled">
<bool>true</bool>
</property>
<property name="readOnly">
<bool>true</bool>
</property>
</widget>
</item>
<item row="3" column="1" colspan="2">
<widget class="QLineEdit" name="lineEdit_Type"/>
</item>
<item row="2" column="1" colspan="2">
<widget class="QLineEdit" name="lineEdit_KeyId">
<property name="enabled">
<bool>true</bool>
</property>
<property name="readOnly">
<bool>true</bool>
</property>
</widget>
</item>
<item row="1" column="1" colspan="2">
<widget class="QLineEdit" name="lineEdit_Nickname">
<property name="enabled">
<bool>true</bool>
</property>
<property name="readOnly">
<bool>true</bool>
</property>
</widget>
</item>
</layout>
</item>
<item row="0" column="1">
<widget class="QLabel" name="avatarLabel">
<property name="sizePolicy">
<sizepolicy hsizetype="Fixed" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
<item row="1" column="1">
<layout class="QGridLayout" name="gridLayout_2">
<property name="sizeConstraint">
<enum>QLayout::SetDefaultConstraint</enum>
</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="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>
<property name="wordWrap">
<bool>true</bool>
</property>
</widget>
</item>
<item row="2" column="0">
<layout class="QHBoxLayout" name="horizontalLayout_4">
<item>
<widget class="QGroupBox" name="reputationGroupBox">
<item row="0" column="0">
<widget class="QLabel" name="avatarLabel">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Preferred">
<sizepolicy hsizetype="Fixed" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="title">
<string>Reputation</string>
<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>
<layout class="QVBoxLayout" name="verticalLayout_2">
<item>
<layout class="QGridLayout" name="gridLayout_2">
<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,&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;and is shared among friends. A final score is calculated according to a formula that accounts your own opinion and your friends' opinions about someone:&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; margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt; S = own_opinion * a + friends_opinion * (1-a)&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; margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;The factor 'a' depends on the type of ID. &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;- anonymous IDs: &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;- PGP-signed IDs by unknown PGP keys: a=&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; 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:&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; margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;S &amp;lt; -0.5: Posts are not stored, nor forwarded &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;S &amp;lt; 0.2: Posts are hidden, but still transmitted&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;S &amp;lt; 0.0: &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; margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;The overall rating is computed in such a way that it is not possible for a single person to deterministically change someone's status at neighbor nodes.&lt;/p&gt;
&lt;p style=&quot;-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
</property>
<property name="currentIndex">
<number>0</number>
</property>
<item>
<property name="text">
<string>Negative</string>
</property>
<property name="icon">
<iconset>
<normaloff>../icons/yellow_biohazard64.png</normaloff>../icons/yellow_biohazard64.png</iconset>
</property>
</item>
<item>
<property name="text">
<string>Neutral</string>
</property>
</item>
<item>
<property name="text">
<string>Positive</string>
</property>
</item>
</widget>
</item>
<item row="3" column="1">
<widget class="QLineEdit" name="overallOpinion_TF">
<property name="toolTip">
<string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Overall reputation score, accounting for yours and your friends'.&lt;/p&gt;&lt;p&gt;Negative is bad, positive is good. Zero is neutral. If the score is too low,&lt;/p&gt;&lt;p&gt;the identity is flagged as bad, and will be filtered out in forums, chat lobbies,&lt;/p&gt;&lt;p&gt;channels, etc.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
</property>
<property name="readOnly">
<bool>true</bool>
</property>
</widget>
</item>
<item row="3" column="0">
<widget class="QLabel" name="label_2">
<property name="font">
<font>
<weight>75</weight>
<bold>true</bold>
</font>
</property>
<property name="text">
<string>Overall:</string>
</property>
</widget>
</item>
</layout>
</item>
</layout>
</widget>
</item>
<item row="1" column="0">
<widget class="QPushButton" name="inviteButton">
<property name="text">
<string>Send Invite</string>
</property>
</widget>
</item>
<item row="2" column="0">
<layout class="QHBoxLayout" name="horizontalLayout_4">
<property name="spacing">
<number>6</number>
</property>
<item>
<widget class="QLabel" name="label_8">
<property name="maximumSize">
<size>
<width>34</width>
<height>34</height>
</size>
</property>
<property name="text">
<string/>
</property>
<property name="pixmap">
<pixmap resource="../icons.qrc">:/icons/png/thumbs-up.png</pixmap>
</property>
<property name="scaledContents">
<bool>true</bool>
</property>
</widget>
</item>
<item>
<widget class="QLabel" name="label_positive">
<property name="font">
<font>
<pointsize>16</pointsize>
</font>
</property>
<property name="toolTip">
<string>Positive votes</string>
</property>
<property name="text">
<string>0</string>
</property>
</widget>
</item>
<item>
<widget class="Line" name="line_3">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
</widget>
</item>
<item>
<widget class="QLabel" name="label_9">
<property name="maximumSize">
<size>
<width>34</width>
<height>34</height>
</size>
</property>
<property name="text">
<string/>
</property>
<property name="pixmap">
<pixmap resource="../icons.qrc">:/icons/png/thumbs-down.png</pixmap>
</property>
<property name="scaledContents">
<bool>true</bool>
</property>
</widget>
</item>
<item>
<widget class="QLabel" name="label_negative">
<property name="font">
<font>
<pointsize>16</pointsize>
</font>
</property>
<property name="toolTip">
<string>Negative votes</string>
</property>
<property name="text">
<string>0</string>
</property>
</widget>
</item>
</layout>
</item>
<item row="3" column="0">
<spacer name="avatarVSpacer_2">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>118</width>
<height>17</height>
</size>
</property>
</spacer>
</item>
</layout>
</item>
<item row="3" column="0" colspan="2">
<spacer name="verticalSpacer_2">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
<height>40</height>
</size>
</property>
</spacer>
</item>
</layout>
</widget>
</item>
</layout>
</item>
<item row="2" column="0">
<spacer name="verticalSpacer">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
<height>40</height>
</size>
</property>
</spacer>
</item>
<item row="3" column="0">
<layout class="QHBoxLayout" name="horizontalLayout_3">
<property name="margin">
<property name="leftMargin">
<number>9</number>
</property>
<property name="topMargin">
<number>9</number>
</property>
<property name="rightMargin">
<number>9</number>
</property>
<property name="bottomMargin">
<number>9</number>
</property>
<item>
@ -367,6 +483,19 @@ p, li { white-space: pre-wrap; }
</item>
</layout>
</item>
<item row="2" column="0">
<spacer name="verticalSpacer">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
<height>40</height>
</size>
</property>
</spacer>
</item>
</layout>
</widget>
<customwidgets>
@ -379,6 +508,7 @@ p, li { white-space: pre-wrap; }
</customwidgets>
<resources>
<include location="../images.qrc"/>
<include location="../icons.qrc"/>
</resources>
<connections/>
</ui>

View File

@ -230,6 +230,8 @@ IdDialog::IdDialog(QWidget *parent) :
ui->mainSplitter->setStretchFactor(0, 0);
ui->mainSplitter->setStretchFactor(1, 1);
ui->inviteFrame->hide();
/*remove
QList<int> sizes;
sizes << width() << 500; // Qt calculates the right sizes
@ -1414,7 +1416,7 @@ bool IdDialog::fillIdListItem(const RsGxsIdGroup& data, QTreeWidgetItem *&item,
/* do filtering */
bool ok = false;
if (data.mMeta.mGroupFlags & RSGXSID_GROUPFLAG_REALID)
if (data.mMeta.mGroupFlags & RSGXSID_GROUPFLAG_REALID_kept_for_compatibility)
{
if (isLinkedToOwnNode && (accept & RSID_FILTER_YOURSELF))
{
@ -1516,7 +1518,7 @@ bool IdDialog::fillIdListItem(const RsGxsIdGroup& data, QTreeWidgetItem *&item,
QString tooltip;
if (data.mMeta.mGroupFlags & RSGXSID_GROUPFLAG_REALID)
if (data.mMeta.mGroupFlags & RSGXSID_GROUPFLAG_REALID_kept_for_compatibility)
{
if (data.mPgpKnown)
{
@ -1758,7 +1760,7 @@ void IdDialog::insertIdDetails(uint32_t token)
}
else
{
if (data.mMeta.mGroupFlags & RSGXSID_GROUPFLAG_REALID)
if (data.mMeta.mGroupFlags & RSGXSID_GROUPFLAG_REALID_kept_for_compatibility)
ui->lineEdit_GpgName->setText(tr("[Unknown node]"));
else
ui->lineEdit_GpgName->setText(tr("Anonymous Id"));
@ -1794,7 +1796,7 @@ void IdDialog::insertIdDetails(uint32_t token)
ui->lineEdit_Type->setText(tr("Identity owned by you, linked to your Retroshare node")) ;
else
ui->lineEdit_Type->setText(tr("Anonymous identity, owned by you")) ;
else if (data.mMeta.mGroupFlags & RSGXSID_GROUPFLAG_REALID)
else if (data.mMeta.mGroupFlags & RSGXSID_GROUPFLAG_REALID_kept_for_compatibility)
{
if (data.mPgpKnown)
if (rsPeers->isGPGAccepted(data.mPgpId))
@ -2458,27 +2460,16 @@ void IdDialog::sendInvite()
{
return;
}
/* create a message */
MessageComposer *composer = MessageComposer::newMsg();
composer->setTitleText(tr("You have a friend invite"));
RsGxsId id(ui->lineEdit_KeyId->text().toStdString());
RsPeerId ownId = rsPeers->getOwnId();
RetroShareLink link;
link.createCertificate(ownId);
if ((QMessageBox::question(this, tr("Send invite?"),tr("Do you really want send a invite with your Certificate?"),QMessageBox::Yes|QMessageBox::No, QMessageBox::Yes))== QMessageBox::Yes)
{
MessageComposer::sendInvite(id);
ui->inviteFrame->show();
ui->inviteButton->setEnabled(false);
}
std::string keyId = item->text(RSID_COL_KEYID).toStdString();
QString sMsgText = inviteMessage();
sMsgText += "<br><br>";
sMsgText += tr("Respond now:") + "<br>";
sMsgText += link.toHtml() + "<br>";
sMsgText += "<br>";
sMsgText += tr("Thanks, <br>") + QString::fromUtf8(rsPeers->getGPGName(rsPeers->getGPGOwnId()).c_str());
composer->setMsgText(sMsgText);
composer->addRecipient(MessageComposer::TO, RsGxsId(keyId));
composer->show();
}
@ -2557,3 +2548,7 @@ QList<QTreeWidgetItem *> selected_items = ui->idTreeWidget->selectedItems();
requestIdList();
}
void IdDialog::on_closeInfoFrameButton_clicked()
{
ui->inviteFrame->setVisible(false);
}

View File

@ -93,7 +93,7 @@ private slots:
void editIdentity();
void chatIdentity();
void sendMsg();
void on_closeInfoFrameButton_clicked();
void updateSelection();

View File

@ -6,8 +6,8 @@
<rect>
<x>0</x>
<y>0</y>
<width>1269</width>
<height>793</height>
<width>1048</width>
<height>656</height>
</rect>
</property>
<property name="sizePolicy">
@ -20,7 +20,16 @@
<string/>
</property>
<layout class="QGridLayout" name="IdDialogGLayout">
<property name="margin">
<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">
@ -38,7 +47,16 @@
<enum>QFrame::Sunken</enum>
</property>
<layout class="QHBoxLayout" name="titleBarFrameHLayout">
<property name="margin">
<property name="leftMargin">
<number>2</number>
</property>
<property name="topMargin">
<number>2</number>
</property>
<property name="rightMargin">
<number>2</number>
</property>
<property name="bottomMargin">
<number>2</number>
</property>
<item>
@ -129,7 +147,16 @@
<enum>QFrame::Sunken</enum>
</property>
<layout class="QHBoxLayout" name="toolBarFrameHLayout">
<property name="margin">
<property name="leftMargin">
<number>1</number>
</property>
<property name="topMargin">
<number>1</number>
</property>
<property name="rightMargin">
<number>1</number>
</property>
<property name="bottomMargin">
<number>1</number>
</property>
<item>
@ -222,7 +249,7 @@
<string>Votes</string>
</property>
<property name="textAlignment">
<set>AlignLeft|AlignVCenter</set>
<set>AlignLeading|AlignVCenter</set>
</property>
<property name="icon">
<iconset resource="../icons.qrc">
@ -290,6 +317,174 @@
</property>
</widget>
</item>
<item row="0" column="3">
<layout class="QVBoxLayout" name="verticalLayout">
<item>
<spacer name="verticalSpacer">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>518</width>
<height>17</height>
</size>
</property>
</spacer>
</item>
<item>
<widget class="QFrame" name="inviteFrame">
<property name="palette">
<palette>
<active>
<colorrole role="Base">
<brush brushstyle="SolidPattern">
<color alpha="255">
<red>255</red>
<green>255</green>
<blue>255</blue>
</color>
</brush>
</colorrole>
<colorrole role="Window">
<brush brushstyle="SolidPattern">
<color alpha="255">
<red>255</red>
<green>255</green>
<blue>178</blue>
</color>
</brush>
</colorrole>
</active>
<inactive>
<colorrole role="Base">
<brush brushstyle="SolidPattern">
<color alpha="255">
<red>255</red>
<green>255</green>
<blue>255</blue>
</color>
</brush>
</colorrole>
<colorrole role="Window">
<brush brushstyle="SolidPattern">
<color alpha="255">
<red>255</red>
<green>255</green>
<blue>178</blue>
</color>
</brush>
</colorrole>
</inactive>
<disabled>
<colorrole role="Base">
<brush brushstyle="SolidPattern">
<color alpha="255">
<red>255</red>
<green>255</green>
<blue>178</blue>
</color>
</brush>
</colorrole>
<colorrole role="Window">
<brush brushstyle="SolidPattern">
<color alpha="255">
<red>255</red>
<green>255</green>
<blue>178</blue>
</color>
</brush>
</colorrole>
</disabled>
</palette>
</property>
<property name="autoFillBackground">
<bool>true</bool>
</property>
<property name="styleSheet">
<string notr="true"/>
</property>
<property name="frameShape">
<enum>QFrame::Box</enum>
</property>
<layout class="QHBoxLayout" name="distantFrameHLayout">
<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="QLabel" name="infoPixmap">
<property name="maximumSize">
<size>
<width>16</width>
<height>16</height>
</size>
</property>
<property name="text">
<string/>
</property>
<property name="pixmap">
<pixmap resource="../images.qrc">:/images/info16.png</pixmap>
</property>
<property name="alignment">
<set>Qt::AlignLeading|Qt::AlignLeft|Qt::AlignTop</set>
</property>
</widget>
</item>
<item>
<widget class="QLabel" name="infoLabel">
<property name="text">
<string notr="true">Invite messages stay into your Outbox until an acknowledgement of receipt has been received.</string>
</property>
</widget>
</item>
<item>
<widget class="QToolButton" name="closeInfoFrameButton">
<property name="maximumSize">
<size>
<width>16</width>
<height>16</height>
</size>
</property>
<property name="focusPolicy">
<enum>Qt::NoFocus</enum>
</property>
<property name="toolTip">
<string>Close</string>
</property>
<property name="styleSheet">
<string notr="true">QToolButton
{
border-image: url(:/images/closenormal.png)
}
QToolButton:hover
{
border-image: url(:/images/closehover.png)
}
QToolButton:pressed {
border-image: url(:/images/closepressed.png)
}</string>
</property>
<property name="autoRaise">
<bool>true</bool>
</property>
</widget>
</item>
</layout>
</widget>
</item>
</layout>
</item>
</layout>
</widget>
</item>
@ -299,14 +494,14 @@
<string>Identity info</string>
</property>
<layout class="QGridLayout" name="gridLayout_3">
<item row="0" column="0">
<item row="1" column="0">
<widget class="QLabel" name="label_Nickname">
<property name="text">
<string>Identity name :</string>
</property>
</widget>
</item>
<item row="0" column="1">
<item row="1" column="1">
<widget class="QLineEdit" name="lineEdit_Nickname">
<property name="enabled">
<bool>true</bool>
@ -316,7 +511,7 @@
</property>
</widget>
</item>
<item row="0" column="2" rowspan="11">
<item row="1" column="2" rowspan="11">
<layout class="QGridLayout" name="gridLayout">
<item row="0" column="0">
<widget class="QLabel" name="avatarLabel">
@ -459,14 +654,14 @@
</item>
</layout>
</item>
<item row="1" column="0">
<item row="2" column="0">
<widget class="QLabel" name="label_KeyId">
<property name="text">
<string>Identity ID :</string>
</property>
</widget>
</item>
<item row="1" column="1">
<item row="2" column="1">
<widget class="QLineEdit" name="lineEdit_KeyId">
<property name="enabled">
<bool>true</bool>
@ -476,24 +671,24 @@
</property>
</widget>
</item>
<item row="2" column="0">
<item row="3" column="0">
<widget class="QLabel" name="label_Type">
<property name="text">
<string>Type:</string>
</property>
</widget>
</item>
<item row="2" column="1">
<item row="3" column="1">
<widget class="QLineEdit" name="lineEdit_Type"/>
</item>
<item row="3" column="0">
<item row="4" column="0">
<widget class="QLabel" name="label_GpgId">
<property name="text">
<string>Owner node ID :</string>
</property>
</widget>
</item>
<item row="3" column="1">
<item row="4" column="1">
<widget class="QLineEdit" name="lineEdit_GpgId">
<property name="enabled">
<bool>true</bool>
@ -503,14 +698,14 @@
</property>
</widget>
</item>
<item row="4" column="0">
<item row="5" column="0">
<widget class="QLabel" name="label_GpgName">
<property name="text">
<string>Owner node name :</string>
</property>
</widget>
</item>
<item row="4" column="1">
<item row="5" column="1">
<widget class="QLineEdit" name="lineEdit_GpgName">
<property name="enabled">
<bool>true</bool>
@ -520,31 +715,31 @@
</property>
</widget>
</item>
<item row="5" column="0">
<item row="6" column="0">
<widget class="QLabel" name="label_LastUsed">
<property name="text">
<string>Last used:</string>
</property>
</widget>
</item>
<item row="5" column="1">
<item row="6" column="1">
<widget class="QLineEdit" name="lineEdit_LastUsed"/>
</item>
<item row="6" column="0" colspan="2">
<item row="7" column="0" colspan="2">
<widget class="Line" name="line">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
</widget>
</item>
<item row="7" column="0">
<item row="8" column="0">
<widget class="QLabel" name="label">
<property name="text">
<string>Your opinion:</string>
</property>
</widget>
</item>
<item row="7" column="1">
<item row="8" column="1">
<widget class="QComboBox" name="ownOpinion_CB">
<property name="sizePolicy">
<sizepolicy hsizetype="Minimum" vsizetype="Fixed">
@ -600,28 +795,28 @@ p, li { white-space: pre-wrap; }
</item>
</widget>
</item>
<item row="8" column="0">
<item row="9" column="0">
<widget class="QLabel" name="banoption_label">
<property name="text">
<string>Ban-option:</string>
</property>
</widget>
</item>
<item row="8" column="1">
<item row="9" column="1">
<widget class="QCheckBox" name="autoBanIdentities_CB">
<property name="text">
<string>Auto-Ban all identities signed by the same node</string>
</property>
</widget>
</item>
<item row="9" column="0">
<item row="10" column="0">
<widget class="QLabel" name="neighborNodesOpinion_LB">
<property name="text">
<string>Friend votes:</string>
</property>
</widget>
</item>
<item row="9" column="1">
<item row="10" 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>
@ -631,7 +826,7 @@ p, li { white-space: pre-wrap; }
</property>
</widget>
</item>
<item row="10" column="0">
<item row="11" column="0">
<widget class="QLabel" name="overallOpinion_LB">
<property name="font">
<font>
@ -644,7 +839,7 @@ p, li { white-space: pre-wrap; }
</property>
</widget>
</item>
<item row="10" column="1">
<item row="11" 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>
@ -845,7 +1040,6 @@ p, li { white-space: pre-wrap; }
</tabstops>
<resources>
<include location="../icons.qrc"/>
<include location="../images.qrc"/>
</resources>
<connections/>
</ui>

View File

@ -262,7 +262,7 @@ void IdEditDialog::loadExistingId(uint32_t token)
setAvatar(avatar);
bool realid = (mEditGroup.mMeta.mGroupFlags & RSGXSID_GROUPFLAG_REALID);
bool realid = (mEditGroup.mMeta.mGroupFlags & RSGXSID_GROUPFLAG_REALID_kept_for_compatibility);
if (realid)
{

View File

@ -679,8 +679,6 @@ void MainWindow::updateStatus()
// This call is essential to remove locks due to QEventLoop re-entrance while asking gpg passwds. Dont' remove it!
if(RsAutoUpdatePage::eventsLocked())
return;
if(Settings->valueFromGroup("StatusBar", "DisableSysTrayToolTip", QVariant(false)).toBool())
return;
float downKb = 0;
float upKb = 0;
rsConfig->GetCurrentDataRates(downKb, upKb);
@ -698,6 +696,8 @@ void MainWindow::updateStatus()
discstatus->update();
}
if(!Settings->valueFromGroup("StatusBar", "DisableSysTrayToolTip", QVariant(false)).toBool()) {
QString tray = "RetroShare\n" + tr("Down: %1 (kB/s)").arg(downKb, 0, 'f', 2) + " | " + tr("Up: %1 (kB/s)").arg(upKb, 0, 'f', 2) + "\n";
if (onlineCount == 1) {
@ -713,6 +713,7 @@ void MainWindow::updateStatus()
tray += notifyToolTip;
}
trayIcon->setToolTip(tray);
}
}
void MainWindow::updateFriends()

View File

@ -84,16 +84,8 @@ ConfCertDialog::ConfCertDialog(const RsPeerId& id, const RsPgpId &pgp_id, QWidge
/* Invoke Qt Designer generated QObject setup routine */
ui.setupUi(this);
// if(id.isNull())
// ui._useOldFormat_CB->setChecked(true) ;
// else
// {
// ui._useOldFormat_CB->setChecked(false) ;
// ui._useOldFormat_CB->setEnabled(false) ;
// }
ui.headerFrame->setHeaderImage(QPixmap(":/images/user/identityinfo64.png"));
ui.headerFrame->setHeaderText(tr("Friend node details"));
ui.headerFrame->setHeaderImage(QPixmap(":/images/user/identityinfo64.png"));
//ui.headerFrame->setHeaderText(tr("Friend node details"));
//ui._chat_CB->hide() ;
@ -142,16 +134,21 @@ void ConfCertDialog::load()
return;
}
//ui.pgpfingerprint->setText(QString::fromUtf8(detail.name.c_str()));
ui.peerid->setText(QString::fromStdString(detail.id.toStdString()));
//ui.pgpfingerprint->setText(QString::fromUtf8(detail.name.c_str()));
ui.peerid->setText(QString::fromStdString(detail.id.toStdString()));
nameAndLocation = QString("%1 (%2)").arg(QString::fromUtf8(detail.name.c_str())).arg(QString::fromUtf8(detail.location.c_str()));
RetroShareLink link;
link.createPerson(detail.gpg_id);
ui.headerFrame->setHeaderText(nameAndLocation);
ui.pgpfingerprint->setText(link.toHtml());
ui.pgpfingerprint->setToolTip(link.title());
ui.avatar->setId(ChatId(peerId));
RetroShareLink link;
link.createPerson(detail.gpg_id);
ui.pgpfingerprint->setText(link.toHtml());
ui.pgpfingerprint->setToolTip(link.title());
ui.avatar->setId(ChatId(peerId));
ui.loc->setText(QString::fromUtf8(detail.location.c_str()));
// Dont Show a timestamp in RS calculate the day
@ -161,6 +158,11 @@ void ConfCertDialog::load()
std::string version;
rsDisc->getPeerVersion(detail.id, version);
ui.version->setText(QString::fromStdString(version));
/* Custom state string */
QString statustring = QString::fromUtf8(rsMsgs->getCustomStateString(detail.id).c_str());
ui.statusmessage->setText(statustring);
RsPeerCryptoParams cdet ;
if(RsControl::instance()->getPeerCryptoDetails(detail.id,cdet) && cdet.connexion_state!=0)

View File

@ -86,6 +86,8 @@ private:
RsPeerId peerId;
RsPgpId pgpId;
QString nameAndLocation;
/** Qt Designer generated object */
Ui::ConfCertDialog ui;
};

View File

@ -6,8 +6,8 @@
<rect>
<x>0</x>
<y>0</y>
<width>742</width>
<height>915</height>
<width>722</width>
<height>546</height>
</rect>
</property>
<property name="windowTitle">
@ -69,7 +69,7 @@
<item row="0" column="0">
<widget class="QTabWidget" name="stabWidget">
<property name="currentIndex">
<number>1</number>
<number>0</number>
</property>
<widget class="QWidget" name="tab">
<attribute name="icon">
@ -85,13 +85,20 @@
<item>
<widget class="QGroupBox" name="groupBox_4">
<property name="title">
<string>Node info</string>
<string>Friend info</string>
</property>
<layout class="QGridLayout" name="gridLayout_3">
<item row="3" column="1">
<widget class="QLineEdit" name="statusline">
<property name="readOnly">
<bool>true</bool>
</property>
</widget>
</item>
<item row="0" column="1">
<widget class="RSTextBrowser" name="pgpfingerprint">
<property name="sizePolicy">
<sizepolicy hsizetype="MinimumExpanding" vsizetype="MinimumExpanding">
<sizepolicy hsizetype="Expanding" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
@ -125,13 +132,6 @@
</property>
</widget>
</item>
<item row="3" column="1">
<widget class="QLineEdit" name="statusline">
<property name="readOnly">
<bool>true</bool>
</property>
</widget>
</item>
<item row="5" column="0">
<widget class="QLabel" name="label_last_contact">
<property name="text">
@ -197,7 +197,17 @@
<item row="0" column="0">
<widget class="QLabel" name="label_name">
<property name="text">
<string>PGP key :</string>
<string>Name:</string>
</property>
</widget>
</item>
<item row="7" column="1">
<widget class="QLineEdit" name="statusmessage"/>
</item>
<item row="7" column="0">
<widget class="QLabel" name="label_2">
<property name="text">
<string>Status message:</string>
</property>
</widget>
</item>
@ -210,14 +220,14 @@
<widget class="AvatarWidget" name="avatar">
<property name="minimumSize">
<size>
<width>96</width>
<height>96</height>
<width>128</width>
<height>128</height>
</size>
</property>
<property name="maximumSize">
<size>
<width>96</width>
<height>96</height>
<width>128</width>
<height>128</height>
</size>
</property>
</widget>
@ -252,7 +262,18 @@
</property>
</spacer>
</item>
<item>
</layout>
</widget>
<widget class="QWidget" name="tab_3">
<attribute name="icon">
<iconset resource="../images.qrc">
<normaloff>:/images/kcmsystem24.png</normaloff>:/images/kcmsystem24.png</iconset>
</attribute>
<attribute name="title">
<string>Advanced</string>
</attribute>
<layout class="QGridLayout" name="gridLayout_15">
<item row="0" column="0">
<widget class="QTabWidget" name="tabWidget">
<property name="currentIndex">
<number>0</number>
@ -403,55 +424,51 @@
</item>
</layout>
</widget>
<widget class="QWidget" name="tab_2">
<attribute name="title">
<string>Retroshare Certificate</string>
</attribute>
<layout class="QGridLayout" name="gridLayout">
<item row="0" column="0">
<widget class="QLabel" name="label">
<property name="text">
<string>Use this certificate to make friends:</string>
</property>
</widget>
</item>
<item row="1" column="0">
<widget class="QTextEdit" name="userCertificateText"/>
</item>
<item row="2" column="0">
<layout class="QHBoxLayout" name="horizontalLayout">
<item>
<widget class="QCheckBox" name="_shouldAddSignatures_CB">
<property name="text">
<string>Include signatures</string>
</property>
</widget>
</item>
<item>
<spacer name="horizontalSpacer_2">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
</layout>
</item>
</layout>
</widget>
</widget>
</item>
</layout>
</widget>
<widget class="QWidget" name="tab_3">
<attribute name="icon">
<iconset resource="../images.qrc">
<normaloff>:/images/view-certificate-sign-32.png</normaloff>:/images/view-certificate-sign-32.png</iconset>
</attribute>
<attribute name="title">
<string>Retroshare Certificate</string>
</attribute>
<layout class="QVBoxLayout" name="verticalLayout">
<item>
<widget class="QLabel" name="label">
<property name="text">
<string>Use this certificate to make friends:</string>
</property>
</widget>
</item>
<item>
<widget class="QTextEdit" name="userCertificateText"/>
</item>
<item>
<layout class="QHBoxLayout" name="horizontalLayout">
<item>
<widget class="QCheckBox" name="_shouldAddSignatures_CB">
<property name="text">
<string>Include signatures</string>
</property>
</widget>
</item>
<item>
<spacer name="horizontalSpacer_2">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
</layout>
</item>
</layout>
</widget>
</widget>
</item>
</layout>

View File

@ -19,6 +19,7 @@
* Boston, MA 02110-1301, USA.
****************************************************************/
#include <QMessageBox>
#include <QDateTime>
#include <QTimer>
@ -62,8 +63,11 @@ MsgItem::MsgItem(FeedHolder *parent, uint32_t feedId, const std::string &msgId,
connect( playButton, SIGNAL( clicked( void ) ), this, SLOT( playMedia ( void ) ) );
connect( deleteButton, SIGNAL( clicked( void ) ), this, SLOT( deleteMsg ( void ) ) );
connect( replyButton, SIGNAL( clicked( void ) ), this, SLOT( replyMsg ( void ) ) );
connect( sendinviteButton, SIGNAL( clicked( void ) ), this, SLOT( sendInvite ( void ) ) );
expandFrame->hide();
inviteFrame->hide();
updateItemStatic();
updateItem();
@ -87,7 +91,7 @@ void MsgItem::updateItemStatic()
/* get peer Id */
if (mi.msgflags & RS_MSG_SIGNED)
if (mi.msgflags & RS_MSG_DISTANT)
avatar->setGxsId(mi.rsgxsid_srcId) ;
else
avatar->setId(ChatId(mi.rspeerid_srcId)) ;
@ -99,7 +103,7 @@ void MsgItem::updateItemStatic()
srcName = "RetroShare";
else
{
if(mi.msgflags & RS_MSG_SIGNED)
if(mi.msgflags & RS_MSG_DISTANT)
{
RsIdentityDetails details ;
rsIdentity->getIdDetails(mi.rsgxsid_srcId, details) ;
@ -110,11 +114,22 @@ void MsgItem::updateItemStatic()
srcName = QString::fromUtf8(rsPeers->getPeerName(mi.rspeerid_srcId).c_str());
}
timestampLabel->setText(DateTime::formatLongDateTime(mi.ts));
if (!mIsHome)
{
title = tr("Message From") + ": ";
if (mi.msgflags & RS_MSG_USER_REQUEST)
{
title = QString::fromUtf8(mi.title.c_str()) + " " + tr("from") + " " + srcName;
replyButton->setText(tr("Reply to invite"));
subjectLabel->hide();
inviteFrame->show();
}
else
{
title = tr("Message From") + ": " + srcName;
sendinviteButton->hide();
inviteFrame->hide();
}
}
else
{
@ -141,11 +156,11 @@ void MsgItem::updateItemStatic()
break;
}
}
title += srcName;
titleLabel->setText(title);
subjectLabel->setText(QString::fromUtf8(mi.title.c_str()));
mMsg = QString::fromUtf8(mi.msg.c_str());
timestampLabel->setText(DateTime::formatLongDateTime(mi.ts));
if (wasExpanded() || expandFrame->isVisible()) {
fillExpandFrame();
@ -344,3 +359,20 @@ void MsgItem::checkMessageReadStatus()
removeItem();
}
void MsgItem::sendInvite()
{
MessageInfo mi;
if (!rsMail)
return;
if (!rsMail->getMessage(mMsgId, mi))
return;
if ((QMessageBox::question(this, tr("Send invite?"),tr("Do you really want send a invite with your Certificate?"),QMessageBox::Yes|QMessageBox::No, QMessageBox::Yes))== QMessageBox::Yes)
{
MessageComposer::sendInvite(mi.rsgxsid_srcId);
}
}

View File

@ -56,6 +56,7 @@ private slots:
void playMedia();
void deleteMsg();
void replyMsg();
void sendInvite();
void checkMessageReadStatus();
void updateItem();

View File

@ -6,8 +6,8 @@
<rect>
<x>0</x>
<y>0</y>
<width>643</width>
<height>146</height>
<width>707</width>
<height>180</height>
</rect>
</property>
<layout class="QGridLayout" name="MsgItemGLayout">
@ -120,7 +120,7 @@
<property name="bottomMargin">
<number>0</number>
</property>
<item row="0" column="0" rowspan="3">
<item row="0" column="0" rowspan="4">
<widget class="AvatarWidget" name="avatar">
<property name="minimumSize">
<size>
@ -146,6 +146,7 @@
</property>
<property name="font">
<font>
<pointsize>12</pointsize>
<weight>75</weight>
<italic>true</italic>
<bold>true</bold>
@ -165,7 +166,7 @@
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeType">
<enum>QSizePolicy::Preferred</enum>
<enum>QSizePolicy::Expanding</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
@ -188,7 +189,7 @@
</property>
</widget>
</item>
<item row="1" column="1" colspan="2">
<item row="2" column="1" colspan="3">
<widget class="QLabel" name="subjectLabel">
<property name="sizePolicy">
<sizepolicy hsizetype="MinimumExpanding" vsizetype="Preferred">
@ -204,8 +205,15 @@
</property>
</widget>
</item>
<item row="2" column="1" colspan="3">
<item row="3" column="1" colspan="3">
<layout class="QHBoxLayout" name="buttonHLayout">
<item>
<widget class="QPushButton" name="sendinviteButton">
<property name="text">
<string>Send Invite</string>
</property>
</widget>
</item>
<item>
<widget class="QToolButton" name="replyButton">
<property name="focusPolicy">
@ -225,7 +233,7 @@
<enum>Qt::ToolButtonTextBesideIcon</enum>
</property>
<property name="autoRaise">
<bool>true</bool>
<bool>false</bool>
</property>
</widget>
</item>
@ -324,6 +332,123 @@
</item>
</layout>
</item>
<item row="1" column="1" colspan="3">
<widget class="QFrame" name="inviteFrame">
<property name="palette">
<palette>
<active>
<colorrole role="Base">
<brush brushstyle="SolidPattern">
<color alpha="255">
<red>255</red>
<green>255</green>
<blue>255</blue>
</color>
</brush>
</colorrole>
<colorrole role="Window">
<brush brushstyle="SolidPattern">
<color alpha="255">
<red>255</red>
<green>255</green>
<blue>178</blue>
</color>
</brush>
</colorrole>
</active>
<inactive>
<colorrole role="Base">
<brush brushstyle="SolidPattern">
<color alpha="255">
<red>255</red>
<green>255</green>
<blue>255</blue>
</color>
</brush>
</colorrole>
<colorrole role="Window">
<brush brushstyle="SolidPattern">
<color alpha="255">
<red>255</red>
<green>255</green>
<blue>178</blue>
</color>
</brush>
</colorrole>
</inactive>
<disabled>
<colorrole role="Base">
<brush brushstyle="SolidPattern">
<color alpha="255">
<red>255</red>
<green>255</green>
<blue>178</blue>
</color>
</brush>
</colorrole>
<colorrole role="Window">
<brush brushstyle="SolidPattern">
<color alpha="255">
<red>255</red>
<green>255</green>
<blue>178</blue>
</color>
</brush>
</colorrole>
</disabled>
</palette>
</property>
<property name="autoFillBackground">
<bool>true</bool>
</property>
<property name="styleSheet">
<string notr="true"/>
</property>
<property name="frameShape">
<enum>QFrame::Box</enum>
</property>
<layout class="QHBoxLayout" name="distantFrameHLayout">
<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="QLabel" name="infoPixmap">
<property name="maximumSize">
<size>
<width>16</width>
<height>16</height>
</size>
</property>
<property name="text">
<string/>
</property>
<property name="pixmap">
<pixmap resource="../images.qrc">:/images/info16.png</pixmap>
</property>
<property name="alignment">
<set>Qt::AlignLeading|Qt::AlignLeft|Qt::AlignTop</set>
</property>
</widget>
</item>
<item>
<widget class="QLabel" name="infoLabel">
<property name="text">
<string notr="true">You get Invite, accept request and send your own Certificate back</string>
</property>
</widget>
</item>
</layout>
</widget>
</item>
</layout>
</widget>
</item>
@ -368,6 +493,7 @@
</customwidgets>
<resources>
<include location="../images.qrc"/>
<include location="../../../../RetroShare/RetroShare/retroshare-gui/src/gui/images.qrc"/>
</resources>
<connections/>
</ui>

View File

@ -402,7 +402,13 @@ void CreateGxsForumMsg::smileyWidgetForums()
void CreateGxsForumMsg::addSmileys()
{
ui.forumMessage->textCursor().insertText(qobject_cast<QPushButton*>(sender())->toolTip().split("|").first());
QString smiley = qobject_cast<QPushButton*>(sender())->toolTip().split("|").first();
// add trailing space
smiley += QString(" ");
// add preceding space when needed (not at start of text or preceding space already exists)
if(!ui.forumMessage->textCursor().atStart() && ui.forumMessage->toPlainText()[ui.forumMessage->textCursor().position() - 1] != QChar(' '))
smiley = QString(" ") + smiley;
ui.forumMessage->textCursor().insertText(smiley);
}
void CreateGxsForumMsg::addFile()

View File

@ -1124,18 +1124,12 @@ QTreeWidgetItem *GxsForumThreadWidget::convertMsgToThreadWidget(const RsGxsForum
// Early check for a message that should be hidden because its author
// is flagged with a bad reputation
RsIdentityDetails iddetails;
RsReputations::ReputationLevel reputation_level = RsReputations::REPUTATION_NEUTRAL;
uint32_t idflags =0;
RsReputations::ReputationLevel reputation_level = rsReputations->overallReputationLevel(msg.mMeta.mAuthorId,&idflags) ;
bool redacted = false;
if( rsIdentity->getIdDetails(msg.mMeta.mAuthorId,iddetails) )
{
reputation_level = iddetails.mReputation.mOverallReputationLevel;
redacted = (reputation_level == RsReputations::REPUTATION_LOCALLY_NEGATIVE);
}
else
reputation_level = RsReputations::REPUTATION_UNKNOWN;
redacted = (reputation_level == RsReputations::REPUTATION_LOCALLY_NEGATIVE);
GxsIdRSTreeWidgetItem *item = new GxsIdRSTreeWidgetItem(mThreadCompareRole,GxsIdDetails::ICON_TYPE_AVATAR );
item->moveToThread(ui->threadTreeWidget->thread());
@ -1158,7 +1152,7 @@ QTreeWidgetItem *GxsForumThreadWidget::convertMsgToThreadWidget(const RsGxsForum
rep_warning_level = 2 ;
rep_tooltip_str = tr("You have banned this ID. The message will not be\ndisplayed nor forwarded to your friends.") ;
}
else if(reputation_level < rsGxsForums->minReputationForForwardingMessages(mForumGroup.mMeta.mSignFlags,iddetails.mFlags))
else if(reputation_level < rsGxsForums->minReputationForForwardingMessages(mForumGroup.mMeta.mSignFlags,idflags))
{
rep_warning_level = 1 ;
rep_tooltip_str = tr("You have not set an opinion for this person,\n and your friends do not vote positively: Spam regulation \nprevents the message to be forwarded to your friends.") ;

View File

@ -51,7 +51,7 @@ public:
unsigned int newCount() { return mNewCount; }
unsigned int unreadCount() { return mUnreadCount; }
QTreeWidgetItem *convertMsgToThreadWidget(const RsGxsForumMsg &msg, bool useChildTS, uint32_t filterColumn, QTreeWidgetItem *parent = NULL);
QTreeWidgetItem *convertMsgToThreadWidget(const RsGxsForumMsg &msg, bool useChildTS, uint32_t filterColumn, QTreeWidgetItem *parent);
QTreeWidgetItem *generateMissingItem(const RsGxsMessageId &msgId);
// Callback for all Loads.

View File

@ -144,9 +144,25 @@ void GxsForumsFillThread::run()
emit status(tr("Retrieving"));
/* get messages */
std::vector<RsGxsForumMsg> msgs;
if (!rsGxsForums->getMsgData(token, msgs)) {
return;
std::map<RsGxsMessageId,RsGxsForumMsg> msgs;
{ // This forces to delete msgs_array after the conversion to std::map.
std::vector<RsGxsForumMsg> msgs_array;
if (!rsGxsForums->getMsgData(token, msgs_array)) {
return;
}
// now put everything into a map in order to make search log(n)
for(uint32_t i=0;i<msgs_array.size();++i)
{
#ifdef DEBUG_FORUMS
std::cerr << "Adding message " << msgs_array[i].mMeta.mMsgId << " with parent " << msgs_array[i].mMeta.mParentId << " to message map" << std::endl;
#endif
msgs[msgs_array[i].mMeta.mMsgId] = msgs_array[i] ;
}
}
emit status(tr("Loading"));
@ -155,131 +171,152 @@ void GxsForumsFillThread::run()
int pos = 0;
int steps = count / PROGRESSBAR_MAX;
int step = 0;
QList<QPair<std::string, QTreeWidgetItem*> > threadList;
QPair<std::string, QTreeWidgetItem*> threadPair;
// ThreadList contains the list of parent threads. The algorithm below iterates through all messages
// and tries to establish parenthood relationships between them, given that we only know the
// immediate parent of a message and now its children. Some messages have a missing parent and for them
// a fake top level parent is generated.
// In order to be efficient, we first create a structure that lists the children of every mesage ID in the list.
// Then the hierarchy of message is build by attaching the kids to every message until all of them have been processed.
// The messages with missing parents will be the last ones remaining in the list.
std::list<std::pair< RsGxsMessageId, QTreeWidgetItem* > > threadStack;
std::map<RsGxsMessageId,std::list<RsGxsMessageId> > kids_array ;
std::set<RsGxsMessageId> missing_parents;
/* add all threads */
std::vector<RsGxsForumMsg>::iterator msgIt;
for (msgIt = msgs.begin(); msgIt != msgs.end(); ) {
if (wasStopped()) {
break;
}
// The first step is to find the top level thread messages. These are defined as the messages without
// any parent message ID.
// this trick is needed because while we remove messages, the parents a given msg may already have been removed
// and wrongly understand as a missing parent.
const RsGxsForumMsg &msg = *msgIt;
std::map<RsGxsMessageId,RsGxsForumMsg> kept_msgs;
if (!mFlatView && !msg.mMeta.mParentId.isNull()) {
++msgIt;
continue;
}
for ( std::map<RsGxsMessageId,RsGxsForumMsg>::iterator msgIt = msgs.begin(); msgIt != msgs.end();++msgIt)
if(mFlatView || msgIt->second.mMeta.mParentId.isNull())
{
/* add all threads */
if (wasStopped())
return;
const RsGxsForumMsg& msg = msgIt->second;
#ifdef DEBUG_FORUMS
std::cerr << "GxsForumsFillThread::run() Adding TopLevel Thread: mId: " << msg.mMeta.mMsgId << std::endl;
std::cerr << "GxsForumsFillThread::run() Adding TopLevel Thread: mId: " << msg.mMeta.mMsgId << std::endl;
#endif
QTreeWidgetItem *item = mParent->convertMsgToThreadWidget(msg, mUseChildTS, mFilterColumn);
if (!mFlatView) {
threadList.push_back(QPair<std::string, QTreeWidgetItem*>(msg.mMeta.mMsgId.toStdString(), item));
}
calculateExpand(msg, item);
QTreeWidgetItem *item = mParent->convertMsgToThreadWidget(msg, mUseChildTS, mFilterColumn,NULL);
mItems.append(item);
if (!mFlatView)
threadStack.push_back(std::make_pair(msg.mMeta.mMsgId,item)) ;
if (++step >= steps) {
step = 0;
emit progress(++pos, PROGRESSBAR_MAX);
}
msgIt = msgs.erase(msgIt);
}
/* process messages */
while (msgs.size())
{
while (!threadList.empty())
{
if (wasStopped()) {
break;
}
threadPair = threadList.front();
threadList.pop_front();
#ifdef DEBUG_FORUMS
std::cerr << "GxsForumsFillThread::run() Getting Children of : " << threadPair.first << std::endl;
#endif
/* iterate through child */
for (msgIt = msgs.begin(); msgIt != msgs.end(); ) {
const RsGxsForumMsg &msg = *msgIt;
if (msg.mMeta.mParentId.toStdString() != threadPair.first) {
++msgIt;
continue;
}
#ifdef DEBUG_FORUMS
std::cerr << "GxsForumsFillThread::run() adding " << msg.mMeta.mMsgId << std::endl;
#endif
QTreeWidgetItem *item = mParent->convertMsgToThreadWidget(msg, mUseChildTS, mFilterColumn, threadPair.second);
calculateExpand(msg, item);
/* add item to process list */
threadList.push_back(QPair<std::string, QTreeWidgetItem*>(msg.mMeta.mMsgId.toStdString(), item));
if (++step >= steps) {
step = 0;
emit progress(++pos, PROGRESSBAR_MAX);
}
msgIt = msgs.erase(msgIt);
}
}
if (wasStopped()) {
break;
}
/* process missing messages */
/* search for a message with missing parent */
for (msgIt = msgs.begin(); msgIt != msgs.end(); ++msgIt) {
const RsGxsForumMsg &msg = *msgIt;
/* search for parent */
std::vector<RsGxsForumMsg>::iterator msgIt1;
for (msgIt1 = msgs.begin(); msgIt1 != msgs.end(); ++msgIt1) {
if (wasStopped()) {
break;
}
const RsGxsForumMsg &msg1 = *msgIt1;
if (msg.mMeta.mParentId == msg1.mMeta.mMsgId) {
/* found parent */
break;
}
}
if (wasStopped()) {
break;
}
if (msgIt1 != msgs.end()) {
/* parant found */
continue;
}
/* add dummy item */
QTreeWidgetItem *item = mParent->generateMissingItem(msg.mMeta.mParentId);
threadList.push_back(QPair<std::string, QTreeWidgetItem*>(msg.mMeta.mParentId.toStdString(), item));
calculateExpand(msg, item);
mItems.append(item);
break;
if (++step >= steps) {
step = 0;
emit progress(++pos, PROGRESSBAR_MAX);
}
}
else
{
#ifdef DEBUG_FORUMS
std::cerr << "GxsForumsFillThread::run() Storing kid " << msgIt->first << " of message " << msgIt->second.mMeta.mParentId << std::endl;
#endif
// The same missing parent may appear multiple times, so we first store them into a unique container.
if(msgs.find(msgIt->second.mMeta.mParentId) == msgs.end())
missing_parents.insert(msgIt->second.mMeta.mParentId);
kids_array[msgIt->second.mMeta.mParentId].push_back(msgIt->first) ;
kept_msgs.insert(*msgIt) ;
}
msgs = kept_msgs;
// Add a fake toplevel item for the parent IDs that we dont actually have.
for(std::set<RsGxsMessageId>::const_iterator it(missing_parents.begin());it!=missing_parents.end();++it)
{
// add dummy parent item
QTreeWidgetItem *parent = mParent->generateMissingItem(*it);
mItems.append( parent );
threadStack.push_back(std::make_pair(*it,parent)) ;
}
#ifdef DEBUG_FORUMS
std::cerr << "GxsForumsFillThread::run() Processing stack:" << std::endl;
#endif
// Now use a stack to go down the hierarchy
while (!threadStack.empty())
{
std::pair<RsGxsMessageId, QTreeWidgetItem*> threadPair = threadStack.front();
threadStack.pop_front();
std::map<RsGxsMessageId, std::list<RsGxsMessageId> >::iterator it = kids_array.find(threadPair.first) ;
#ifdef DEBUG_FORUMS
std::cerr << "GxsForumsFillThread::run() Node: " << threadPair.first << std::endl;
#endif
if(it == kids_array.end())
continue ;
if (wasStopped())
return;
for(std::list<RsGxsMessageId>::const_iterator it2(it->second.begin());it2!=it->second.end();++it2)
{
// We iterate through the top level thread items, and look for which message has the current item as parent.
// When found, the item is put in the thread list itself, as a potential new parent.
std::map<RsGxsMessageId,RsGxsForumMsg>::iterator mit = msgs.find(*it2) ;
if(mit == msgs.end())
{
std::cerr << "GxsForumsFillThread::run() Cannot find submessage " << *it2 << " !!!" << std::endl;
continue ;
}
const RsGxsForumMsg& msg(mit->second) ;
#ifdef DEBUG_FORUMS
std::cerr << "GxsForumsFillThread::run() adding sub_item " << msg.mMeta.mMsgId << std::endl;
#endif
QTreeWidgetItem *item = mParent->convertMsgToThreadWidget(msg, mUseChildTS, mFilterColumn, threadPair.second);
calculateExpand(msg, item);
/* add item to process list */
threadStack.push_back(std::make_pair(msg.mMeta.mMsgId, item));
if (++step >= steps) {
step = 0;
emit progress(++pos, PROGRESSBAR_MAX);
}
msgs.erase(mit);
}
#ifdef DEBUG_FORUMS
std::cerr << "GxsForumsFillThread::run() Erasing entry " << it->first << " from kids tab." << std::endl;
#endif
kids_array.erase(it) ; // This is not strictly needed, but it improves performance by reducing the search space.
}
#ifdef DEBUG_FORUMS
std::cerr << "Kids array now has " << kids_array.size() << " elements" << std::endl;
for(std::map<RsGxsMessageId,std::list<RsGxsMessageId> >::const_iterator it(kids_array.begin());it!=kids_array.end();++it)
{
std::cerr << "Node " << it->first << std::endl;
for(std::list<RsGxsMessageId>::const_iterator it2(it->second.begin());it2!=it->second.end();++it2)
std::cerr << " " << *it2 << std::endl;
}
std::cerr << "GxsForumsFillThread::run() stopped: " << (wasStopped() ? "yes" : "no") << std::endl;
#endif
}

View File

@ -2200,7 +2200,13 @@ void MessageComposer::smileyWidget()
void MessageComposer::addSmileys()
{
ui.msgText->textCursor().insertText(qobject_cast<QPushButton*>(sender())->toolTip().split("|").first());
QString smiley = qobject_cast<QPushButton*>(sender())->toolTip().split("|").first();
// add trailing space
smiley += QString(" ");
// add preceding space when needed (not at start of text or preceding space already exists)
if(!ui.msgText->textCursor().atStart() && ui.msgText->toPlainText()[ui.msgText->textCursor().position() - 1] != QChar(' '))
smiley = QString(" ") + smiley;
ui.msgText->textCursor().insertText(smiley);
}
void MessageComposer::currentCharFormatChanged(const QTextCharFormat &format)
@ -2758,3 +2764,44 @@ void MessageComposer::on_closeInfoFrameButton_clicked()
{
ui.distantFrame->setVisible(false);
}
QString MessageComposer::inviteMessage()
{
return tr("Hi,<br>I want to be friends with you on RetroShare.<br>");
}
void MessageComposer::sendInvite(const RsGxsId &to, const QString &msg, bool autoSend)
{
/* create a message */
MessageComposer *composer = MessageComposer::newMsg();
composer->setTitleText(tr("You have a friend invite"));
composer->msgFlags |= RS_MSG_USER_REQUEST;
RsPeerId ownId = rsPeers->getOwnId();
RetroShareLink link;
link.createCertificate(ownId);
QString sMsgText = inviteMessage();
sMsgText += "<br><br>";
sMsgText += tr("Respond now:") + "<br>";
sMsgText += link.toHtml() + "<br>";
sMsgText += "<br>";
sMsgText += tr("Thanks, <br>") + QString::fromUtf8(rsPeers->getGPGName(rsPeers->getGPGOwnId()).c_str());
composer->setMsgText(sMsgText);
composer->addRecipient(MessageComposer::TO, RsGxsId(to));
if (autoSend) {
if (composer->sendMessage_internal(false)) {
composer->close();
return;
}
}
//composer->show();
/* window will destroy itself! */
}

View File

@ -64,6 +64,7 @@ public:
static QString recommendMessage();
static void recommendFriend(const std::set <RsPeerId> &sslIds, const RsPeerId &to = RsPeerId(), const QString &msg = "", bool autoSend = false);
static void sendConnectAttemptMsg(const RsPgpId &gpgId, const RsPeerId &sslId, const QString &sslName);
static void sendInvite(const RsGxsId &to = RsGxsId(), const QString &msg = "", bool autoSend = true);
#ifdef UNUSED_CODE
static void sendChannelPublishKey(RsGxsChannelGroup &group);
static void sendForumPublishKey(RsGxsForumGroup &group);
@ -164,6 +165,8 @@ private slots:
void tagRemoveAll();
void on_closeInfoFrameButton_clicked();
static QString inviteMessage();
private:
static QString buildReplyHeader(const MessageInfo &msgInfo);

View File

@ -135,6 +135,7 @@ MessageWidget::MessageWidget(bool controlled, QWidget *parent, Qt::WindowFlags f
connect(ui.expandFilesButton, SIGNAL(clicked()), this, SLOT(togglefileview()));
connect(ui.downloadButton, SIGNAL(clicked()), this, SLOT(getallrecommended()));
connect(ui.msgText, SIGNAL(anchorClicked(QUrl)), this, SLOT(anchorClicked(QUrl)));
connect(ui.sendinviteButton, SIGNAL(clicked()), this, SLOT(sendInvite()));
connect(NotifyQt::getInstance(), SIGNAL(messagesTagsChanged()), this, SLOT(messagesTagsChanged()));
connect(NotifyQt::getInstance(), SIGNAL(messagesChanged()), this, SLOT(messagesChanged()));
@ -173,6 +174,8 @@ MessageWidget::MessageWidget(bool controlled, QWidget *parent, Qt::WindowFlags f
}
ui.dateText-> setText("");
ui.inviteFrame->hide();
}
MessageWidget::~MessageWidget()
@ -478,6 +481,12 @@ void MessageWidget::fill(const std::string &msgId)
std::cerr << "MessageWidget::fill() Couldn't find Msg" << std::endl;
return;
}
if (msgInfo.msgflags & RS_MSG_USER_REQUEST){
ui.inviteFrame->show();
} else {
ui.inviteFrame->hide();
}
const std::list<FileInfo> &recList = msgInfo.files;
std::list<FileInfo>::const_iterator it;
@ -738,3 +747,20 @@ void MessageWidget::loadImagesAlways()
rsMail->MessageLoadEmbeddedImages(currMsgId, true);
}
void MessageWidget::sendInvite()
{
MessageInfo mi;
if (!rsMail)
return;
if (!rsMail->getMessage(currMsgId, mi))
return;
if ((QMessageBox::question(this, tr("Send invite?"),tr("Do you really want send a invite with your Certificate?"),QMessageBox::Yes|QMessageBox::No, QMessageBox::Yes))== QMessageBox::Yes)
{
MessageComposer::sendInvite(mi.rsgxsid_srcId);
}
}

View File

@ -69,6 +69,8 @@ private slots:
void printPreview();
void saveAs();
void refill();
void sendInvite();
void msgfilelistWidgetCostumPopupMenu(QPoint);
void messagesTagsChanged();

View File

@ -288,11 +288,157 @@
</property>
</widget>
</item>
<item>
<widget class="QFrame" name="inviteFrame">
<property name="palette">
<palette>
<active>
<colorrole role="Base">
<brush brushstyle="SolidPattern">
<color alpha="255">
<red>255</red>
<green>255</green>
<blue>255</blue>
</color>
</brush>
</colorrole>
<colorrole role="Window">
<brush brushstyle="SolidPattern">
<color alpha="255">
<red>255</red>
<green>255</green>
<blue>178</blue>
</color>
</brush>
</colorrole>
</active>
<inactive>
<colorrole role="Base">
<brush brushstyle="SolidPattern">
<color alpha="255">
<red>255</red>
<green>255</green>
<blue>255</blue>
</color>
</brush>
</colorrole>
<colorrole role="Window">
<brush brushstyle="SolidPattern">
<color alpha="255">
<red>255</red>
<green>255</green>
<blue>178</blue>
</color>
</brush>
</colorrole>
</inactive>
<disabled>
<colorrole role="Base">
<brush brushstyle="SolidPattern">
<color alpha="255">
<red>255</red>
<green>255</green>
<blue>178</blue>
</color>
</brush>
</colorrole>
<colorrole role="Window">
<brush brushstyle="SolidPattern">
<color alpha="255">
<red>255</red>
<green>255</green>
<blue>178</blue>
</color>
</brush>
</colorrole>
</disabled>
</palette>
</property>
<property name="autoFillBackground">
<bool>true</bool>
</property>
<property name="styleSheet">
<string notr="true"/>
</property>
<property name="frameShape">
<enum>QFrame::Box</enum>
</property>
<layout class="QHBoxLayout" name="distantFrameHLayout">
<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="QLabel" name="infoPixmap">
<property name="maximumSize">
<size>
<width>16</width>
<height>16</height>
</size>
</property>
<property name="text">
<string/>
</property>
<property name="pixmap">
<pixmap resource="../images.qrc">:/images/info16.png</pixmap>
</property>
<property name="alignment">
<set>Qt::AlignLeading|Qt::AlignLeft|Qt::AlignTop</set>
</property>
</widget>
</item>
<item>
<widget class="QLabel" name="infoLabel">
<property name="text">
<string notr="true">You get Invite, accept request and send your own Certificate back</string>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="sendinviteButton">
<property name="text">
<string>Send Invite</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>
<layout class="QHBoxLayout" name="_2">
<item>
<layout class="QGridLayout" name="_3">
<property name="margin">
<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="spacing">

View File

@ -439,10 +439,17 @@ PeerItem QLabel#peerNameLabel {
color: #990033
}
MsgItem > QFrame#frame {
border: 2px solid #3EA2FF;
background-color: qlineargradient(x1: 0, y1: 0, x2: 0, y2: 1, stop: 0 #2291E0, stop: 1 #3EB3FF);
border-radius: 10px;
MsgItem QFrame#frame {
border: 2px solid #0099cc;
border-radius: 6px;
background: white;
}
MsgItem QFrame#inviteFrame {
border: 1px solid #DCDC41;
border-radius: 6px;
background: #FFFFD7;
background-color: qlineargradient(x1:0, y1:0, x2:0, y2:1, stop:0 #FFFFD7, stop:1 #FFFFB2);
}
MsgItem QWidget#avatar {
@ -553,6 +560,13 @@ MessageWidget QFrame#decryptFrame {
background-color: qlineargradient(x1:0, y1:0, x2:0, y2:1, stop:0 #CCFFCC, stop:1 #AAFFAA);
}
MessageWidget QFrame#inviteFrame {
border: 1px solid #DCDC41;
border-radius: 6px;
background: #FFFFD7;
background-color: qlineargradient(x1:0, y1:0, x2:0, y2:1, stop:0 #FFFFD7, stop:1 #FFFFB2);
}
/* Posted Links */
PostedCreatePostDialog QLabel#info_label {
@ -614,6 +628,10 @@ IdDialog QLabel#headerTextLabel {
color: rgb(255, 255, 255);
}
IdDialog QLabel#headerTextLabel_Person {
color: rgb(255, 255, 255);
}
IdDialog QLabel#headerTextLabel_Circles {
color: rgb(255, 255, 255);
}
@ -623,6 +641,13 @@ IdDialog QLabel#avlabel {
border-radius: 10px;
}
IdDialog QFrame#inviteFrame {
border: 1px solid #DCDC41;
border-radius: 6px;
background: #FFFFD7;
background-color: qlineargradient(x1:0, y1:0, x2:0, y2:1, stop:0 #FFFFD7, stop:1 #FFFFB2);
}
GxsChannelPostsWidget QFrame#infoFrame
{
border: 1px solid #DCDC41;

View File

@ -145,7 +145,7 @@
<item>
<widget class="QComboBox" name="_e2e_encryption_CB">
<property name="toolTip">
<string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Anonymous tunnels can be end-o-end encrypted. In order to maintain backward compatibility, this can be made optional (choosing &amp;quot;Accepted&amp;quot;), but in the end, all Retroshare nodes will be switched to &amp;quot;Enforced&amp;quot;, meaning that all anonymous transfers will be end-to-end encrypted.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
<string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Anonymous tunnels can be end-o-end encrypted. In order to maintain backward compatibility, this can be made optional (choosing &amp;quot;Accepted&amp;quot;), but in the end, all Retroshare nodes will be switched to &amp;quot;Enforced&amp;quot;, meaning that all anonymous transfers will be end-to-end encrypted. With &amp;quot;Accepted&amp;quot;, it is likely that you will transfer using twice as many tunnels, since there is no way to know that an encrypted and a clear tunnel actually transfer from the same source.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
</property>
<item>
<property name="text">

View File

@ -168,6 +168,13 @@ RsHtml::RsHtml()
void RsHtml::initEmoticons(const QHash<QString, QPair<QVector<QString>, QHash<QString, QString> > >& hash)
{
//add rules for standard emoticons
QString genericpattern;
genericpattern += "(?:^|\\s)(:\\w{1,40}:)(?:$|\\s)|"; //generic rule for :emoji_name:
genericpattern += "(?:^|\\s)(\\(\\w{1,40}\\))(?:$|\\s)"; //generic rule for (emoji_name)
QRegExp genericrx(genericpattern);
genericrx.setMinimal(true);
QString newRE;
for(QHash<QString, QPair<QVector<QString>, QHash<QString, QString> > >::const_iterator groupit = hash.begin(); groupit != hash.end(); ++groupit) {
QHash<QString,QString> group = groupit.value().second;
@ -177,38 +184,42 @@ void RsHtml::initEmoticons(const QHash<QString, QPair<QVector<QString>, QHash<QS
continue;
}
defEmbedImg.smileys.insert(smile, it.value());
// add space around smileys
newRE += "(?:^|\\s)(" + QRegExp::escape(smile) + ")(?:$|\\s)|";
// explanations:
// (?:^|\s)(*smiley*)(?:$|\s)
//
// (?:^|\s) Non-capturing group
// 1st Alternative: ^
// ^ assert position at start of the string
// 2nd Alternative: \s
// \s match any white space character [\r\n\t\f ]
//
// 1st Capturing group (*smiley*)
// *smiley* matches the characters *smiley* literally (case sensitive)
//
// (?:$|\s) Non-capturing group
// 1st Alternative: $
// $ assert position at end of the string
// 2nd Alternative: \s
// \s match any white space character [\r\n\t\f ]
//check if smiley is using standard format :new-format: or (old-format) and don't make a new regexp for it
if(!genericrx.exactMatch(smile)) {
// add space around smileys
newRE += "(?:^|\\s)(" + QRegExp::escape(smile) + ")(?:$|\\s)|";
// explanations:
// (?:^|\s)(*smiley*)(?:$|\s)
//
// (?:^|\s) Non-capturing group
// 1st Alternative: ^
// ^ assert position at start of the string
// 2nd Alternative: \s
// \s match any white space character [\r\n\t\f ]
//
// 1st Capturing group (*smiley*)
// *smiley* matches the characters *smiley* literally (case sensitive)
//
// (?:$|\s) Non-capturing group
// 1st Alternative: $
// $ assert position at end of the string
// 2nd Alternative: \s
// \s match any white space character [\r\n\t\f ]
/*
/*
* TODO
* a better version is:
* (?<=^|\s)(*smile*)(?=$|\s) using the lookbehind/lookahead operator instead of non-capturing groups.
* This solves the problem that spaces are matched, too (see workaround in RsHtml::embedHtml)
* This is not supported by Qt4!
*/
}
}
}
newRE.chop(1); // remove last |
defEmbedImg.myREs.append(QRegExp(newRE));
QRegExp emojimatcher(newRE + genericpattern);
emojimatcher.setMinimal(true);
defEmbedImg.myREs.append(emojimatcher);
}
bool RsHtml::canReplaceAnchor(QDomDocument &/*doc*/, QDomElement &/*element*/, const RetroShareLink &link)
@ -311,6 +322,22 @@ void RsHtml::replaceAnchorWithImg(QDomDocument &doc, QDomElement &element, QText
element.appendChild(img);
}
int RsHtml::indexInWithValidation(QRegExp &rx, const QString &text, EmbedInHtml &embedInfos, int pos)
{
int index = rx.indexIn(text, pos);
if(index == -1 || embedInfos.myType != Img) return index;
const EmbedInHtmlImg& embedImg = static_cast<const EmbedInHtmlImg&>(embedInfos);
while((index = rx.indexIn(text, pos)) != -1) {
if(embedImg.smileys.contains(rx.cap(0).trimmed()))
return index;
else
++pos;
}
return -1;
}
/**
* Parses a DOM tree and replaces text by HTML tags.
* The tree is traversed depth-first, but only through children of Element type
@ -376,13 +403,13 @@ void RsHtml::embedHtml(QTextDocument *textDocument, QDomDocument& doc, QDomEleme
if(myRE.pattern().length() == 0) // we'll get stuck with an empty regexp
return;
if(myRE.indexIn(tempText) == -1)
int nextPos = 0;
if((nextPos = indexInWithValidation(myRE, tempText, embedInfos)) == -1)
continue;
// there is at least one link inside, we start replacing
int currentPos = 0;
int nextPos = 0;
while((nextPos = myRE.indexIn(tempText, currentPos)) != -1) {
do {
// if nextPos == 0 it means the text begins by a link
if(nextPos > 0) {
QDomText textPart = doc.createTextNode(tempText.mid(currentPos, nextPos - currentPos));
@ -439,7 +466,7 @@ void RsHtml::embedHtml(QTextDocument *textDocument, QDomDocument& doc, QDomEleme
index++;
currentPos = nextPos + myRE.matchedLength();
}
} while((nextPos = indexInWithValidation(myRE, tempText, embedInfos, currentPos)) != -1);
// text after the last link, only if there's one, don't touch the index
// otherwise decrement the index because we're going to remove node

View File

@ -86,6 +86,9 @@ protected:
virtual bool canReplaceAnchor(QDomDocument &doc, QDomElement &element, const RetroShareLink &link);
virtual void anchorTextForImg(QDomDocument &doc, QDomElement &element, const RetroShareLink &link, QString &text);
virtual void anchorStylesheetForImg(QDomDocument &doc, QDomElement &element, const RetroShareLink &link, QString &styleSheet);
private:
int indexInWithValidation(QRegExp &rx, const QString &text, EmbedInHtml &embedInfos, int pos = 0);
};
#endif // HANDLE_RICH_TEXT_H_

View File

@ -55,6 +55,10 @@ no_rs_gxs:CONFIG -= rs_gxs
CONFIG *= no_rs_nodeprecatedwarning
rs_nodeprecatedwarning:CONFIG -= no_rs_nodeprecatedwarning
# To disable Cpp #Warning append the following
# assignation to qmake command line "CONFIG+=rs_nocppwarning"
CONFIG *= no_rs_nocppwarning
rs_nocppwarning:CONFIG -= no_rs_nocppwarning
unix {
isEmpty(PREFIX) { PREFIX = "/usr" }
@ -166,4 +170,10 @@ rs_nodeprecatedwarning {
warning("QMAKE: You have disable deprecated warnings.")
}
rs_nocppwarning {
QMAKE_CXXFLAGS += -Wno-cpp
DEFINES *= RS_NO_WARN_CPP
warning("QMAKE: You have disable cpp warnings.")
}
rs_gxs_mail:DEFINES *= RS_GXS_MAIL

View File

@ -204,7 +204,7 @@ bool GxsPeerNode::createIdentity(const std::string &name,
id.mMeta.mGroupName = name;
if (pgpLinked)
{
id.mMeta.mGroupFlags = RSGXSID_GROUPFLAG_REALID;
id.mMeta.mGroupFlags = RSGXSID_GROUPFLAG_REALID_kept_for_compatibility;
}
else
{