Merge remote-tracking branch 'upstream/master' into v0.6-BugFixing_8

This commit is contained in:
csoler 2021-02-09 20:43:22 +01:00
commit faadd24ef3
61 changed files with 1654 additions and 1379 deletions

View File

@ -285,6 +285,64 @@ are marked with the custom doxygen command +@jsonapi{RS_VERSION,manualwrapper}+
and their wrappers are not automatically generated but written manually into
+JsonApiServer::JsonApiServer(...)+.
== Quirks
=== 64 bits integers handling
While JSON doesn't have problems representing 64 bits integers JavaScript, Dart
and other languages are not capable to handle those numbers natively.
To overcome this limitation JSON API output 64 bit integers as an object with
two keys, one as proper integer and one as string representation.
.JSON API 64 bit integer output example
[source,json]
--------------------------------------------------------------------------------
"lobby_id": { "xint64": 6215642878098695544, "xstr64": "6215642878098695544" }
--------------------------------------------------------------------------------
So from languages that have proper 64bit integers support like Python or C++ one
better read from `xint64` which is represented as a JSON integer, from languages
where there is no proper 64bit integers support like JavaScript one can read from
`xstr64` which is represented as JSON string (note that the first is not wrapped
in "" while the latter is).
When one input a 64bit integer into the JSON API it first try to parse it as if
it was sent the old way for retrocompatibility.
.JSON API 64 bit integer deprecated format input example
[source,json]
--------------------------------------------------------------------------------
"lobby_id":6215642878098695544
--------------------------------------------------------------------------------
This way is *DEPRECATED* and may disappear in the future, it is TEMPORALLY kept
only for retrocompatibiliy with old clients.
If retrocompatible parsing attempt fail then it try to parse with the new way
with proper JSON integer format.
.JSON API 64 bit integer new proper integer format input example
[source,json]
--------------------------------------------------------------------------------
lobby_id": { "xint64": 6215642878098695544 }
--------------------------------------------------------------------------------
If this fails then it try to parse with the new way with JSON string format.
.JSON API 64 bit integer new string format input example
[source,json]
--------------------------------------------------------------------------------
"lobby_id": { "xstr64": "6215642878098695544" }
--------------------------------------------------------------------------------
[WARNING]
================================================================================
Clients written in languages without proper 64bit integers support must
use *ONLY* the string format otherwise they will send approximated values and
get unexpected results from the JSON API, because parsing will success but the
value will not be exactly the one you believe you sent.
================================================================================
== A bit of history

View File

