merged upstream/master

This commit is contained in:
csoler 2017-02-11 10:46:51 +01:00
commit f3824f2348
47 changed files with 1639 additions and 646 deletions

View file

@ -1,7 +1,7 @@
ZLIB_VERSION=1.2.3 ZLIB_VERSION=1.2.3
BZIP2_VERSION=1.0.6 BZIP2_VERSION=1.0.6
MINIUPNPC_VERSION=2.0 MINIUPNPC_VERSION=2.0
OPENSSL_VERSION=1.0.2h OPENSSL_VERSION=1.0.2k
SPEEX_VERSION=1.2rc2 SPEEX_VERSION=1.2rc2
SPEEXDSP_VERSION=1.2rc3 SPEEXDSP_VERSION=1.2rc3
OPENCV_VERSION=2.4.13 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 ); //KeyValueReference<RsPgpId> pgp_id("pgp_id",grp.mPgpId );
// not very happy about this, i think the flags should stay hidden in rsidentities // 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 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); bool subscribed = IS_GROUP_SUBSCRIBED(grp.mMeta.mSubscribeFlags);
resp.mDataStream.getStreamToMember() resp.mDataStream.getStreamToMember()
<< id << id

View file

@ -156,8 +156,8 @@ void IdentityHandler::handleWildcard(Request & /*req*/, Response &resp)
RsGxsIdGroup& grp = *vit; RsGxsIdGroup& grp = *vit;
//electron: not very happy about this, i think the flags should stay hidden in rsidentities //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 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 ) ;
resp.mDataStream.getStreamToMember() 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("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("gxs_id", grp.mMeta.mGroupId)
<< makeKeyValueReference("pgp_id",grp.mPgpId ) << 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) ; 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_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)) 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 )) 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 // 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_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 )) 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 // serialise subdirs entry indexes
for(uint32_t i=0;i<allowed_subdirs.size();++i) 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 // serialise directory subfiles, with info for each of them
unsigned char *file_section_data = (unsigned char *)rs_malloc(FL_BASE_TMP_SECTION_SIZE) ; unsigned char *file_section_data = (unsigned char *)rs_malloc(FL_BASE_TMP_SECTION_SIZE) ;
if(!file_section_data) if(!file_section_data)
{
free(section_data);
return false ; return false ;
}
uint32_t file_section_size = FL_BASE_TMP_SECTION_SIZE ; uint32_t file_section_size = FL_BASE_TMP_SECTION_SIZE ;
@ -774,14 +777,14 @@ bool LocalDirectoryStorage::serialiseDirEntry(const EntryIndex& indx,RsTlvBinary
continue ; 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_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 )) 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 )) 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)) 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 // 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 #ifdef DEBUG_LOCAL_DIRECTORY_STORAGE
std::cerr << " pushing subfile " << file->hash << ", array position=" << i << " indx=" << dir->subfiles[i] << std::endl; 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; std::cerr << "Serialised dir entry to send for entry index " << (void*)(intptr_t)indx << ". Data size is " << section_size << " bytes" << std::endl;
#endif #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 ; bindata.bin_len = section_offset ;
return true ; return true ;
@ -865,6 +868,9 @@ bool RemoteDirectoryStorage::deserialiseUpdateDirEntry(const EntryIndex& indx,co
// deserialise directory subfiles, with info for each of them // deserialise directory subfiles, with info for each of them
std::vector<InternalFileHierarchyStorage::FileEntry> subfiles_array ; 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) ; unsigned char *file_section_data = (unsigned char *)rs_malloc(FL_BASE_TMP_SECTION_SIZE) ;
if(!file_section_data) if(!file_section_data)
@ -876,17 +882,17 @@ bool RemoteDirectoryStorage::deserialiseUpdateDirEntry(const EntryIndex& indx,co
{ {
// Read the full data section for the file // 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 ; uint32_t file_section_offset = 0 ;
InternalFileHierarchyStorage::FileEntry f; InternalFileHierarchyStorage::FileEntry f;
uint32_t modtime =0; 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_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 )) 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 )) 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 )) 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 ; 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) 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; return false;
val = (unsigned char *)rs_malloc(size) ; if(!checkSectionSize(val,size,0,local_size)) // allocate val if needed to handle local_size bytes.
if(!val)
return false; return false;
memcpy(val,&buff[offset],size); memcpy(val,&buff[offset],local_size);
offset += size ; offset += local_size ;
return true ; 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. // 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)) 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_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 )) 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)) 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)) 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 )) 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); free(section_data);
return true; return true;
@ -387,11 +390,11 @@ bool HashStorage::writeHashStorageInfo(unsigned char *& data,uint32_t& total_si
uint32_t section_offset = 0 ; uint32_t section_offset = 0 ;
uint32_t section_size = FL_BASE_TMP_SECTION_SIZE; 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_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 )) 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)) 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)) 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 )) 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 // 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 // if policy is STRICT
// - disable clear, enforce encryption // - disable clear, enforce encryption
// else // else
// - if not specified, use clear // - if not specified, use both
// //
if(mDefaultEncryptionPolicy == RS_FILE_CTRL_ENCRYPTION_POLICY_STRICT) 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 ; flags &= ~RS_FILE_REQ_UNENCRYPTED ;
} }
else if(!(flags & ( RS_FILE_REQ_ENCRYPTED | 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 if(size == 0) // we treat this special case because
{ {

View file

@ -1569,7 +1569,9 @@ bool RsGenExchange::checkGroupMetaConsistency(const RsGroupMetaData& meta)
return false; 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; 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 ; return false ;

View file

@ -177,7 +177,7 @@ class RsGixsReputation
{ {
public: public:
// get Reputation. // 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 ****/ /*** This Class pulls all the GXS Interfaces together ****/

View file

@ -457,45 +457,6 @@ void RsGxsNetService::cleanRejectedMessages()
++it ; ++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) RsGxsGroupId RsGxsNetService::hashGrpId(const RsGxsGroupId& gid,const RsPeerId& pid)
{ {
static const uint32_t SIZE = RsGxsGroupId::SIZE_IN_BYTES + RsPeerId::SIZE_IN_BYTES ; static const uint32_t SIZE = RsGxsGroupId::SIZE_IN_BYTES + RsPeerId::SIZE_IN_BYTES ;
@ -4218,6 +4179,7 @@ void RsGxsNetService::handleRecvSyncMessage(RsNxsSyncMsgReqItem *item,bool item_
delete *it ; delete *it ;
itemL.clear() ; itemL.clear() ;
delete mItem ;
break ; break ;
} }
} }

View file

@ -49,6 +49,70 @@ void freeAndClearContainerResource(Container container)
container.clear(); 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) inline RsGxsGrpMsgIdPair getMsgIdPair(RsNxsMsg& msg)
{ {
return RsGxsGrpMsgIdPair(std::make_pair(msg.grpId, msg.msgId)); return RsGxsGrpMsgIdPair(std::make_pair(msg.grpId, msg.msgId));

View file

@ -43,8 +43,12 @@ extern RsIdentity *rsIdentity;
// GroupFlags: Only one so far: // 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. // THESE ARE FLAGS FOR INTERFACE.
#define RSID_TYPE_MASK 0xff00 #define RSID_TYPE_MASK 0xff00

View file

@ -48,7 +48,7 @@ public:
struct ReputationInfo 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 ; RsReputations::Opinion mOwnOpinion ;
@ -63,7 +63,10 @@ public:
virtual bool setOwnOpinion(const RsGxsId& key_id, const Opinion& op) =0; virtual bool setOwnOpinion(const RsGxsId& key_id, const Opinion& op) =0;
virtual bool getOwnOpinion(const RsGxsId& key_id, 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 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 // 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 ) ; RsCertificate cert( Detail,mem_block,mem_block_size ) ;
delete[] mem_block ;
return cert.armouredPGPKey() ; 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 ) ; RsCertificate cert( Detail,mem_block,mem_block_size ) ;
delete[] mem_block ;
return cert.toStdString() ; return cert.toStdString() ;
} }

View file

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

View file

@ -451,24 +451,25 @@ void p3GxsReputation::cleanup()
++it ; ++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 *******/ RsStackMutex stack(mReputationMtx); /****** LOCKED MUTEX *******/
for(std::map<RsGxsId,Reputation>::iterator it(mReputations.begin());it!=mReputations.end();++it) for(std::map<RsGxsId,Reputation>::iterator it(mReputations.begin());it!=mReputations.end();++it)
{ if(it->second.mOwnOpinion == RsReputations::OPINION_NEUTRAL)
bool is_a_contact = rsIdentity->isARegularContact(it->first) ; should_set_to_positive_candidates.push_back(it->first) ;
if(mAutoSetPositiveOptionToContacts && is_a_contact && it->second.mOwnOpinion == RsReputations::OPINION_NEUTRAL)
should_set_to_positive.push_back(it->first) ;
}
} }
for(std::list<RsGxsId>::const_iterator it(should_set_to_positive.begin());it!=should_set_to_positive.end();++it) for(std::list<RsGxsId>::const_iterator it(should_set_to_positive_candidates.begin());it!=should_set_to_positive_candidates.end();++it)
setOwnOpinion(*it,RsReputations::OPINION_POSITIVE) ; if(rsIdentity->isARegularContact(*it))
setOwnOpinion(*it,RsReputations::OPINION_POSITIVE) ;
} }
} }
@ -767,14 +768,45 @@ bool p3GxsReputation::updateLatestUpdate(RsPeerId peerid,time_t latest_update)
* Opinion * Opinion
****/ ****/
RsReputations::ReputationLevel p3GxsReputation::overallReputationLevel(const RsGxsId& id) RsReputations::ReputationLevel p3GxsReputation::overallReputationLevel(const RsGxsId& id,uint32_t *identity_flags)
{ {
ReputationInfo info ; ReputationInfo info ;
getReputationInfo(id,RsPgpId(),info) ; getReputationInfo(id,RsPgpId(),info) ;
RsPgpId owner_id ;
if(identity_flags)
getIdentityFlagsAndOwnerId(id,*identity_flags,owner_id);
return info.mOverallReputationLevel ; 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) bool p3GxsReputation::getReputationInfo(const RsGxsId& gxsid, const RsPgpId& ownerNode, RsReputations::ReputationInfo& info, bool stamp)
{ {
if(gxsid.isNull()) if(gxsid.isNull())

View file

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

View file

@ -695,12 +695,26 @@ bool p3IdService::createIdentity(uint32_t& token, RsIdentityParameters &params)
if (params.isPgpLinked) 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 else
{ id.mMeta.mGroupFlags |= GXS_SERV::FLAG_PRIVACY_PUBLIC;
id.mMeta.mGroupFlags = 0;
}
createGroup(token, id); createGroup(token, id);
@ -1260,7 +1274,7 @@ bool p3IdService::opinion_handlerequest(uint32_t token)
} }
// update IdScore too. // 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.updateIdScore(pgpId, ssdata.pgp.validatedSignature);
ssdata.score.rep.update(); ssdata.score.rep.update();
@ -1876,7 +1890,7 @@ void RsGxsIdCache::init(const RsGxsIdGroupItem *item, const RsTlvPublicRSAKey& i
details.mFlags = 0 ; details.mFlags = 0 ;
if(item->meta.mSubscribeFlags & GXS_SERV::GROUP_SUBSCRIBE_ADMIN) details.mFlags |= RS_IDENTITY_FLAGS_IS_OWN_ID; 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 // do some tests
if(details.mFlags & RS_IDENTITY_FLAGS_IS_OWN_ID) if(details.mFlags & RS_IDENTITY_FLAGS_IS_OWN_ID)
@ -2830,7 +2844,7 @@ RsGenExchange::ServiceCreate_Return p3IdService::service_CreateGroup(RsGxsGrpIte
ServiceCreate_Return createStatus; ServiceCreate_Return createStatus;
if (item->meta.mGroupFlags & RSGXSID_GROUPFLAG_REALID) if (item->meta.mGroupFlags & RSGXSID_GROUPFLAG_REALID_kept_for_compatibility)
{ {
/* create the hash */ /* create the hash */
Sha1CheckSum hash; Sha1CheckSum hash;
@ -3033,7 +3047,7 @@ bool p3IdService::pgphash_handlerequest(uint32_t token)
#endif // DEBUG_IDS #endif // DEBUG_IDS
/* Filter based on IdType */ /* Filter based on IdType */
if (!(vit->mMeta.mGroupFlags & RSGXSID_GROUPFLAG_REALID)) if (!(vit->mMeta.mGroupFlags & RSGXSID_GROUPFLAG_REALID_kept_for_compatibility))
{ {
#ifdef DEBUG_IDS #ifdef DEBUG_IDS
std::cerr << "p3IdService::pgphash_request() discarding AnonID"; std::cerr << "p3IdService::pgphash_request() discarding AnonID";
@ -3609,7 +3623,7 @@ bool p3IdService::recogn_process()
ssdata.recogntags.publishTs = item->meta.mPublishTs; ssdata.recogntags.publishTs = item->meta.mPublishTs;
// update IdScore too. // 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.updateIdScore(pgpId, ssdata.pgp.validatedSignature);
ssdata.score.rep.update(); ssdata.score.rep.update();
@ -3830,7 +3844,7 @@ void p3IdService::generateDummy_FriendPGP()
RsGxsIdGroup id; 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); int idx = RSRandom::random_f32() * (gpgids.size() - 1);
it = gpgids.begin(); it = gpgids.begin();
@ -3867,7 +3881,7 @@ void p3IdService::generateDummy_UnknownPGP()
RsGxsIdGroup id; RsGxsIdGroup id;
// FAKE DATA. // FAKE DATA.
id.mMeta.mGroupFlags = RSGXSID_GROUPFLAG_REALID; id.mMeta.mGroupFlags = RSGXSID_GROUPFLAG_REALID_kept_for_compatibility;
id.mPgpIdHash = Sha1CheckSum::random() ; id.mPgpIdHash = Sha1CheckSum::random() ;
id.mPgpIdSign = RSRandom::random_alphaNumericString(20) ; id.mPgpIdSign = RSRandom::random_alphaNumericString(20) ;
id.mMeta.mGroupName = RSRandom::random_alphaNumericString(10) ; id.mMeta.mGroupName = RSRandom::random_alphaNumericString(10) ;

View file

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

View file

@ -24,6 +24,8 @@
#include "gui/gxs/GxsIdDetails.h" #include "gui/gxs/GxsIdDetails.h"
#include "gui/settings/rsharesettings.h" #include "gui/settings/rsharesettings.h"
#include "gui/common/UIStateHelper.h" #include "gui/common/UIStateHelper.h"
#include "gui/msgs/MessageComposer.h"
#include "gui/RetroShareLink.h"
#include <retroshare/rspeers.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(accepted()), this, SLOT(changeGroup()));
connect(ui->buttonBox, SIGNAL(rejected()), this, SLOT(reject())); connect(ui->buttonBox, SIGNAL(rejected()), this, SLOT(reject()));
connect(ui->ownOpinion_CB, SIGNAL(currentIndexChanged(int)), this, SLOT(modifyReputation())); 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(); requestIdDetails();
} }
@ -98,6 +103,17 @@ IdDetailsDialog::~IdDetailsDialog()
delete(mIdQueue); 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) static QString getHumanReadableDuration(uint32_t seconds)
{ {
if(seconds < 60) 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_Nickname->setText(QString::fromUtf8(data.mMeta.mGroupName.c_str()));
ui->lineEdit_KeyId->setText(QString::fromStdString(data.mMeta.mGroupId.toStdString())); ui->lineEdit_KeyId->setText(QString::fromStdString(data.mMeta.mGroupId.toStdString()));
//ui->lineEdit_GpgHash->setText(QString::fromStdString(data.mPgpIdHash.toStdString())); if(data.mPgpKnown)
ui->lineEdit_GpgId->setText(QString::fromStdString(data.mPgpId.toStdString())); 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) ; time_t now = time(NULL) ;
ui->lineEdit_LastUsed->setText(getHumanReadableDuration(now - data.mLastUsageTS)) ; ui->lineEdit_LastUsed->setText(getHumanReadableDuration(now - data.mLastUsageTS)) ;
@ -183,7 +204,7 @@ void IdDetailsDialog::insertIdDetails(uint32_t token)
} }
else 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")); 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); bool isOwnId = (data.mPgpKnown && (data.mPgpId == ownPgpId)) || (data.mMeta.mSubscribeFlags & GXS_SERV::GROUP_SUBSCRIBE_ADMIN);
if (isOwnId) if (isOwnId)
{
if (data.mPgpKnown) if (data.mPgpKnown)
ui->lineEdit_Type->setText(tr("Identity owned by you, linked to your Retroshare node")) ; ui->lineEdit_Type->setText(tr("Identity owned by you, linked to your Retroshare node")) ;
else else
ui->lineEdit_Type->setText(tr("Anonymous identity, owned by you")) ; 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)) if (rsPeers->isGPGAccepted(data.mPgpId))
ui->lineEdit_Type->setText(tr("Owned by a friend Retroshare node")) ; ui->lineEdit_Type->setText(tr("Owned by a friend Retroshare node")) ;
else else
@ -238,6 +261,8 @@ void IdDetailsDialog::insertIdDetails(uint32_t token)
// No Reputation yet! // No Reputation yet!
mStateHelper->setWidgetEnabled(ui->ownOpinion_CB, true); mStateHelper->setWidgetEnabled(ui->ownOpinion_CB, true);
} }
ui->autoBanIdentities_CB->setChecked(rsReputations->isNodeBanned(data.mPgpId));
/* now fill in the reputation information */ /* 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) ; rsReputations->getReputationInfo(RsGxsId(data.mMeta.mGroupId),data.mPgpId,info) ;
#warning (csoler) Do we need to do this? This code is apparently not used. #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) switch(info.mOwnOpinion)
{ {
@ -408,3 +453,34 @@ void IdDetailsDialog::loadRequest(const TokenQueue *queue, const TokenRequest &r
std::cerr << std::endl; 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: private slots:
void modifyReputation(); void modifyReputation();
void toggleAutoBanIdentities(bool b);
static QString inviteMessage();
void sendInvite();
private : private :
void requestIdDetails(); void requestIdDetails();
void insertIdDetails(uint32_t token); void insertIdDetails(uint32_t token);

View file

@ -6,8 +6,8 @@
<rect> <rect>
<x>0</x> <x>0</x>
<y>0</y> <y>0</y>
<width>698</width> <width>688</width>
<height>472</height> <height>475</height>
</rect> </rect>
</property> </property>
<property name="windowTitle"> <property name="windowTitle">
@ -18,7 +18,16 @@
<normaloff>:/images/logo/logo_32.png</normaloff>:/images/logo/logo_32.png</iconset> <normaloff>:/images/logo/logo_32.png</normaloff>:/images/logo/logo_32.png</iconset>
</property> </property>
<layout class="QGridLayout" name="gridLayout_4"> <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> <number>0</number>
</property> </property>
<item row="0" column="0"> <item row="0" column="0">
@ -53,9 +62,113 @@
<layout class="QGridLayout" name="gridLayout_3"> <layout class="QGridLayout" name="gridLayout_3">
<item row="0" column="0" rowspan="2"> <item row="0" column="0" rowspan="2">
<layout class="QGridLayout" name="gridLayout"> <layout class="QGridLayout" name="gridLayout">
<property name="margin"> <property name="leftMargin">
<number>6</number> <number>6</number>
</property> </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"> <item row="4" column="0">
<widget class="QLabel" name="PgpId_LB"> <widget class="QLabel" name="PgpId_LB">
<property name="text"> <property name="text">
@ -70,39 +183,6 @@
</property> </property>
</widget> </widget>
</item> </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"> <item row="5" column="0">
<widget class="QLabel" name="PgpName_LB"> <widget class="QLabel" name="PgpName_LB">
<property name="text"> <property name="text">
@ -110,16 +190,6 @@
</property> </property>
</widget> </widget>
</item> </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"> <item row="1" column="0">
<widget class="QLabel" name="label"> <widget class="QLabel" name="label">
<property name="text"> <property name="text">
@ -134,20 +204,28 @@
</property> </property>
</widget> </widget>
</item> </item>
<item row="8" column="0" colspan="2"> <item row="6" column="0">
<spacer name="verticalSpacer_2"> <widget class="QLabel" name="label_7">
<property name="orientation"> <property name="text">
<enum>Qt::Vertical</enum> <string>Last used:</string>
</property> </property>
<property name="sizeHint" stdset="0"> </widget>
<size>
<width>20</width>
<height>40</height>
</size>
</property>
</spacer>
</item> </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"> <widget class="QLineEdit" name="lineEdit_LastUsed">
<property name="enabled"> <property name="enabled">
<bool>true</bool> <bool>true</bool>
@ -157,189 +235,227 @@
</property> </property>
</widget> </widget>
</item> </item>
<item row="6" column="0"> <item row="5" column="1" colspan="2">
<widget class="QLabel" name="label_7"> <widget class="QLineEdit" name="lineEdit_GpgName">
<property name="text"> <property name="enabled">
<string>Last used:</string> <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> </property>
</widget> </widget>
</item> </item>
</layout> </layout>
</item> </item>
<item row="0" column="1"> <item row="1" column="1">
<widget class="QLabel" name="avatarLabel"> <layout class="QGridLayout" name="gridLayout_2">
<property name="sizePolicy"> <property name="sizeConstraint">
<sizepolicy hsizetype="Fixed" vsizetype="Fixed"> <enum>QLayout::SetDefaultConstraint</enum>
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property> </property>
<property name="minimumSize"> <item row="0" column="0">
<size> <widget class="QLabel" name="avatarLabel">
<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">
<property name="sizePolicy"> <property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Preferred"> <sizepolicy hsizetype="Fixed" vsizetype="Fixed">
<horstretch>0</horstretch> <horstretch>0</horstretch>
<verstretch>0</verstretch> <verstretch>0</verstretch>
</sizepolicy> </sizepolicy>
</property> </property>
<property name="title"> <property name="minimumSize">
<string>Reputation</string> <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> </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> </widget>
</item> </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> </layout>
</item> </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> </layout>
</widget> </widget>
</item> </item>
</layout> </layout>
</item> </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"> <item row="3" column="0">
<layout class="QHBoxLayout" name="horizontalLayout_3"> <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> <number>9</number>
</property> </property>
<item> <item>
@ -367,6 +483,19 @@ p, li { white-space: pre-wrap; }
</item> </item>
</layout> </layout>
</item> </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> </layout>
</widget> </widget>
<customwidgets> <customwidgets>
@ -379,6 +508,7 @@ p, li { white-space: pre-wrap; }
</customwidgets> </customwidgets>
<resources> <resources>
<include location="../images.qrc"/> <include location="../images.qrc"/>
<include location="../icons.qrc"/>
</resources> </resources>
<connections/> <connections/>
</ui> </ui>

View file

@ -230,6 +230,8 @@ IdDialog::IdDialog(QWidget *parent) :
ui->mainSplitter->setStretchFactor(0, 0); ui->mainSplitter->setStretchFactor(0, 0);
ui->mainSplitter->setStretchFactor(1, 1); ui->mainSplitter->setStretchFactor(1, 1);
ui->inviteFrame->hide();
/*remove /*remove
QList<int> sizes; QList<int> sizes;
sizes << width() << 500; // Qt calculates the right sizes sizes << width() << 500; // Qt calculates the right sizes
@ -1414,7 +1416,7 @@ bool IdDialog::fillIdListItem(const RsGxsIdGroup& data, QTreeWidgetItem *&item,
/* do filtering */ /* do filtering */
bool ok = false; 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)) if (isLinkedToOwnNode && (accept & RSID_FILTER_YOURSELF))
{ {
@ -1516,7 +1518,7 @@ bool IdDialog::fillIdListItem(const RsGxsIdGroup& data, QTreeWidgetItem *&item,
QString tooltip; QString tooltip;
if (data.mMeta.mGroupFlags & RSGXSID_GROUPFLAG_REALID) if (data.mMeta.mGroupFlags & RSGXSID_GROUPFLAG_REALID_kept_for_compatibility)
{ {
if (data.mPgpKnown) if (data.mPgpKnown)
{ {
@ -1758,7 +1760,7 @@ void IdDialog::insertIdDetails(uint32_t token)
} }
else 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]")); ui->lineEdit_GpgName->setText(tr("[Unknown node]"));
else else
ui->lineEdit_GpgName->setText(tr("Anonymous Id")); 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")) ; ui->lineEdit_Type->setText(tr("Identity owned by you, linked to your Retroshare node")) ;
else else
ui->lineEdit_Type->setText(tr("Anonymous identity, owned by you")) ; 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)) if (rsPeers->isGPGAccepted(data.mPgpId))
@ -2458,27 +2460,16 @@ void IdDialog::sendInvite()
{ {
return; 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(); 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)
RetroShareLink link; {
link.createCertificate(ownId); 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(); requestIdList();
} }
void IdDialog::on_closeInfoFrameButton_clicked()
{
ui->inviteFrame->setVisible(false);
}

View file

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

View file

@ -6,8 +6,8 @@
<rect> <rect>
<x>0</x> <x>0</x>
<y>0</y> <y>0</y>
<width>1269</width> <width>1048</width>
<height>793</height> <height>656</height>
</rect> </rect>
</property> </property>
<property name="sizePolicy"> <property name="sizePolicy">
@ -20,7 +20,16 @@
<string/> <string/>
</property> </property>
<layout class="QGridLayout" name="IdDialogGLayout"> <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> <number>0</number>
</property> </property>
<item row="0" column="0"> <item row="0" column="0">
@ -38,7 +47,16 @@
<enum>QFrame::Sunken</enum> <enum>QFrame::Sunken</enum>
</property> </property>
<layout class="QHBoxLayout" name="titleBarFrameHLayout"> <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> <number>2</number>
</property> </property>
<item> <item>
@ -129,7 +147,16 @@
<enum>QFrame::Sunken</enum> <enum>QFrame::Sunken</enum>
</property> </property>
<layout class="QHBoxLayout" name="toolBarFrameHLayout"> <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> <number>1</number>
</property> </property>
<item> <item>
@ -222,7 +249,7 @@
<string>Votes</string> <string>Votes</string>
</property> </property>
<property name="textAlignment"> <property name="textAlignment">
<set>AlignLeft|AlignVCenter</set> <set>AlignLeading|AlignVCenter</set>
</property> </property>
<property name="icon"> <property name="icon">
<iconset resource="../icons.qrc"> <iconset resource="../icons.qrc">
@ -290,6 +317,174 @@
</property> </property>
</widget> </widget>
</item> </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> </layout>
</widget> </widget>
</item> </item>
@ -299,14 +494,14 @@
<string>Identity info</string> <string>Identity info</string>
</property> </property>
<layout class="QGridLayout" name="gridLayout_3"> <layout class="QGridLayout" name="gridLayout_3">
<item row="0" column="0"> <item row="1" column="0">
<widget class="QLabel" name="label_Nickname"> <widget class="QLabel" name="label_Nickname">
<property name="text"> <property name="text">
<string>Identity name :</string> <string>Identity name :</string>
</property> </property>
</widget> </widget>
</item> </item>
<item row="0" column="1"> <item row="1" column="1">
<widget class="QLineEdit" name="lineEdit_Nickname"> <widget class="QLineEdit" name="lineEdit_Nickname">
<property name="enabled"> <property name="enabled">
<bool>true</bool> <bool>true</bool>
@ -316,7 +511,7 @@
</property> </property>
</widget> </widget>
</item> </item>
<item row="0" column="2" rowspan="11"> <item row="1" column="2" rowspan="11">
<layout class="QGridLayout" name="gridLayout"> <layout class="QGridLayout" name="gridLayout">
<item row="0" column="0"> <item row="0" column="0">
<widget class="QLabel" name="avatarLabel"> <widget class="QLabel" name="avatarLabel">
@ -459,14 +654,14 @@
</item> </item>
</layout> </layout>
</item> </item>
<item row="1" column="0"> <item row="2" column="0">
<widget class="QLabel" name="label_KeyId"> <widget class="QLabel" name="label_KeyId">
<property name="text"> <property name="text">
<string>Identity ID :</string> <string>Identity ID :</string>
</property> </property>
</widget> </widget>
</item> </item>
<item row="1" column="1"> <item row="2" column="1">
<widget class="QLineEdit" name="lineEdit_KeyId"> <widget class="QLineEdit" name="lineEdit_KeyId">
<property name="enabled"> <property name="enabled">
<bool>true</bool> <bool>true</bool>
@ -476,24 +671,24 @@
</property> </property>
</widget> </widget>
</item> </item>
<item row="2" column="0"> <item row="3" column="0">
<widget class="QLabel" name="label_Type"> <widget class="QLabel" name="label_Type">
<property name="text"> <property name="text">
<string>Type:</string> <string>Type:</string>
</property> </property>
</widget> </widget>
</item> </item>
<item row="2" column="1"> <item row="3" column="1">
<widget class="QLineEdit" name="lineEdit_Type"/> <widget class="QLineEdit" name="lineEdit_Type"/>
</item> </item>
<item row="3" column="0"> <item row="4" column="0">
<widget class="QLabel" name="label_GpgId"> <widget class="QLabel" name="label_GpgId">
<property name="text"> <property name="text">
<string>Owner node ID :</string> <string>Owner node ID :</string>
</property> </property>
</widget> </widget>
</item> </item>
<item row="3" column="1"> <item row="4" column="1">
<widget class="QLineEdit" name="lineEdit_GpgId"> <widget class="QLineEdit" name="lineEdit_GpgId">
<property name="enabled"> <property name="enabled">
<bool>true</bool> <bool>true</bool>
@ -503,14 +698,14 @@
</property> </property>
</widget> </widget>
</item> </item>
<item row="4" column="0"> <item row="5" column="0">
<widget class="QLabel" name="label_GpgName"> <widget class="QLabel" name="label_GpgName">
<property name="text"> <property name="text">
<string>Owner node name :</string> <string>Owner node name :</string>
</property> </property>
</widget> </widget>
</item> </item>
<item row="4" column="1"> <item row="5" column="1">
<widget class="QLineEdit" name="lineEdit_GpgName"> <widget class="QLineEdit" name="lineEdit_GpgName">
<property name="enabled"> <property name="enabled">
<bool>true</bool> <bool>true</bool>
@ -520,31 +715,31 @@
</property> </property>
</widget> </widget>
</item> </item>
<item row="5" column="0"> <item row="6" column="0">
<widget class="QLabel" name="label_LastUsed"> <widget class="QLabel" name="label_LastUsed">
<property name="text"> <property name="text">
<string>Last used:</string> <string>Last used:</string>
</property> </property>
</widget> </widget>
</item> </item>
<item row="5" column="1"> <item row="6" column="1">
<widget class="QLineEdit" name="lineEdit_LastUsed"/> <widget class="QLineEdit" name="lineEdit_LastUsed"/>
</item> </item>
<item row="6" column="0" colspan="2"> <item row="7" column="0" colspan="2">
<widget class="Line" name="line"> <widget class="Line" name="line">
<property name="orientation"> <property name="orientation">
<enum>Qt::Horizontal</enum> <enum>Qt::Horizontal</enum>
</property> </property>
</widget> </widget>
</item> </item>
<item row="7" column="0"> <item row="8" column="0">
<widget class="QLabel" name="label"> <widget class="QLabel" name="label">
<property name="text"> <property name="text">
<string>Your opinion:</string> <string>Your opinion:</string>
</property> </property>
</widget> </widget>
</item> </item>
<item row="7" column="1"> <item row="8" column="1">
<widget class="QComboBox" name="ownOpinion_CB"> <widget class="QComboBox" name="ownOpinion_CB">
<property name="sizePolicy"> <property name="sizePolicy">
<sizepolicy hsizetype="Minimum" vsizetype="Fixed"> <sizepolicy hsizetype="Minimum" vsizetype="Fixed">
@ -600,28 +795,28 @@ p, li { white-space: pre-wrap; }
</item> </item>
</widget> </widget>
</item> </item>
<item row="8" column="0"> <item row="9" column="0">
<widget class="QLabel" name="banoption_label"> <widget class="QLabel" name="banoption_label">
<property name="text"> <property name="text">
<string>Ban-option:</string> <string>Ban-option:</string>
</property> </property>
</widget> </widget>
</item> </item>
<item row="8" column="1"> <item row="9" column="1">
<widget class="QCheckBox" name="autoBanIdentities_CB"> <widget class="QCheckBox" name="autoBanIdentities_CB">
<property name="text"> <property name="text">
<string>Auto-Ban all identities signed by the same node</string> <string>Auto-Ban all identities signed by the same node</string>
</property> </property>
</widget> </widget>
</item> </item>
<item row="9" column="0"> <item row="10" column="0">
<widget class="QLabel" name="neighborNodesOpinion_LB"> <widget class="QLabel" name="neighborNodesOpinion_LB">
<property name="text"> <property name="text">
<string>Friend votes:</string> <string>Friend votes:</string>
</property> </property>
</widget> </widget>
</item> </item>
<item row="9" column="1"> <item row="10" column="1">
<widget class="QLineEdit" name="neighborNodesOpinion_TF"> <widget class="QLineEdit" name="neighborNodesOpinion_TF">
<property name="toolTip"> <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> <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> </property>
</widget> </widget>
</item> </item>
<item row="10" column="0"> <item row="11" column="0">
<widget class="QLabel" name="overallOpinion_LB"> <widget class="QLabel" name="overallOpinion_LB">
<property name="font"> <property name="font">
<font> <font>
@ -644,7 +839,7 @@ p, li { white-space: pre-wrap; }
</property> </property>
</widget> </widget>
</item> </item>
<item row="10" column="1"> <item row="11" column="1">
<widget class="QLineEdit" name="overallOpinion_TF"> <widget class="QLineEdit" name="overallOpinion_TF">
<property name="toolTip"> <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> <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> </tabstops>
<resources> <resources>
<include location="../icons.qrc"/> <include location="../icons.qrc"/>
<include location="../images.qrc"/>
</resources> </resources>
<connections/> <connections/>
</ui> </ui>

View file

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

View file

@ -692,8 +692,6 @@ void MainWindow::updateStatus()
// This call is essential to remove locks due to QEventLoop re-entrance while asking gpg passwds. Dont' remove it! // This call is essential to remove locks due to QEventLoop re-entrance while asking gpg passwds. Dont' remove it!
if(RsAutoUpdatePage::eventsLocked()) if(RsAutoUpdatePage::eventsLocked())
return; return;
if(Settings->valueFromGroup("StatusBar", "DisableSysTrayToolTip", QVariant(false)).toBool())
return;
float downKb = 0; float downKb = 0;
float upKb = 0; float upKb = 0;
rsConfig->GetCurrentDataRates(downKb, upKb); rsConfig->GetCurrentDataRates(downKb, upKb);
@ -711,6 +709,8 @@ void MainWindow::updateStatus()
discstatus->update(); 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"; 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) { if (onlineCount == 1) {
@ -726,6 +726,7 @@ void MainWindow::updateStatus()
tray += notifyToolTip; tray += notifyToolTip;
} }
trayIcon->setToolTip(tray); trayIcon->setToolTip(tray);
}
} }
void MainWindow::updateFriends() 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 */ /* Invoke Qt Designer generated QObject setup routine */
ui.setupUi(this); ui.setupUi(this);
// if(id.isNull()) ui.headerFrame->setHeaderImage(QPixmap(":/images/user/identityinfo64.png"));
// ui._useOldFormat_CB->setChecked(true) ; //ui.headerFrame->setHeaderText(tr("Friend node details"));
// 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._chat_CB->hide() ; //ui._chat_CB->hide() ;
@ -142,16 +134,21 @@ void ConfCertDialog::load()
return; return;
} }
//ui.pgpfingerprint->setText(QString::fromUtf8(detail.name.c_str())); //ui.pgpfingerprint->setText(QString::fromUtf8(detail.name.c_str()));
ui.peerid->setText(QString::fromStdString(detail.id.toStdString())); 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; ui.headerFrame->setHeaderText(nameAndLocation);
link.createPerson(detail.gpg_id);
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())); ui.loc->setText(QString::fromUtf8(detail.location.c_str()));
// Dont Show a timestamp in RS calculate the day // Dont Show a timestamp in RS calculate the day
@ -161,6 +158,11 @@ void ConfCertDialog::load()
std::string version; std::string version;
rsDisc->getPeerVersion(detail.id, version); rsDisc->getPeerVersion(detail.id, version);
ui.version->setText(QString::fromStdString(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 ; RsPeerCryptoParams cdet ;
if(RsControl::instance()->getPeerCryptoDetails(detail.id,cdet) && cdet.connexion_state!=0) if(RsControl::instance()->getPeerCryptoDetails(detail.id,cdet) && cdet.connexion_state!=0)

View file

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

View file

@ -6,8 +6,8 @@
<rect> <rect>
<x>0</x> <x>0</x>
<y>0</y> <y>0</y>
<width>742</width> <width>722</width>
<height>915</height> <height>546</height>
</rect> </rect>
</property> </property>
<property name="windowTitle"> <property name="windowTitle">
@ -69,7 +69,7 @@
<item row="0" column="0"> <item row="0" column="0">
<widget class="QTabWidget" name="stabWidget"> <widget class="QTabWidget" name="stabWidget">
<property name="currentIndex"> <property name="currentIndex">
<number>1</number> <number>0</number>
</property> </property>
<widget class="QWidget" name="tab"> <widget class="QWidget" name="tab">
<attribute name="icon"> <attribute name="icon">
@ -85,13 +85,20 @@
<item> <item>
<widget class="QGroupBox" name="groupBox_4"> <widget class="QGroupBox" name="groupBox_4">
<property name="title"> <property name="title">
<string>Node info</string> <string>Friend info</string>
</property> </property>
<layout class="QGridLayout" name="gridLayout_3"> <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"> <item row="0" column="1">
<widget class="RSTextBrowser" name="pgpfingerprint"> <widget class="RSTextBrowser" name="pgpfingerprint">
<property name="sizePolicy"> <property name="sizePolicy">
<sizepolicy hsizetype="MinimumExpanding" vsizetype="MinimumExpanding"> <sizepolicy hsizetype="Expanding" vsizetype="Fixed">
<horstretch>0</horstretch> <horstretch>0</horstretch>
<verstretch>0</verstretch> <verstretch>0</verstretch>
</sizepolicy> </sizepolicy>
@ -125,13 +132,6 @@
</property> </property>
</widget> </widget>
</item> </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"> <item row="5" column="0">
<widget class="QLabel" name="label_last_contact"> <widget class="QLabel" name="label_last_contact">
<property name="text"> <property name="text">
@ -197,7 +197,17 @@
<item row="0" column="0"> <item row="0" column="0">
<widget class="QLabel" name="label_name"> <widget class="QLabel" name="label_name">
<property name="text"> <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> </property>
</widget> </widget>
</item> </item>
@ -210,14 +220,14 @@
<widget class="AvatarWidget" name="avatar"> <widget class="AvatarWidget" name="avatar">
<property name="minimumSize"> <property name="minimumSize">
<size> <size>
<width>96</width> <width>128</width>
<height>96</height> <height>128</height>
</size> </size>
</property> </property>
<property name="maximumSize"> <property name="maximumSize">
<size> <size>
<width>96</width> <width>128</width>
<height>96</height> <height>128</height>
</size> </size>
</property> </property>
</widget> </widget>
@ -252,7 +262,18 @@
</property> </property>
</spacer> </spacer>
</item> </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"> <widget class="QTabWidget" name="tabWidget">
<property name="currentIndex"> <property name="currentIndex">
<number>0</number> <number>0</number>
@ -403,55 +424,51 @@
</item> </item>
</layout> </layout>
</widget> </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> </widget>
</item> </item>
</layout> </layout>
</widget> </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> </widget>
</item> </item>
</layout> </layout>

View file

@ -19,6 +19,7 @@
* Boston, MA 02110-1301, USA. * Boston, MA 02110-1301, USA.
****************************************************************/ ****************************************************************/
#include <QMessageBox>
#include <QDateTime> #include <QDateTime>
#include <QTimer> #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( playButton, SIGNAL( clicked( void ) ), this, SLOT( playMedia ( void ) ) );
connect( deleteButton, SIGNAL( clicked( void ) ), this, SLOT( deleteMsg ( void ) ) ); connect( deleteButton, SIGNAL( clicked( void ) ), this, SLOT( deleteMsg ( void ) ) );
connect( replyButton, SIGNAL( clicked( void ) ), this, SLOT( replyMsg ( void ) ) ); connect( replyButton, SIGNAL( clicked( void ) ), this, SLOT( replyMsg ( void ) ) );
connect( sendinviteButton, SIGNAL( clicked( void ) ), this, SLOT( sendInvite ( void ) ) );
expandFrame->hide(); expandFrame->hide();
inviteFrame->hide();
updateItemStatic(); updateItemStatic();
updateItem(); updateItem();
@ -87,7 +91,7 @@ void MsgItem::updateItemStatic()
/* get peer Id */ /* get peer Id */
if (mi.msgflags & RS_MSG_SIGNED) if (mi.msgflags & RS_MSG_DISTANT)
avatar->setGxsId(mi.rsgxsid_srcId) ; avatar->setGxsId(mi.rsgxsid_srcId) ;
else else
avatar->setId(ChatId(mi.rspeerid_srcId)) ; avatar->setId(ChatId(mi.rspeerid_srcId)) ;
@ -99,7 +103,7 @@ void MsgItem::updateItemStatic()
srcName = "RetroShare"; srcName = "RetroShare";
else else
{ {
if(mi.msgflags & RS_MSG_SIGNED) if(mi.msgflags & RS_MSG_DISTANT)
{ {
RsIdentityDetails details ; RsIdentityDetails details ;
rsIdentity->getIdDetails(mi.rsgxsid_srcId, details) ; rsIdentity->getIdDetails(mi.rsgxsid_srcId, details) ;
@ -110,11 +114,22 @@ void MsgItem::updateItemStatic()
srcName = QString::fromUtf8(rsPeers->getPeerName(mi.rspeerid_srcId).c_str()); srcName = QString::fromUtf8(rsPeers->getPeerName(mi.rspeerid_srcId).c_str());
} }
timestampLabel->setText(DateTime::formatLongDateTime(mi.ts));
if (!mIsHome) 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 else
{ {
@ -141,11 +156,11 @@ void MsgItem::updateItemStatic()
break; break;
} }
} }
title += srcName;
titleLabel->setText(title); titleLabel->setText(title);
subjectLabel->setText(QString::fromUtf8(mi.title.c_str())); subjectLabel->setText(QString::fromUtf8(mi.title.c_str()));
mMsg = QString::fromUtf8(mi.msg.c_str()); mMsg = QString::fromUtf8(mi.msg.c_str());
timestampLabel->setText(DateTime::formatLongDateTime(mi.ts));
if (wasExpanded() || expandFrame->isVisible()) { if (wasExpanded() || expandFrame->isVisible()) {
fillExpandFrame(); fillExpandFrame();
@ -344,3 +359,20 @@ void MsgItem::checkMessageReadStatus()
removeItem(); 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 playMedia();
void deleteMsg(); void deleteMsg();
void replyMsg(); void replyMsg();
void sendInvite();
void checkMessageReadStatus(); void checkMessageReadStatus();
void updateItem(); void updateItem();

View file

@ -6,8 +6,8 @@
<rect> <rect>
<x>0</x> <x>0</x>
<y>0</y> <y>0</y>
<width>643</width> <width>707</width>
<height>146</height> <height>180</height>
</rect> </rect>
</property> </property>
<layout class="QGridLayout" name="MsgItemGLayout"> <layout class="QGridLayout" name="MsgItemGLayout">
@ -120,7 +120,7 @@
<property name="bottomMargin"> <property name="bottomMargin">
<number>0</number> <number>0</number>
</property> </property>
<item row="0" column="0" rowspan="3"> <item row="0" column="0" rowspan="4">
<widget class="AvatarWidget" name="avatar"> <widget class="AvatarWidget" name="avatar">
<property name="minimumSize"> <property name="minimumSize">
<size> <size>
@ -146,6 +146,7 @@
</property> </property>
<property name="font"> <property name="font">
<font> <font>
<pointsize>12</pointsize>
<weight>75</weight> <weight>75</weight>
<italic>true</italic> <italic>true</italic>
<bold>true</bold> <bold>true</bold>
@ -165,7 +166,7 @@
<enum>Qt::Horizontal</enum> <enum>Qt::Horizontal</enum>
</property> </property>
<property name="sizeType"> <property name="sizeType">
<enum>QSizePolicy::Preferred</enum> <enum>QSizePolicy::Expanding</enum>
</property> </property>
<property name="sizeHint" stdset="0"> <property name="sizeHint" stdset="0">
<size> <size>
@ -188,7 +189,7 @@
</property> </property>
</widget> </widget>
</item> </item>
<item row="1" column="1" colspan="2"> <item row="2" column="1" colspan="3">
<widget class="QLabel" name="subjectLabel"> <widget class="QLabel" name="subjectLabel">
<property name="sizePolicy"> <property name="sizePolicy">
<sizepolicy hsizetype="MinimumExpanding" vsizetype="Preferred"> <sizepolicy hsizetype="MinimumExpanding" vsizetype="Preferred">
@ -204,8 +205,15 @@
</property> </property>
</widget> </widget>
</item> </item>
<item row="2" column="1" colspan="3"> <item row="3" column="1" colspan="3">
<layout class="QHBoxLayout" name="buttonHLayout"> <layout class="QHBoxLayout" name="buttonHLayout">
<item>
<widget class="QPushButton" name="sendinviteButton">
<property name="text">
<string>Send Invite</string>
</property>
</widget>
</item>
<item> <item>
<widget class="QToolButton" name="replyButton"> <widget class="QToolButton" name="replyButton">
<property name="focusPolicy"> <property name="focusPolicy">
@ -225,7 +233,7 @@
<enum>Qt::ToolButtonTextBesideIcon</enum> <enum>Qt::ToolButtonTextBesideIcon</enum>
</property> </property>
<property name="autoRaise"> <property name="autoRaise">
<bool>true</bool> <bool>false</bool>
</property> </property>
</widget> </widget>
</item> </item>
@ -324,6 +332,123 @@
</item> </item>
</layout> </layout>
</item> </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> </layout>
</widget> </widget>
</item> </item>
@ -368,6 +493,7 @@
</customwidgets> </customwidgets>
<resources> <resources>
<include location="../images.qrc"/> <include location="../images.qrc"/>
<include location="../../../../RetroShare/RetroShare/retroshare-gui/src/gui/images.qrc"/>
</resources> </resources>
<connections/> <connections/>
</ui> </ui>

View file

@ -400,7 +400,13 @@ void CreateGxsForumMsg::smileyWidgetForums()
void CreateGxsForumMsg::addSmileys() 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() void CreateGxsForumMsg::addFile()

View file

@ -1110,18 +1110,12 @@ QTreeWidgetItem *GxsForumThreadWidget::convertMsgToThreadWidget(const RsGxsForum
// Early check for a message that should be hidden because its author // Early check for a message that should be hidden because its author
// is flagged with a bad reputation // 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; bool redacted = false;
if( rsIdentity->getIdDetails(msg.mMeta.mAuthorId,iddetails) ) redacted = (reputation_level == RsReputations::REPUTATION_LOCALLY_NEGATIVE);
{
reputation_level = iddetails.mReputation.mOverallReputationLevel;
redacted = (reputation_level == RsReputations::REPUTATION_LOCALLY_NEGATIVE);
}
else
reputation_level = RsReputations::REPUTATION_UNKNOWN;
GxsIdRSTreeWidgetItem *item = new GxsIdRSTreeWidgetItem(mThreadCompareRole,GxsIdDetails::ICON_TYPE_AVATAR ); GxsIdRSTreeWidgetItem *item = new GxsIdRSTreeWidgetItem(mThreadCompareRole,GxsIdDetails::ICON_TYPE_AVATAR );
item->moveToThread(ui->threadTreeWidget->thread()); item->moveToThread(ui->threadTreeWidget->thread());
@ -1144,7 +1138,7 @@ QTreeWidgetItem *GxsForumThreadWidget::convertMsgToThreadWidget(const RsGxsForum
rep_warning_level = 2 ; rep_warning_level = 2 ;
rep_tooltip_str = tr("You have banned this ID. The message will not be\ndisplayed nor forwarded to your friends.") ; 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_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.") ; 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 newCount() { return mNewCount; }
unsigned int unreadCount() { return mUnreadCount; } 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); QTreeWidgetItem *generateMissingItem(const RsGxsMessageId &msgId);
// Callback for all Loads. // Callback for all Loads.

View file

@ -144,9 +144,25 @@ void GxsForumsFillThread::run()
emit status(tr("Retrieving")); emit status(tr("Retrieving"));
/* get messages */ /* get messages */
std::vector<RsGxsForumMsg> msgs; std::map<RsGxsMessageId,RsGxsForumMsg> msgs;
if (!rsGxsForums->getMsgData(token, msgs)) {
return; { // 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")); emit status(tr("Loading"));
@ -155,131 +171,152 @@ void GxsForumsFillThread::run()
int pos = 0; int pos = 0;
int steps = count / PROGRESSBAR_MAX; int steps = count / PROGRESSBAR_MAX;
int step = 0; 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 */ // The first step is to find the top level thread messages. These are defined as the messages without
std::vector<RsGxsForumMsg>::iterator msgIt; // any parent message ID.
for (msgIt = msgs.begin(); msgIt != msgs.end(); ) {
if (wasStopped()) { // this trick is needed because while we remove messages, the parents a given msg may already have been removed
break; // and wrongly understand as a missing parent.
}
const RsGxsForumMsg &msg = *msgIt; std::map<RsGxsMessageId,RsGxsForumMsg> kept_msgs;
if (!mFlatView && !msg.mMeta.mParentId.isNull()) { for ( std::map<RsGxsMessageId,RsGxsForumMsg>::iterator msgIt = msgs.begin(); msgIt != msgs.end();++msgIt)
++msgIt; if(mFlatView || msgIt->second.mMeta.mParentId.isNull())
continue; {
}
/* add all threads */
if (wasStopped())
return;
const RsGxsForumMsg& msg = msgIt->second;
#ifdef DEBUG_FORUMS #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 #endif
QTreeWidgetItem *item = mParent->convertMsgToThreadWidget(msg, mUseChildTS, mFilterColumn); QTreeWidgetItem *item = mParent->convertMsgToThreadWidget(msg, mUseChildTS, mFilterColumn,NULL);
if (!mFlatView) {
threadList.push_back(QPair<std::string, QTreeWidgetItem*>(msg.mMeta.mMsgId.toStdString(), item));
}
calculateExpand(msg, item);
mItems.append(item); if (!mFlatView)
threadStack.push_back(std::make_pair(msg.mMeta.mMsgId,item)) ;
if (++step >= steps) { calculateExpand(msg, item);
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));
mItems.append(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 #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; std::cerr << "GxsForumsFillThread::run() stopped: " << (wasStopped() ? "yes" : "no") << std::endl;
#endif #endif
} }

View file

@ -2200,7 +2200,13 @@ void MessageComposer::smileyWidget()
void MessageComposer::addSmileys() 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) void MessageComposer::currentCharFormatChanged(const QTextCharFormat &format)
@ -2758,3 +2764,44 @@ void MessageComposer::on_closeInfoFrameButton_clicked()
{ {
ui.distantFrame->setVisible(false); 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 QString recommendMessage();
static void recommendFriend(const std::set <RsPeerId> &sslIds, const RsPeerId &to = RsPeerId(), const QString &msg = "", bool autoSend = false); 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 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 #ifdef UNUSED_CODE
static void sendChannelPublishKey(RsGxsChannelGroup &group); static void sendChannelPublishKey(RsGxsChannelGroup &group);
static void sendForumPublishKey(RsGxsForumGroup &group); static void sendForumPublishKey(RsGxsForumGroup &group);
@ -164,6 +165,8 @@ private slots:
void tagRemoveAll(); void tagRemoveAll();
void on_closeInfoFrameButton_clicked(); void on_closeInfoFrameButton_clicked();
static QString inviteMessage();
private: private:
static QString buildReplyHeader(const MessageInfo &msgInfo); 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.expandFilesButton, SIGNAL(clicked()), this, SLOT(togglefileview()));
connect(ui.downloadButton, SIGNAL(clicked()), this, SLOT(getallrecommended())); connect(ui.downloadButton, SIGNAL(clicked()), this, SLOT(getallrecommended()));
connect(ui.msgText, SIGNAL(anchorClicked(QUrl)), this, SLOT(anchorClicked(QUrl))); 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(messagesTagsChanged()), this, SLOT(messagesTagsChanged()));
connect(NotifyQt::getInstance(), SIGNAL(messagesChanged()), this, SLOT(messagesChanged())); 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.dateText-> setText("");
ui.inviteFrame->hide();
} }
MessageWidget::~MessageWidget() MessageWidget::~MessageWidget()
@ -478,6 +481,12 @@ void MessageWidget::fill(const std::string &msgId)
std::cerr << "MessageWidget::fill() Couldn't find Msg" << std::endl; std::cerr << "MessageWidget::fill() Couldn't find Msg" << std::endl;
return; return;
} }
if (msgInfo.msgflags & RS_MSG_USER_REQUEST){
ui.inviteFrame->show();
} else {
ui.inviteFrame->hide();
}
const std::list<FileInfo> &recList = msgInfo.files; const std::list<FileInfo> &recList = msgInfo.files;
std::list<FileInfo>::const_iterator it; std::list<FileInfo>::const_iterator it;
@ -738,3 +747,20 @@ void MessageWidget::loadImagesAlways()
rsMail->MessageLoadEmbeddedImages(currMsgId, true); 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 printPreview();
void saveAs(); void saveAs();
void refill(); void refill();
void sendInvite();
void msgfilelistWidgetCostumPopupMenu(QPoint); void msgfilelistWidgetCostumPopupMenu(QPoint);
void messagesTagsChanged(); void messagesTagsChanged();

View file

@ -288,11 +288,157 @@
</property> </property>
</widget> </widget>
</item> </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> <item>
<layout class="QHBoxLayout" name="_2"> <layout class="QHBoxLayout" name="_2">
<item> <item>
<layout class="QGridLayout" name="_3"> <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> <number>0</number>
</property> </property>
<property name="spacing"> <property name="spacing">

View file

@ -440,10 +440,17 @@ PeerItem QLabel#peerNameLabel {
color: #990033 color: #990033
} }
MsgItem > QFrame#frame { MsgItem QFrame#frame {
border: 2px solid #3EA2FF; border: 2px solid #0099cc;
background-color: qlineargradient(x1: 0, y1: 0, x2: 0, y2: 1, stop: 0 #2291E0, stop: 1 #3EB3FF); border-radius: 6px;
border-radius: 10px; 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 { MsgItem QWidget#avatar {
@ -554,6 +561,13 @@ MessageWidget QFrame#decryptFrame {
background-color: qlineargradient(x1:0, y1:0, x2:0, y2:1, stop:0 #CCFFCC, stop:1 #AAFFAA); 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 */ /* Posted Links */
PostedCreatePostDialog QLabel#info_label { PostedCreatePostDialog QLabel#info_label {
@ -615,6 +629,10 @@ IdDialog QLabel#headerTextLabel {
color: rgb(255, 255, 255); color: rgb(255, 255, 255);
} }
IdDialog QLabel#headerTextLabel_Person {
color: rgb(255, 255, 255);
}
IdDialog QLabel#headerTextLabel_Circles { IdDialog QLabel#headerTextLabel_Circles {
color: rgb(255, 255, 255); color: rgb(255, 255, 255);
} }
@ -624,6 +642,13 @@ IdDialog QLabel#avlabel {
border-radius: 10px; 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 GxsChannelPostsWidget QFrame#infoFrame
{ {
border: 1px solid #DCDC41; border: 1px solid #DCDC41;

View file

@ -145,7 +145,7 @@
<item> <item>
<widget class="QComboBox" name="_e2e_encryption_CB"> <widget class="QComboBox" name="_e2e_encryption_CB">
<property name="toolTip"> <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> </property>
<item> <item>
<property name="text"> <property name="text">

View file

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

View file

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