@ -760,7 +760,7 @@ bool ftServer::handleTunnelRequest(const RsFileHash& hash,const RsPeerId& peer_i
// share the file!
FileChunksInfo info2 ;
if(rsFiles->FileDownloadChunksDetails(hash, info2))
if(rsFiles->FileDownloadChunksDetails(real_hash, info2))
for(uint32_t i=0;i<info2.chunks.size();++i)
if(info2.chunks[i] == FileChunksInfo::CHUNK_DONE)
{

View File

@ -1141,8 +1141,10 @@ bool GxsSecurity::validateNxsGrp(const RsNxsGrp& grp, const RsTlvKeySignature& s
signOk = EVP_VerifyFinal(mdctx, sigbuf, siglen, signKey);
EVP_MD_CTX_destroy(mdctx);
#ifdef GXS_SECURITY_DEBUG
if(i>0)
std::cerr << "(WW) Checking group signature with old api version " << i+1 << " : tag " << std::hex << api_versions_to_check[i] << std::dec << " result: " << signOk << std::endl;
#endif
}
/* clean up */

View File

@ -1379,7 +1379,16 @@ bool RsGenExchange::getGroupMeta(const uint32_t &token, std::list<RsGroupMetaDat
{
m.mPop= 0 ;
m.mVisibleMsgCount = 0 ;
}
}
// We could save this in the net service, but it's a bit more than that since some services have
// specific usage footprints for their groups.
m.mLastSeen = (IS_GROUP_SUBSCRIBED(gMeta.mSubscribeFlags)) ? time(nullptr) : service_getLastGroupSeenTs(gMeta.mGroupId);
#ifdef GEN_EXCH_DEBUG
std::cerr << "Group: " << gMeta.mGroupId << " name \"" << gMeta.mGroupName << "\" last seen=" << m.mLastSeen << " now=" << time(nullptr) << std::endl;
#endif
groupInfo.push_back(m);
}
@ -1556,6 +1565,7 @@ bool RsGenExchange::getGroupData(const uint32_t &token, std::vector<RsGxsGrpItem
if((!(IS_GROUP_SUBSCRIBED(gItem->meta.mSubscribeFlags))) || gItem->meta.mLastPost == 0)
gItem->meta.mLastPost = sts.mLastGroupModificationTS ;
}
else
{
@ -1563,6 +1573,14 @@ bool RsGenExchange::getGroupData(const uint32_t &token, std::vector<RsGxsGrpItem
gItem->meta.mVisibleMsgCount = 0;
}
// We could save this in the net service, but it's a bit more than that since some services have
// specific usage footprints for their groups.
gItem->meta.mLastSeen = (IS_GROUP_SUBSCRIBED(gItem->meta.mSubscribeFlags)) ? time(nullptr) : service_getLastGroupSeenTs(gItem->meta.mGroupId);
#ifdef GEN_EXCH_DEBUG
std::cerr << "Group: " << gItem->meta.mGroupId << " name \"" << gItem->meta.mGroupName << "\" last seen=" << gItem->meta.mLastSeen << " now=" << time(nullptr) << std::endl;
#endif
// Also check the group privacy flags. A while ago, it as possible to publish a group without privacy flags. Now it is not possible anymore.
// As a consequence, it's important to supply a correct value in this flag before the data can be edited/updated.

View File

@ -667,6 +667,14 @@ protected:
*/
virtual bool service_checkIfGroupIsStillUsed(const RsGxsGrpMetaData& /* meta */) { return true; } // see RsGenExchange
/*!
* \brief service_getLastGroupSeenTs
* \return
* returns the last time a friend sent information (statistics) about this group. That practically means when the
* group was still being subscribed by at least one friend. This is used by service_checkIfGroupIsStillUsed() to
* help getting rid of dead groups.
*/
virtual rstime_t service_getLastGroupSeenTs(const RsGxsGroupId&) { return 0; }
public:
/*!

View File

@ -2430,7 +2430,6 @@ void p3PeerMgrIMPL::saveDone()
bool p3PeerMgrIMPL::loadList(std::list<RsItem *>& load)
{
// DEFAULTS.
bool useExtAddrFinder = true;
std::string proxyIpAddressTor = kConfigDefaultProxyServerIpAddr;
@ -2679,13 +2678,31 @@ bool p3PeerMgrIMPL::loadList(std::list<RsItem *>& load)
groupList[info.id] = info;
}
// Also filter out profiles in groups that are not friends. Normally this shouldn't be needed, but it's a precaution
for(auto group_pair:groupList)
{
for(auto profileIdIt(group_pair.second.peerIds.begin());profileIdIt!=group_pair.second.peerIds.end();)
if(AuthGPG::getAuthGPG()->isGPGAccepted(*profileIdIt) || *profileIdIt == AuthGPG::getAuthGPG()->getGPGOwnId())
++profileIdIt;
else
{
std::cerr << "(WW) filtering out profile " << profileIdIt->toStdString() << " from group " << group_pair.first.toStdString() << " because it is not a friend anymore" << std::endl;
auto tmp = profileIdIt;
++tmp;
group_pair.second.peerIds.erase(profileIdIt);
profileIdIt=tmp;
IndicateConfigChanged();
}
}
}
// If we are hidden - don't want ExtAddrFinder - ever!
if (isHidden())
{
useExtAddrFinder = false;
}
mNetMgr->setIPServersEnabled(useExtAddrFinder);

View File

@ -470,18 +470,11 @@ int pqihandler::UpdateRates()
// for our up bandwidth we take into account the max down provided by peers via BwCtrl
// because we don't want to clog our outqueues, the TCP buffers, and the peers inbound queues
mod -> pqi -> setMaxRate(false, out_max_bw);
if ((rateMap_it = rateMap.find(mod->pqi->PeerId())) != rateMap.end())
{
if (rateMap_it->second.mAllowedOut > 0)
{
if (out_max_bw > rateMap_it->second.mAllowedOut)
mod -> pqi -> setMaxRate(false, rateMap_it->second.mAllowedOut);
else
mod -> pqi -> setMaxRate(false, out_max_bw);
}
else
mod -> pqi -> setMaxRate(false, out_max_bw);
}
}
#ifdef UPDATE_RATES_DEBUG

View File

@ -863,10 +863,10 @@ int pqissl::Basic_Connection_Complete()
{
// error - reset socket.
// this is a definite bad socket!.
#ifdef PQISSL_LOG_DEBUG2
rslog(RSL_WARNING, pqisslzone,
"pqissl::Basic_Connection_Complete() Select ERROR(2)");
#endif
net_internal_close(sockfd);
sockfd=-1;
//reset();
@ -1598,7 +1598,9 @@ int pqissl::readdata(void *data, int len)
reset_locked();
}
#ifdef PQISSL_LOG_DEBUG2
rslog(RSL_ALERT, pqisslzone, out);
#endif
//std::cerr << out << std::endl ;
return -1;
}

View File

@ -88,9 +88,10 @@ struct RsGroupMetaData : RsSerializable
uint32_t mSubscribeFlags;
uint32_t mPop; // Popularity = number of friend subscribers
uint32_t mVisibleMsgCount; // Max messages reported by friends
rstime_t mLastPost; // Timestamp for last message. Not used yet.
uint32_t mPop; // Popularity = number of friend subscribers
uint32_t mVisibleMsgCount; // Max messages reported by friends
rstime_t mLastPost; // Timestamp for last message. Not used yet.
rstime_t mLastSeen; // Last time the group was advertised by friends.
uint32_t mGroupStatus;

View File

@ -40,7 +40,6 @@
#include "retroshare/rsevents.h"
#include "services/rseventsservice.h"
/*******************
#define TICK_DEBUG 1
*******************/
@ -110,14 +109,15 @@ RsServer::RsServer() :
mStatusSrv = NULL;
mGxsTunnels = NULL;
/* timers */
mLastts = getCurrentTS();
mTickInterval = maxTickInterval ;
mAvgRunDuration = 0;
mLastRunDuration = 0;
mCycle1 = 0;
mCycle2 = 0;
mCycle3 = 0;
mCycle4 = 0;
mCycle1 = mLastts;
mCycle2 = mLastts;
mCycle3 = mLastts;
mCycle4 = mLastts;
/* caches (that need ticking) */
@ -136,10 +136,10 @@ RsServer::~RsServer()
void RsServer::threadTick()
{
#ifdef TICK_DEBUG
RsDbg() << "TICK_DEBUG ticking interval "<< mTickInterval << std::endl;
RsDbg() << "TICK_DEBUG ticking interval " << std::dec << (int) (1000 * mTickInterval) << " ms";
#endif
// we try to tick at a regular interval which depends on the load
// we try to tick at a regular interval depending on the load
// if there is time left, we sleep
double timeToSleep = mTickInterval - mAvgRunDuration;
@ -148,7 +148,7 @@ void RsServer::threadTick()
timeToSleep = 0.050;
#ifdef TICK_DEBUG
RsDbg() << "TICK_DEBUG will sleep " << (int) (1000 * timeToSleep) << " ms" << std::endl;
RsDbg() << "TICK_DEBUG will sleep " << std::dec << (int) (1000 * timeToSleep) << " ms";
#endif
rstime::rs_usleep(timeToSleep * 1000000);
@ -156,24 +156,24 @@ void RsServer::threadTick()
mLastts = ts;
// stuff we do always
// tick the core
// tick the core
#ifdef TICK_DEBUG
RsDbg() << "TICK_DEBUG ticking server" << std::endl;
RsDbg() << "TICK_DEBUG ticking RS core";
#endif
lockRsCore();
int moreToTick = pqih->tick();
unlockRsCore();
// tick the managers
// tick the managers
#ifdef TICK_DEBUG
RsDbg() << "TICK_DEBUG ticking mPeerMgr" << std::endl;
RsDbg() << "TICK_DEBUG ticking mPeerMgr";
#endif
mPeerMgr->tick();
#ifdef TICK_DEBUG
RsDbg() << "TICK_DEBUG ticking mLinkMgr" << std::endl;
RsDbg() << "TICK_DEBUG ticking mLinkMgr";
#endif
mLinkMgr->tick();
#ifdef TICK_DEBUG
RsDbg() << "TICK_DEBUG ticking mNetMgr" << std::endl;
RsDbg() << "TICK_DEBUG ticking mNetMgr";
#endif
mNetMgr->tick();
@ -182,11 +182,16 @@ void RsServer::threadTick()
if (ts - mCycle1 > 1)
{
#ifdef TICK_DEBUG
RsDbg() << "TICK_DEBUG every second" << std::endl;
RsDbg() << "TICK_DEBUG every second";
#endif
// slow services
if (rsPlugins)
{
#ifdef TICK_DEBUG
RsDbg() << "TICK_DEBUG ticking slow tick plugins";
#endif
rsPlugins->slowTickPlugins((rstime_t)ts);
}
// UDP keepalive
// tou_tick_stunkeepalive();
// other stuff to tick
@ -198,10 +203,8 @@ void RsServer::threadTick()
if (ts - mCycle2 > 5)
{
#ifdef TICK_DEBUG
RsDbg() << "TICK_DEBUG every 5 seconds" << std::endl;
RsDbg() << "TICK_DEBUG every 5 seconds";
#endif
// save stuff
mConfigMgr->tick();
mCycle2 = ts;
}
@ -209,7 +212,7 @@ void RsServer::threadTick()
if (ts - mCycle3 > 60)
{
#ifdef TICK_DEBUG
RsDbg() << "TICK_DEBUG every 60 seconds" << std::endl;
RsDbg() << "TICK_DEBUG every 60 seconds";
#endif
// force saving FileTransferStatus TODO
// ftserver->saveFileTransferStatus();
@ -222,8 +225,13 @@ void RsServer::threadTick()
if (ts - mCycle4 > 3600)
{
#ifdef TICK_DEBUG
RsDbg() << "TICK_DEBUG every hour" << std::endl;
RsDbg() << "TICK_DEBUG every hour";
#endif
// save configuration files
#ifdef TICK_DEBUG
RsDbg() << "TICK_DEBUG ticking mConfigMgr";
#endif
mConfigMgr->tick();
mCycle4 = ts;
}
@ -237,22 +245,22 @@ void RsServer::threadTick()
mAvgRunDuration = maxTickInterval;
#ifdef TICK_DEBUG
RsDbg() << "TICK_DEBUG new mLastRunDuration " << mLastRunDuration << " mAvgRunDuration " << mAvgRunDuration << std::endl;
RsDbg() << "TICK_DEBUG mLastRunDuration " << std::dec << (int) (1000 * mLastRunDuration) << " ms, mAvgRunDuration " << (int) (1000 * mAvgRunDuration) << " ms";
if (mLastRunDuration > WARN_BIG_CYCLE_TIME)
RsDbg() << "TICK_DEBUG excessively long cycle time " << mLastRunDuration << std::endl;
RsDbg() << "TICK_DEBUG excessively long cycle time " << std::dec << (int) (1000 * mLastRunDuration) << " ms";
#endif
// if the core has returned that there is more to tick we decrease the ticking interval, else we increse it
// this should be studied closer as I dont think that the core ever returns 1
// if the core has returned that there is more to tick we decrease the ticking interval, else we increase it
// TODO: this should be investigated as it seems that the core never returns 1
#ifdef TICK_DEBUG
RsDbg() << "TICK_DEBUG moreToTick " << moreToTick << std::endl;
RsDbg() << "TICK_DEBUG moreToTick " << moreToTick;
#endif
if (moreToTick == 1)
mTickInterval = 0.9 * mTickInterval;
else
mTickInterval = 1.1 * mTickInterval;
#ifdef TICK_DEBUG
RsDbg() << "TICK_DEBUG new tick interval " << mTickInterval << std::endl;
RsDbg() << "TICK_DEBUG new tick interval " << std::dec << (int) (1000 * mTickInterval) << " ms";
#endif
// keep the tick interval target within allowed limits
@ -261,7 +269,7 @@ void RsServer::threadTick()
else if (mTickInterval > maxTickInterval)
mTickInterval = maxTickInterval;
#ifdef TICK_DEBUG
RsDbg() << "TICK_DEBUG new tick interval after limiter " << mTickInterval << std::endl;
RsDbg() << "TICK_DEBUG new tick interval after limiter " << std::dec << (int) (1000 * mTickInterval) << " ms";
#endif
}

View File

@ -1700,6 +1700,24 @@ bool p3GxsCircles::locked_checkCircleCacheForAutoSubscribe(RsGxsCircleCache& cac
return true;
}
rstime_t p3GxsCircles::service_getLastGroupSeenTs(const RsGxsGroupId& gid)
{
rstime_t now = time(nullptr);
RS_STACK_MUTEX(mKnownCirclesMtx);
auto it = mKnownCircles.find(gid);
bool unknown_posted = (it == mKnownCircles.end());
if(unknown_posted)
{
mKnownCircles[gid] = now;
IndicateConfigChanged();
return now;
}
else
return it->second;
}
bool p3GxsCircles::service_checkIfGroupIsStillUsed(const RsGxsGrpMetaData& meta)
{
#ifdef GXSFORUMS_CHANNELS

View File

@ -290,6 +290,7 @@ public:
virtual void updateGroup(uint32_t &token, RsGxsCircleGroup &group) override;
virtual bool service_checkIfGroupIsStillUsed(const RsGxsGrpMetaData& meta) override;
virtual rstime_t service_getLastGroupSeenTs(const RsGxsGroupId&) override;
/* membership management for external circles */

View File

@ -417,6 +417,24 @@ void p3GxsForums::service_tick()
return;
}
rstime_t p3GxsForums::service_getLastGroupSeenTs(const RsGxsGroupId& gid)
{
rstime_t now = time(nullptr);
RS_STACK_MUTEX(mKnownForumsMutex);
auto it = mKnownForums.find(gid);
bool unknown_forum = it == mKnownForums.end();
if(unknown_forum)
{
mKnownForums[gid] = now;
IndicateConfigChanged();
return now;
}
else
return it->second;
}
bool p3GxsForums::service_checkIfGroupIsStillUsed(const RsGxsGrpMetaData& meta)
{
#ifdef GXSFORUMS_DEBUG

View File

@ -53,6 +53,7 @@ protected:
virtual bool loadList(std::list<RsItem *>& loadList) override; // @see p3Config::loadList(std::list<RsItem *>&)
virtual bool service_checkIfGroupIsStillUsed(const RsGxsGrpMetaData& meta) override;
virtual rstime_t service_getLastGroupSeenTs(const RsGxsGroupId&) override;
public:
/// @see RsGxsForums::createForumV2
bool createForumV2(

View File

@ -47,6 +47,7 @@
* #define DEBUG_IDS 1
* #define DEBUG_RECOGN 1
* #define DEBUG_OPINION 1
* #define DEBUG_SERVICE_STRING 1
* #define GXSID_GEN_DUMMY_DATA 1
****/
@ -102,6 +103,7 @@ RsIdentity* rsIdentity = nullptr;
#define GXSIDREQ_RECOGN 0x0020
#define GXSIDREQ_OPINION 0x0030
#define GXSIDREQ_SERIALIZE_TO_MEMORY 0x0040
#define GXSIDREQ_LOAD_PGPIDDATA 0x0080
#define GXSIDREQ_CACHETEST 0x1000
@ -166,6 +168,7 @@ p3IdService::p3IdService( RsGeneralDataService *gds
, mMaxKeepKeysBanned(MAX_KEEP_KEYS_BANNED_DEFAULT)
{
mLastKeyCleaningTime = time(NULL) - int(MAX_DELAY_BEFORE_CLEANING * 0.9) ;
mLastPGPHashProcessTime = 0;
// Kick off Cache Testing, + Others.
RsTickEvent::schedule_now(GXSID_EVENT_CACHEOWNIDS);//First Thing to do
@ -587,6 +590,13 @@ void p3IdService::service_tick()
cleanUnusedKeys() ;
mLastKeyCleaningTime = now ;
}
if(mLastPGPHashProcessTime + PGPHASH_PROC_PERIOD < now && !mGroupsToProcess.empty())
{
pgphash_process();
mLastPGPHashProcessTime=now;
}
return;
}
@ -2377,7 +2387,7 @@ bool SSGxsIdGroup::load(const std::string &input)
// split into parts.
if (3 != sscanf(input.c_str(), "v2 {P:%[^}]}{T:%[^}]}{R:%[^}]}", pgpstr, recognstr, scorestr))
{
#ifdef DEBUG_IDS
#ifdef DEBUG_SERVICE_STRING
std::cerr << "SSGxsIdGroup::load() Failed to extract 4 Parts";
std::cerr << std::endl;
#endif // DEBUG_IDS
@ -2387,14 +2397,14 @@ bool SSGxsIdGroup::load(const std::string &input)
bool ok = true;
if (pgp.load(pgpstr))
{
#ifdef DEBUG_IDS
#ifdef DEBUG_SERVICE_STRING
std::cerr << "SSGxsIdGroup::load() pgpstr: " << pgpstr;
std::cerr << std::endl;
#endif // DEBUG_IDS
}
else
{
#ifdef DEBUG_IDS
#ifdef DEBUG_SERVICE_STRING
std::cerr << "SSGxsIdGroup::load() Invalid pgpstr: " << pgpstr;
std::cerr << std::endl;
#endif // DEBUG_IDS
@ -2419,14 +2429,14 @@ bool SSGxsIdGroup::load(const std::string &input)
if (score.load(scorestr))
{
#ifdef DEBUG_IDS
#ifdef DEBUG_SERVICE_STRING
std::cerr << "SSGxsIdGroup::load() scorestr: " << scorestr;
std::cerr << std::endl;
#endif // DEBUG_IDS
}
else
{
#ifdef DEBUG_IDS
#ifdef DEBUG_SERVICE_STRING
std::cerr << "SSGxsIdGroup::load() Invalid scorestr: " << scorestr;
std::cerr << std::endl;
#endif // DEBUG_IDS
@ -3450,7 +3460,7 @@ void p3IdService::CacheArbitrationDone(uint32_t mode)
/************************************************************************************/
/************************************************************************************/
/* Task to determine GPGHash matches
/* Task to determine PGPHash matches
*
* Info to be stored in GroupServiceString + Cache.
*
@ -3693,15 +3703,17 @@ bool p3IdService::pgphash_start()
// ACTUALLY only need summary - but have written code for data.
// Also need to use opts.groupFlags to filter stuff properly to REALID's only.
// TODO
// TODO
uint32_t ansType = RS_TOKREQ_ANSTYPE_SUMMARY;
RsTokReqOptions opts;
opts.mReqType = GXS_REQUEST_TYPE_GROUP_META;
uint32_t token = 0;
RsGenExchange::getTokenService()->requestGroupInfo(token, ansType, opts);
GxsTokenQueue::queueRequest(token, GXSIDREQ_PGPHASH);
uint32_t ansType = RS_TOKREQ_ANSTYPE_DATA;
RsTokReqOptions opts;
opts.mReqType = GXS_REQUEST_TYPE_GROUP_DATA;
uint32_t token = 0;
RsGenExchange::getTokenService()->requestGroupInfo(token, ansType, opts);
GxsTokenQueue::queueRequest(token, GXSIDREQ_PGPHASH);
return true;
}
@ -3723,44 +3735,52 @@ bool p3IdService::pgphash_handlerequest(uint32_t token)
// We Will do this later!
std::vector<RsGxsIdGroup> groups;
bool groupsToProcess = false;
bool ok = getGroupData(token, groups);
std::list<RsGroupMetaData> group_metas;
std::list<RsGxsGroupId> groups_to_process;
bool ok = getGroupMeta(token, group_metas);
if(ok)
{
#ifdef DEBUG_IDS
std::cerr << "p3IdService::pgphash_request() Have " << groups.size() << " Groups";
std::cerr << std::endl;
std::cerr << "p3IdService::pgphash_request() Have " << group_metas.size() << " Groups" << std::endl;
#endif // DEBUG_IDS
std::vector<RsGxsIdGroup>::iterator vit;
for(vit = groups.begin(); vit != groups.end(); ++vit)
for(auto vit = group_metas.begin(); vit != group_metas.end(); ++vit)
{
#ifdef DEBUG_IDS
std::cerr << "p3IdService::pgphash_request() Group Id: " << vit->mMeta.mGroupId;
std::cerr << std::endl;
std::cerr << "p3IdService::pgphash_request() Group Id: " << vit->mGroupId << " ";
#endif // DEBUG_IDS
/* Filter based on IdType */
if (!(vit->mMeta.mGroupFlags & RSGXSID_GROUPFLAG_REALID_kept_for_compatibility))
/* Filter based on IdType */
if (!(vit->mGroupFlags & RSGXSID_GROUPFLAG_REALID_kept_for_compatibility))
{
#ifdef DEBUG_IDS
std::cerr << "p3IdService::pgphash_request() discarding AnonID";
std::cerr << std::endl;
std::cerr << "p3IdService::pgphash_request() discarding AnonID" << std::endl;
#endif // DEBUG_IDS
continue;
}
{
RsStackMutex stack(mIdMtx); /********** STACK LOCKED MTX ******/
if(mGroupsToProcess.find(vit->mGroupId) != mGroupsToProcess.end())
{
#ifdef DEBUG_IDS
std::cerr << " => already in checking list!" << std::endl;
#endif
continue;
}
}
/* now we need to decode the Service String - see what is saved there */
SSGxsIdGroup ssdata;
if (ssdata.load(vit->mMeta.mServiceString))
SSGxsIdGroup ssdata;
if (ssdata.load(vit->mServiceString))
{
if (ssdata.pgp.validatedSignature)
{
#ifdef DEBUG_IDS
std::cerr << "p3IdService::pgphash_request() discarding Already Known";
std::cerr << std::endl;
std::cerr << "p3IdService::pgphash_request() discarding Already Known" << std::endl;
#endif // DEBUG_IDS
continue;
}
@ -3773,11 +3793,11 @@ bool p3IdService::pgphash_handlerequest(uint32_t token)
#define SECS_PER_DAY (3600 * 24)
rstime_t age = time(NULL) - ssdata.pgp.lastCheckTs;
rstime_t wait_period = ssdata.pgp.checkAttempts * SECS_PER_DAY;
rstime_t wait_period = ssdata.pgp.checkAttempts * SECS_PER_DAY;
if (wait_period > 30 * SECS_PER_DAY)
{
wait_period = 30 * SECS_PER_DAY;
}
wait_period = 30 * SECS_PER_DAY;
#ifdef DEBUG_IDS
std::cerr << "p3IdService: group " << *vit << " age=" << age << ", attempts=" << ssdata.pgp.checkAttempts << ", wait period = " << wait_period ;
#endif
@ -3789,20 +3809,17 @@ bool p3IdService::pgphash_handlerequest(uint32_t token)
#endif // DEBUG_IDS
continue;
}
#ifdef DEBUG_IDS
std::cerr << " => recheck!" << std::endl;
#endif
}
/* if we get here -> then its to be processed */
#ifdef DEBUG_IDS
std::cerr << "p3IdService::pgphash_request() ToProcess Group: " << vit->mMeta.mGroupId;
std::cerr << std::endl;
#endif // DEBUG_IDS
RsStackMutex stack(mIdMtx); /********** STACK LOCKED MTX ******/
mGroupsToProcess.push_back(*vit);
groupsToProcess = true;
groups_to_process.push_back(vit->mGroupId);
}
}
else
@ -3811,28 +3828,56 @@ bool p3IdService::pgphash_handlerequest(uint32_t token)
std::cerr << std::endl;
}
if (groupsToProcess)
{
// update PgpIdList -> if there are groups to process.
getPgpIdList();
}
// If they are groups to process, load the data for these groups
// Schedule Processing.
RsTickEvent::schedule_in(GXSID_EVENT_PGPHASH_PROC, PGPHASH_PROC_PERIOD);
return true;
if(!groups_to_process.empty())
{
uint32_t ansType = RS_TOKREQ_ANSTYPE_DATA;
RsTokReqOptions opts;
opts.mReqType = GXS_REQUEST_TYPE_GROUP_DATA;
uint32_t token = 0;
RsGenExchange::getTokenService()->requestGroupInfo(token, ansType, opts,groups_to_process);
GxsTokenQueue::queueRequest(token, GXSIDREQ_LOAD_PGPIDDATA);
}
return true;
}
bool p3IdService::pgphash_load_group_data(uint32_t token)
{
// Update PgpIdList -> if there are groups to process.
getPgpIdList();
std::vector<RsGxsIdGroup> groups;
// Add the loaded groups into the list of groups to process
getGroupData(token, groups);
RsStackMutex stack(mIdMtx); /********** STACK LOCKED MTX ******/
for(auto grp:groups)
{
mGroupsToProcess[grp.mMeta.mGroupId] = grp;
#ifdef DEBUG_IDS
std::cerr << "pgphash_load_group_data(): loaded group data for group " << grp.mMeta.mGroupId << ". mGroupsToProcess contains " << mGroupsToProcess.size() << " elements." << std::endl;
#endif
}
return true;
}
bool p3IdService::pgphash_process()
{
/* each time this is called - process one Id from mGroupsToProcess */
/* each time this is called - process one Id from mGroupsToProcess */
RsGxsIdGroup pg;
bool isDone = false;
{
RsStackMutex stack(mIdMtx); /********** STACK LOCKED MTX ******/
if (!mGroupsToProcess.empty())
{
pg = mGroupsToProcess.front();
mGroupsToProcess.pop_front();
pg = mGroupsToProcess.begin()->second;
mGroupsToProcess.erase(mGroupsToProcess.begin());
#ifdef DEBUG_IDS
std::cerr << "p3IdService::pgphash_process() Popped Group: " << pg.mMeta.mGroupId;
@ -3840,9 +3885,7 @@ bool p3IdService::pgphash_process()
#endif // DEBUG_IDS
}
else
{
isDone = true;
}
}
if (isDone)
@ -3911,13 +3954,17 @@ bool p3IdService::pgphash_process()
cache_update_if_cached(RsGxsId(pg.mMeta.mGroupId), serviceString);
}
// Schedule Next Processing.
RsTickEvent::schedule_in(GXSID_EVENT_PGPHASH_PROC, PGPHASH_PROC_PERIOD);
return false; // as there are more items on the queue to process.
return true;
}
// This method allows to have a null issuer ID in the signature, in which case the signature is anonymous.
// The correct PGP key to check is looked for by bruteforcing
//
// grp.mPgpIdHash == SHA1( GroupId | PgpFingerPrint )
//
// For now, this is probably never used because signed IDs use a clear signature. The advntage of hiding the
// ID has not been clearly demonstrated anyway, which allows to directly look for the ID in the list of
// known keys instead of computing tons of hashes.
bool p3IdService::checkId(const RsGxsIdGroup &grp, RsPgpId &pgpId,bool& error)
{
@ -3937,99 +3984,97 @@ bool p3IdService::checkId(const RsGxsIdGroup &grp, RsPgpId &pgpId,bool& error)
#endif // DEBUG_IDS
/* iterate through and check hash */
Sha1CheckSum ans = grp.mPgpIdHash;
Sha1CheckSum hash;
#ifdef DEBUG_IDS
std::string esign ;
Radix64::encode((unsigned char *) grp.mPgpIdSign.c_str(), grp.mPgpIdSign.length(),esign) ;
std::cerr << "Checking group signature " << esign << std::endl;
#endif
RsPgpId issuer_id ;
RsPgpFingerprint pgp_fingerprint;
pgpId.clear() ;
if(mPgpUtils->parseSignature((unsigned char *) grp.mPgpIdSign.c_str(), grp.mPgpIdSign.length(),issuer_id))
if(mPgpUtils->parseSignature((unsigned char *) grp.mPgpIdSign.c_str(), grp.mPgpIdSign.length(),issuer_id) && !issuer_id.isNull())
{
RsStackMutex stack(mIdMtx); /********** STACK LOCKED MTX ******/
pgpId = issuer_id ;
auto mit = mPgpFingerprintMap.find(issuer_id);
if(mit == mPgpFingerprintMap.end())
{
#ifdef DEBUG_IDS
std::cerr << "Issuer found: " << issuer_id << std::endl;
std::cerr << "Issuer Id: " << issuer_id << " is not known. Key will be marked as non verified." << std::endl;
#endif
pgpId = issuer_id ;
error = false;
return false;
}
calcPGPHash(RsGxsId(grp.mMeta.mGroupId), mit->second, hash);
#ifdef DEBUG_IDS
std::cerr << "Issuer from PGP signature: " << issuer_id << " is known. Computed corresponding hash: " << hash << std::endl;
#endif
if(grp.mPgpIdHash != hash)
{
std::cerr << "(EE) Unexpected situation: GxsId signature hash (" << hash << ") doesn't correspond to what's listed in the mPgpIdHash field (" << grp.mPgpIdHash << ")." << std::endl;
error = true;
return false;
}
pgp_fingerprint = mit->second;
}
else
{
std::cerr << "Signature parsing failed!!" << std::endl;
pgpId.clear() ;
RsStackMutex stack(mIdMtx); /********** STACK LOCKED MTX ******/
#ifdef DEBUG_IDS
std::cerr << "Bruteforcing PGP hash from GxsId mPgpHash: " << grp.mPgpIdHash << std::endl;
#endif
for(auto mit = mPgpFingerprintMap.begin(); mit != mPgpFingerprintMap.end(); ++mit)
{
calcPGPHash(RsGxsId(grp.mMeta.mGroupId), mit->second, hash);
std::cerr << " profile key " << mit->first << " (" << mit->second << ") : ";
if (grp.mPgpIdHash == hash)
{
#ifdef DEBUG_IDS
std::cerr << "MATCH!" << std::endl;
#endif
pgpId = mit->first;
pgp_fingerprint = mit->second;
break;
}
#ifdef DEBUG_IDS
else
std::cerr << "fails" << std::endl;
#endif
}
}
// Look for the PGP id given by the signature
#ifdef DEBUG_IDS
std::cerr << "\tExpected Answer: " << ans.toStdString();
std::cerr << std::endl;
#endif // DEBUG_IDS
RsStackMutex stack(mIdMtx); /********** STACK LOCKED MTX ******/
std::map<RsPgpId, PGPFingerprintType>::iterator mit;
for(mit = mPgpFingerprintMap.begin(); mit != mPgpFingerprintMap.end(); ++mit)
{
Sha1CheckSum hash;
calcPGPHash(RsGxsId(grp.mMeta.mGroupId), mit->second, hash);
if (ans == hash)
{
#ifdef DEBUG_IDS
std::cerr << "p3IdService::checkId() HASH MATCH!";
std::cerr << std::endl;
std::cerr << "p3IdService::checkId() Hash : " << hash.toStdString();
std::cerr << std::endl;
std::cerr << "Now checking the signature: ";
#endif
/* miracle match! */
/* check signature too */
if (mPgpUtils->VerifySignBin((void *) hash.toByteArray(), hash.SIZE_IN_BYTES,
(unsigned char *) grp.mPgpIdSign.c_str(), grp.mPgpIdSign.length(),
mit->second))
{
if (mPgpUtils->VerifySignBin((void *) hash.toByteArray(), hash.SIZE_IN_BYTES, (unsigned char *) grp.mPgpIdSign.c_str(), grp.mPgpIdSign.length(), pgp_fingerprint))
{
#ifdef DEBUG_IDS
std::cerr << "p3IdService::checkId() Signature Okay too!";
std::cerr << std::endl;
std::cerr << " Signature validates!" << std::endl;
#endif
pgpId = mit->first;
return true;
}
/* error */
std::cerr << "p3IdService::checkId() ERROR Signature Failed";
std::cerr << std::endl;
std::cerr << "p3IdService::checkId() Matched PGPID: " << mit->first.toStdString();
std::cerr << " Fingerprint: " << mit->second.toStdString();
std::cerr << std::endl;
std::cerr << "p3IdService::checkId() Signature: ";
std::string strout;
/* push binary into string -> really bad! */
for(unsigned int i = 0; i < grp.mPgpIdSign.length(); i++)
{
rs_sprintf_append(strout, "%02x", (uint32_t) ((uint8_t) grp.mPgpIdSign[i]));
}
std::cerr << strout;
std::cerr << std::endl;
error = true ;
return false ;
}
}
error = false;
return true;
}
else
{
#ifdef DEBUG_IDS
std::cerr << "p3IdService::checkId() Checked " << mPgpFingerprintMap.size() << " Hashes without Match";
std::cerr << std::endl;
#endif // DEBUG_IDS
return false;
std::cerr << " Signature fails!" << std::endl;
#endif
error = true;
return false;
}
}
/* worker functions */
void p3IdService::getPgpIdList()
{
@ -4742,6 +4787,9 @@ void p3IdService::handleResponse(uint32_t token, uint32_t req_type
case GXSIDREQ_OPINION:
if (status == RsTokenService::COMPLETE) opinion_handlerequest(token);
break;
case GXSIDREQ_LOAD_PGPIDDATA:
if (status == RsTokenService::COMPLETE) pgphash_load_group_data(token);
break;
case GXSIDREQ_SERIALIZE_TO_MEMORY:
if (status == RsTokenService::COMPLETE) handle_get_serialized_grp(token);
break;
@ -4780,10 +4828,6 @@ void p3IdService::handle_event(uint32_t event_type, const std::string &/*elabel*
pgphash_start();
break;
case GXSID_EVENT_PGPHASH_PROC:
pgphash_process();
break;
case GXSID_EVENT_RECOGN:
recogn_start();
break;

View File

@ -488,7 +488,8 @@ private:
*
*/
bool pgphash_start();
bool pgphash_handlerequest(uint32_t token);
bool pgphash_load_group_data(uint32_t token);
bool pgphash_handlerequest(uint32_t token);
bool pgphash_process();
bool checkId(const RsGxsIdGroup &grp, RsPgpId &pgp_id, bool &error);
@ -497,7 +498,7 @@ private:
/* MUTEX PROTECTED DATA (mIdMtx - maybe should use a 2nd?) */
std::map<RsPgpId, RsPgpFingerprint> mPgpFingerprintMap;
std::list<RsGxsIdGroup> mGroupsToProcess;
std::map<RsGxsGroupId,RsGxsIdGroup> mGroupsToProcess;
/************************************************************************
* recogn processing.
@ -625,7 +626,7 @@ private:
*/
PgpAuxUtils *mPgpUtils;
rstime_t mLastPGPHashProcessTime ;
rstime_t mLastKeyCleaningTime ;
rstime_t mLastConfigUpdate ;

View File

@ -77,8 +77,10 @@ void TS_dumpState() ;
// - The total number of TR per second emmited from self will be MAX_TUNNEL_REQS_PER_SECOND / TIME_BETWEEN_TUNNEL_MANAGEMENT_CALLS = 0.5
// - I updated forward probabilities to higher values, and min them to 1/nb_connected_friends to prevent blocking tunnels.
//
static const rstime_t TUNNEL_REQUESTS_LIFE_TIME = 240 ; /// life time for tunnel requests in the cache.
static const rstime_t SEARCH_REQUESTS_LIFE_TIME = 240 ; /// life time for search requests in the cache
static const rstime_t TUNNEL_REQUESTS_LIFE_TIME = 600 ; /// life time for tunnel requests in the cache.
static const rstime_t TUNNEL_REQUESTS_RESULT_TIME = 20 ; /// maximum time during which we process/forward results for known tunnel requests
static const rstime_t SEARCH_REQUESTS_LIFE_TIME = 600 ; /// life time for search requests in the cache
static const rstime_t SEARCH_REQUESTS_RESULT_TIME = 20 ; /// maximum time during which we process/forward results for known search requests
static const rstime_t REGULAR_TUNNEL_DIGGING_TIME = 300 ; /// maximum interval between two tunnel digging campaigns.
static const rstime_t MAXIMUM_TUNNEL_IDLE_TIME = 60 ; /// maximum life time of an unused tunnel.
static const rstime_t EMPTY_TUNNELS_DIGGING_TIME = 50 ; /// look into tunnels regularly every 50 sec.
@ -1163,6 +1165,17 @@ void p3turtle::handleSearchResult(RsTurtleSearchResultItem *item)
return ;
}
// Is this result too old?
// Search Requests younger than SEARCH_REQUESTS_LIFE_TIME are kept in the cache, so that they are not duplicated if they bounce in the network
// Nevertheless results received for Search Requests older than SEARCH_REQUESTS_RESULT_TIME are considered obsolete and discarded
if (time(NULL) > it->second.time_stamp + SEARCH_REQUESTS_RESULT_TIME)
{
#ifdef P3TURTLE_DEBUG
RsDbg() << "TURTLE p3turtle::handleSearchResult Search Request is known, but result arrives too late, dropping";
#endif
return;
}
// Is this result's target actually ours ?
if(it->second.origin == _own_id)
@ -1873,6 +1886,17 @@ void p3turtle::handleTunnelResult(RsTurtleTunnelOkItem *item)
#endif
}
// Is this result too old?
// Tunnel Requests younger than TUNNEL_REQUESTS_LIFE_TIME are kept in the cache, so that they are not duplicated if they bounce in the network
// Nevertheless results received for Tunnel Requests older than TUNNEL_REQUESTS_RESULT_TIME are considered obsolete and discarded
if (time(NULL) > it->second.time_stamp + TUNNEL_REQUESTS_RESULT_TIME)
{
#ifdef P3TURTLE_DEBUG
RsDbg() << "TURTLE p3turtle::handleTunnelResult Tunnel Request is known, but result arrives too late, dropping";
#endif
return;
}
// Is this result's target actually ours ?
if(it->second.origin == _own_id)

View File

@ -58,6 +58,7 @@ HomePage::HomePage(QWidget *parent) :
updateCertificate();
connect(ui->addButton, SIGNAL(clicked()), this, SLOT(addFriend()));
connect(ui->copyIDButton, SIGNAL(clicked()), this, SLOT(copyId()));
QAction *WebMailAction = new QAction(QIcon(),tr("Invite via WebMail"), this);
connect(WebMailAction, SIGNAL(triggered()), this, SLOT(webMail()));
@ -107,9 +108,9 @@ HomePage::HomePage(QWidget *parent) :
<div align=center>\
<IMG align=\"center\" width=\"%2\" src=\":/images/network_map.png\"/> \
</div>\
<p>To do so, copy your certificate on this page and send it to friends, and add your friends' certificate.</p> \
<p>To do so, copy your Retroshare ID on this page and send it to friends, and add your friends' Retroshare ID.</p> \
<p>Another option is to search the internet for \"Retroshare chat servers\" (independently administrated). These servers allow you to exchange \
certificates with a dedicated Retroshare node, through which\
Retroshare ID with a dedicated Retroshare node, through which\
you will be able to anonymously meet other people.</p> ").arg(QString::number(2*S)).arg(width()*0.5);
registerHelpButton(ui->helpButton,help_str,"HomePage") ;
@ -344,7 +345,7 @@ void HomePage::webMail()
void HomePage::openWebHelp()
{
QDesktopServices::openUrl(QUrl(QString("https://retroshare.readthedocs.io")));
QDesktopServices::openUrl(QUrl(QString("https://retroshare.readthedocs.io/en/latest/")));
}
void HomePage::toggleUseOldFormat()

View File

@ -13,8 +13,37 @@
<property name="windowTitle">
<string>Form</string>
</property>
<layout class="QGridLayout" name="gridLayout_2">
<item row="0" column="0" colspan="3">
<layout class="QGridLayout" name="gridLayout">
<item row="3" column="0" rowspan="7">
<spacer name="horizontalSpacer_2">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeType">
<enum>QSizePolicy::Preferred</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>50</width>
<height>408</height>
</size>
</property>
</spacer>
</item>
<item row="2" column="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>
<item row="0" column="0" colspan="5">
<widget class="QLabel" name="label">
<property name="sizePolicy">
<sizepolicy hsizetype="Expanding" vsizetype="Maximum">
@ -33,7 +62,7 @@
</property>
</widget>
</item>
<item row="1" column="0" colspan="3">
<item row="1" column="0" colspan="5">
<widget class="QLabel" name="label_2">
<property name="font">
<font>
@ -50,39 +79,171 @@ private and secure decentralized communication platform.
</property>
</widget>
</item>
<item row="2" column="0" rowspan="4">
<spacer name="horizontalSpacer_2">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeType">
<enum>QSizePolicy::Preferred</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>94</width>
<height>408</height>
</size>
</property>
</spacer>
<item row="4" column="1" colspan="3">
<widget class="QFrame" name="retroshareIDframe">
<layout class="QGridLayout" name="gridLayout_2">
<property name="leftMargin">
<number>9</number>
</property>
<property name="topMargin">
<number>9</number>
</property>
<property name="rightMargin">
<number>9</number>
</property>
<property name="bottomMargin">
<number>9</number>
</property>
<property name="verticalSpacing">
<number>0</number>
</property>
<item row="1" column="2">
<widget class="QLabel" name="retroshareid">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="font">
<font>
<family>Courier New</family>
<pointsize>10</pointsize>
<weight>75</weight>
<bold>true</bold>
</font>
</property>
<property name="contextMenuPolicy">
<enum>Qt::DefaultContextMenu</enum>
</property>
<property name="text">
<string/>
</property>
<property name="alignment">
<set>Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter</set>
</property>
<property name="wordWrap">
<bool>false</bool>
</property>
<property name="textInteractionFlags">
<set>Qt::LinksAccessibleByMouse|Qt::TextSelectableByMouse</set>
</property>
</widget>
</item>
<item row="1" column="5">
<spacer name="horizontalSpacer_5">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
<item row="0" column="0" colspan="6">
<widget class="QLabel" name="userCertLabel">
<property name="sizePolicy">
<sizepolicy hsizetype="Expanding" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="font">
<font>
<pointsize>11</pointsize>
</font>
</property>
<property name="text">
<string>This is your Retroshare ID. Copy and share with your friends!</string>
</property>
<property name="alignment">
<set>Qt::AlignBottom|Qt::AlignHCenter</set>
</property>
</widget>
</item>
<item row="1" column="4">
<widget class="QToolButton" name="helpButton">
<property name="text">
<string>...</string>
</property>
<property name="icon">
<iconset resource="icons.qrc">
<normaloff>:/icons/help_64.png</normaloff>:/icons/help_64.png</iconset>
</property>
<property name="checkable">
<bool>true</bool>
</property>
<property name="autoRaise">
<bool>true</bool>
</property>
</widget>
</item>
<item row="1" column="0">
<spacer name="horizontalSpacer_6">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
<item row="1" column="1">
<widget class="QToolButton" name="copyIDButton">
<property name="toolTip">
<string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Copy your RetroShare ID to clipboard&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
</property>
<property name="text">
<string>...</string>
</property>
<property name="icon">
<iconset resource="icons.qrc">
<normaloff>:/icons/png/copy.png</normaloff>:/icons/png/copy.png</iconset>
</property>
</widget>
</item>
<item row="1" column="3">
<widget class="QToolButton" name="shareButton">
<property name="sizePolicy">
<sizepolicy hsizetype="Fixed" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="focusPolicy">
<enum>Qt::NoFocus</enum>
</property>
<property name="toolTip">
<string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Share your RetroShare ID&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
</property>
<property name="icon">
<iconset resource="icons.qrc">
<normaloff>:/icons/svg/share.svg</normaloff>:/icons/svg/share.svg</iconset>
</property>
<property name="iconSize">
<size>
<width>24</width>
<height>24</height>
</size>
</property>
<property name="popupMode">
<enum>QToolButton::InstantPopup</enum>
</property>
<property name="autoRaise">
<bool>true</bool>
</property>
</widget>
</item>
</layout>
</widget>
</item>
<item row="2" column="2" rowspan="4">
<spacer name="horizontalSpacer_3">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeType">
<enum>QSizePolicy::Preferred</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>78</width>
<height>388</height>
</size>
</property>
</spacer>
</item>
<item row="3" column="1">
<item row="7" column="1" colspan="3">
<widget class="QFrame" name="addframe">
<property name="sizePolicy">
<sizepolicy hsizetype="Expanding" vsizetype="Preferred">
@ -93,23 +254,24 @@ private and secure decentralized communication platform.
<property name="styleSheet">
<string notr="true"/>
</property>
<layout class="QHBoxLayout" name="horizontalLayout">
<item>
<widget class="QLabel" name="label_3">
<property name="font">
<font>
<pointsize>11</pointsize>
</font>
<layout class="QGridLayout" name="gridLayout_4">
<property name="bottomMargin">
<number>12</number>
</property>
<item row="1" column="2">
<spacer name="horizontalSpacer_4">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="styleSheet">
<string notr="true"/>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
</property>
<property name="text">
<string>Did you receive a Retroshare id from a friend?</string>
</property>
</widget>
</spacer>
</item>
<item>
<item row="1" column="0">
<spacer name="horizontalSpacer">
<property name="orientation">
<enum>Qt::Horizontal</enum>
@ -122,15 +284,11 @@ private and secure decentralized communication platform.
</property>
</spacer>
</item>
<item>
<item row="1" column="1">
<widget class="QToolButton" name="addButton">
<property name="text">
<string>Add friend</string>
</property>
<property name="icon">
<iconset resource="icons.qrc">
<normaloff>:/icons/png/invite.png</normaloff>:/icons/png/invite.png</iconset>
</property>
<property name="iconSize">
<size>
<width>24</width>
@ -145,10 +303,60 @@ private and secure decentralized communication platform.
</property>
</widget>
</item>
<item row="0" column="0" colspan="3">
<widget class="QLabel" name="label_3">
<property name="font">
<font>
<pointsize>11</pointsize>
</font>
</property>
<property name="styleSheet">
<string notr="true"/>
</property>
<property name="text">
<string>Did you receive a Retroshare ID from a friend?</string>
</property>
<property name="alignment">
<set>Qt::AlignCenter</set>
</property>
</widget>
</item>
</layout>
</widget>
</item>
<item row="4" column="1">
<item row="9" column="1" colspan="3">
<spacer name="verticalSpacer">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<property name="sizeType">
<enum>QSizePolicy::Expanding</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
<height>40</height>
</size>
</property>
</spacer>
</item>
<item row="3" column="4" rowspan="7">
<spacer name="horizontalSpacer_3">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeType">
<enum>QSizePolicy::Preferred</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>50</width>
<height>408</height>
</size>
</property>
</spacer>
</item>
<item row="8" column="1" colspan="3">
<widget class="QFrame" name="helpframe">
<property name="sizePolicy">
<sizepolicy hsizetype="Expanding" vsizetype="Preferred">
@ -160,25 +368,29 @@ private and secure decentralized communication platform.
<string notr="true"/>
</property>
<property name="frameShape">
<enum>QFrame::StyledPanel</enum>
<enum>QFrame::NoFrame</enum>
</property>
<property name="frameShadow">
<enum>QFrame::Raised</enum>
<enum>QFrame::Plain</enum>
</property>
<layout class="QHBoxLayout" name="horizontalLayout_2">
<item>
<widget class="QLabel" name="label_4">
<property name="font">
<font>
<pointsize>11</pointsize>
</font>
<layout class="QGridLayout" name="gridLayout_3">
<property name="verticalSpacing">
<number>9</number>
</property>
<item row="1" column="2">
<spacer name="horizontalSpacer_7">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="text">
<string>Do you need help with Retroshare?</string>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</widget>
</spacer>
</item>
<item>
<item row="1" column="1">
<widget class="QToolButton" name="openwebhelp">
<property name="text">
<string>Open Web Help</string>
@ -198,135 +410,37 @@ private and secure decentralized communication platform.
</property>
</widget>
</item>
<item row="1" column="0">
<spacer name="horizontalSpacer_8">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
<item row="0" column="0" colspan="3">
<widget class="QLabel" name="label_4">
<property name="font">
<font>
<pointsize>11</pointsize>
</font>
</property>
<property name="text">
<string>Do you need help with Retroshare?</string>
</property>
<property name="alignment">
<set>Qt::AlignCenter</set>
</property>
</widget>
</item>
</layout>
</widget>
</item>
<item row="5" column="1">
<spacer name="verticalSpacer">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<property name="sizeType">
<enum>QSizePolicy::Expanding</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
<height>40</height>
</size>
</property>
</spacer>
</item>
<item row="2" column="1">
<layout class="QGridLayout" name="gridLayout">
<property name="horizontalSpacing">
<number>6</number>
</property>
<property name="verticalSpacing">
<number>0</number>
</property>
<item row="2" column="0">
<widget class="QLabel" name="retroshareid">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="font">
<font>
<family>Courier New</family>
<pointsize>10</pointsize>
<weight>75</weight>
<bold>true</bold>
</font>
</property>
<property name="contextMenuPolicy">
<enum>Qt::DefaultContextMenu</enum>
</property>
<property name="text">
<string/>
</property>
<property name="wordWrap">
<bool>false</bool>
</property>
<property name="textInteractionFlags">
<set>Qt::LinksAccessibleByMouse|Qt::TextSelectableByMouse</set>
</property>
</widget>
</item>
<item row="0" column="2">
<widget class="QToolButton" name="shareButton">
<property name="sizePolicy">
<sizepolicy hsizetype="Fixed" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="focusPolicy">
<enum>Qt::NoFocus</enum>
</property>
<property name="toolTip">
<string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Share your RetroShare ID&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
</property>
<property name="icon">
<iconset resource="icons.qrc">
<normaloff>:/icons/svg/share.svg</normaloff>:/icons/svg/share.svg</iconset>
</property>
<property name="iconSize">
<size>
<width>24</width>
<height>24</height>
</size>
</property>
<property name="popupMode">
<enum>QToolButton::InstantPopup</enum>
</property>
<property name="autoRaise">
<bool>true</bool>
</property>
</widget>
</item>
<item row="0" column="0" colspan="2">
<widget class="QLabel" name="userCertLabel">
<property name="sizePolicy">
<sizepolicy hsizetype="Expanding" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="font">
<font>
<pointsize>11</pointsize>
</font>
</property>
<property name="text">
<string>This is your Retroshare ID. Copy and share with your friends!</string>
</property>
<property name="alignment">
<set>Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter</set>
</property>
</widget>
</item>
<item row="0" column="3">
<widget class="QToolButton" name="helpButton">
<property name="text">
<string>...</string>
</property>
<property name="icon">
<iconset resource="icons.qrc">
<normaloff>:/icons/help_64.png</normaloff>:/icons/help_64.png</iconset>
</property>
<property name="checkable">
<bool>true</bool>
</property>
<property name="autoRaise">
<bool>true</bool>
</property>
</widget>
</item>
</layout>
</item>
</layout>
</widget>
<resources>

View File

@ -366,6 +366,7 @@ IdDialog::IdDialog(QWidget *parent) : MainPage(parent), ui(new Ui::IdDialog)
/* Set header resize modes and initial section sizes */
QHeaderView * idheader = ui->idTreeWidget->header();
QHeaderView_setSectionResizeModeColumn(idheader, RSID_COL_VOTES, QHeaderView::ResizeToContents);
idheader->setStretchLastSection(true);
mStateHelper->setActive(IDDIALOG_IDDETAILS, false);
mStateHelper->setActive(IDDIALOG_REPLIST, false);
@ -695,7 +696,12 @@ void IdDialog::loadCircles(const std::list<RsGroupMetaData>& groupInfo)
if(am_I_subscribed)
tooltip += tr("subscribed (Receive/forward membership requests from others and invite list).") ;
else
tooltip += tr("unsubscribed (Only receive invite list).") ;
{
if(vit->mLastSeen>0)
tooltip += tr("unsubscribed (Only receive invite list). Last seen: %1 days ago.").arg( (time(nullptr)-vit->mLastSeen)/86400 );
else
tooltip += tr("unsubscribed (Only receive invite list).");
}
tooltip += "\n"+tr("Your status: ") ;

View File

@ -186,6 +186,11 @@ public:
ToasterDisable *toasterDisableInstance();
SysTrayStatus *sysTrayStatusInstance();
QString get_nameAndLocation()
{
return nameAndLocation;
}
static bool hiddenmode;
public slots:

View File

@ -162,8 +162,8 @@ void AvatarDialog::loadAvatarWidget()
if(stickerTabs.count() == 0) {
ui->nostickersLabel->setText("");
QString message = "No stickers installed.\nYou can install them by putting images into one of these folders:\n" /*+ stickerFolders.join('\n')*/;
message += "RetroShare/stickers\n RetroShare/Data/stickers\n RetroShare/Data/Location/stickers";
QString message = "No Avatars or Stickers installed.\nYou can install them by putting images into one of these folders:\n" + stickerFolders.join('\n');
message += "\n RetroShare/stickers\n RetroShare/Data/stickers\n RetroShare/Data/Location/stickers";
ui->nostickersLabel->setText(message);
} else {
ui->infoframe->hide();

View File

@ -34,10 +34,10 @@ ElidedLabel::ElidedLabel(const QString &text, QWidget *parent)
, mElided(false)
, mOnlyPlainText(false)
, mContent(text)
, mRectElision(QRect())
, mTextColor(QColor())
{
setStyleSheet("background-color: rgba(0,0,0,0%)");
mRectElision = QRect();
setStyleSheet("ElidedLabel{background-color: rgba(0,0,0,0%)}");
setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Preferred);
}
@ -46,10 +46,10 @@ ElidedLabel::ElidedLabel(QWidget *parent)
, mElided(false)
, mOnlyPlainText(false)
, mContent("")
, mRectElision(QRect())
, mTextColor(QColor())
{
setStyleSheet("background-color: rgba(0,0,0,0%)");
mRectElision = QRect();
setStyleSheet("ElidedLabel{background-color: rgba(0,0,0,0%)}");
setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Preferred);
}
@ -256,6 +256,7 @@ void ElidedLabel::mousePressEvent(QMouseEvent *ev)
return; // eat event
}
QLabel::mousePressEvent(ev);
emit clicked(ev->pos());
}
void ElidedLabel::setTextColor(const QColor &color)

View File

@ -38,7 +38,7 @@ class ElidedLabel : public QLabel
Q_PROPERTY(QColor textColor READ textColor WRITE setTextColor)
public:
ElidedLabel(const QString &text, QWidget *parent = 0);
explicit ElidedLabel(const QString &text, QWidget *parent = 0);
ElidedLabel(QWidget *parent = 0);
const QString & text() const { return mContent; }
@ -77,6 +77,7 @@ protected:
signals:
void elisionChanged(bool elided);
void clicked(QPoint pos);
private:
bool mElided;

View File

@ -97,11 +97,11 @@ GroupTreeWidget::GroupTreeWidget(QWidget *parent) :
QTreeWidgetItem *headerItem = ui->treeWidget->headerItem();
headerItem->setText(GTW_COLUMN_NAME, tr("Name"));
headerItem->setText(GTW_COLUMN_UNREAD, tr("Unread"));
headerItem->setText(GTW_COLUMN_POSTS, tr("F Posts"));
headerItem->setText(GTW_COLUMN_POPULARITY, tr("Popularity"));
headerItem->setText(GTW_COLUMN_LAST_POST, tr("Last Post"));
headerItem->setToolTip(GTW_COLUMN_NAME, tr("Name"));
headerItem->setText(GTW_COLUMN_UNREAD, "");
headerItem->setText(GTW_COLUMN_POSTS, "");
headerItem->setText(GTW_COLUMN_POPULARITY, "");
headerItem->setText(GTW_COLUMN_LAST_POST, "");
headerItem->setToolTip(GTW_COLUMN_NAME, tr("Group Name"));
headerItem->setToolTip(GTW_COLUMN_UNREAD, tr("Number of Unread message"));
headerItem->setToolTip(GTW_COLUMN_POSTS, tr("Friend's Posts"));
headerItem->setToolTip(GTW_COLUMN_POPULARITY, tr("Popularity"));
@ -109,9 +109,9 @@ GroupTreeWidget::GroupTreeWidget(QWidget *parent) :
/* Set header resize modes and initial section sizes */
QHeaderView *header = ui->treeWidget->header ();
header->setStretchLastSection(false);
QHeaderView_setSectionResizeModeColumn(header, GTW_COLUMN_NAME, QHeaderView::Stretch);
header->resizeSection(GTW_COLUMN_NAME, 10*W) ;
header->setStretchLastSection(true);
QHeaderView_setSectionResizeModeColumn(header, GTW_COLUMN_NAME, QHeaderView::Interactive);
header->resizeSection(GTW_COLUMN_NAME, 40*W) ;
QHeaderView_setSectionResizeModeColumn(header, GTW_COLUMN_UNREAD, QHeaderView::Interactive);
header->resizeSection(GTW_COLUMN_UNREAD, 3*W+4) ;
QHeaderView_setSectionResizeModeColumn(header, GTW_COLUMN_POSTS, QHeaderView::Interactive);
@ -191,8 +191,6 @@ void GroupTreeWidget::processSettings(bool load)
if (load) {
// load Settings
bool showHeader = Settings->value("GroupShowHeader", false).toBool();
actionShowHeader->setChecked(showHeader);
// state of order
bool ascSort = Settings->value("GroupAscSort", true).toBool();
@ -230,7 +228,6 @@ void GroupTreeWidget::processSettings(bool load)
}
} else {
// save Settings
Settings->setValue("GroupShowHeader", !(actionShowHeader && actionShowHeader->isChecked())); //False by default
// state of order
Settings->setValue("GroupAscSort", !(actionSortDescending && actionSortDescending->isChecked())); //True by default
@ -257,10 +254,6 @@ void GroupTreeWidget::initDisplayMenu(QToolButton *toolButton)
displayMenu = new QMenu();
QActionGroup *actionGroupAsc = new QActionGroup(displayMenu);
actionShowHeader = displayMenu->addAction(tr("Show Header"));
connect(actionShowHeader, SIGNAL(toggled(bool)), this, SLOT(showHeader(bool)));
actionShowHeader->setCheckable(true);
actionSortDescending = displayMenu->addAction(FilesDefs::getIconFromQtResourcePath(":/images/sort_decrease.png"), tr("Sort Descending Order"), this, SLOT(sort()));
actionSortDescending->setCheckable(true);
actionSortDescending->setActionGroup(actionGroupAsc);
@ -777,11 +770,6 @@ void GroupTreeWidget::distantSearch()
ui->distantSearchLineEdit->clear();
}
void GroupTreeWidget::showHeader(bool toShow)
{
ui->treeWidget->header()->setVisible(toShow);
}
void GroupTreeWidget::sort()
{
resort(NULL);

View File

@ -140,7 +140,6 @@ private slots:
void filterChanged();
void distantSearch();
void showHeader(bool toShow);
void sort();
private:
@ -152,7 +151,6 @@ private:
private:
QMenu *displayMenu;
QAction *actionShowHeader;
QAction *actionSortAscending;
QAction *actionSortDescending;
QAction *actionSortByName;

View File

@ -91,7 +91,7 @@
<bool>true</bool>
</property>
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Expanding">
<sizepolicy hsizetype="Expanding" vsizetype="Expanding">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
@ -137,7 +137,7 @@
<customwidget>
<class>LineEditClear</class>
<extends>QLineEdit</extends>
<header>gui/common/LineEditClear.h</header>
<header location="global">gui/common/LineEditClear.h</header>
</customwidget>
<customwidget>
<class>RSTreeWidget</class>

View File

@ -250,7 +250,7 @@ QMenu *RSTreeWidget::createStandardContextMenu(QMenu *contextMenu)
contextMenu->addSeparator();
}
if(!mContextMenuActions.isEmpty() || mEnableColumnCustomize ||!mContextMenuActions.isEmpty() || !mContextMenuMenus.isEmpty()) {
if(!mContextMenuActions.isEmpty() || !mContextMenuMenus.isEmpty() || mEnableColumnCustomize) {
QWidget *widget = new QWidget(contextMenu);
widget->setStyleSheet( ".QWidget{background-color: qlineargradient(x1:0, y1:0, x2:0, y2:1,stop:0 #FEFEFE, stop:1 #E8E8E8); border: 1px solid #CCCCCC;}");
@ -279,22 +279,28 @@ QMenu *RSTreeWidget::createStandardContextMenu(QMenu *contextMenu)
}
if (mEnableColumnCustomize) {
QAction *actShowHeader = contextMenu->addAction(QIcon(), tr("Show Header"), this, SLOT(headerVisible()));
actShowHeader->setCheckable(true);
actShowHeader->setChecked(!isHeaderHidden());
QMenu *headerMenu = contextMenu->addMenu(QIcon(),tr("Show column..."));
QTreeWidgetItem *item = headerItem();
int columnCount = item->columnCount();
for (int column = 0; column < columnCount; ++column)
{
{
QMap<int, bool>::const_iterator it = mColumnCustomizable.find(column);
if (it != mColumnCustomizable.end() && *it == false) {
continue;
}
QString txt = item->text(column) ;
if(txt == "")
txt = item->data(column,Qt::UserRole).toString() ;
QString txt = item->text(column) ;
if(txt == "")
txt = item->data(column,Qt::UserRole).toString() ;
if(txt == "")
txt = item->data(column,Qt::ToolTipRole).toString() ;
if(txt=="")
txt = tr("[no title]") ;
if(txt=="")
txt = tr("[no title]") ;
QAction *action = headerMenu->addAction(QIcon(), txt, this, SLOT(columnVisible()));
action->setCheckable(true);
@ -343,6 +349,19 @@ void RSTreeWidget::headerContextMenuRequested(const QPoint &pos)
delete contextMenu;
}
void RSTreeWidget::headerVisible()
{
QAction *action = dynamic_cast<QAction*>(sender());
if (!action) {
return;
}
bool visible = action->isChecked();
setHeaderHidden(!visible);
emit headerVisibleChanged(visible);
}
void RSTreeWidget::columnVisible()
{
QAction *action = dynamic_cast<QAction*>(sender());

View File

@ -58,6 +58,7 @@ public:
signals:
void signalMouseMiddleButtonClicked(QTreeWidgetItem *item);
void headerVisibleChanged(bool visible);
void columnVisibleChanged(int column, bool visible);
private:
@ -66,6 +67,7 @@ private:
private slots:
void headerContextMenuRequested(const QPoint &pos);
void headerVisible();
void columnVisible();
protected:

View File

@ -365,11 +365,9 @@ void BoardsCommentsItem::setup()
mInFill = false;
/* clear ui */
//ui->titleLabel->setText(tr("Loading"));
ui->datetimeLabel->clear();
ui->replyFrame->hide();
ui->commentButton->setIcon(FilesDefs::getIconFromQtResourcePath(":/icons/png/comment.png"));
ui->copyLinkButton->setIcon(FilesDefs::getIconFromQtResourcePath(":/icons/png/copy.png"));
ui->expandButton->setIcon(FilesDefs::getIconFromQtResourcePath(":/icons/png/down-arrow.png"));
ui->readAndClearButton->setIcon(FilesDefs::getIconFromQtResourcePath(":/icons/png/correct.png"));
@ -379,7 +377,6 @@ void BoardsCommentsItem::setup()
connect(ui->clearButton, SIGNAL(clicked()), this, SLOT(removeItem()));
/* specific */
connect(ui->commentButton, SIGNAL( clicked()), this, SLOT(loadComments()));
connect(ui->voteUpButton, SIGNAL(clicked()), this, SLOT(makeUpVote()));
connect(ui->voteDownButton, SIGNAL(clicked()), this, SLOT( makeDownVote()));
connect(ui->expandButton, SIGNAL(clicked()), this, SLOT( toggle()));
@ -394,7 +391,6 @@ void BoardsCommentsItem::setup()
// hide expand button, replies is not implemented yet
ui->expandButton->hide();
ui->unsubscribeButton->hide();
ui->clearButton->hide();
ui->readAndClearButton->hide();
@ -448,13 +444,14 @@ void BoardsCommentsItem::setCommentsSize(int comNb)
else if(comNb > 1)
sComButText = tr("Comments ").append("(%1)").arg(comNb);
ui->commentButton->setText(sComButText);
//ui->commentButton->setText(sComButText);
}
void BoardsCommentsItem::fill()
{
ui->logoLabel->setPixmap( FilesDefs::getPixmapFromQtResourcePath(":/icons/png/comment.png"));
ui->logoLabel->hide();
//ui->logoLabel->setPixmap( FilesDefs::getPixmapFromQtResourcePath(":/icons/png/comment.png"));
//RetroShareLink link = RetroShareLink::createGxsGroupLink(RetroShareLink::TYPE_POSTED, mGroupMeta.mGroupId, groupName());
//ui->titleLabel->setText(link.toHtml());
@ -472,9 +469,9 @@ void BoardsCommentsItem::fill()
{
// feed.
//frame_comment->show();
ui->commentButton->show();
//ui->commentButton->show();
if (mPost.mComments)
/*if (mPost.mComments)
{
QString commentText = QString::number(mPost.mComments);
commentText += " ";
@ -484,7 +481,7 @@ void BoardsCommentsItem::fill()
else
{
ui->commentButton->setText(tr("Comment"));
}
}*/
//setReadStatus(IS_MSG_NEW(mPost.mMeta.mMsgStatus), IS_MSG_UNREAD(mPost.mMeta.mMsgStatus) || IS_MSG_NEW(mPost.mMeta.mMsgStatus));
}
@ -492,7 +489,6 @@ void BoardsCommentsItem::fill()
{
// no feed.
//frame_comment->hide();
ui->commentButton->hide();
ui->readButton->hide();
}
@ -506,7 +502,6 @@ void BoardsCommentsItem::fill()
{
ui->clearButton->show();
ui->readAndClearButton->show();
ui->titleLabel->hide();
}
// hide read button not yet functional

View File

@ -7,7 +7,7 @@
<x>0</x>
<y>0</y>
<width>755</width>
<height>201</height>
<height>175</height>
</rect>
</property>
<layout class="QGridLayout" name="gridLayout_3">
@ -23,7 +23,7 @@
<property name="bottomMargin">
<number>1</number>
</property>
<item row="0" column="0">
<item row="1" column="0">
<widget class="QFrame" name="mainFrame">
<property name="sizePolicy">
<sizepolicy hsizetype="Expanding" vsizetype="Fixed">
@ -41,62 +41,46 @@
<enum>QFrame::Sunken</enum>
</property>
<layout class="QGridLayout" name="gridLayout_2">
<item row="0" column="0" rowspan="4">
<layout class="QVBoxLayout" name="verticalLayout">
<property name="topMargin">
<number>9</number>
</property>
<item row="2" column="1">
<layout class="QHBoxLayout" name="buttonHLayout">
<property name="spacing">
<number>8</number>
</property>
<item>
<widget class="QLabel" name="logoLabel">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Maximum">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="minimumSize">
<size>
<width>70</width>
<height>70</height>
</size>
</property>
<widget class="QPushButton" name="readButton">
<property name="maximumSize">
<size>
<width>70</width>
<height>70</height>
<width>24</width>
<height>16777215</height>
</size>
</property>
<property name="text">
<string/>
<property name="focusPolicy">
<enum>Qt::NoFocus</enum>
</property>
<property name="scaledContents">
<property name="toolTip">
<string>Toggle Message Read Status</string>
</property>
<property name="checkable">
<bool>true</bool>
</property>
<property name="alignment">
<set>Qt::AlignCenter</set>
<property name="checked">
<bool>false</bool>
</property>
<property name="flat">
<bool>false</bool>
</property>
</widget>
</item>
<item>
<spacer name="verticalSpacer">
<property name="orientation">
<enum>Qt::Vertical</enum>
<widget class="QLabel" name="logoLabel">
<property name="text">
<string>Avatar</string>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
<height>40</height>
</size>
</property>
</spacer>
</widget>
</item>
</layout>
</item>
<item row="0" column="1">
<layout class="QHBoxLayout" name="tilteHLayout">
<property name="spacing">
<number>9</number>
</property>
<property name="rightMargin">
<number>9</number>
</property>
<item>
<widget class="QLabel" name="newCommentLabel">
<property name="sizePolicy">
@ -135,272 +119,6 @@
</property>
</widget>
</item>
<item>
<widget class="QLabel" name="titleLabel">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="font">
<font>
<weight>75</weight>
<italic>true</italic>
<bold>true</bold>
</font>
</property>
<property name="text">
<string notr="true">Channel Subject</string>
</property>
<property name="scaledContents">
<bool>false</bool>
</property>
<property name="openExternalLinks">
<bool>true</bool>
</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>
<item>
<widget class="QLabel" name="datetimeLabel">
<property name="font">
<font>
<weight>75</weight>
<bold>true</bold>
</font>
</property>
<property name="text">
<string notr="true">DateTime</string>
</property>
</widget>
</item>
</layout>
</item>
<item row="1" column="1">
<widget class="QFrame" name="commentFrame">
<property name="sizePolicy">
<sizepolicy hsizetype="Expanding" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="styleSheet">
<string notr="true"/>
</property>
<layout class="QGridLayout" name="gridLayout">
<property name="sizeConstraint">
<enum>QLayout::SetDefaultConstraint</enum>
</property>
<property name="leftMargin">
<number>0</number>
</property>
<property name="topMargin">
<number>0</number>
</property>
<property name="rightMargin">
<number>0</number>
</property>
<property name="bottomMargin">
<number>0</number>
</property>
<property name="horizontalSpacing">
<number>6</number>
</property>
<property name="verticalSpacing">
<number>0</number>
</property>
<item row="0" column="3">
<spacer name="horizontalSpacer_3">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeType">
<enum>QSizePolicy::Expanding</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>288</width>
<height>17</height>
</size>
</property>
</spacer>
</item>
<item row="1" column="0">
<spacer name="verticalSpacer_3">
<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="0" column="2">
<widget class="GxsIdLabel" name="nameLabel">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="font">
<font>
<weight>75</weight>
<bold>true</bold>
</font>
</property>
<property name="text">
<string>Name</string>
</property>
<property name="alignment">
<set>Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter</set>
</property>
</widget>
</item>
<item row="0" column="0">
<widget class="QLabel" name="avatarLabel">
<property name="minimumSize">
<size>
<width>32</width>
<height>32</height>
</size>
</property>
<property name="maximumSize">
<size>
<width>32</width>
<height>32</height>
</size>
</property>
<property name="text">
<string>Avatar</string>
</property>
</widget>
</item>
<item row="1" column="2" colspan="2">
<widget class="QLabel" name="commLabel">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="font">
<font>
<family>MS Sans Serif</family>
<pointsize>10</pointsize>
</font>
</property>
<property name="text">
<string>Comm value</string>
</property>
<property name="alignment">
<set>Qt::AlignLeading|Qt::AlignLeft|Qt::AlignTop</set>
</property>
<property name="wordWrap">
<bool>true</bool>
</property>
<property name="textInteractionFlags">
<set>Qt::LinksAccessibleByMouse|Qt::TextSelectableByMouse</set>
</property>
</widget>
</item>
</layout>
</widget>
</item>
<item row="2" column="1">
<layout class="QHBoxLayout" name="buttonHLayout">
<property name="spacing">
<number>8</number>
</property>
<item>
<widget class="QPushButton" name="readButton">
<property name="maximumSize">
<size>
<width>24</width>
<height>16777215</height>
</size>
</property>
<property name="focusPolicy">
<enum>Qt::NoFocus</enum>
</property>
<property name="toolTip">
<string>Toggle Message Read Status</string>
</property>
<property name="checkable">
<bool>true</bool>
</property>
<property name="checked">
<bool>false</bool>
</property>
<property name="flat">
<bool>false</bool>
</property>
</widget>
</item>
<item>
<widget class="QLabel" name="scoreLabel">
<property name="font">
<font>
<weight>75</weight>
<bold>true</bold>
</font>
</property>
<property name="text">
<string>0</string>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="voteUpButton">
<property name="toolTip">
<string>I like this</string>
</property>
<property name="text">
<string/>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="voteDownButton">
<property name="toolTip">
<string>I dislike this</string>
</property>
<property name="text">
<string/>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="commentButton">
<property name="font">
<font>
<family>MS Sans Serif</family>
<pointsize>10</pointsize>
<weight>75</weight>
<bold>true</bold>
</font>
</property>
<property name="text">
<string>Comments</string>
</property>
</widget>
</item>
<item>
<spacer name="horizontalSpacer_2">
<property name="orientation">
@ -414,25 +132,6 @@
</property>
</spacer>
</item>
<item>
<widget class="QPushButton" name="unsubscribeButton">
<property name="sizePolicy">
<sizepolicy hsizetype="Fixed" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="focusPolicy">
<enum>Qt::NoFocus</enum>
</property>
<property name="toolTip">
<string>Unsubscribe From Channel</string>
</property>
<property name="text">
<string>Unsubscribe</string>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="copyLinkButton">
<property name="sizePolicy">
@ -569,6 +268,200 @@
</layout>
</widget>
</item>
<item row="0" column="0" rowspan="4">
<layout class="QVBoxLayout" name="verticalLayout">
<item>
<widget class="QLabel" name="avatarLabel">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Maximum">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="minimumSize">
<size>
<width>70</width>
<height>70</height>
</size>
</property>
<property name="maximumSize">
<size>
<width>70</width>
<height>70</height>
</size>
</property>
<property name="text">
<string/>
</property>
<property name="scaledContents">
<bool>true</bool>
</property>
<property name="alignment">
<set>Qt::AlignCenter</set>
</property>
</widget>
</item>
<item>
<layout class="QHBoxLayout" name="horizontalLayout">
<item>
<widget class="QPushButton" name="voteUpButton">
<property name="toolTip">
<string>I like this</string>
</property>
<property name="text">
<string/>
</property>
</widget>
</item>
<item>
<widget class="QLabel" name="scoreLabel">
<property name="font">
<font>
<weight>75</weight>
<bold>true</bold>
</font>
</property>
<property name="text">
<string>0</string>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="voteDownButton">
<property name="toolTip">
<string>I dislike this</string>
</property>
<property name="text">
<string/>
</property>
</widget>
</item>
</layout>
</item>
<item>
<spacer name="verticalSpacer">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>58</width>
<height>10</height>
</size>
</property>
</spacer>
</item>
</layout>
</item>
<item row="0" column="1">
<widget class="QFrame" name="commentFrame">
<property name="sizePolicy">
<sizepolicy hsizetype="Expanding" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="styleSheet">
<string notr="true"/>
</property>
<layout class="QGridLayout" name="gridLayout">
<property name="leftMargin">
<number>3</number>
</property>
<property name="topMargin">
<number>3</number>
</property>
<property name="rightMargin">
<number>9</number>
</property>
<property name="bottomMargin">
<number>0</number>
</property>
<item row="0" column="2">
<spacer name="horizontalSpacer_3">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeType">
<enum>QSizePolicy::Expanding</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>288</width>
<height>17</height>
</size>
</property>
</spacer>
</item>
<item row="0" column="3">
<widget class="QLabel" name="datetimeLabel">
<property name="font">
<font>
<weight>75</weight>
<bold>true</bold>
</font>
</property>
<property name="text">
<string notr="true">DateTime</string>
</property>
<property name="alignment">
<set>Qt::AlignLeading|Qt::AlignLeft|Qt::AlignTop</set>
</property>
</widget>
</item>
<item row="0" column="0" colspan="2">
<widget class="GxsIdLabel" name="nameLabel">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="font">
<font>
<weight>75</weight>
<bold>true</bold>
</font>
</property>
<property name="text">
<string>Name</string>
</property>
<property name="alignment">
<set>Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter</set>
</property>
</widget>
</item>
<item row="1" column="0" colspan="4">
<widget class="QLabel" name="commLabel">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="font">
<font>
<family>MS Sans Serif</family>
<pointsize>10</pointsize>
</font>
</property>
<property name="text">
<string>Comm value</string>
</property>
<property name="alignment">
<set>Qt::AlignLeading|Qt::AlignLeft|Qt::AlignTop</set>
</property>
<property name="wordWrap">
<bool>true</bool>
</property>
<property name="textInteractionFlags">
<set>Qt::LinksAccessibleByMouse|Qt::TextSelectableByMouse</set>
</property>
</widget>
</item>
</layout>
</widget>
</item>
</layout>
</widget>
</item>

View File

@ -133,11 +133,11 @@ void ChannelsCommentsItem::setup()
// This is particularly important here because a channel may contain many posts, so duplicating the QImages here is deadly for the
// memory.
ui->logoLabel->setPixmap(FilesDefs::getPixmapFromQtResourcePath(":/icons/png/comment.png"));
ui->logoLabel->hide();
//ui->logoLabel->setPixmap(FilesDefs::getPixmapFromQtResourcePath(":/icons/png/comment.png"));
ui->readButton->setIcon(FilesDefs::getIconFromQtResourcePath(":/images/message-state-unread.png"));
ui->voteUpButton->setIcon(FilesDefs::getIconFromQtResourcePath(":/images/vote_up.png"));
ui->voteDownButton->setIcon(FilesDefs::getIconFromQtResourcePath(":/images/vote_down.png"));
ui->commentButton->setIcon(FilesDefs::getIconFromQtResourcePath(":/icons/png/comment.png"));
ui->copyLinkButton->setIcon(FilesDefs::getIconFromQtResourcePath(":/icons/png/copy.png"));
ui->expandButton->setIcon(FilesDefs::getIconFromQtResourcePath(":/icons/png/down-arrow.png"));
ui->readAndClearButton->setIcon(FilesDefs::getIconFromQtResourcePath(":/icons/png/correct.png"));
@ -150,8 +150,7 @@ void ChannelsCommentsItem::setup()
mLoaded = false;
/* clear ui */
//ui->titleLabel->setText(tr("Loading..."));
ui->datetimelabel->clear();
ui->datetimeLabel->clear();
/* general ones */
connect(ui->expandButton, SIGNAL(clicked()), this, SLOT(toggle()));
@ -159,13 +158,10 @@ void ChannelsCommentsItem::setup()
/* specific */
connect(ui->readAndClearButton, SIGNAL(clicked()), this, SLOT(readAndClearItem()));
connect(ui->unsubscribeButton, SIGNAL(clicked()), this, SLOT(unsubscribeChannel()));
// HACK FOR NOW.
ui->commentButton->hide();// hidden until properly enabled.
connect(ui->commentButton, SIGNAL(clicked()), this, SLOT(loadComments()));
//connect(ui->commentButton, SIGNAL(clicked()), this, SLOT(loadComments()));
connect(ui->copyLinkButton, SIGNAL(clicked()), this, SLOT(copyMessageLink()));
connect(ui->readButton, SIGNAL(toggled(bool)), this, SLOT(readToggled(bool)));
// hide voting buttons, backend is not implemented yet
@ -178,9 +174,6 @@ void ChannelsCommentsItem::setup()
// hide expand button, replies is not implemented yet
ui->expandButton->hide();
ui->unsubscribeButton->hide();
//ui->titleLabel->setMinimumWidth(100);
ui->mainFrame->setProperty("new", false);
ui->mainFrame->style()->unpolish(ui->mainFrame);
@ -312,12 +305,12 @@ void ChannelsCommentsItem::loadMessage()
RsQThreadUtils::postToObject( [cmt,this]()
{
uint32_t autorized_lines = (int)floor((ui->logoLabel->height() - ui->titleLabel->height() - ui->buttonHLayout->sizeHint().height())/QFontMetricsF(ui->subjectLabel->font()).height());
uint32_t autorized_lines = (int)floor((ui->logoLabel->height() - ui->buttonHLayout->sizeHint().height())/QFontMetricsF(ui->subjectLabel->font()).height());
ui->commLabel->setText(RsHtml().formatText(NULL, RsStringUtil::CopyLines(QString::fromUtf8(cmt.mComment.c_str()), autorized_lines), RSHTML_FORMATTEXT_EMBED_LINKS));
ui->nameLabel->setId(cmt.mMeta.mAuthorId);
ui->datetimelabel->setText(DateTime::formatLongDateTime(cmt.mMeta.mPublishTs));
ui->datetimeLabel->setText(DateTime::formatLongDateTime(cmt.mMeta.mPublishTs));
RsIdentityDetails idDetails ;
rsIdentity->getIdDetails(cmt.mMeta.mAuthorId,idDetails);
@ -381,7 +374,7 @@ void ChannelsCommentsItem::loadComment()
else if(comNb > 1)
sComButText = tr("Comments ").append("(%1)").arg(comNb);
ui->commentButton->setText(sComButText);
//ui->commentButton->setText(sComButText);
}, this );
});
@ -403,7 +396,7 @@ void ChannelsCommentsItem::fill()
mInFill = true;
QString title;
//QString title;
//float f = QFontMetricsF(font()).height()/14.0 ;
if (!mIsHome)
@ -421,14 +414,14 @@ void ChannelsCommentsItem::fill()
if (IS_GROUP_SUBSCRIBED(mGroupMeta.mSubscribeFlags) || IS_GROUP_ADMIN(mGroupMeta.mSubscribeFlags))
{
ui->unsubscribeButton->setEnabled(true);
//ui->unsubscribeButton->setEnabled(true);
}
else
{
ui->unsubscribeButton->setEnabled(false);
//ui->unsubscribeButton->setEnabled(false);
}
ui->readButton->hide();
ui->titleLabel->hide();
//ui->titleLabel->hide();
if (IS_MSG_NEW(mPost.mMeta.mMsgStatus)) {
mCloseOnRead = true;
@ -439,7 +432,7 @@ void ChannelsCommentsItem::fill()
/* subject */
//ui->titleLabel->setText(QString::fromUtf8(mPost.mMeta.mMsgName.c_str()));
uint32_t autorized_lines = (int)floor((ui->logoLabel->height() - ui->titleLabel->height() - ui->buttonHLayout->sizeHint().height())/QFontMetricsF(ui->subjectLabel->font()).height());
uint32_t autorized_lines = (int)floor((ui->logoLabel->height() - ui->buttonHLayout->sizeHint().height())/QFontMetricsF(ui->subjectLabel->font()).height());
// fill first 4 lines of message. (csoler) Disabled the replacement of smileys and links, because the cost is too crazy
//ui->subjectLabel->setText(RsHtml().formatText(NULL, RsStringUtil::CopyLines(QString::fromUtf8(mPost.mMsg.c_str()), autorized_lines), RSHTML_FORMATTEXT_EMBED_SMILEYS | RSHTML_FORMATTEXT_EMBED_LINKS));
@ -451,12 +444,10 @@ void ChannelsCommentsItem::fill()
/* disable buttons: deletion facility not enabled with cache services yet */
ui->clearButton->setEnabled(false);
ui->unsubscribeButton->setEnabled(false);
ui->clearButton->hide();
ui->readAndClearButton->hide();
ui->unsubscribeButton->hide();
ui->copyLinkButton->show();
ui->titleLabel->hide();
//ui->titleLabel->hide();
if (IS_GROUP_SUBSCRIBED(mGroupMeta.mSubscribeFlags) || IS_GROUP_ADMIN(mGroupMeta.mSubscribeFlags))
{
@ -475,7 +466,7 @@ void ChannelsCommentsItem::fill()
// differences between Feed or Top of Comment.
if (mFeedHolder)
{
ui->commentButton->show();
//ui->commentButton->show();
// Not yet functional
/*if (mPost.mCommentCount)
@ -493,7 +484,7 @@ void ChannelsCommentsItem::fill()
}
else
{
ui->commentButton->hide();
//ui->commentButton->hide();
}
// disable voting buttons - if they have already voted.

View File

@ -7,7 +7,7 @@
<x>0</x>
<y>0</y>
<width>755</width>
<height>201</height>
<height>173</height>
</rect>
</property>
<layout class="QGridLayout" name="gridLayout_3">
@ -23,7 +23,7 @@
<property name="bottomMargin">
<number>1</number>
</property>
<item row="0" column="0">
<item row="1" column="0">
<widget class="QFrame" name="mainFrame">
<property name="sizePolicy">
<sizepolicy hsizetype="Expanding" vsizetype="Fixed">
@ -41,62 +41,46 @@
<enum>QFrame::Sunken</enum>
</property>
<layout class="QGridLayout" name="gridLayout_2">
<item row="0" column="0" rowspan="4">
<layout class="QVBoxLayout" name="verticalLayout">
<property name="topMargin">
<number>9</number>
</property>
<item row="2" column="1">
<layout class="QHBoxLayout" name="buttonHLayout">
<property name="spacing">
<number>8</number>
</property>
<item>
<widget class="QLabel" name="logoLabel">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Maximum">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="minimumSize">
<size>
<width>70</width>
<height>70</height>
</size>
</property>
<widget class="QPushButton" name="readButton">
<property name="maximumSize">
<size>
<width>70</width>
<height>70</height>
<width>24</width>
<height>16777215</height>
</size>
</property>
<property name="text">
<string/>
<property name="focusPolicy">
<enum>Qt::NoFocus</enum>
</property>
<property name="scaledContents">
<property name="toolTip">
<string>Toggle Message Read Status</string>
</property>
<property name="checkable">
<bool>true</bool>
</property>
<property name="alignment">
<set>Qt::AlignCenter</set>
<property name="checked">
<bool>false</bool>
</property>
<property name="flat">
<bool>false</bool>
</property>
</widget>
</item>
<item>
<spacer name="verticalSpacer">
<property name="orientation">
<enum>Qt::Vertical</enum>
<widget class="QLabel" name="logoLabel">
<property name="text">
<string>Avatar</string>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
<height>40</height>
</size>
</property>
</spacer>
</widget>
</item>
</layout>
</item>
<item row="0" column="1">
<layout class="QHBoxLayout" name="tilteHLayout">
<property name="spacing">
<number>9</number>
</property>
<property name="rightMargin">
<number>9</number>
</property>
<item>
<widget class="QLabel" name="newCommentLabel">
<property name="sizePolicy">
@ -135,272 +119,6 @@
</property>
</widget>
</item>
<item>
<widget class="QLabel" name="titleLabel">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="font">
<font>
<weight>75</weight>
<italic>true</italic>
<bold>true</bold>
</font>
</property>
<property name="text">
<string notr="true">Channel Subject</string>
</property>
<property name="scaledContents">
<bool>false</bool>
</property>
<property name="openExternalLinks">
<bool>true</bool>
</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>
<item>
<widget class="QLabel" name="datetimelabel">
<property name="font">
<font>
<weight>75</weight>
<bold>true</bold>
</font>
</property>
<property name="text">
<string notr="true">DateTime</string>
</property>
</widget>
</item>
</layout>
</item>
<item row="1" column="1">
<widget class="QFrame" name="commentFrame">
<property name="sizePolicy">
<sizepolicy hsizetype="Expanding" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="styleSheet">
<string notr="true"/>
</property>
<layout class="QGridLayout" name="gridLayout">
<property name="sizeConstraint">
<enum>QLayout::SetDefaultConstraint</enum>
</property>
<property name="leftMargin">
<number>0</number>
</property>
<property name="topMargin">
<number>0</number>
</property>
<property name="rightMargin">
<number>0</number>
</property>
<property name="bottomMargin">
<number>0</number>
</property>
<property name="horizontalSpacing">
<number>6</number>
</property>
<property name="verticalSpacing">
<number>0</number>
</property>
<item row="0" column="3">
<spacer name="horizontalSpacer_3">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeType">
<enum>QSizePolicy::Expanding</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>288</width>
<height>17</height>
</size>
</property>
</spacer>
</item>
<item row="1" column="0">
<spacer name="verticalSpacer_3">
<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="0" column="2">
<widget class="GxsIdLabel" name="nameLabel">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="font">
<font>
<weight>75</weight>
<bold>true</bold>
</font>
</property>
<property name="text">
<string>Name</string>
</property>
<property name="alignment">
<set>Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter</set>
</property>
</widget>
</item>
<item row="0" column="0">
<widget class="QLabel" name="avatarLabel">
<property name="minimumSize">
<size>
<width>32</width>
<height>32</height>
</size>
</property>
<property name="maximumSize">
<size>
<width>32</width>
<height>32</height>
</size>
</property>
<property name="text">
<string>Avatar</string>
</property>
</widget>
</item>
<item row="1" column="2" colspan="2">
<widget class="QLabel" name="commLabel">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="font">
<font>
<family>MS Sans Serif</family>
<pointsize>10</pointsize>
</font>
</property>
<property name="text">
<string>Comm value</string>
</property>
<property name="alignment">
<set>Qt::AlignLeading|Qt::AlignLeft|Qt::AlignTop</set>
</property>
<property name="wordWrap">
<bool>true</bool>
</property>
<property name="textInteractionFlags">
<set>Qt::LinksAccessibleByMouse|Qt::TextSelectableByMouse</set>
</property>
</widget>
</item>
</layout>
</widget>
</item>
<item row="2" column="1">
<layout class="QHBoxLayout" name="buttonHLayout">
<property name="spacing">
<number>8</number>
</property>
<item>
<widget class="QPushButton" name="readButton">
<property name="maximumSize">
<size>
<width>24</width>
<height>16777215</height>
</size>
</property>
<property name="focusPolicy">
<enum>Qt::NoFocus</enum>
</property>
<property name="toolTip">
<string>Toggle Message Read Status</string>
</property>
<property name="checkable">
<bool>true</bool>
</property>
<property name="checked">
<bool>false</bool>
</property>
<property name="flat">
<bool>false</bool>
</property>
</widget>
</item>
<item>
<widget class="QLabel" name="scoreLabel">
<property name="font">
<font>
<weight>75</weight>
<bold>true</bold>
</font>
</property>
<property name="text">
<string>0</string>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="voteUpButton">
<property name="toolTip">
<string>I like this</string>
</property>
<property name="text">
<string/>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="voteDownButton">
<property name="toolTip">
<string>I dislike this</string>
</property>
<property name="text">
<string/>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="commentButton">
<property name="font">
<font>
<family>MS Sans Serif</family>
<pointsize>10</pointsize>
<weight>75</weight>
<bold>true</bold>
</font>
</property>
<property name="text">
<string>Comments</string>
</property>
</widget>
</item>
<item>
<spacer name="horizontalSpacer_2">
<property name="orientation">
@ -414,25 +132,6 @@
</property>
</spacer>
</item>
<item>
<widget class="QPushButton" name="unsubscribeButton">
<property name="sizePolicy">
<sizepolicy hsizetype="Fixed" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="focusPolicy">
<enum>Qt::NoFocus</enum>
</property>
<property name="toolTip">
<string>Unsubscribe From Channel</string>
</property>
<property name="text">
<string>Unsubscribe</string>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="copyLinkButton">
<property name="sizePolicy">
@ -569,6 +268,200 @@
</layout>
</widget>
</item>
<item row="0" column="0" rowspan="4">
<layout class="QVBoxLayout" name="verticalLayout">
<item>
<widget class="QLabel" name="avatarLabel">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Maximum">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="minimumSize">
<size>
<width>70</width>
<height>70</height>
</size>
</property>
<property name="maximumSize">
<size>
<width>70</width>
<height>70</height>
</size>
</property>
<property name="text">
<string/>
</property>
<property name="scaledContents">
<bool>true</bool>
</property>
<property name="alignment">
<set>Qt::AlignCenter</set>
</property>
</widget>
</item>
<item>
<layout class="QHBoxLayout" name="horizontalLayout">
<item>
<widget class="QPushButton" name="voteUpButton">
<property name="toolTip">
<string>I like this</string>
</property>
<property name="text">
<string/>
</property>
</widget>
</item>
<item>
<widget class="QLabel" name="scoreLabel">
<property name="font">
<font>
<weight>75</weight>
<bold>true</bold>
</font>
</property>
<property name="text">
<string>0</string>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="voteDownButton">
<property name="toolTip">
<string>I dislike this</string>
</property>
<property name="text">
<string/>
</property>
</widget>
</item>
</layout>
</item>
<item>
<spacer name="verticalSpacer">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>58</width>
<height>40</height>
</size>
</property>
</spacer>
</item>
</layout>
</item>
<item row="0" column="1" rowspan="2">
<widget class="QFrame" name="commentFrame">
<property name="sizePolicy">
<sizepolicy hsizetype="Expanding" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="styleSheet">
<string notr="true"/>
</property>
<layout class="QGridLayout" name="gridLayout">
<property name="leftMargin">
<number>3</number>
</property>
<property name="topMargin">
<number>3</number>
</property>
<property name="rightMargin">
<number>9</number>
</property>
<property name="bottomMargin">
<number>0</number>
</property>
<item row="0" column="2">
<spacer name="horizontalSpacer_3">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeType">
<enum>QSizePolicy::Expanding</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>288</width>
<height>17</height>
</size>
</property>
</spacer>
</item>
<item row="0" column="3">
<widget class="QLabel" name="datetimeLabel">
<property name="font">
<font>
<weight>75</weight>
<bold>true</bold>
</font>
</property>
<property name="text">
<string notr="true">DateTime</string>
</property>
<property name="alignment">
<set>Qt::AlignLeading|Qt::AlignLeft|Qt::AlignTop</set>
</property>
</widget>
</item>
<item row="0" column="0" colspan="2">
<widget class="GxsIdLabel" name="nameLabel">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="font">
<font>
<weight>75</weight>
<bold>true</bold>
</font>
</property>
<property name="text">
<string>Name</string>
</property>
<property name="alignment">
<set>Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter</set>
</property>
</widget>
</item>
<item row="1" column="0" colspan="4">
<widget class="QLabel" name="commLabel">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="font">
<font>
<family>MS Sans Serif</family>
<pointsize>10</pointsize>
</font>
</property>
<property name="text">
<string>Comm value</string>
</property>
<property name="alignment">
<set>Qt::AlignLeading|Qt::AlignLeft|Qt::AlignTop</set>
</property>
<property name="wordWrap">
<bool>true</bool>
</property>
<property name="textInteractionFlags">
<set>Qt::LinksAccessibleByMouse|Qt::TextSelectableByMouse</set>
</property>
</widget>
</item>
</layout>
</widget>
</item>
</layout>
</widget>
</item>

View File

@ -24,7 +24,7 @@
<number>1</number>
</property>
<item row="0" column="0">
<widget class="QFrame" name="frame">
<widget class="QFrame" name="mainFrame">
<property name="sizePolicy">
<sizepolicy hsizetype="Expanding" vsizetype="Preferred">
<horstretch>0</horstretch>

View File

@ -24,7 +24,7 @@
<number>1</number>
</property>
<item row="0" column="0">
<widget class="QFrame" name="frame">
<widget class="QFrame" name="mainFrame">
<property name="sizePolicy">
<sizepolicy hsizetype="Expanding" vsizetype="Preferred">
<horstretch>0</horstretch>
@ -310,7 +310,7 @@
<string/>
</property>
<property name="pixmap">
<pixmap resource="../images.qrc">:/images/contacts24.png</pixmap>
<pixmap>:/images/contacts24.png</pixmap>
</property>
</widget>
</item>

View File

@ -24,7 +24,7 @@
<number>1</number>
</property>
<item row="0" column="0">
<widget class="QFrame" name="frame">
<widget class="QFrame" name="mainFrame">
<property name="sizePolicy">
<sizepolicy hsizetype="Expanding" vsizetype="Preferred">
<horstretch>0</horstretch>
@ -310,7 +310,7 @@
<string/>
</property>
<property name="pixmap">
<pixmap resource="../images.qrc">:/images/contacts24.png</pixmap>
<pixmap>:/images/contacts24.png</pixmap>
</property>
</widget>
</item>

View File

@ -470,9 +470,9 @@ void GxsForumMsgItem::toggle()
void GxsForumMsgItem::setReadStatus(bool isNew, bool /*isUnread*/)
{
ui->frame->setProperty("new", isNew);
ui->frame->style()->unpolish(ui->frame);
ui->frame->style()->polish( ui->frame);
ui->mainFrame->setProperty("new", isNew);
ui->mainFrame->style()->unpolish(ui->mainFrame);
ui->mainFrame->style()->polish( ui->mainFrame);
}
/*********** SPECIFIC FUNCTIONS ***********************/

View File

@ -24,7 +24,7 @@
<number>1</number>
</property>
<item row="2" column="0">
<widget class="QFrame" name="frame">
<widget class="QFrame" name="mainFrame">
<property name="sizePolicy">
<sizepolicy hsizetype="Expanding" vsizetype="Preferred">
<horstretch>0</horstretch>

View File

@ -27,7 +27,7 @@
<number>1</number>
</property>
<item row="0" column="0">
<widget class="QFrame" name="frame">
<widget class="QFrame" name="mainFrame">
<property name="sizePolicy">
<sizepolicy hsizetype="Expanding" vsizetype="Preferred">
<horstretch>0</horstretch>

View File

@ -24,7 +24,7 @@
<number>1</number>
</property>
<item row="0" column="0">
<widget class="QFrame" name="frame">
<widget class="QFrame" name="mainFrame">
<property name="sizePolicy">
<sizepolicy hsizetype="Expanding" vsizetype="Fixed">
<horstretch>0</horstretch>
@ -35,7 +35,7 @@
<string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;This warning is here to protect you against traffic forwarding attacks. In such a case, the friend you're connected to will not see your external IP, but the attacker's IP. &lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;However, if you just changed IPs for some reason (some ISPs regularly force change IPs) this warning just tells you that a friend connected to the new IP before Retroshare figured out the IP changed. Nothing's wrong in this case.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;You can easily suppress false warnings by white-listing your own IPs (e.g. the range of your ISP), or by completely disabling these warnings in Options-&amp;gt;Notify-&amp;gt;News Feed.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
</property>
<property name="autoFillBackground">
<bool>false</bool>
<bool>true</bool>
</property>
<property name="frameShape">
<enum>QFrame::Box</enum>

View File

@ -277,7 +277,7 @@ GxsForumThreadWidget::GxsForumThreadWidget(const RsGxsGroupId &forumId, QWidget
connect(ui->versions_CB, SIGNAL(currentIndexChanged(int)), this, SLOT(changedVersion()));
connect(ui->threadTreeWidget, SIGNAL(customContextMenuRequested(QPoint)), this, SLOT(threadListCustomPopupMenu(QPoint)));
connect(ui->postText, SIGNAL(customContextMenuRequested(QPoint)), this, SLOT(contextMenuTextBrowser(QPoint)));
connect(ui->forumName, SIGNAL(clicked()), this, SLOT(showForumInfo()));
connect(ui->forumName, SIGNAL(clicked(QPoint)), this, SLOT(showForumInfo()));
ui->subscribeToolButton->hide() ;
connect(ui->subscribeToolButton, SIGNAL(subscribe(bool)), this, SLOT(subscribeGroup(bool)));
@ -1068,6 +1068,11 @@ void GxsForumThreadWidget::updateForumDescription(bool success)
forum_description += QString("<b>%1: \t</b>%2<br/>").arg(tr("Synchronization"),getDurationString( rsGxsForums->getSyncPeriod(group.mMeta.mGroupId)/86400 )) ;
forum_description += QString("<b>%1: \t</b>%2<br/>").arg(tr("Storage"),getDurationString( rsGxsForums->getStoragePeriod(group.mMeta.mGroupId)/86400));
}
else
{
if(group.mMeta.mLastSeen > 0)
forum_description += QString("<b>%1: \t</b>%2 days ago<br/>").arg(tr("Last seen at friends:"),QString::number((time(nullptr) - group.mMeta.mLastSeen)/86400));
}
QString distrib_string = tr("[unknown]");
switch(static_cast<RsGxsCircleType>(group.mMeta.mCircleType))

View File

@ -112,15 +112,18 @@
</widget>
</item>
<item>
<widget class="QPushButton" name="forumName">
<widget class="StyledElidedLabel" name="forumName">
<property name="sizePolicy">
<sizepolicy hsizetype="Expanding" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="toolTip">
<string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Click here to clear current selected thread and display more information about this forum.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
</property>
<property name="text">
<string>PushButton</string>
</property>
<property name="flat">
<bool>true</bool>
<string>Forum Name</string>
</property>
</widget>
</item>
@ -130,11 +133,11 @@
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeType">
<enum>QSizePolicy::MinimumExpanding</enum>
<enum>QSizePolicy::Fixed</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>0</width>
<width>1</width>
<height>0</height>
</size>
</property>
@ -527,6 +530,11 @@
<extends>QLineEdit</extends>
<header>gui/common/LineEditClear.h</header>
</customwidget>
<customwidget>
<class>StyledElidedLabel</class>
<extends>QLabel</extends>
<header>gui/common/StyledElidedLabel.h</header>
</customwidget>
<customwidget>
<class>SubscribeToolButton</class>
<extends>QToolButton</extends>
@ -545,8 +553,8 @@
</customwidget>
</customwidgets>
<resources>
<include location="../images.qrc"/>
<include location="../icons.qrc"/>
<include location="../images.qrc"/>
</resources>
<connections/>
</ui>

View File

@ -392,7 +392,7 @@ void ImHistoryBrowser::customContextMenuRequested(QPoint /*pos*/)
QAction *sendItem = NULL;
if (textEdit) {
sendItem = new QAction(tr("Send"), &contextMnu);
sendItem = new QAction(tr("Quote"), &contextMnu);
if (currentItem) {
connect(sendItem, SIGNAL(triggered()), this, SLOT(sendMessage()));
} else {
@ -427,23 +427,7 @@ void ImHistoryBrowser::customContextMenuRequested(QPoint /*pos*/)
void ImHistoryBrowser::copyMessage()
{
QListWidgetItem *currentItem = ui.listWidget->currentItem();
if (currentItem) {
uint32_t msgId = currentItem->data(ROLE_MSGID).toString().toInt();
HistoryMsg msg;
if (rsHistory->getMessage(msgId, msg)) {
RsIdentityDetails details;
QString name = (rsIdentity->getIdDetails(RsGxsId(msg.peerName), details))
? QString::fromUtf8(details.mNickname.c_str())
: QString::fromUtf8(msg.peerName.c_str());
QDateTime date = msg.incoming
? QDateTime::fromTime_t(msg.sendTime)
: QDateTime::fromTime_t(msg.recvTime);
QTextDocument doc;
doc.setHtml(QString::fromUtf8(msg.message.c_str()));
QApplication::clipboard()->setText("> " + date.toString() + " " + name + ":" + doc.toPlainText());
}
}
QApplication::clipboard()->setText(getCurrentItemsQuotedText());
}
void ImHistoryBrowser::removeMessages()
@ -461,20 +445,37 @@ void ImHistoryBrowser::clearHistory()
void ImHistoryBrowser::sendMessage()
{
if (textEdit) {
QListWidgetItem *currentItem = ui.listWidget->currentItem();
if (currentItem) {
uint32_t msgId = currentItem->data(ROLE_MSGID).toString().toInt();
HistoryMsg msg;
if (rsHistory->getMessage(msgId, msg)) {
textEdit->clear();
textEdit->setText(QString::fromUtf8(msg.message.c_str()));
textEdit->setFocus();
QTextCursor cursor = textEdit->textCursor();
cursor.movePosition(QTextCursor::End);
textEdit->setTextCursor(cursor);
close();
}
}
}
if (textEdit) {
QString msg =getCurrentItemsQuotedText();
QTextCursor cursor = textEdit->textCursor();
cursor.movePosition(QTextCursor::End);
if (cursor.columnNumber()>0)
cursor.insertText("\n");
cursor.insertText(msg);
textEdit->setFocus();
close();
}
}
QString ImHistoryBrowser::getCurrentItemsQuotedText()
{
QListWidgetItem *currentItem = ui.listWidget->currentItem();
if (currentItem) {
uint32_t msgId = currentItem->data(ROLE_MSGID).toString().toInt();
HistoryMsg msg;
if (rsHistory->getMessage(msgId, msg)) {
RsIdentityDetails details;
QString name = (rsIdentity->getIdDetails(RsGxsId(msg.peerName), details))
? QString::fromUtf8(details.mNickname.c_str())
: QString::fromUtf8(msg.peerName.c_str());
QDateTime date = msg.incoming
? QDateTime::fromTime_t(msg.sendTime)
: QDateTime::fromTime_t(msg.recvTime);
QTextDocument doc;
doc.setHtml(QString::fromUtf8(msg.message.c_str()));
return "> " + date.toString() + " " + name + ":" + doc.toPlainText().replace("\n","\n> ");
}
}
return QString();
}

View File

@ -73,6 +73,7 @@ private:
void filterItems(const QString &text, QListWidgetItem *item = NULL);
void getSelectedItems(std::list<uint32_t> &items);
QString getCurrentItemsQuotedText();
ImHistoryBrowserCreateItemsThread *m_createThread;

Binary file not shown.

After

Width:  |  Height:  |  Size: 117 KiB

View File

@ -2,7 +2,7 @@
#include "retroshare_win.rc.h"
#include "retroshare/rsversion.h"
IDI_ICON1 ICON "logo/logo_64.ico"
IDI_ICON1 ICON "logo/logo_256.ico"
#define STRINGIZER(version) #version
#define VERSION_STRING(major,minor,mini,extra) STRINGIZER(major) "." STRINGIZER(minor) "." STRINGIZER(mini) STRINGIZER(extra)

View File

@ -373,14 +373,16 @@ uint32_t RsMessageModel::updateFilterStatus(ForumModelIndex /*i*/,int /*column*/
void RsMessageModel::setFilter(FilterType filter_type, const QStringList& strings)
{
std::cerr << "Setting filter to filter_type=" << int(filter_type) << " and strings to " ;
foreach(const QString& str,strings)
std::cerr << "\"" << str.toStdString() << "\" " ;
std::cerr << std::endl;
#ifdef DEBUG_MESSAGE_MODEL
std::cerr << "Setting filter to filter_type=" << int(filter_type) << " and strings to " ;
foreach(const QString& str,strings)
std::cerr << "\"" << str.toStdString() << "\" " ;
std::cerr << std::endl;
#endif
preMods();
preMods();
mFilterType = filter_type;
mFilterType = filter_type;
mFilterStrings = strings;
postMods();
@ -388,7 +390,7 @@ void RsMessageModel::setFilter(FilterType filter_type, const QStringList& string
QVariant RsMessageModel::toolTipRole(const Rs::Msgs::MsgInfoSummary& fmpe,int column) const
{
if(column == COLUMN_THREAD_AUTHOR)
if(column == COLUMN_THREAD_AUTHOR)
{
QString str,comment ;
QList<QIcon> icons;
@ -460,45 +462,44 @@ QVariant RsMessageModel::displayRole(const Rs::Msgs::MsgInfoSummary& fmpe,int co
{
switch(col)
{
case COLUMN_THREAD_SUBJECT: return QVariant(QString::fromUtf8(fmpe.title.c_str()));
case COLUMN_THREAD_ATTACHMENT:return QVariant(QString::number(fmpe.count));
case COLUMN_THREAD_SUBJECT: return QVariant(QString::fromUtf8(fmpe.title.c_str()));
case COLUMN_THREAD_ATTACHMENT:return QVariant(QString::number(fmpe.count));
case COLUMN_THREAD_STAR:
case COLUMN_THREAD_SPAM:
case COLUMN_THREAD_READ:return QVariant();
case COLUMN_THREAD_DATE:{
QDateTime qtime;
qtime.setTime_t(fmpe.ts);
case COLUMN_THREAD_STAR:
case COLUMN_THREAD_SPAM:
case COLUMN_THREAD_READ:return QVariant();
case COLUMN_THREAD_DATE:{
QDateTime qtime;
qtime.setTime_t(fmpe.ts);
return QVariant(DateTime::formatDateTime(qtime));
}
return QVariant(DateTime::formatDateTime(qtime));
}
case COLUMN_THREAD_TAGS:{
// Tags
Rs::Msgs::MsgTagInfo tagInfo;
rsMsgs->getMessageTag(fmpe.msgId, tagInfo);
case COLUMN_THREAD_TAGS:{
// Tags
Rs::Msgs::MsgTagInfo tagInfo;
rsMsgs->getMessageTag(fmpe.msgId, tagInfo);
Rs::Msgs::MsgTagType Tags;
rsMsgs->getMessageTagTypes(Tags);
Rs::Msgs::MsgTagType Tags;
rsMsgs->getMessageTagTypes(Tags);
QString text;
QString text;
// build tag names
std::map<uint32_t, std::pair<std::string, uint32_t> >::iterator Tag;
for (auto tagit = tagInfo.tagIds.begin(); tagit != tagInfo.tagIds.end(); ++tagit)
{
if (!text.isNull())
text += ",";
// build tag names
for (auto tagit = tagInfo.tagIds.begin(); tagit != tagInfo.tagIds.end(); ++tagit)
{
if (!text.isNull())
text += ",";
auto Tag = Tags.types.find(*tagit);
auto Tag = Tags.types.find(*tagit);
if (Tag != Tags.types.end())
text += TagDefs::name(Tag->first, Tag->second.first);
else
std::cerr << "(WW) unknown tag " << (int)Tag->first << " in message " << fmpe.msgId << std::endl;
}
return text;
}
if (Tag != Tags.types.end())
text += TagDefs::name(Tag->first, Tag->second.first);
else
RS_WARN("Unknown tag ", (int)Tag->first, " in message ", fmpe.msgId);
}
return text;
}
case COLUMN_THREAD_AUTHOR:{
QString name;
RsGxsId id = RsGxsId(fmpe.srcId.toStdString());
@ -510,11 +511,10 @@ QVariant RsMessageModel::displayRole(const Rs::Msgs::MsgInfoSummary& fmpe,int co
return QVariant(tr("[Unknown]"));
}
default:
default:
return QVariant("[ TODO ]");
}
return QVariant("[ERROR]");
}
@ -614,23 +614,24 @@ void RsMessageModel::setMessages(const std::list<Rs::Msgs::MsgInfoSummary>& msgs
void RsMessageModel::setCurrentBox(BoxName bn)
{
if(mCurrentBox != bn)
{
if(mCurrentBox != bn)
{
mCurrentBox = bn;
updateMessages();
}
updateMessages();
}
}
void RsMessageModel::setQuickViewFilter(QuickViewFilter fn)
{
if(fn != mQuickViewFilter)
{
std::cerr << "Changing new quickview filter to " << fn << std::endl;
if(fn != mQuickViewFilter)
{
#ifdef DEBUG_MESSAGE_MODEL
std::cerr << "Changing new quickview filter to " << fn << std::endl;
#endif
preMods();
mQuickViewFilter = fn ;
postMods();
}
mQuickViewFilter = fn ;
updateMessages();
}
}
void RsMessageModel::getMessageSummaries(BoxName box,std::list<Rs::Msgs::MsgInfoSummary>& msgs)
@ -717,8 +718,10 @@ QModelIndex RsMessageModel::getIndexOfMessage(const std::string& mid) const
return createIndex(it->second,0,ref);
}
#ifdef DEBUG_MESSAGE_MODEL
void RsMessageModel::debug_dump() const
{
for(auto it(mMessages.begin());it!=mMessages.end();++it)
std::cerr << "Id: " << it->msgId << ": from " << it->srcId << ": flags=" << it->msgflags << ": title=\"" << it->title << "\"" << std::endl;
for(auto& it : mMessages)
std::cerr << "Id: " << it.msgId << ": from " << it.srcId << ": flags=" << it.msgflags << ": title=\"" << it.title << "\"" << std::endl;
}
#endif

View File

@ -140,15 +140,17 @@ public:
QVariant textColorRole (const Rs::Msgs::MsgInfoSummary& fmpe, int col) const;
QVariant backgroundRole(const Rs::Msgs::MsgInfoSummary& fmpe, int col) const;
/*!
* \brief debug_dump
* Dumps the hierarchy of posts in the terminal, to allow checking whether the internal representation is correct.
*/
void debug_dump() const;
#ifdef DEBUG_MESSAGE_MODEL
/*!
* \brief debug_dump
* Dumps the hierarchy of posts in the terminal, to allow checking whether the internal representation is correct.
*/
void debug_dump() const;
#endif
// control over message flags and so on. This is handled by the model because it will allow it to update accordingly
// control over message flags and so on. This is handled by the model because it will allow it to update accordingly
void setMsgReadStatus(const QModelIndex& i, bool read_status);
void setMsgStar(const QModelIndex& index,bool star) ;
void setMsgStar(const QModelIndex& index,bool star) ;
void setMsgJunk(const QModelIndex& index,bool junk) ;
public slots:

View File

@ -797,29 +797,12 @@ ConnectFriendWizard QPlainTextEdit#friendCertEdit {
background: white;
}
HomePage QPlainTextEdit#userCertEdit {
background: transparent;
}
HomePage QFrame#addframe{
border: 2px solid #0099cc;
border-radius: 6px;
background: white;
}
ConnectFriendWizard QFrame#friendFrame {
border: 2px solid #0099cc;
border-radius: 6px;
background: white;
}
HomePage QFrame#helpframe{
border: 2px solid #009933;
border-radius: 6px;
background: white;
}
StartDialog QPushButton#loadButton {
border-image: url(:/images/btn_blue.png) 4;
border-width: 4;
@ -884,7 +867,9 @@ GxsForumThreadWidget QToolButton#subscribeToolButton:hover {
border-radius: 4px;
}
GxsForumMsgItem QFrame#frame{
GxsForumMsgItem QFrame#mainFrame, PeerItem QFrame#mainFrame, GxsForumGroupItem QFrame#mainFrame,
GxsChannelGroupItem QFrame#mainFrame, MsgItem QFrame#mainFrame, ChatMsgItem QFrame#mainFrame
SecurityIpItem QFrame#mainFrame {
background-color: white;
}
@ -958,6 +943,35 @@ PostedGroupItem QFrame#frame {
background-color: white;
}
HomePage QLabel#userCertLabel {
color: #0099cc;
font: bold;
}
HomePage QPlainTextEdit#userCertEdit {
background: transparent;
}
HomePage QToolButton#addButton {
font: bold;
font-size: 15pt;
color: white;
background: #0099cc;
border-radius: 4px;
max-height: 27px;
min-width: 4em;
padding: 2px;
}
HomePage QToolButton#addButton:hover {
background: #03b1f3;
border-radius: 4px;
min-width: 4em;
padding: 2px;
}
PostedItem QFrame#mainFrame {
background-color: white;
}
@ -1190,4 +1204,3 @@ BoardsCommentsItem QLabel#subjectLabel, QLabel#titleLabel , QLabel#nameLabel {
font: 14px;
font: bold;
}

View File

@ -29,6 +29,11 @@ ChatWidget QLabel#titleLabel, ChatWidget QLabel#statusLabel
qproperty-fontSizeFactor: 125;
}
ChatWidget QFrame#pluginTitleFrame, QFrame#pluginTopFrame
{
background: transparent;
}
FriendsDialog QLabel#nicknameLabel
{
qproperty-fontSizeFactor: 200;
@ -149,6 +154,13 @@ ForumsDialog, GxsForumThreadWidget
qproperty-backgroundColorFiltered: rgb(255, 240, 210);
}
GxsForumThreadWidget StyledElidedLabel#forumName
{
padding: 2px;
font: bold;
font-size: 1.5em;
}
GroupTreeWidget
{
qproperty-textColorCategory: rgb(79, 79, 79);

View File

@ -136,6 +136,14 @@ void AppearancePage::updateRbtPageOnToolBar()
{
Settings->setPageButtonLoc(!ui.mainPageButtonType_CB->currentIndex());
Settings->setActionButtonLoc(!ui.mainPageButtonType_CB->currentIndex());
int index = ui.mainPageButtonType_CB->currentIndex();
if (index != 0) {
ui.cmboTollButtonsStyle->hide();
}else {
ui.cmboTollButtonsStyle->show();
}
NotifyQt::getInstance()->notifySettingsChanged();
}
void AppearancePage::updateStatusToolTip() { MainWindow::getInstance()->toggleStatusToolTip(ui.checkBoxDisableSysTrayToolTip->isChecked()); }
@ -173,11 +181,11 @@ void AppearancePage::updateCmboToolButtonSize()
Settings->setListItemIconSize(16);
break;
case 2:
default:
Settings->setToolButtonSize(24);
Settings->setListItemIconSize(24);
break;
case 3:
default:
Settings->setToolButtonSize(32);
Settings->setListItemIconSize(32);
break;
@ -234,6 +242,13 @@ void AppearancePage::load()
index = ui.cmboStyleSheet->findData("");
}
whileBlocking(ui.cmboStyleSheet)->setCurrentIndex(index);
index = ui.mainPageButtonType_CB->findData(Settings->getPageButtonLoc());
if (index != 0) {
ui.cmboTollButtonsStyle->hide();
}else {
ui.cmboTollButtonsStyle->show();
}
whileBlocking(ui.mainPageButtonType_CB)->setCurrentIndex(!Settings->getPageButtonLoc());
// ui.menuItemsButtonType_CB->setCurrentIndex(!Settings->getActionButtonLoc());
@ -262,10 +277,10 @@ void AppearancePage::load()
whileBlocking(ui.cmboTollButtonsSize)->setCurrentIndex(1);
break;
case 24:
default:
whileBlocking(ui.cmboTollButtonsSize)->setCurrentIndex(2);
break;
case 32:
default:
whileBlocking(ui.cmboTollButtonsSize)->setCurrentIndex(3);
break;
case 64:

View File

@ -6,8 +6,8 @@
<rect>
<x>0</x>
<y>0</y>
<width>1170</width>
<height>897</height>
<width>662</width>
<height>585</height>
</rect>
</property>
<property name="contextMenuPolicy">
@ -249,6 +249,40 @@
<enum>QFrame::NoFrame</enum>
</property>
<layout class="QGridLayout" name="frameToolListStyleGLayout">
<item row="1" column="0">
<widget class="QComboBox" name="cmboTollButtonsSize">
<item>
<property name="text">
<string>Icon Size = 8x8</string>
</property>
</item>
<item>
<property name="text">
<string>Icon Size = 16x16</string>
</property>
</item>
<item>
<property name="text">
<string>Icon Size = 24x24</string>
</property>
</item>
<item>
<property name="text">
<string>Icon Size = 32x32</string>
</property>
</item>
<item>
<property name="text">
<string>Icon Size = 64x64</string>
</property>
</item>
<item>
<property name="text">
<string>Icon Size = 128x128</string>
</property>
</item>
</widget>
</item>
<item row="2" column="0">
<widget class="QComboBox" name="cmboTollButtonsStyle">
<item>
@ -286,39 +320,18 @@
</property>
</widget>
</item>
<item row="1" column="0">
<widget class="QComboBox" name="cmboTollButtonsSize">
<item>
<property name="text">
<string>Icon Size = 8x8</string>
</property>
</item>
<item>
<property name="text">
<string>Icon Size = 16x16</string>
</property>
</item>
<item>
<property name="text">
<string>Icon Size = 24x24</string>
</property>
</item>
<item>
<property name="text">
<string>Icon Size = 32x32</string>
</property>
</item>
<item>
<property name="text">
<string>Icon Size = 64x64</string>
</property>
</item>
<item>
<property name="text">
<string>Icon Size = 128x128</string>
</property>
</item>
</widget>
<item row="3" column="0">
<spacer name="verticalSpacer">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
<height>40</height>
</size>
</property>
</spacer>
</item>
</layout>
</widget>

View File

@ -267,13 +267,6 @@
</item>
<item>
<layout class="QVBoxLayout" name="testToasterVLayout">
<item>
<widget class="QPushButton" name="testToasterButton">
<property name="text">
<string>Test</string>
</property>
</widget>
</item>
<item>
<spacer name="testToasterVSpacer">
<property name="orientation">
@ -292,83 +285,114 @@
</layout>
</item>
<item>
<layout class="QGridLayout" name="positionGLayout">
<item row="1" column="0">
<widget class="QLabel" name="labelToasterPosition">
<property name="sizePolicy">
<sizepolicy hsizetype="Minimum" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="text">
<string>Position</string>
</property>
</widget>
</item>
<item row="1" column="1" colspan="3">
<widget class="QComboBox" name="comboBoxToasterPosition">
<property name="sizePolicy">
<sizepolicy hsizetype="MinimumExpanding" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
</widget>
</item>
<item row="2" column="0">
<widget class="QLabel" name="labelToasterXMargin">
<property name="sizePolicy">
<sizepolicy hsizetype="Minimum" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="text">
<string>X Margin</string>
</property>
</widget>
</item>
<item row="2" column="1">
<widget class="QSpinBox" name="spinBoxToasterXMargin">
<property name="sizePolicy">
<sizepolicy hsizetype="Fixed" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="maximum">
<number>20</number>
</property>
</widget>
</item>
<item row="2" column="2">
<widget class="QLabel" name="labelToasterYMargin">
<property name="sizePolicy">
<sizepolicy hsizetype="Minimum" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="text">
<string>Y Margin</string>
</property>
</widget>
</item>
<item row="2" column="3">
<widget class="QSpinBox" name="spinBoxToasterYMargin">
<property name="sizePolicy">
<sizepolicy hsizetype="Fixed" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="maximum">
<number>20</number>
</property>
</widget>
</item>
</layout>
<widget class="QGroupBox" name="groupBox">
<property name="title">
<string>Toaster position</string>
</property>
<layout class="QGridLayout" name="positionGLayout">
<property name="leftMargin">
<number>9</number>
</property>
<property name="topMargin">
<number>9</number>
</property>
<property name="rightMargin">
<number>9</number>
</property>
<property name="bottomMargin">
<number>9</number>
</property>
<item row="1" column="5">
<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>
<item row="1" column="0">
<widget class="QLabel" name="labelToasterPosition">
<property name="text">
<string>Position</string>
</property>
</widget>
</item>
<item row="2" column="0">
<widget class="QLabel" name="labelToasterXMargin">
<property name="sizePolicy">
<sizepolicy hsizetype="Minimum" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="text">
<string>X Margin</string>
</property>
</widget>
</item>
<item row="3" column="0">
<widget class="QLabel" name="labelToasterYMargin">
<property name="sizePolicy">
<sizepolicy hsizetype="Minimum" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="text">
<string>Y Margin</string>
</property>
</widget>
</item>
<item row="2" column="1" colspan="2">
<widget class="QSpinBox" name="spinBoxToasterXMargin">
<property name="sizePolicy">
<sizepolicy hsizetype="Fixed" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="maximum">
<number>20</number>
</property>
</widget>
</item>
<item row="3" column="1" colspan="2">
<widget class="QSpinBox" name="spinBoxToasterYMargin">
<property name="sizePolicy">
<sizepolicy hsizetype="Fixed" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="maximum">
<number>20</number>
</property>
</widget>
</item>
<item row="2" column="3">
<widget class="QPushButton" name="testToasterButton">
<property name="text">
<string>Test</string>
</property>
</widget>
</item>
<item row="1" column="1" colspan="3">
<widget class="QComboBox" name="comboBoxToasterPosition">
<property name="sizePolicy">
<sizepolicy hsizetype="Expanding" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
</widget>
</item>
</layout>
</widget>
</item>
<item>
<spacer name="tabToastersVSpacer">
@ -448,7 +472,6 @@
</layout>
</widget>
<tabstops>
<tabstop>tabWidget</tabstop>
<tabstop>notify_Peers</tabstop>
<tabstop>notify_Channels</tabstop>
<tabstop>notify_Forums</tabstop>
@ -467,10 +490,7 @@
<tabstop>popup_GroupChat</tabstop>
<tabstop>popup_ChatLobby</tabstop>
<tabstop>popup_ConnectAttempt</tabstop>
<tabstop>testToasterButton</tabstop>
<tabstop>comboBoxToasterPosition</tabstop>
<tabstop>spinBoxToasterXMargin</tabstop>
<tabstop>spinBoxToasterYMargin</tabstop>
<tabstop>systray_GroupChat</tabstop>
<tabstop>systray_ChatLobby</tabstop>
<tabstop>pushButtonDisableAll</tabstop>

View File

@ -266,7 +266,7 @@ int RshareSettings::getToolButtonSize()
{
static int sizes[6] = { 8,16,24,32,64,128 } ;
return value(SETTING_TOOLBUTTONSIZE, computeBestIconSize(6,sizes,24)).toInt();
return value(SETTING_TOOLBUTTONSIZE, computeBestIconSize(6,sizes,32)).toInt();
}
/** Sets the tool button's size.*/
@ -281,10 +281,10 @@ void RshareSettings::setToolButtonSize(int size)
setValue(SETTING_TOOLBUTTONSIZE, 16);
break;
case 24:
default:
setValue(SETTING_TOOLBUTTONSIZE, 24);
break;
case 32:
default:
setValue(SETTING_TOOLBUTTONSIZE, 32);
break;
case 64:

View File

@ -36,6 +36,7 @@
#include <gui/settings/rsharesettings.h>
#include "gui/common/FilesDefs.h"
#include <gui/MainWindow.h>
#include <gui/statistics/TurtleRouterStatistics.h>
#include <gui/statistics/GlobalRouterStatistics.h>
#include <gui/statistics/GxsIdStatistics.h>
@ -105,6 +106,7 @@ StatisticsWindow::StatisticsWindow(QWidget *parent) :
int toolSize = Settings->getToolButtonSize();
ui->toolBar->setToolButtonStyle(Settings->getToolButtonStyle());
ui->toolBar->setIconSize(QSize(toolSize,toolSize));
setWindowTitle("RetroShare Statistics - " + MainWindow::getInstance()->get_nameAndLocation());
}
StatisticsWindow::~StatisticsWindow()

View File

@ -2305,3 +2305,21 @@ BoardsCommentsItem QLabel#subjectLabel, QLabel#titleLabel , QLabel#nameLabel {
font: 14px;
font: bold;
}
HomePage QToolButton#addButton {
font: bold;
font-size: 15pt;
color: white;
background: #0099cc;
border-radius: 4px;
max-height: 27px;
min-width: 4em;
padding: 2px;
}
HomePage QToolButton#addButton:hover {
background: #03b1f3;
border-radius: 4px;
min-width: 4em;
padding: 2px;
}

View File

@ -1493,11 +1493,6 @@ RSTextBrowser, MimeTextEdit
qproperty-textColorQuotes: ColorList(#789922 #039bd5 #800000 #800080 #008080 #b10dc9 #85144b #3d9970);
}
ChatWidget QFrame#pluginTitleFrame
{
background: transparent;
}
PulseTopLevel QFrame#frame, PulseViewGroup QFrame#frame, PulseReply QFrame#frame {
border: 2px solid #38444d;
border-radius: 6px;
@ -1539,3 +1534,21 @@ BoardsCommentsItem QLabel#subjectLabel, QLabel#titleLabel , QLabel#nameLabel {
font: 14px;
font: bold;
}
HomePage QToolButton#addButton {
font: bold;
font-size: 15pt;
color: white;
background: #0099cc;
border-radius: 4px;
max-height: 27px;
min-width: 4em;
padding: 2px;
}
HomePage QToolButton#addButton:hover {
background: #03b1f3;
border-radius: 4px;
min-width: 4em;
padding: 2px;
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 124 KiB

View File

@ -136,6 +136,8 @@ win32-g++|win32-clang-g++ {
} else {
QMAKE_PRE_LINK = $(CHK_DIR_EXISTS) lib || $(MKDIR) lib
}
RC_FILE = retroshare-service_win.rc
}
################################### COMMON stuff ##################################

View File

@ -0,0 +1,4 @@
#include <winver.h>
#include "retroshare-service_win.rc.h"
IDI_ICON1 ICON "logo.ico"

View File

@ -0,0 +1,22 @@
/*******************************************************************************
* retroshare-service/retroshare-service_win.rc.h *
* *
* Copyright (C) 2006 by RetroShare team <retroshare.project@gmail.com> *
* *
* This program is free software: you can redistribute it and/or modify *
* it under the terms of the GNU Affero General Public License as *
* published by the Free Software Foundation, either version 3 of the *
* License, or (at your option) any later version. *
* *
* This program is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU Affero General Public License for more details. *
* *
* You should have received a copy of the GNU Affero General Public License *
* along with this program. If not, see <https://www.gnu.org/licenses/>. *
* *
*******************************************************************************/
#define IDI_ICON1 101