fixed conflict with master

This commit is contained in:
csoler 2021-01-19 22:34:44 +01:00
commit f491e3c20e
61 changed files with 1202 additions and 892 deletions

View File

@ -50,9 +50,10 @@ void GxsTokenQueue::checkRequests()
for(it = mQueue.begin(); it != mQueue.end();) for(it = mQueue.begin(); it != mQueue.end();)
{ {
uint32_t token = it->mToken; uint32_t token = it->mToken;
uint32_t status = mGenExchange->getTokenService()->requestStatus(token); it->mStatus = mGenExchange->getTokenService()->requestStatus(token);
if (status == RsTokenService::COMPLETE) if ( it->mStatus == RsTokenService::COMPLETE
|| it->mStatus == RsTokenService::CANCELLED )
{ {
toload.push_back(*it); toload.push_back(*it);
it = mQueue.erase(it); it = mQueue.erase(it);
@ -64,7 +65,7 @@ void GxsTokenQueue::checkRequests()
#endif #endif
++it; ++it;
} }
else if (status == RsTokenService::FAILED) else if (it->mStatus == RsTokenService::FAILED)
{ {
// maybe we should do alternative callback? // maybe we should do alternative callback?
std::cerr << __PRETTY_FUNCTION__ << " ERROR Request Failed! " std::cerr << __PRETTY_FUNCTION__ << " ERROR Request Failed! "
@ -87,7 +88,7 @@ void GxsTokenQueue::checkRequests()
{ {
for(it = toload.begin(); it != toload.end(); ++it) for(it = toload.begin(); it != toload.end(); ++it)
{ {
handleResponse(it->mToken, it->mReqType); handleResponse(it->mToken, it->mReqType, it->mStatus);
} }
} }
} }

View File

@ -23,19 +23,22 @@
#define R_GXS_TOKEN_QUEUE_H #define R_GXS_TOKEN_QUEUE_H
#include "gxs/rsgenexchange.h" #include "gxs/rsgenexchange.h"
#include "retroshare/rsservicecontrol.h"
#include "util/rsthreads.h" #include "util/rsthreads.h"
struct GxsTokenQueueItem struct GxsTokenQueueItem
{ {
public:
GxsTokenQueueItem(const uint32_t token, const uint32_t req_type) : GxsTokenQueueItem(const uint32_t token, const uint32_t req_type) :
mToken(token), mReqType(req_type) {} mToken(token), mReqType(req_type), mStatus(RsTokenService::PENDING) {}
GxsTokenQueueItem(): mToken(0), mReqType(0) {} GxsTokenQueueItem(): mToken(0), mReqType(0), mStatus(RsTokenService::PENDING) {}
uint32_t mToken; uint32_t mToken;
uint32_t mReqType; uint32_t mReqType;
RsTokenService::GxsRequestStatus mStatus;
}; };
@ -54,7 +57,8 @@ public:
protected: protected:
/// This must be overloaded to complete the functionality. /// This must be overloaded to complete the functionality.
virtual void handleResponse(uint32_t token, uint32_t req_type) = 0; virtual void handleResponse(uint32_t token, uint32_t req_type
, RsTokenService::GxsRequestStatus status) = 0;
private: private:
RsGenExchange *mGenExchange; RsGenExchange *mGenExchange;

View File

@ -693,10 +693,10 @@ bool RsGxsDataAccess::getServiceStatistic(const uint32_t &token, GxsServiceStati
} }
GxsRequest* RsGxsDataAccess::locked_retrieveCompletedRequest(const uint32_t& token) GxsRequest* RsGxsDataAccess::locked_retrieveCompletedRequest(const uint32_t& token)
{ {
auto it = mCompletedRequests.find(token) ; auto it = mCompletedRequests.find(token) ;
if(it == mCompletedRequests.end()) if(it == mCompletedRequests.end())
return nullptr; return nullptr;
return it->second; return it->second;
} }
@ -720,6 +720,7 @@ void RsGxsDataAccess::processRequests()
{ {
if(now > mRequestQueue.begin()->second->reqTime + MAX_REQUEST_AGE) if(now > mRequestQueue.begin()->second->reqTime + MAX_REQUEST_AGE)
{ {
mPublicToken[mRequestQueue.begin()->second->token] = CANCELLED;
delete mRequestQueue.begin()->second; delete mRequestQueue.begin()->second;
mRequestQueue.erase(mRequestQueue.begin()); mRequestQueue.erase(mRequestQueue.begin());
continue; continue;
@ -833,8 +834,8 @@ void RsGxsDataAccess::processRequests()
} }
else else
{ {
req->status = FAILED;
mPublicToken[req->token] = FAILED; mPublicToken[req->token] = FAILED;
delete req;//req belongs to no one now
#ifdef DATA_DEBUG #ifdef DATA_DEBUG
RsDbg() << " Request failed. Marking as FAILED." << std::endl; RsDbg() << " Request failed. Marking as FAILED." << std::endl;
#endif #endif
@ -1024,7 +1025,7 @@ bool RsGxsDataAccess::getMsgMetaDataList( const GxsMsgReq& msgIds, const RsTokRe
for(meta_it = result.begin(); meta_it != result.end(); ++meta_it) for(meta_it = result.begin(); meta_it != result.end(); ++meta_it)
{ {
const RsGxsGroupId& grpId = meta_it->first; //const RsGxsGroupId& grpId = meta_it->first;
//auto& filter( metaFilter[grpId] ); // does the initialization of metaFilter[grpId] and avoids further O(log(n)) calls //auto& filter( metaFilter[grpId] ); // does the initialization of metaFilter[grpId] and avoids further O(log(n)) calls
@ -1122,8 +1123,7 @@ bool RsGxsDataAccess::getMsgMetaDataList( const GxsMsgReq& msgIds, const RsTokRe
for(uint32_t i=0;i<metaV.size();++i) for(uint32_t i=0;i<metaV.size();++i)
if(metaV[i] != nullptr) if(metaV[i] != nullptr)
{ {
const auto& msgMeta = metaV[i]; const auto& msgMeta = metaV[i];
bool add = false;
/* if we are grabbing thread Head... then parentId == empty. */ /* if we are grabbing thread Head... then parentId == empty. */
if (onlyThreadHeadMsgs && !msgMeta->mParentId.isNull()) if (onlyThreadHeadMsgs && !msgMeta->mParentId.isNull())

View File

@ -137,11 +137,15 @@ void p3GxsTrans::registerGxsTransClient(
mServClients[serviceType] = service; mServClients[serviceType] = service;
} }
void p3GxsTrans::handleResponse(uint32_t token, uint32_t req_type) void p3GxsTrans::handleResponse(uint32_t token, uint32_t req_type
, RsTokenService::GxsRequestStatus status)
{ {
#ifdef DEBUG_GXSTRANS #ifdef DEBUG_GXSTRANS
std::cout << "p3GxsTrans::handleResponse(" << token << ", " << req_type << ")" << std::endl; std::cout << "p3GxsTrans::handleResponse(" << token << ", " << req_type << ", " << status << ")" << std::endl;
#endif #endif
if (status != RsTokenService::COMPLETE)
return; //For now, only manage Complete request
bool changed = false ; bool changed = false ;
switch (req_type) switch (req_type)

View File

@ -159,7 +159,7 @@ public:
GxsTransClient* service ); GxsTransClient* service );
/// @see RsGenExchange::getServiceInfo() /// @see RsGenExchange::getServiceInfo()
virtual RsServiceInfo getServiceInfo() { return RsServiceInfo( RS_SERVICE_TYPE_GXS_TRANS, "GXS Mails", 0, 1, 0, 1 ); } virtual RsServiceInfo getServiceInfo() override { return RsServiceInfo( RS_SERVICE_TYPE_GXS_TRANS, "GXS Mails", 0, 1, 0, 1 ); }
static const uint32_t GXS_STORAGE_PERIOD = 15*86400; // 15 days. static const uint32_t GXS_STORAGE_PERIOD = 15*86400; // 15 days.
static const uint32_t GXS_SYNC_PERIOD = 15*86400; static const uint32_t GXS_SYNC_PERIOD = 15*86400;
@ -230,30 +230,32 @@ private:
inMap mIncomingQueue; inMap mIncomingQueue;
RsMutex mIngoingMutex; RsMutex mIngoingMutex;
/// @see GxsTokenQueue::handleResponse(uint32_t token, uint32_t req_type) /// @see GxsTokenQueue::handleResponse(uint32_t token, uint32_t req_type
virtual void handleResponse(uint32_t token, uint32_t req_type); /// , RsTokenService::GxsRequestStatus status)
virtual void handleResponse(uint32_t token, uint32_t req_type
, RsTokenService::GxsRequestStatus status) override;
/// @see RsGenExchange::service_tick() /// @see RsGenExchange::service_tick()
virtual void service_tick(); virtual void service_tick() override;
/// @see RsGenExchange::service_CreateGroup(...) /// @see RsGenExchange::service_CreateGroup(...)
RsGenExchange::ServiceCreate_Return service_CreateGroup( RsGenExchange::ServiceCreate_Return service_CreateGroup(
RsGxsGrpItem* grpItem, RsTlvSecurityKeySet& ); RsGxsGrpItem* grpItem, RsTlvSecurityKeySet& ) override;
/// @see RsGenExchange::notifyChanges(std::vector<RsGxsNotify *> &changes) /// @see RsGenExchange::notifyChanges(std::vector<RsGxsNotify *> &changes)
void notifyChanges(std::vector<RsGxsNotify *> &changes); void notifyChanges(std::vector<RsGxsNotify *> &changes) override;
/// @see p3Config::setupSerialiser() /// @see p3Config::setupSerialiser()
virtual RsSerialiser* setupSerialiser(); virtual RsSerialiser* setupSerialiser() override;
/// @see p3Config::saveList(bool &cleanup, std::list<RsItem *>&) /// @see p3Config::saveList(bool &cleanup, std::list<RsItem *>&)
virtual bool saveList(bool &cleanup, std::list<RsItem *>&saveList); virtual bool saveList(bool &cleanup, std::list<RsItem *>&saveList) override;
/// @see p3Config::saveDone() /// @see p3Config::saveDone()
void saveDone(); void saveDone() override;
/// @see p3Config::loadList(std::list<RsItem *>&) /// @see p3Config::loadList(std::list<RsItem *>&)
virtual bool loadList(std::list<RsItem *>& loadList); virtual bool loadList(std::list<RsItem *>& loadList) override;
/// Request groups list to GXS backend. Async method. /// Request groups list to GXS backend. Async method.
bool requestGroupsData(const std::list<RsGxsGroupId>* groupIds = NULL); bool requestGroupsData(const std::list<RsGxsGroupId>* groupIds = NULL);
@ -325,9 +327,9 @@ private:
// Overloaded from RsGenExchange. // Overloaded from RsGenExchange.
bool acceptNewMessage(const RsGxsMsgMetaData *msgMeta, uint32_t size) ; bool acceptNewMessage(const RsGxsMsgMetaData *msgMeta, uint32_t size) override;
GxsTransIntegrityCleanupThread *mCleanupThread ; GxsTransIntegrityCleanupThread *mCleanupThread ;
// statistics of the load across all groups, per user. // statistics of the load across all groups, per user.

View File

@ -1134,12 +1134,14 @@ void p3GxsChannels::handleUnprocessedPost(const RsGxsChannelPost &msg)
// Overloaded from GxsTokenQueue for Request callbacks. // Overloaded from GxsTokenQueue for Request callbacks.
void p3GxsChannels::handleResponse(uint32_t token, uint32_t req_type) void p3GxsChannels::handleResponse(uint32_t token, uint32_t req_type
, RsTokenService::GxsRequestStatus status)
{ {
#ifdef GXSCHANNELS_DEBUG #ifdef GXSCHANNELS_DEBUG
std::cerr << "p3GxsChannels::handleResponse(" << token << "," << req_type << ")"; std::cerr << "p3GxsChannels::handleResponse(" << token << "," << req_type << "," << status << ")" << std::endl;
std::cerr << std::endl;
#endif // GXSCHANNELS_DEBUG #endif // GXSCHANNELS_DEBUG
if (status != RsTokenService::COMPLETE)
return; //For now, only manage Complete request
// stuff. // stuff.
switch(req_type) switch(req_type)

View File

@ -178,15 +178,15 @@ virtual bool getChannelDownloadDirectory(const RsGxsGroupId &groupId, std::strin
// Overloaded from RsGxsIface. // Overloaded from RsGxsIface.
virtual bool subscribeToGroup(uint32_t &token, const RsGxsGroupId &groupId, bool subscribe); virtual bool subscribeToGroup(uint32_t &token, const RsGxsGroupId &groupId, bool subscribe) override;
// Set Statuses. // Set Statuses.
virtual void setMessageProcessedStatus(uint32_t& token, const RsGxsGrpMsgIdPair& msgId, bool processed); virtual void setMessageProcessedStatus(uint32_t& token, const RsGxsGrpMsgIdPair& msgId, bool processed);
virtual void setMessageReadStatus(uint32_t& token, const RsGxsGrpMsgIdPair& msgId, bool read); virtual void setMessageReadStatus(uint32_t& token, const RsGxsGrpMsgIdPair& msgId, bool read) override;
// File Interface // File Interface
virtual bool ExtraFileHash(const std::string& path); virtual bool ExtraFileHash(const std::string& path) override;
virtual bool ExtraFileRemove(const RsFileHash &hash); virtual bool ExtraFileRemove(const RsFileHash &hash) override;
/// Implementation of @see RsGxsChannels::getChannelsSummaries /// Implementation of @see RsGxsChannels::getChannelsSummaries
@ -277,7 +277,7 @@ virtual bool ExtraFileRemove(const RsFileHash &hash);
bool subscribe ) override; bool subscribe ) override;
/// @see RsGxsChannels /// @see RsGxsChannels
virtual bool markRead(const RsGxsGrpMsgIdPair& msgId, bool read); virtual bool markRead(const RsGxsGrpMsgIdPair& msgId, bool read) override;
/// @see RsGxsChannels /// @see RsGxsChannels
bool exportChannelLink( bool exportChannelLink(
@ -295,7 +295,7 @@ virtual bool ExtraFileRemove(const RsFileHash &hash);
) override; ) override;
virtual bool shareChannelKeys( virtual bool shareChannelKeys(
const RsGxsGroupId& channelId, const std::set<RsPeerId>& peers ); const RsGxsGroupId& channelId, const std::set<RsPeerId>& peers ) override;
/// Implementation of @see RsGxsChannels::createChannel /// Implementation of @see RsGxsChannels::createChannel
RS_DEPRECATED_FOR(createChannelV2) RS_DEPRECATED_FOR(createChannelV2)
@ -316,7 +316,8 @@ virtual bool ExtraFileRemove(const RsFileHash &hash);
protected: protected:
// Overloaded from GxsTokenQueue for Request callbacks. // Overloaded from GxsTokenQueue for Request callbacks.
virtual void handleResponse(uint32_t token, uint32_t req_type); virtual void handleResponse(uint32_t token, uint32_t req_type
, RsTokenService::GxsRequestStatus status) override;
private: private:

View File

@ -434,13 +434,13 @@ bool p3GxsCircles::revokeIdsFromCircle( const std::set<RsGxsId>& identities, con
return false; return false;
} }
// /!\ AVOID calling circleGrp.mInvitedMembers.erase(identities.begin(),identities.end()), because it is not the same set. Consequently // /!\ AVOID calling circleGrp.mInvitedMembers.erase(identities.begin(),identities.end()), because it is not the same set. Consequently
// STL code would corrupt the structure of mInvitedMembers. // STL code would corrupt the structure of mInvitedMembers.
std::set<RsGxsId> new_invited_members; std::set<RsGxsId> new_invited_members;
for(auto& gxs_id: circleGrp.mInvitedMembers) for(auto& gxs_id: circleGrp.mInvitedMembers)
if(identities.find(gxs_id) == identities.end()) if(identities.find(gxs_id) == identities.end())
new_invited_members.insert(gxs_id); new_invited_members.insert(gxs_id);
circleGrp.mInvitedMembers = new_invited_members; circleGrp.mInvitedMembers = new_invited_members;
@ -585,8 +585,8 @@ void p3GxsCircles::notifyChanges(std::vector<RsGxsNotify *> &changes)
std::cerr << std::endl; std::cerr << std::endl;
#endif #endif
p3Notify *notify = RsServer::notify(); //p3Notify *notify = RsServer::notify();
std::set<RsGxsCircleId> circles_to_reload; std::set<RsGxsCircleId> circles_to_reload;
for(auto it = changes.begin(); it != changes.end(); ++it) for(auto it = changes.begin(); it != changes.end(); ++it)
{ {
@ -1505,8 +1505,8 @@ bool p3GxsCircles::locked_checkCircleCacheForMembershipUpdate(RsGxsCircleCache&
{ {
rstime_t now = time(NULL) ; rstime_t now = time(NULL) ;
if(cache.mStatus < CircleEntryCacheStatus::UPDATING) if(cache.mStatus < CircleEntryCacheStatus::UPDATING)
return false; return false;
if(cache.mLastUpdatedMembershipTS + GXS_CIRCLE_DELAY_TO_FORCE_MEMBERSHIP_UPDATE < now) if(cache.mLastUpdatedMembershipTS + GXS_CIRCLE_DELAY_TO_FORCE_MEMBERSHIP_UPDATE < now)
{ {
@ -1559,8 +1559,8 @@ bool p3GxsCircles::locked_checkCircleCacheForAutoSubscribe(RsGxsCircleCache& cac
return false; return false;
} }
if(cache.mStatus < CircleEntryCacheStatus::UPDATING) if(cache.mStatus < CircleEntryCacheStatus::UPDATING)
return false; return false;
/* if we appear in the group - then autosubscribe, and mark as processed. This also applies if we're the group admin */ /* if we appear in the group - then autosubscribe, and mark as processed. This also applies if we're the group admin */
@ -1702,12 +1702,15 @@ bool p3GxsCircles::service_checkIfGroupIsStillUsed(const RsGxsGrpMetaData& meta)
//====================================================================================// //====================================================================================//
// Overloaded from GxsTokenQueue for Request callbacks. // Overloaded from GxsTokenQueue for Request callbacks.
void p3GxsCircles::handleResponse(uint32_t token, uint32_t req_type) void p3GxsCircles::handleResponse(uint32_t token, uint32_t req_type
, RsTokenService::GxsRequestStatus status)
{ {
#ifdef DEBUG_CIRCLES #ifdef DEBUG_CIRCLES
std::cerr << "p3GxsCircles::handleResponse(" << token << "," << req_type << ")"; std::cerr << "p3GxsCircles::handleResponse(" << token << "," << req_type << "," << status << ")" << std::endl;
std::cerr << std::endl;
#endif // DEBUG_CIRCLES #endif // DEBUG_CIRCLES
if (status != RsTokenService::COMPLETE)
return; //For now, only manage Complete request
// stuff. // stuff.
switch(req_type) switch(req_type)

View File

@ -250,10 +250,10 @@ public:
bool revokeIdsFromCircle( const std::set<RsGxsId>& identities, bool revokeIdsFromCircle( const std::set<RsGxsId>& identities,
const RsGxsCircleId& circleId ) override; const RsGxsCircleId& circleId ) override;
/// @see RsGxsCircles /// @see RsGxsCircles
bool getCircleRequest(const RsGxsGroupId& circleId, bool getCircleRequest(const RsGxsGroupId& circleId,
const RsGxsMessageId& msgId, const RsGxsMessageId& msgId,
RsGxsCircleMsg& msg) override; RsGxsCircleMsg& msg) override;
/// @see RsGxsCircles /// @see RsGxsCircles
bool exportCircleLink( bool exportCircleLink(
@ -270,58 +270,59 @@ public:
std::string& errMsg = RS_DEFAULT_STORAGE_PARAM(std::string) std::string& errMsg = RS_DEFAULT_STORAGE_PARAM(std::string)
) override; ) override;
virtual bool getCircleDetails(const RsGxsCircleId &id, RsGxsCircleDetails &details) override; virtual bool getCircleDetails(const RsGxsCircleId &id, RsGxsCircleDetails &details) override;
virtual bool getCircleExternalIdList(std::set<RsGxsCircleId> &circleIds) override; virtual bool getCircleExternalIdList(std::set<RsGxsCircleId> &circleIds) override;
virtual bool isLoaded(const RsGxsCircleId &circleId) override; virtual bool isLoaded(const RsGxsCircleId &circleId) override;
virtual bool loadCircle(const RsGxsCircleId &circleId) override; virtual bool loadCircle(const RsGxsCircleId &circleId) override;
virtual int canSend(const RsGxsCircleId &circleId, const RsPgpId &id, bool &should_encrypt) override; virtual int canSend(const RsGxsCircleId &circleId, const RsPgpId &id, bool &should_encrypt) override;
virtual int canReceive(const RsGxsCircleId &circleId, const RsPgpId &id) override; virtual int canReceive(const RsGxsCircleId &circleId, const RsPgpId &id) override;
virtual bool recipients(const RsGxsCircleId &circleId, std::list<RsPgpId> &friendlist) override; virtual bool recipients(const RsGxsCircleId &circleId, std::list<RsPgpId> &friendlist) override;
virtual bool recipients(const RsGxsCircleId &circleId, const RsGxsGroupId& dest_group, std::list<RsGxsId> &gxs_ids) override; virtual bool recipients(const RsGxsCircleId &circleId, const RsGxsGroupId& dest_group, std::list<RsGxsId> &gxs_ids) override;
virtual bool isRecipient(const RsGxsCircleId &circleId, const RsGxsGroupId& destination_group, const RsGxsId& id) override; virtual bool isRecipient(const RsGxsCircleId &circleId, const RsGxsGroupId& destination_group, const RsGxsId& id) override;
virtual bool getGroupData(const uint32_t &token, std::vector<RsGxsCircleGroup> &groups) override; virtual bool getGroupData(const uint32_t &token, std::vector<RsGxsCircleGroup> &groups) override;
virtual bool getMsgData(const uint32_t &token, std::vector<RsGxsCircleMsg> &msgs) override; virtual bool getMsgData(const uint32_t &token, std::vector<RsGxsCircleMsg> &msgs) override;
virtual void createGroup(uint32_t& token, RsGxsCircleGroup &group) override; virtual void createGroup(uint32_t& token, RsGxsCircleGroup &group) override;
virtual void updateGroup(uint32_t &token, RsGxsCircleGroup &group) override; virtual void updateGroup(uint32_t &token, RsGxsCircleGroup &group) override;
virtual bool service_checkIfGroupIsStillUsed(const RsGxsGrpMetaData& meta) override; virtual bool service_checkIfGroupIsStillUsed(const RsGxsGrpMetaData& meta) override;
/* membership management for external circles */
virtual bool requestCircleMembership(const RsGxsId &own_gxsid, const RsGxsCircleId& circle_id) override;
virtual bool cancelCircleMembership(const RsGxsId &own_gxsid, const RsGxsCircleId& circle_id) override;
/* membership management for external circles */
virtual bool requestCircleMembership(const RsGxsId &own_gxsid, const RsGxsCircleId& circle_id) override;
virtual bool cancelCircleMembership(const RsGxsId &own_gxsid, const RsGxsCircleId& circle_id) override;
/**********************************************/ /**********************************************/
// needed for background processing. // needed for background processing.
virtual void service_tick() override; virtual void service_tick() override;
protected: protected:
// overloads p3Config // overloads p3Config
virtual bool saveList(bool &cleanup, std::list<RsItem *>&saveList) override; virtual bool saveList(bool &cleanup, std::list<RsItem *>&saveList) override;
virtual bool loadList(std::list<RsItem *>& loadList) override; virtual bool loadList(std::list<RsItem *>& loadList) override;
virtual RsSerialiser *setupSerialiser() override; virtual RsSerialiser *setupSerialiser() override;
bool pushCircleMembershipRequest(const RsGxsId& own_gxsid, const RsGxsCircleId& circle_id, RsGxsCircleSubscriptionType request_type) ; bool pushCircleMembershipRequest(const RsGxsId& own_gxsid, const RsGxsCircleId& circle_id, RsGxsCircleSubscriptionType request_type) ;
static uint32_t circleAuthenPolicy(); static uint32_t circleAuthenPolicy();
/** Notifications **/ /** Notifications **/
virtual void notifyChanges(std::vector<RsGxsNotify*>& changes) override; virtual void notifyChanges(std::vector<RsGxsNotify*>& changes) override;
/** Overloaded to add PgpIdHash to Group Definition **/ /** Overloaded to add PgpIdHash to Group Definition **/
virtual ServiceCreate_Return service_CreateGroup(RsGxsGrpItem* grpItem, RsTlvSecurityKeySet& keySet) override; virtual ServiceCreate_Return service_CreateGroup(RsGxsGrpItem* grpItem, RsTlvSecurityKeySet& keySet) override;
// Overloaded from GxsTokenQueue for Request callbacks. // Overloaded from GxsTokenQueue for Request callbacks.
virtual void handleResponse(uint32_t token, uint32_t req_type) override; virtual void handleResponse(uint32_t token, uint32_t req_type
, RsTokenService::GxsRequestStatus status) override;
// Overloaded from RsTickEvent. // Overloaded from RsTickEvent.
virtual void handle_event(uint32_t event_type, const std::string &elabel) override; virtual void handle_event(uint32_t event_type, const std::string &elabel) override;
private: private:

View File

@ -199,7 +199,7 @@ bool p3GxsCommentService::getGxsCommentData(const uint32_t &token, std::vector<R
for(; mit != msgData.end(); ++mit) for(; mit != msgData.end(); ++mit)
{ {
RsGxsGroupId grpId = mit->first; //RsGxsGroupId grpId = mit->first;
std::vector<RsGxsMsgItem*>& msgItems = mit->second; std::vector<RsGxsMsgItem*>& msgItems = mit->second;
std::vector<RsGxsMsgItem*>::iterator vit = msgItems.begin(); std::vector<RsGxsMsgItem*>::iterator vit = msgItems.begin();
@ -697,12 +697,15 @@ bool p3GxsCommentService::acknowledgeVote(const uint32_t& token, RsGxsGrpMsgIdPa
// Overloaded from GxsTokenQueue for Request callbacks. // Overloaded from GxsTokenQueue for Request callbacks.
void p3GxsCommentService::handleResponse(uint32_t token, uint32_t req_type) void p3GxsCommentService::handleResponse(uint32_t token, uint32_t req_type
, RsTokenService::GxsRequestStatus status)
{ {
#ifdef DEBUG_GXSCOMMON #ifdef DEBUG_GXSCOMMON
std::cerr << "p3GxsCommentService::handleResponse(" << token << "," << req_type << ")"; std::cerr << "p3GxsCommentService::handleResponse(" << token << "," << req_type << "," << status << ")" << std::endl;
std::cerr << std::endl;
#endif #endif
if (status != RsTokenService::COMPLETE)
return; //For now, only manage Complete request
// stuff. // stuff.
switch(req_type) switch(req_type)

View File

@ -82,7 +82,8 @@ static double calculateBestScore(int upVotes, int downVotes);
protected: protected:
// Overloaded from GxsTokenQueue for Request callbacks. // Overloaded from GxsTokenQueue for Request callbacks.
virtual void handleResponse(uint32_t token, uint32_t req_type); virtual void handleResponse(uint32_t token, uint32_t req_type
, RsTokenService::GxsRequestStatus status) override;
private: private:

View File

@ -151,27 +151,26 @@ RsIdentity* rsIdentity = nullptr;
/******************* Startup / Tick ******************************************/ /******************* Startup / Tick ******************************************/
/********************************************************************************/ /********************************************************************************/
p3IdService::p3IdService( p3IdService::p3IdService( RsGeneralDataService *gds
RsGeneralDataService *gds, RsNetworkExchangeService *nes, , RsNetworkExchangeService *nes
PgpAuxUtils *pgpUtils ) : , PgpAuxUtils *pgpUtils )
RsGxsIdExchange( gds, nes, new RsGxsIdSerialiser(), : RsGxsIdExchange( gds, nes, new RsGxsIdSerialiser(),
RS_SERVICE_GXS_TYPE_GXSID, idAuthenPolicy() ), RS_SERVICE_GXS_TYPE_GXSID, idAuthenPolicy() )
RsIdentity(static_cast<RsGxsIface&>(*this)), GxsTokenQueue(this), , RsIdentity(static_cast<RsGxsIface&>(*this))
RsTickEvent(), mKeyCache(GXSID_MAX_CACHE_SIZE, "GxsIdKeyCache"), , GxsTokenQueue(this), RsTickEvent(), p3Config()
mIdMtx("p3IdService"), mNes(nes), mPgpUtils(pgpUtils) , mKeyCache(GXSID_MAX_CACHE_SIZE, "GxsIdKeyCache")
, mBgSchedule_Active(false), mBgSchedule_Mode(0)
, mIdMtx("p3IdService"), mNes(nes), mPgpUtils(pgpUtils)
, mLastConfigUpdate(0), mOwnIdsLoaded(false)
, mAutoAddFriendsIdentitiesAsContacts(true) /*default*/
, mMaxKeepKeysBanned(MAX_KEEP_KEYS_BANNED_DEFAULT)
{ {
mBgSchedule_Mode = 0; mLastKeyCleaningTime = time(NULL) - int(MAX_DELAY_BEFORE_CLEANING * 0.9) ;
mBgSchedule_Active = false;
mLastKeyCleaningTime = time(NULL) - int(MAX_DELAY_BEFORE_CLEANING * 0.9) ;
mLastConfigUpdate = 0 ;
mOwnIdsLoaded = false ;
mAutoAddFriendsIdentitiesAsContacts = true; // default
mMaxKeepKeysBanned = MAX_KEEP_KEYS_BANNED_DEFAULT;
// Kick off Cache Testing, + Others. // Kick off Cache Testing, + Others.
RsTickEvent::schedule_now(GXSID_EVENT_CACHEOWNIDS);//First Thing to do
RsTickEvent::schedule_in(GXSID_EVENT_PGPHASH, PGPHASH_PERIOD); RsTickEvent::schedule_in(GXSID_EVENT_PGPHASH, PGPHASH_PERIOD);
RsTickEvent::schedule_in(GXSID_EVENT_REPUTATION, REPUTATION_PERIOD); RsTickEvent::schedule_in(GXSID_EVENT_REPUTATION, REPUTATION_PERIOD);
RsTickEvent::schedule_now(GXSID_EVENT_CACHEOWNIDS);
//RsTickEvent::schedule_in(GXSID_EVENT_CACHETEST, CACHETEST_PERIOD); //RsTickEvent::schedule_in(GXSID_EVENT_CACHETEST, CACHETEST_PERIOD);
@ -4478,7 +4477,7 @@ void p3IdService::generateDummy_OwnIds()
/* grab all the gpg ids... and make some ids */ /* grab all the gpg ids... and make some ids */
RsPgpId ownId = mPgpUtils->getPGPOwnId(); /*RsPgpId ownId = */mPgpUtils->getPGPOwnId();
#if 0 #if 0
// generate some ownIds. // generate some ownIds.
@ -4694,36 +4693,37 @@ void p3IdService::checkPeerForIdentities()
// Overloaded from GxsTokenQueue for Request callbacks. // Overloaded from GxsTokenQueue for Request callbacks.
void p3IdService::handleResponse(uint32_t token, uint32_t req_type) void p3IdService::handleResponse(uint32_t token, uint32_t req_type
, RsTokenService::GxsRequestStatus status)
{ {
#ifdef DEBUG_IDS #ifdef DEBUG_IDS
std::cerr << "p3IdService::handleResponse(" << token << "," << req_type << ")"; std::cerr << "p3IdService::handleResponse(" << token << "," << req_type << "," << status << ")" << std::endl;
std::cerr << std::endl;
#endif // DEBUG_IDS #endif // DEBUG_IDS
// stuff. // stuff.
switch(req_type) switch(req_type)
{ {
case GXSIDREQ_CACHEOWNIDS: case GXSIDREQ_CACHEOWNIDS:
cache_load_ownids(token); if (status == RsTokenService::COMPLETE) cache_load_ownids(token);
if (status == RsTokenService::CANCELLED) RsTickEvent::schedule_now(GXSID_EVENT_CACHEOWNIDS);//Cancelled by time-out so ask a new time
break; break;
case GXSIDREQ_CACHELOAD: case GXSIDREQ_CACHELOAD:
cache_load_for_token(token); if (status == RsTokenService::COMPLETE) cache_load_for_token(token);
break; break;
case GXSIDREQ_PGPHASH: case GXSIDREQ_PGPHASH:
pgphash_handlerequest(token); if (status == RsTokenService::COMPLETE) pgphash_handlerequest(token);
break; break;
case GXSIDREQ_RECOGN: case GXSIDREQ_RECOGN:
recogn_handlerequest(token); if (status == RsTokenService::COMPLETE) recogn_handlerequest(token);
break; break;
case GXSIDREQ_CACHETEST: case GXSIDREQ_CACHETEST:
cachetest_handlerequest(token); if (status == RsTokenService::COMPLETE) cachetest_handlerequest(token);
break; break;
case GXSIDREQ_OPINION: case GXSIDREQ_OPINION:
opinion_handlerequest(token); if (status == RsTokenService::COMPLETE) opinion_handlerequest(token);
break; break;
case GXSIDREQ_SERIALIZE_TO_MEMORY: case GXSIDREQ_SERIALIZE_TO_MEMORY:
handle_get_serialized_grp(token); if (status == RsTokenService::COMPLETE) handle_get_serialized_grp(token);
break; break;
default: default:
std::cerr << "p3IdService::handleResponse() Unknown Request Type: " std::cerr << "p3IdService::handleResponse() Unknown Request Type: "

View File

@ -404,8 +404,9 @@ protected:
// Overloads RsGxsGenExchange // Overloads RsGxsGenExchange
virtual bool acceptNewGroup(const RsGxsGrpMetaData *grpMeta) override ; virtual bool acceptNewGroup(const RsGxsGrpMetaData *grpMeta) override ;
// Overloaded from GxsTokenQueue for Request callbacks. // Overloaded from GxsTokenQueue for Request callbacks.
virtual void handleResponse(uint32_t token, uint32_t req_type) override; virtual void handleResponse(uint32_t token, uint32_t req_type
, RsTokenService::GxsRequestStatus status) override;
// Overloaded from RsTickEvent. // Overloaded from RsTickEvent.
virtual void handle_event(uint32_t event_type, const std::string &elabel) override; virtual void handle_event(uint32_t event_type, const std::string &elabel) override;
@ -558,7 +559,7 @@ private:
void cleanUnusedKeys() ; void cleanUnusedKeys() ;
void slowIndicateConfigChanged() ; void slowIndicateConfigChanged() ;
virtual void timeStampKey(const RsGxsId& id, const RsIdentityUsage& reason) ; virtual void timeStampKey(const RsGxsId& id, const RsIdentityUsage& reason) override;
rstime_t locked_getLastUsageTS(const RsGxsId& gxs_id); rstime_t locked_getLastUsageTS(const RsGxsId& gxs_id);
std::string genRandomId(int len = 20); std::string genRandomId(int len = 20);

View File

@ -322,7 +322,7 @@ bool p3PhotoService::createAlbum(RsPhotoAlbum &album)
return submitAlbumDetails(token, album) && waitToken(token) == RsTokenService::COMPLETE; return submitAlbumDetails(token, album) && waitToken(token) == RsTokenService::COMPLETE;
} }
bool p3PhotoService::updateAlbum(const RsPhotoAlbum &album) bool p3PhotoService::updateAlbum(const RsPhotoAlbum &/*album*/)
{ {
// TODO // TODO
return false; return false;

View File

@ -31,7 +31,7 @@ class p3PhotoService : public RsGenExchange, public RsPhoto
public: public:
p3PhotoService(RsGeneralDataService* gds, RsNetworkExchangeService* nes, RsGixs* gixs); p3PhotoService(RsGeneralDataService* gds, RsNetworkExchangeService* nes, RsGixs* gixs);
virtual RsServiceInfo getServiceInfo(); virtual RsServiceInfo getServiceInfo() override;
static uint32_t photoAuthenPolicy(); static uint32_t photoAuthenPolicy();
@ -40,38 +40,38 @@ public:
/*! /*!
* @return true if a change has occured * @return true if a change has occured
*/ */
bool updated(); bool updated() override;
/*! /*!
* *
*/ */
void service_tick(); void service_tick() override;
protected: protected:
void notifyChanges(std::vector<RsGxsNotify*>& changes); void notifyChanges(std::vector<RsGxsNotify*>& changes) override;
public: public:
/** Requests **/ /** Requests **/
void groupsChanged(std::list<RsGxsGroupId>& grpIds); void groupsChanged(std::list<RsGxsGroupId>& grpIds) override;
void msgsChanged(GxsMsgIdResult& msgs); void msgsChanged(GxsMsgIdResult& msgs) override;
RsTokenService* getTokenService(); RsTokenService* getTokenService() override;
bool getGroupList(const uint32_t &token, std::list<RsGxsGroupId> &groupIds); bool getGroupList(const uint32_t &token, std::list<RsGxsGroupId> &groupIds) override;
bool getMsgList(const uint32_t &token, GxsMsgIdResult& msgIds); bool getMsgList(const uint32_t &token, GxsMsgIdResult& msgIds) override;
/* Generic Summary */ /* Generic Summary */
bool getGroupSummary(const uint32_t &token, std::list<RsGroupMetaData> &groupInfo); bool getGroupSummary(const uint32_t &token, std::list<RsGroupMetaData> &groupInfo) override;
bool getMsgSummary(const uint32_t &token, MsgMetaResult &msgInfo); bool getMsgSummary(const uint32_t &token, MsgMetaResult &msgInfo) override;
/* Specific Service Data */ /* Specific Service Data */
bool getAlbum(const uint32_t &token, std::vector<RsPhotoAlbum> &albums); bool getAlbum(const uint32_t &token, std::vector<RsPhotoAlbum> &albums) override;
bool getPhoto(const uint32_t &token, PhotoResult &photos); bool getPhoto(const uint32_t &token, PhotoResult &photos) override;
public: public:
/* Comment service - Provide RsGxsCommentService - redirect to p3GxsCommentService */ /* Comment service - Provide RsGxsCommentService - redirect to p3GxsCommentService */
@ -109,6 +109,13 @@ public:
return acknowledgeMsg(token, msgId); return acknowledgeMsg(token, msgId);
} }
//Not currently used
virtual bool setCommentAsRead(uint32_t& /*token*/,const RsGxsGroupId& /*gid*/,const RsGxsMessageId& /*comment_msg_id*/) override
{
return true;
}
// Blocking versions. // Blocking versions.
virtual bool createComment(RsGxsComment &msg) override virtual bool createComment(RsGxsComment &msg) override
{ {
@ -126,7 +133,7 @@ public:
* @param token token to redeem for acknowledgement * @param token token to redeem for acknowledgement
* @param album album to be submitted * @param album album to be submitted
*/ */
bool submitAlbumDetails(uint32_t& token, RsPhotoAlbum &album); bool submitAlbumDetails(uint32_t& token, RsPhotoAlbum &album) override;
/*! /*!
* submits photo, which returns a token that needs * submits photo, which returns a token that needs
@ -134,7 +141,7 @@ public:
* @param token token to redeem for acknowledgement * @param token token to redeem for acknowledgement
* @param photo photo to be submitted * @param photo photo to be submitted
*/ */
bool submitPhoto(uint32_t& token, RsPhotoPhoto &photo); bool submitPhoto(uint32_t& token, RsPhotoPhoto &photo) override;
/*! /*!
* submits photo comment, which returns a token that needs * submits photo comment, which returns a token that needs
@ -152,7 +159,7 @@ public:
* @param token token to redeem for acknowledgement * @param token token to redeem for acknowledgement
* @param grpId the id of the group to subscribe to * @param grpId the id of the group to subscribe to
*/ */
bool subscribeToAlbum(uint32_t& token, const RsGxsGroupId& grpId, bool subscribe); bool subscribeToAlbum(uint32_t& token, const RsGxsGroupId& grpId, bool subscribe) override;
/*! /*!
* This allows the client service to acknowledge that their msgs has * This allows the client service to acknowledge that their msgs has
@ -161,7 +168,7 @@ public:
* @param msgIds map of grpid->msgIds of message created/modified * @param msgIds map of grpid->msgIds of message created/modified
* @return true if token exists false otherwise * @return true if token exists false otherwise
*/ */
bool acknowledgeMsg(const uint32_t& token, std::pair<RsGxsGroupId, RsGxsMessageId>& msgId); bool acknowledgeMsg(const uint32_t& token, std::pair<RsGxsGroupId, RsGxsMessageId>& msgId) override;
/*! /*!
* This allows the client service to acknowledge that their grps has * This allows the client service to acknowledge that their grps has
@ -170,7 +177,7 @@ public:
* @param msgIds vector of ids of groups created/modified * @param msgIds vector of ids of groups created/modified
* @return true if token exists false otherwise * @return true if token exists false otherwise
*/ */
bool acknowledgeGrp(const uint32_t& token, RsGxsGroupId& grpId); bool acknowledgeGrp(const uint32_t& token, RsGxsGroupId& grpId) override;
// Blocking versions. // Blocking versions.
/*! /*!

View File

@ -849,12 +849,14 @@ bool p3PostBase::background_cleanup()
// Overloaded from GxsTokenQueue for Request callbacks. // Overloaded from GxsTokenQueue for Request callbacks.
void p3PostBase::handleResponse(uint32_t token, uint32_t req_type) void p3PostBase::handleResponse(uint32_t token, uint32_t req_type
, RsTokenService::GxsRequestStatus status)
{ {
#ifdef POSTBASE_DEBUG #ifdef POSTBASE_DEBUG
std::cerr << "p3PostBase::handleResponse(" << token << "," << req_type << ")"; std::cerr << "p3PostBase::handleResponse(" << token << "," << req_type << "," << status << ")" << std::endl;
std::cerr << std::endl;
#endif #endif
if (status != RsTokenService::COMPLETE)
return; //For now, only manage Complete request
// stuff. // stuff.
switch(req_type) switch(req_type)

View File

@ -70,17 +70,18 @@ public:
p3PostBase(RsGeneralDataService *gds, RsNetworkExchangeService *nes, RsGixs* gixs, p3PostBase(RsGeneralDataService *gds, RsNetworkExchangeService *nes, RsGixs* gixs,
RsSerialType* serviceSerialiser, uint16_t serviceType); RsSerialType* serviceSerialiser, uint16_t serviceType);
virtual void service_tick() override; virtual void service_tick() override;
protected: protected:
virtual void notifyChanges(std::vector<RsGxsNotify*>& changes) override; virtual void notifyChanges(std::vector<RsGxsNotify*>& changes) override;
// Overloaded from GxsTokenQueue for Request callbacks. // Overloaded from GxsTokenQueue for Request callbacks.
virtual void handleResponse(uint32_t token, uint32_t req_type) override; virtual void handleResponse(uint32_t token, uint32_t req_type
, RsTokenService::GxsRequestStatus status) override;
// Overloaded from RsTickEvent. // Overloaded from RsTickEvent.
virtual void handle_event(uint32_t event_type, const std::string &elabel) override; virtual void handle_event(uint32_t event_type, const std::string &elabel) override;
// overloads p3Config // overloads p3Config
virtual RsSerialiser* setupSerialiser() override; // @see p3Config::setupSerialiser() virtual RsSerialiser* setupSerialiser() override; // @see p3Config::setupSerialiser()

View File

@ -110,6 +110,6 @@ android-* {
} }
################################### Pkg-Config Stuff ############################# ################################### Pkg-Config Stuff #############################
!isEmpty(PKGCONFIG) {
LIBS *= $$system(pkg-config --libs $$PKGCONFIG) LIBS *= $$system(pkg-config --libs $$PKGCONFIG)
}

View File

@ -377,7 +377,9 @@ MainWindow::~MainWindow()
delete sysTrayStatus; delete sysTrayStatus;
delete trayIcon; delete trayIcon;
delete trayMenu; delete trayMenu;
// delete notifyMenu; // already deleted by the deletion of trayMenu // delete notifyMenu; // already deleted by the deletion of trayMenu
StatisticsWindow::releaseInstance();
#ifdef MESSENGER_WINDOW #ifdef MESSENGER_WINDOW
MessengerWindow::releaseInstance(); MessengerWindow::releaseInstance();
#endif #endif

View File

@ -69,6 +69,7 @@ PeopleDialog::PeopleDialog(QWidget *parent)
tabWidget->removeTab(1); tabWidget->removeTab(1);
//hide circle flow widget not functional yet //hide circle flow widget not functional yet
pictureFlowWidgetExternal->hide(); pictureFlowWidgetExternal->hide();
widgetExternal->hide();
//need erase QtCreator Layout first(for Win) //need erase QtCreator Layout first(for Win)
delete idExternal->layout(); delete idExternal->layout();

View File

@ -20,76 +20,25 @@
<string/> <string/>
</property> </property>
<layout class="QGridLayout" name="titleBarLayout"> <layout class="QGridLayout" name="titleBarLayout">
<property name="margin"> <property name="leftMargin">
<number>0</number>
</property>
<property name="topMargin">
<number>0</number>
</property>
<property name="rightMargin">
<number>0</number>
</property>
<property name="bottomMargin">
<number>0</number> <number>0</number>
</property> </property>
<item row="0" column="0"> <item row="0" column="0">
<widget class="QFrame" name="titleBarFrame">
<property name="frameShape">
<enum>QFrame::Box</enum>
</property>
<property name="frameShadow">
<enum>QFrame::Sunken</enum>
</property>
<layout class="QHBoxLayout">
<property name="margin">
<number>2</number>
</property>
<item>
<widget class="QLabel" name="titleBarPixmap">
<property name="minimumSize">
<size>
<width>0</width>
<height>0</height>
</size>
</property>
<property name="maximumSize">
<size>
<width>24</width>
<height>24</height>
</size>
</property>
<property name="text">
<string/>
</property>
<property name="pixmap">
<pixmap resource="../images.qrc">:/images/identity/identities_32.png</pixmap>
</property>
<property name="scaledContents">
<bool>true</bool>
</property>
</widget>
</item>
<item>
<widget class="StyledLabel" name="titleBarLabel">
<property name="text">
<string>People</string>
</property>
</widget>
</item>
<item>
<spacer name="titleBarSpacer">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
</layout>
</widget>
</item>
<item row="1" column="0">
<widget class="QTabWidget" name="tabWidget"> <widget class="QTabWidget" name="tabWidget">
<property name="enabled"> <property name="enabled">
<bool>true</bool> <bool>true</bool>
</property> </property>
<property name="currentIndex"> <property name="currentIndex">
<number>1</number> <number>0</number>
</property> </property>
<widget class="QWidget" name="tabExternal"> <widget class="QWidget" name="tabExternal">
<property name="sizePolicy"> <property name="sizePolicy">
@ -129,7 +78,7 @@
<layout class="QVBoxLayout"/> <layout class="QVBoxLayout"/>
</widget> </widget>
</widget> </widget>
<widget class="QWidget" name="widgetExternal"> <widget class="QFrame" name="widgetExternal">
<layout class="QGridLayout" name="layoutExternal"> <layout class="QGridLayout" name="layoutExternal">
<item row="0" column="0"> <item row="0" column="0">
<widget class="QLabel" name="label_External"> <widget class="QLabel" name="label_External">
@ -234,11 +183,6 @@
</layout> </layout>
</widget> </widget>
<customwidgets> <customwidgets>
<customwidget>
<class>StyledLabel</class>
<extends>QLabel</extends>
<header>gui/common/StyledLabel.h</header>
</customwidget>
<customwidget> <customwidget>
<class>PictureFlow</class> <class>PictureFlow</class>
<extends>QWidget</extends> <extends>QWidget</extends>

View File

@ -365,6 +365,9 @@
<property name="openExternalLinks"> <property name="openExternalLinks">
<bool>true</bool> <bool>true</bool>
</property> </property>
<property name="textInteractionFlags">
<set>Qt::LinksAccessibleByMouse|Qt::TextSelectableByMouse</set>
</property>
</widget> </widget>
</item> </item>
<item> <item>

View File

@ -72,55 +72,57 @@ void RsPostedPostsModel::handleEvent_main_thread(std::shared_ptr<const RsEvent>
switch(e->mPostedEventCode) switch(e->mPostedEventCode)
{ {
case RsPostedEventCode::UPDATED_MESSAGE: case RsPostedEventCode::UPDATED_MESSAGE:
case RsPostedEventCode::READ_STATUS_CHANGED: case RsPostedEventCode::READ_STATUS_CHANGED:
case RsPostedEventCode::MESSAGE_VOTES_UPDATED: case RsPostedEventCode::MESSAGE_VOTES_UPDATED:
case RsPostedEventCode::NEW_MESSAGE: case RsPostedEventCode::NEW_MESSAGE:
{ {
// Normally we should just emit dataChanged() on the index of the data that has changed: // Normally we should just emit dataChanged() on the index of the data that has changed:
// //
// We need to update the data! // We need to update the data!
if(e->mPostedGroupId == mPostedGroup.mMeta.mGroupId) RsGxsPostedEvent E(*e);
RsThread::async([this, e]()
{
// 1 - get message data from p3GxsChannels
std::vector<RsPostedPost> posts; if(E.mPostedGroupId == mPostedGroup.mMeta.mGroupId)
std::vector<RsGxsComment> comments; RsThread::async([this, E]()
std::vector<RsGxsVote> votes;
if(!rsPosted->getBoardContent(mPostedGroup.mMeta.mGroupId,std::set<RsGxsMessageId>{ e->mPostedMsgId }, posts,comments,votes))
{ {
std::cerr << __PRETTY_FUNCTION__ << " failed to retrieve channel message data for channel/msg " << e->mPostedGroupId << "/" << e->mPostedMsgId << std::endl; // 1 - get message data from p3GxsChannels
return;
}
// 2 - update the model in the UI thread. std::vector<RsPostedPost> posts;
std::vector<RsGxsComment> comments;
std::vector<RsGxsVote> votes;
RsQThreadUtils::postToObject( [posts,comments,votes,this]() if(!rsPosted->getBoardContent(mPostedGroup.mMeta.mGroupId,std::set<RsGxsMessageId>{ E.mPostedMsgId }, posts,comments,votes))
{
for(uint32_t i=0;i<posts.size();++i)
{ {
// linear search. Not good at all, but normally this is for a single post. RS_ERR(" failed to retrieve channel message data for channel/msg ", E.mPostedGroupId, "/", E.mPostedMsgId);
return;
for(uint32_t j=0;j<mPosts.size();++j)
if(mPosts[j].mMeta.mMsgId == posts[i].mMeta.mMsgId)
{
mPosts[j] = posts[i];
//emit dataChanged(createIndex(0,0,(void*)NULL), createIndex(mFilteredPosts.size(),0,(void*)NULL));
preMods();
postMods();
}
} }
},this);
});
default: // 2 - update the model in the UI thread.
break;
RsQThreadUtils::postToObject( [posts,comments,votes,this]()
{
for(uint32_t i=0;i<posts.size();++i)
{
// linear search. Not good at all, but normally this is for a single post.
for(uint32_t j=0;j<mPosts.size();++j)
if(mPosts[j].mMeta.mMsgId == posts[i].mMeta.mMsgId)
{
mPosts[j] = posts[i];
//emit dataChanged(createIndex(0,0,(void*)NULL), createIndex(mFilteredPosts.size(),0,(void*)NULL));
preMods();
postMods();
}
}
},this);
});
} }
default:
break;
} }
} }
@ -138,42 +140,38 @@ void RsPostedPostsModel::initEmptyHierarchy()
void RsPostedPostsModel::preMods() void RsPostedPostsModel::preMods()
{ {
beginResetModel(); emit layoutAboutToBeChanged();
} }
void RsPostedPostsModel::postMods() void RsPostedPostsModel::postMods()
{ {
endResetModel(); update();
emit layoutChanged();
emit dataChanged(createIndex(0,0,(void*)NULL), createIndex(mDisplayedNbPosts,0,(void*)NULL));
} }
void RsPostedPostsModel::update() void RsPostedPostsModel::update()
{ {
emit dataChanged(createIndex(0,0,(void*)NULL), createIndex(mDisplayedNbPosts,0,(void*)NULL)); emit dataChanged(createIndex(0,0,(void*)NULL), createIndex(mDisplayedNbPosts,0,(void*)NULL));
} }
void RsPostedPostsModel::triggerRedraw() void RsPostedPostsModel::triggerRedraw()
{ {
preMods(); preMods();
postMods(); postMods();
} }
void RsPostedPostsModel::setFilter(const QStringList& strings, uint32_t& count) void RsPostedPostsModel::setFilter(const QStringList& strings, uint32_t& count)
{ {
preMods(); preMods();
beginRemoveRows(QModelIndex(),0,rowCount()-1); beginResetModel();
endRemoveRows(); mFilteredPosts.clear();
endResetModel();
if(strings.empty()) if(strings.empty())
{ {
mFilteredPosts.clear();
for(int i=0;i<(int)(mPosts.size());++i) for(int i=0;i<(int)(mPosts.size());++i)
mFilteredPosts.push_back(i); mFilteredPosts.push_back(i);
} }
else else
{ {
mFilteredPosts.clear();
//mFilteredPosts.push_back(0);
for(int i=0;i<static_cast<int>(mPosts.size());++i) for(int i=0;i<static_cast<int>(mPosts.size());++i)
{ {
bool passes_strings = true; bool passes_strings = true;
@ -197,8 +195,11 @@ void RsPostedPostsModel::setFilter(const QStringList& strings, uint32_t& count)
std::cerr << "After filtering: " << count << " posts remain." << std::endl; std::cerr << "After filtering: " << count << " posts remain." << std::endl;
beginInsertRows(QModelIndex(),0,rowCount()-1); if (rowCount()>0)
endInsertRows(); {
beginInsertRows(QModelIndex(),0,rowCount()-1);
endInsertRows();
}
postMods(); postMods();
} }
@ -208,11 +209,11 @@ int RsPostedPostsModel::rowCount(const QModelIndex& parent) const
if(parent.column() > 0) if(parent.column() > 0)
return 0; return 0;
if(mFilteredPosts.empty()) // security. Should never happen. if(mFilteredPosts.empty()) // rowCount is called by internal Qt so maybe before posts are populated.
return 0; return 0;
if(!parent.isValid()) if(!parent.isValid())
return mDisplayedNbPosts; return mDisplayedNbPosts;
RsErr() << __PRETTY_FUNCTION__ << " rowCount cannot figure out the porper number of rows." << std::endl; RsErr() << __PRETTY_FUNCTION__ << " rowCount cannot figure out the porper number of rows." << std::endl;
return 0; return 0;
@ -471,7 +472,7 @@ private:
Qt::ItemFlags RsPostedPostsModel::flags(const QModelIndex& index) const Qt::ItemFlags RsPostedPostsModel::flags(const QModelIndex& index) const
{ {
if (!index.isValid()) if (!index.isValid())
return 0; return Qt::ItemFlags();
return QAbstractItemModel::flags(index) | Qt::ItemIsEditable; return QAbstractItemModel::flags(index) | Qt::ItemIsEditable;
} }
@ -493,16 +494,16 @@ void RsPostedPostsModel::setPostsInterval(int start,int nb_posts)
preMods(); preMods();
uint32_t old_nb_rows = rowCount() ; uint32_t old_nb_rows = rowCount() ;
mDisplayedNbPosts = (uint32_t)std::min(nb_posts,(int)mFilteredPosts.size() - (start+1)); mDisplayedNbPosts = (uint32_t)std::min(nb_posts,(int)mFilteredPosts.size() - (start+1));
mDisplayedStartIndex = start; mDisplayedStartIndex = start;
beginRemoveRows(QModelIndex(),mDisplayedNbPosts,old_nb_rows); beginRemoveRows(QModelIndex(),mDisplayedNbPosts,old_nb_rows);
endRemoveRows(); endRemoveRows();
beginInsertRows(QModelIndex(),old_nb_rows,mDisplayedNbPosts); beginInsertRows(QModelIndex(),old_nb_rows,mDisplayedNbPosts);
endInsertRows(); endInsertRows();
postMods(); postMods();
} }
@ -515,26 +516,30 @@ void RsPostedPostsModel::deepUpdate()
void RsPostedPostsModel::setPosts(const RsPostedGroup& group, std::vector<RsPostedPost>& posts) void RsPostedPostsModel::setPosts(const RsPostedGroup& group, std::vector<RsPostedPost>& posts)
{ {
preMods(); preMods();
beginRemoveRows(QModelIndex(),0,rowCount()-1); beginResetModel();
endRemoveRows();
mPosts.clear(); mPosts.clear();
mPostedGroup = group; mPostedGroup = group;
createPostsArray(posts); endResetModel();
std::sort(mPosts.begin(),mPosts.end(), PostSorter(mSortingStrategy)); createPostsArray(posts);
uint32_t tmpval; std::sort(mPosts.begin(),mPosts.end(), PostSorter(mSortingStrategy));
setFilter(QStringList(),tmpval);
mDisplayedNbPosts = std::min((uint32_t)mFilteredPosts.size(),DEFAULT_DISPLAYED_NB_POSTS); uint32_t tmpval;
mDisplayedStartIndex = 0; setFilter(QStringList(),tmpval);
beginInsertRows(QModelIndex(),0,rowCount()-1); mDisplayedNbPosts = std::min((uint32_t)mFilteredPosts.size(),DEFAULT_DISPLAYED_NB_POSTS);
endInsertRows(); mDisplayedStartIndex = 0;
if (rowCount()>0)
{
beginInsertRows(QModelIndex(),0,rowCount()-1);
endInsertRows();
}
postMods(); postMods();
@ -597,8 +602,6 @@ void RsPostedPostsModel::update_posts(const RsGxsGroupId& group_id)
}); });
} }
//static bool decreasing_time_comp(const std::pair<time_t,RsGxsMessageId>& e1,const std::pair<time_t,RsGxsMessageId>& e2) { return e2.first < e1.first ; }
void RsPostedPostsModel::createPostsArray(std::vector<RsPostedPost>& posts) void RsPostedPostsModel::createPostsArray(std::vector<RsPostedPost>& posts)
{ {
#ifdef TODO #ifdef TODO

View File

@ -224,14 +224,22 @@ void AvatarWidget::refreshStatus()
status = statusInfo.status ; status = statusInfo.status ;
} }
else if(mId.isDistantChatId()) else if(mId.isDistantChatId())
{ {
DistantChatPeerInfo dcpinfo ; DistantChatPeerInfo dcpinfo ;
if(rsMsgs->getDistantChatStatus(mId.toDistantChatId(),dcpinfo)) if(rsMsgs->getDistantChatStatus(mId.toDistantChatId(),dcpinfo))
status = dcpinfo.status ; {
else switch (dcpinfo.status)
std::cerr << "(EE) cannot get distant chat status for ID=" << mId.toDistantChatId() << std::endl; {
} case RS_DISTANT_CHAT_STATUS_CAN_TALK : status = RS_STATUS_ONLINE ; break;
case RS_DISTANT_CHAT_STATUS_UNKNOWN : // Fall-through
case RS_DISTANT_CHAT_STATUS_TUNNEL_DN : // Fall-through
case RS_DISTANT_CHAT_STATUS_REMOTELY_CLOSED : status = RS_STATUS_OFFLINE;
}
}
else
std::cerr << "(EE) cannot get distant chat status for ID=" << mId.toDistantChatId() << std::endl;
}
else else
{ {
std::cerr << "Unhandled chat id type in AvatarWidget::refreshStatus()" << std::endl; std::cerr << "Unhandled chat id type in AvatarWidget::refreshStatus()" << std::endl;

View File

@ -152,93 +152,95 @@ void RsFriendListModel::setDisplayGroups(bool b)
} }
void RsFriendListModel::preMods() void RsFriendListModel::preMods()
{ {
beginResetModel(); emit layoutAboutToBeChanged();
} }
void RsFriendListModel::postMods() void RsFriendListModel::postMods()
{ {
endResetModel(); emit dataChanged(createIndex(0,0,(void*)NULL), createIndex(rowCount()-1,columnCount()-1,(void*)NULL));
emit layoutChanged();
emit dataChanged(createIndex(0,0,(void*)NULL), createIndex(rowCount()-1,columnCount()-1,(void*)NULL));
} }
int RsFriendListModel::rowCount(const QModelIndex& parent) const int RsFriendListModel::rowCount(const QModelIndex& parent) const
{ {
if(parent.column() >= COLUMN_THREAD_NB_COLUMNS) if(parent.column() >= COLUMN_THREAD_NB_COLUMNS)
return 0; return 0;
if(parent.internalId() == 0) if(parent.internalId() == 0)
return mTopLevel.size(); return mTopLevel.size();
EntryIndex index; EntryIndex index;
if(!convertInternalIdToIndex<sizeof(uintptr_t)>(parent.internalId(),index)) if(!convertInternalIdToIndex<sizeof(uintptr_t)>(parent.internalId(),index))
return 0; return 0;
if(index.type == ENTRY_TYPE_GROUP) if(index.type == ENTRY_TYPE_GROUP)
return mGroups[index.group_index].child_profile_indices.size(); return mGroups[index.group_index].child_profile_indices.size();
if(index.type == ENTRY_TYPE_PROFILE) if(index.type == ENTRY_TYPE_PROFILE)
{ {
if(index.group_index < UNDEFINED_GROUP_INDEX_VALUE) if(index.group_index < UNDEFINED_GROUP_INDEX_VALUE)
return mProfiles[mGroups[index.group_index].child_profile_indices[index.profile_index]].child_node_indices.size(); return mProfiles[mGroups[index.group_index].child_profile_indices[index.profile_index]].child_node_indices.size();
else else
return mProfiles[index.profile_index].child_node_indices.size(); return mProfiles[index.profile_index].child_node_indices.size();
} }
else //if(index.type == ENTRY_TYPE_NODE) else //if(index.type == ENTRY_TYPE_NODE)
return 0; return 0;
} }
int RsFriendListModel::columnCount(const QModelIndex &parent) const int RsFriendListModel::columnCount(const QModelIndex &/*parent*/) const
{ {
return COLUMN_THREAD_NB_COLUMNS ; return COLUMN_THREAD_NB_COLUMNS ;
} }
bool RsFriendListModel::hasChildren(const QModelIndex &parent) const bool RsFriendListModel::hasChildren(const QModelIndex &parent) const
{ {
if(!parent.isValid()) if(!parent.isValid())
return true; return true;
EntryIndex parent_index ; EntryIndex parent_index ;
convertInternalIdToIndex<sizeof(uintptr_t)>(parent.internalId(),parent_index); convertInternalIdToIndex<sizeof(uintptr_t)>(parent.internalId(),parent_index);
if(parent_index.type == ENTRY_TYPE_NODE) if(parent_index.type == ENTRY_TYPE_NODE)
return false; return false;
if(parent_index.type == ENTRY_TYPE_PROFILE) if(parent_index.type == ENTRY_TYPE_PROFILE)
{
if(parent_index.group_index < UNDEFINED_GROUP_INDEX_VALUE) if(parent_index.group_index < UNDEFINED_GROUP_INDEX_VALUE)
return !mProfiles[mGroups[parent_index.group_index].child_profile_indices[parent_index.profile_index]].child_node_indices.empty(); return !mProfiles[mGroups[parent_index.group_index].child_profile_indices[parent_index.profile_index]].child_node_indices.empty();
else else
return !mProfiles[parent_index.profile_index].child_node_indices.empty(); return !mProfiles[parent_index.profile_index].child_node_indices.empty();
}
if(parent_index.type == ENTRY_TYPE_GROUP) if(parent_index.type == ENTRY_TYPE_GROUP)
return !mGroups[parent_index.group_index].child_profile_indices.empty(); return !mGroups[parent_index.group_index].child_profile_indices.empty();
return false; return false;
} }
RsFriendListModel::EntryIndex RsFriendListModel::EntryIndex::parent() const RsFriendListModel::EntryIndex RsFriendListModel::EntryIndex::parent() const
{ {
EntryIndex i(*this); EntryIndex i(*this);
switch(type) switch(type)
{ {
case ENTRY_TYPE_GROUP: return EntryIndex(); case ENTRY_TYPE_GROUP: return EntryIndex();
case ENTRY_TYPE_PROFILE: case ENTRY_TYPE_PROFILE:
if(i.group_index==UNDEFINED_GROUP_INDEX_VALUE) if(i.group_index==UNDEFINED_GROUP_INDEX_VALUE)
return EntryIndex(); return EntryIndex();
else else
{ {
i.type = ENTRY_TYPE_GROUP; i.type = ENTRY_TYPE_GROUP;
i.profile_index = UNDEFINED_PROFILE_INDEX_VALUE; i.profile_index = UNDEFINED_PROFILE_INDEX_VALUE;
} }
break; break;
case ENTRY_TYPE_NODE: i.type = ENTRY_TYPE_PROFILE; case ENTRY_TYPE_NODE: i.type = ENTRY_TYPE_PROFILE;
i.node_index = UNDEFINED_NODE_INDEX_VALUE; i.node_index = UNDEFINED_NODE_INDEX_VALUE;
break; break;
} case ENTRY_TYPE_UNKNOWN:
RS_ERR("Unknown Entry type for parent.");
}
return i; return i;
} }
RsFriendListModel::EntryIndex RsFriendListModel::EntryIndex::child(int row,const std::vector<EntryIndex>& top_level) const RsFriendListModel::EntryIndex RsFriendListModel::EntryIndex::child(int row,const std::vector<EntryIndex>& top_level) const
@ -310,32 +312,32 @@ QModelIndex RsFriendListModel::index(int row, int column, const QModelIndex& par
QModelIndex RsFriendListModel::parent(const QModelIndex& index) const QModelIndex RsFriendListModel::parent(const QModelIndex& index) const
{ {
if(!index.isValid()) if(!index.isValid())
return QModelIndex(); return QModelIndex();
EntryIndex I ; EntryIndex I ;
convertInternalIdToIndex<sizeof(uintptr_t)>(index.internalId(),I); convertInternalIdToIndex<sizeof(uintptr_t)>(index.internalId(),I);
EntryIndex p = I.parent(); EntryIndex p = I.parent();
if(p.type == ENTRY_TYPE_UNKNOWN) if(p.type == ENTRY_TYPE_UNKNOWN)
return QModelIndex(); return QModelIndex();
quintptr i; quintptr i;
convertIndexToInternalId<sizeof(uintptr_t)>(p,i); convertIndexToInternalId<sizeof(uintptr_t)>(p,i);
return createIndex(I.parentRow(mGroups.size()),0,i); return createIndex(I.parentRow(mGroups.size()),0,i);
} }
Qt::ItemFlags RsFriendListModel::flags(const QModelIndex& index) const Qt::ItemFlags RsFriendListModel::flags(const QModelIndex& index) const
{ {
if (!index.isValid()) if (!index.isValid())
return 0; return Qt::ItemFlags();
return QAbstractItemModel::flags(index); return QAbstractItemModel::flags(index);
} }
QVariant RsFriendListModel::headerData(int section, Qt::Orientation orientation, int role) const QVariant RsFriendListModel::headerData(int section, Qt::Orientation /*orientation*/, int role) const
{ {
if(role == Qt::DisplayRole) if(role == Qt::DisplayRole)
switch(section) switch(section)
@ -414,17 +416,17 @@ QVariant RsFriendListModel::textColorRole(const EntryIndex& fmpe,int column) con
} }
} }
QVariant RsFriendListModel::statusRole(const EntryIndex& fmpe,int column) const QVariant RsFriendListModel::statusRole(const EntryIndex& /*fmpe*/,int /*column*/) const
{ {
return QVariant();//fmpe.mMsgStatus); return QVariant();//fmpe.mMsgStatus);
} }
bool RsFriendListModel::passesFilter(const EntryIndex& e,int column) const bool RsFriendListModel::passesFilter(const EntryIndex& e,int /*column*/) const
{ {
QString s ; QString s ;
bool passes_strings = true ; bool passes_strings = true ;
if(e.type == ENTRY_TYPE_PROFILE && !mFilterStrings.empty()) if(e.type == ENTRY_TYPE_PROFILE && !mFilterStrings.empty())
{ {
switch(mFilterType) switch(mFilterType)
{ {
@ -435,6 +437,8 @@ bool RsFriendListModel::passesFilter(const EntryIndex& e,int column) const
if(s.isNull()) if(s.isNull())
passes_strings = false; passes_strings = false;
break; break;
case FILTER_TYPE_NONE:
RS_ERR("None Type for Filter.");
}; };
} }
@ -447,18 +451,15 @@ bool RsFriendListModel::passesFilter(const EntryIndex& e,int column) const
QVariant RsFriendListModel::filterRole(const EntryIndex& e,int column) const QVariant RsFriendListModel::filterRole(const EntryIndex& e,int column) const
{ {
if(passesFilter(e,column)) if(passesFilter(e,column))
return QVariant(FilterString); return QVariant(FilterString);
return QVariant(QString()); return QVariant(QString());
} }
uint32_t RsFriendListModel::updateFilterStatus(ForumModelIndex i,int column,const QStringList& strings) uint32_t RsFriendListModel::updateFilterStatus(ForumModelIndex /*i*/,int /*column*/,const QStringList& /*strings*/)
{ {
QString s ; return 0;
uint32_t count = 0;
return count;
} }
@ -479,7 +480,7 @@ void RsFriendListModel::setFilter(FilterType filter_type, const QStringList& str
postMods(); postMods();
} }
QVariant RsFriendListModel::toolTipRole(const EntryIndex& fmpe,int column) const QVariant RsFriendListModel::toolTipRole(const EntryIndex& /*fmpe*/,int /*column*/) const
{ {
return QVariant(); return QVariant();
} }
@ -489,14 +490,14 @@ QVariant RsFriendListModel::sizeHintRole(const EntryIndex& e,int col) const
float x_factor = QFontMetricsF(QApplication::font()).height()/14.0f ; float x_factor = QFontMetricsF(QApplication::font()).height()/14.0f ;
float y_factor = QFontMetricsF(QApplication::font()).height()/14.0f ; float y_factor = QFontMetricsF(QApplication::font()).height()/14.0f ;
if(e.type == ENTRY_TYPE_NODE) if(e.type == ENTRY_TYPE_NODE)
y_factor *= 3.0; y_factor *= 3.0;
if((e.type == ENTRY_TYPE_PROFILE) && !isProfileExpanded(e)) if((e.type == ENTRY_TYPE_PROFILE) && !isProfileExpanded(e))
y_factor *= 3.0; y_factor *= 3.0;
if(e.type == ENTRY_TYPE_GROUP) if(e.type == ENTRY_TYPE_GROUP)
y_factor = std::max(y_factor, 24.0f / 14.0f ); // allows to fit the 24 pixels icon for groups in the line y_factor = std::max(y_factor, 24.0f / 14.0f ); // allows to fit the 24 pixels icon for groups in the line
switch(col) switch(col)
{ {
@ -542,7 +543,7 @@ QVariant RsFriendListModel::sortRole(const EntryIndex& entry,int column) const
} }
} }
QVariant RsFriendListModel::onlineRole(const EntryIndex& e, int col) const QVariant RsFriendListModel::onlineRole(const EntryIndex& e, int /*col*/) const
{ {
switch(e.type) switch(e.type)
{ {
@ -698,7 +699,7 @@ QVariant RsFriendListModel::displayRole(const EntryIndex& e, int col) const
if(col == COLUMN_THREAD_IP) return QVariant(most_recent_ip); if(col == COLUMN_THREAD_IP) return QVariant(most_recent_ip);
} }
} }// Fall-through
default: default:
return QVariant(); return QVariant();
} }
@ -826,7 +827,6 @@ const RsFriendListModel::HierarchicalNodeInformation *RsFriendListModel::getNode
if(e.node_index >= mProfiles[pindex].child_node_indices.size()) if(e.node_index >= mProfiles[pindex].child_node_indices.size())
return NULL ; return NULL ;
time_t now = time(NULL);
HierarchicalNodeInformation& node(mLocations[mProfiles[pindex].child_node_indices[e.node_index]]); HierarchicalNodeInformation& node(mLocations[mProfiles[pindex].child_node_indices[e.node_index]]);
return &node; return &node;
@ -895,8 +895,6 @@ void RsFriendListModel::clear()
emit friendListChanged(); emit friendListChanged();
} }
static bool decreasing_time_comp(const std::pair<time_t,RsGxsMessageId>& e1,const std::pair<time_t,RsGxsMessageId>& e2) { return e2.first < e1.first ; }
void RsFriendListModel::debug_dump() const void RsFriendListModel::debug_dump() const
{ {
std::cerr << "==== FriendListModel Debug dump ====" << std::endl; std::cerr << "==== FriendListModel Debug dump ====" << std::endl;
@ -1084,14 +1082,14 @@ void RsFriendListModel::updateInternalData()
{ {
preMods(); preMods();
beginRemoveRows(QModelIndex(),0,mTopLevel.size()-1); beginResetModel();
mGroups.clear(); mGroups.clear();
mProfiles.clear(); mProfiles.clear();
mLocations.clear(); mLocations.clear();
mTopLevel.clear(); mTopLevel.clear();
endRemoveRows(); endResetModel();
auto TL = mTopLevel ; // This allows to fill TL without touching mTopLevel outside of [begin/end]InsertRows(). auto TL = mTopLevel ; // This allows to fill TL without touching mTopLevel outside of [begin/end]InsertRows().
@ -1218,17 +1216,19 @@ void RsFriendListModel::updateInternalData()
TL.push_back(e); TL.push_back(e);
} }
// finally, tell the model client that layout has changed. // finally, tell the model client that layout has changed.
beginInsertRows(QModelIndex(),0,TL.size()-1); mTopLevel = TL;
mTopLevel = TL; if (TL.size()>0)
{
beginInsertRows(QModelIndex(),0,TL.size()-1);
endInsertRows();
}
endInsertRows(); postMods();
postMods(); mLastInternalDataUpdate = time(NULL);
mLastInternalDataUpdate = time(NULL);
} }
QModelIndex RsFriendListModel::getIndexOfGroup(const RsNodeGroupId& mid) const QModelIndex RsFriendListModel::getIndexOfGroup(const RsNodeGroupId& mid) const
@ -1251,7 +1251,7 @@ void RsFriendListModel::collapseItem(const QModelIndex& index)
if(!convertInternalIdToIndex<sizeof(uintptr_t)>(index.internalId(),entry)) if(!convertInternalIdToIndex<sizeof(uintptr_t)>(index.internalId(),entry))
return; return;
const HierarchicalProfileInformation *hp = getProfileInfo(entry); const HierarchicalProfileInformation *hp = getProfileInfo(entry);
const HierarchicalGroupInformation *hg = getGroupInfo(entry); const HierarchicalGroupInformation *hg = getGroupInfo(entry);
std::string s ; std::string s ;
@ -1276,7 +1276,7 @@ void RsFriendListModel::expandItem(const QModelIndex& index)
if(!convertInternalIdToIndex<sizeof(uintptr_t)>(index.internalId(),entry)) if(!convertInternalIdToIndex<sizeof(uintptr_t)>(index.internalId(),entry))
return; return;
const HierarchicalProfileInformation *hp = getProfileInfo(entry); const HierarchicalProfileInformation *hp = getProfileInfo(entry);
const HierarchicalGroupInformation *hg = getGroupInfo(entry); const HierarchicalGroupInformation *hg = getGroupInfo(entry);
std::string s ; std::string s ;

View File

@ -202,7 +202,7 @@ void RSElidedItemDelegate::paint(QPainter *painter, const QStyleOptionViewItem &
moOption.decorationPosition = QStyleOptionViewItem::Left; moOption.decorationPosition = QStyleOptionViewItem::Left;
moOption.decorationSize = QSize(); moOption.decorationSize = QSize();
moOption.displayAlignment = Qt::AlignLeft | Qt::AlignTop; moOption.displayAlignment = Qt::AlignLeft | Qt::AlignTop;
moOption.features=0; moOption.features=QStyleOptionViewItem::ViewItemFeatures();
moOption.font = QFont(); moOption.font = QFont();
moOption.icon = QIcon(); moOption.icon = QIcon();
moOption.index = QModelIndex(); moOption.index = QModelIndex();
@ -217,7 +217,8 @@ void RSElidedItemDelegate::paint(QPainter *painter, const QStyleOptionViewItem &
moOption.palette = QPalette(); moOption.palette = QPalette();
moOption.styleObject = nullptr; moOption.styleObject = nullptr;
} }
QStyledItemDelegate::paint(&moPnt, moOption, QModelIndex()); //QStyledItemDelegate::paint(&moPnt, moOption, QModelIndex(index));//This update option now.
ownStyle->drawControl(QStyle::CE_ItemViewItem, &moOption, &moPnt, widget);
//// But these lines doesn't works. //// But these lines doesn't works.
{ {
@ -300,9 +301,9 @@ void RSElidedItemDelegate::paint(QPainter *painter, const QStyleOptionViewItem &
{ {
QStyleOptionViewItem tstOption = option; QStyleOptionViewItem tstOption = option;
// Reduce rect to get this item bg color external and base internal // Reduce rect to get this item bg color external and base internal
tstOption.rect.adjust(3,3,-6,-6); tstOption.rect.adjust(2,2,-2,-2);
// To draw with base for debug purpose // To draw with base for debug purpose
QStyledItemDelegate::paint(painter, tstOption, index); RSStyledItemDelegate::paint(painter, tstOption, index);
} }
#endif #endif
@ -379,6 +380,10 @@ void RSElidedItemDelegate::paint(QPainter *painter, const QStyleOptionViewItem &
QTextLayout textLayout(ownOption.text, painter->font()); QTextLayout textLayout(ownOption.text, painter->font());
QTextOption to = textLayout.textOption(); QTextOption to = textLayout.textOption();
const int textHMargin = ownStyle->pixelMetric(QStyle::PM_FocusFrameHMargin, nullptr, widget) + 1;
const int textVMargin = ownStyle->pixelMetric(QStyle::PM_FocusFrameVMargin, nullptr, widget) + 1;
textRect = textRect.adjusted(textHMargin, textVMargin, -textHMargin, -textVMargin); // remove width padding
StyledElidedLabel::paintElidedLine(painter,ownOption.text,textRect,ownOption.font,ownOption.displayAlignment,to.wrapMode()&QTextOption::WordWrap,mPaintRoundedRect); StyledElidedLabel::paintElidedLine(painter,ownOption.text,textRect,ownOption.font,ownOption.displayAlignment,to.wrapMode()&QTextOption::WordWrap,mPaintRoundedRect);
} }
painter->restore(); painter->restore();
@ -393,7 +398,9 @@ bool RSElidedItemDelegate::editorEvent(QEvent *event, QAbstractItemModel *model,
QMouseEvent *ev = static_cast<QMouseEvent *>(event); QMouseEvent *ev = static_cast<QMouseEvent *>(event);
if (ev) { if (ev) {
if (ev->buttons()==Qt::LeftButton) { if (ev->buttons()==Qt::LeftButton) {
#ifdef DEBUG_EID_PAINT
QVariant var = index.data(); QVariant var = index.data();
#endif
if (index.data().type() == QVariant::String) { if (index.data().type() == QVariant::String) {
QString text = index.data().toString(); QString text = index.data().toString();
if (!text.isEmpty()) { if (!text.isEmpty()) {
@ -417,6 +424,9 @@ bool RSElidedItemDelegate::editorEvent(QEvent *event, QAbstractItemModel *model,
ownOption.fontMetrics = QFontMetrics(font); ownOption.fontMetrics = QFontMetrics(font);
} }
QRect textRect = ownStyle->subElementRect(QStyle::SE_ItemViewItemText, &ownOption, widget); QRect textRect = ownStyle->subElementRect(QStyle::SE_ItemViewItemText, &ownOption, widget);
const int textHMargin = ownStyle->pixelMetric(QStyle::PM_FocusFrameHMargin, nullptr, widget) + 1;
const int textVMargin = ownStyle->pixelMetric(QStyle::PM_FocusFrameVMargin, nullptr, widget) + 1;
textRect = textRect.adjusted(textHMargin, textVMargin, -textHMargin, -textVMargin); // remove width padding
QTextLayout textLayout(text, ownOption.font); QTextLayout textLayout(text, ownOption.font);
QTextOption to = textLayout.textOption(); QTextOption to = textLayout.textOption();

View File

@ -345,7 +345,11 @@ void RSGraphWidget::paintEvent(QPaintEvent *)
_painter->setRenderHint(QPainter::TextAntialiasing); _painter->setRenderHint(QPainter::TextAntialiasing);
/* Fill in the background */ /* Fill in the background */
_painter->fillRect(_rec, QBrush(BACK_COLOR)); if (_flags & RSGRAPH_FLAGS_DARK_STYLE){
_painter->fillRect(_rec, QBrush(BACK_COLOR_DARK));
}else {
_painter->fillRect(_rec, QBrush(BACK_COLOR));
}
_painter->drawRect(_rec); _painter->drawRect(_rec);
/* Paint the scale */ /* Paint the scale */
@ -649,10 +653,17 @@ void RSGraphWidget::paintScale1()
QString text = _source->displayValue(scale) ; QString text = _source->displayValue(scale) ;
_painter->setPen(SCALE_COLOR); if (_flags & RSGRAPH_FLAGS_DARK_STYLE){
_painter->drawText(QPointF(SCALE_WIDTH*fact - QFontMetricsF(font()).width(text) - 4*fact, pos+0.4*FS), text); _painter->setPen(SCALE_COLOR_DARK);
_painter->setPen(GRID_COLOR); _painter->drawText(QPointF(SCALE_WIDTH*fact - QFontMetricsF(font()).width(text) - 4*fact, pos+0.4*FS), text);
_painter->drawLine(QPointF(SCALE_WIDTH*fact, pos), QPointF(_rec.width(), pos)); _painter->setPen(GRID_COLOR_DARK);
_painter->drawLine(QPointF(SCALE_WIDTH*fact, pos), QPointF(_rec.width(), pos));
}else{
_painter->setPen(SCALE_COLOR);
_painter->drawText(QPointF(SCALE_WIDTH*fact - QFontMetricsF(font()).width(text) - 4*fact, pos+0.4*FS), text);
_painter->setPen(GRID_COLOR);
_painter->drawLine(QPointF(SCALE_WIDTH*fact, pos), QPointF(_rec.width(), pos));
}
} }
/* Draw vertical separator */ /* Draw vertical separator */
@ -675,8 +686,10 @@ void RSGraphWidget::paintScale2()
int seconds = (_rec.width()-i)/_time_scale ; // pixels / (pixels per second) => seconds int seconds = (_rec.width()-i)/_time_scale ; // pixels / (pixels per second) => seconds
QString text = QString::number(seconds)+ " secs"; QString text = QString::number(seconds)+ " secs";
if (_flags & RSGRAPH_FLAGS_DARK_STYLE)
_painter->setPen(SCALE_COLOR); _painter->setPen(SCALE_COLOR_DARK);
else
_painter->setPen(SCALE_COLOR);
_painter->drawText(QPointF(i, _rec.height()-0.5*FS), text); _painter->drawText(QPointF(i, _rec.height()-0.5*FS), text);
} }
} }
@ -743,8 +756,10 @@ void RSGraphWidget::paintLegend()
_painter->setPen(pen); _painter->setPen(pen);
_painter->drawLine(QPointF(SCALE_WIDTH*fact+10.0*fact, pos+FS/3), QPointF(SCALE_WIDTH*fact+30.0*fact, pos+FS/3)); _painter->drawLine(QPointF(SCALE_WIDTH*fact+10.0*fact, pos+FS/3), QPointF(SCALE_WIDTH*fact+30.0*fact, pos+FS/3));
_painter->setPen(oldPen); _painter->setPen(oldPen);
if (_flags & RSGRAPH_FLAGS_DARK_STYLE)
_painter->setPen(SCALE_COLOR); _painter->setPen(SCALE_COLOR_DARK);
else
_painter->setPen(SCALE_COLOR);
_painter->drawText(QPointF(SCALE_WIDTH *fact+ 40*fact,pos + 0.5*FS), text) ; _painter->drawText(QPointF(SCALE_WIDTH *fact+ 40*fact,pos + 0.5*FS), text) ;
++j ; ++j ;

View File

@ -36,11 +36,14 @@
#define MINUSER_SCALE 2000 /** 2000 users is the minimum scale */ #define MINUSER_SCALE 2000 /** 2000 users is the minimum scale */
#define SCROLL_STEP 4 /** Horizontal change on graph update */ #define SCROLL_STEP 4 /** Horizontal change on graph update */
#define BACK_COLOR Qt::white #define BACK_COLOR Qt::white
#define SCALE_COLOR Qt::black #define SCALE_COLOR Qt::black
#define GRID_COLOR Qt::lightGray #define GRID_COLOR Qt::lightGray
#define RSDHT_COLOR Qt::magenta #define BACK_COLOR_DARK Qt::black
#define ALLDHT_COLOR Qt::yellow #define SCALE_COLOR_DARK Qt::green
#define GRID_COLOR_DARK Qt::darkGreen
#define RSDHT_COLOR Qt::magenta
#define ALLDHT_COLOR Qt::yellow
struct ZeroInitFloat struct ZeroInitFloat
{ {
@ -145,6 +148,7 @@ public:
static const uint32_t RSGRAPH_FLAGS_LEGEND_CUMULATED = 0x0040 ;// show the total in the legend rather than current values static const uint32_t RSGRAPH_FLAGS_LEGEND_CUMULATED = 0x0040 ;// show the total in the legend rather than current values
static const uint32_t RSGRAPH_FLAGS_PAINT_STYLE_DOTS = 0x0080 ;// use dots static const uint32_t RSGRAPH_FLAGS_PAINT_STYLE_DOTS = 0x0080 ;// use dots
static const uint32_t RSGRAPH_FLAGS_LEGEND_INTEGER = 0x0100 ;// use integer number in the legend, and move the lines to match integers static const uint32_t RSGRAPH_FLAGS_LEGEND_INTEGER = 0x0100 ;// use integer number in the legend, and move the lines to match integers
static const uint32_t RSGRAPH_FLAGS_DARK_STYLE = 0x0200 ;// darkstyle graph
/** Bandwidth graph style. */ /** Bandwidth graph style. */
enum GraphStyle enum GraphStyle

View File

@ -37,7 +37,9 @@
Q_DECLARE_METATYPE(ChannelPostFileInfo) Q_DECLARE_METATYPE(ChannelPostFileInfo)
#ifdef DEBUG_CHANNEL_MODEL
static std::ostream& operator<<(std::ostream& o, const QModelIndex& i);// defined elsewhere static std::ostream& operator<<(std::ostream& o, const QModelIndex& i);// defined elsewhere
#endif
RsGxsChannelPostFilesModel::RsGxsChannelPostFilesModel(QObject *parent) RsGxsChannelPostFilesModel::RsGxsChannelPostFilesModel(QObject *parent)
: QAbstractItemModel(parent) : QAbstractItemModel(parent)
@ -50,45 +52,43 @@ RsGxsChannelPostFilesModel::RsGxsChannelPostFilesModel(QObject *parent)
void RsGxsChannelPostFilesModel::initEmptyHierarchy() void RsGxsChannelPostFilesModel::initEmptyHierarchy()
{ {
preMods(); beginResetModel();
mFiles.clear(); mFiles.clear();
mFilteredFiles.clear(); mFilteredFiles.clear();
postMods(); endResetModel();
} }
void RsGxsChannelPostFilesModel::preMods() void RsGxsChannelPostFilesModel::preMods()
{ {
//emit layoutAboutToBeChanged(); //Generate SIGSEGV when click on button move next/prev. emit layoutAboutToBeChanged();
beginResetModel();
} }
void RsGxsChannelPostFilesModel::postMods() void RsGxsChannelPostFilesModel::postMods()
{ {
endResetModel(); emit QAbstractItemModel::dataChanged(createIndex(0,0,(void*)NULL), createIndex(mFilteredFiles.size(),COLUMN_FILES_NB_COLUMNS-1,(void*)NULL));
emit layoutChanged();
emit dataChanged(createIndex(0,0,(void*)NULL), createIndex(mFilteredFiles.size(),COLUMN_FILES_NB_COLUMNS-1,(void*)NULL));
} }
void RsGxsChannelPostFilesModel::update() void RsGxsChannelPostFilesModel::update()
{ {
emit dataChanged(createIndex(0,0,(void*)NULL), createIndex(mFilteredFiles.size(),COLUMN_FILES_NB_COLUMNS-1,(void*)NULL)); preMods();
postMods();
} }
int RsGxsChannelPostFilesModel::rowCount(const QModelIndex& parent) const int RsGxsChannelPostFilesModel::rowCount(const QModelIndex& parent) const
{ {
if(parent.column() > 0) if(parent.column() > 0)
return 0; return 0;
if(mFilteredFiles.empty()) // security. Should never happen. if(mFilteredFiles.empty()) // security. Should never happen.
return 0; return 0;
if(!parent.isValid()) if(!parent.isValid())
return mFilteredFiles.size(); // mFilteredPosts always has an item at 0, so size()>=1, and mColumn>=1 return mFilteredFiles.size(); // mFilteredPosts always has an item at 0, so size()>=1, and mColumn>=1
RsErr() << __PRETTY_FUNCTION__ << " rowCount cannot figure out the porper number of rows." << std::endl; RS_ERR(" rowCount cannot figure out the proper number of rows.");
return 0; return 0;
} }
int RsGxsChannelPostFilesModel::columnCount(const QModelIndex &/*parent*/) const int RsGxsChannelPostFilesModel::columnCount(const QModelIndex &/*parent*/) const
@ -99,15 +99,15 @@ int RsGxsChannelPostFilesModel::columnCount(const QModelIndex &/*parent*/) const
bool RsGxsChannelPostFilesModel::getFileData(const QModelIndex& i,ChannelPostFileInfo& fmpe) const bool RsGxsChannelPostFilesModel::getFileData(const QModelIndex& i,ChannelPostFileInfo& fmpe) const
{ {
if(!i.isValid()) if(!i.isValid())
return true; return true;
quintptr ref = i.internalId(); quintptr ref = i.internalId();
uint32_t entry = 0; uint32_t entry = 0;
if(!convertRefPointerToTabEntry(ref,entry) || entry >= mFiles.size()) if(!convertRefPointerToTabEntry(ref,entry) || entry >= mFiles.size())
return false ; return false ;
fmpe = mFiles[mFilteredFiles[entry]]; fmpe = mFiles[mFilteredFiles[entry]];
return true; return true;
@ -115,8 +115,8 @@ bool RsGxsChannelPostFilesModel::getFileData(const QModelIndex& i,ChannelPostFil
bool RsGxsChannelPostFilesModel::hasChildren(const QModelIndex &parent) const bool RsGxsChannelPostFilesModel::hasChildren(const QModelIndex &parent) const
{ {
if(!parent.isValid()) if(!parent.isValid())
return true; return true;
return false; // by default, no channel post has children return false; // by default, no channel post has children
} }
@ -167,22 +167,19 @@ QModelIndex RsGxsChannelPostFilesModel::index(int row, int column, const QModelI
return createIndex(row,column,ref) ; return createIndex(row,column,ref) ;
} }
QModelIndex RsGxsChannelPostFilesModel::parent(const QModelIndex& index) const QModelIndex RsGxsChannelPostFilesModel::parent(const QModelIndex& /*index*/) const
{ {
if(!index.isValid())
return QModelIndex();
return QModelIndex(); // there's no hierarchy here. So nothing to do! return QModelIndex(); // there's no hierarchy here. So nothing to do!
} }
Qt::ItemFlags RsGxsChannelPostFilesModel::flags(const QModelIndex& index) const Qt::ItemFlags RsGxsChannelPostFilesModel::flags(const QModelIndex& index) const
{ {
if (!index.isValid()) if (!index.isValid())
return 0; return Qt::ItemFlag();
if(index.column() == COLUMN_FILES_FILE) if(index.column() == COLUMN_FILES_FILE)
return QAbstractItemModel::flags(index) | Qt::ItemIsEditable; return QAbstractItemModel::flags(index) | Qt::ItemIsEditable;
else else
return QAbstractItemModel::flags(index); return QAbstractItemModel::flags(index);
} }
@ -191,7 +188,7 @@ quintptr RsGxsChannelPostFilesModel::getChildRef(quintptr ref,int index) const
if (index < 0) if (index < 0)
return 0; return 0;
if(ref == quintptr(0)) if(ref == quintptr(0))
{ {
quintptr new_ref; quintptr new_ref;
convertTabEntryToRefPointer(index,new_ref); convertTabEntryToRefPointer(index,new_ref);
@ -221,15 +218,13 @@ quintptr RsGxsChannelPostFilesModel::getParentRow(quintptr ref,int& row) const
int RsGxsChannelPostFilesModel::getChildrenCount(quintptr ref) const int RsGxsChannelPostFilesModel::getChildrenCount(quintptr ref) const
{ {
uint32_t entry = 0 ; if(ref == quintptr(0))
return rowCount()-1;
if(ref == quintptr(0))
return rowCount()-1;
return 0; return 0;
} }
QVariant RsGxsChannelPostFilesModel::headerData(int section, Qt::Orientation orientation, int role) const QVariant RsGxsChannelPostFilesModel::headerData(int section, Qt::Orientation /*orientation*/, int role) const
{ {
if (role != Qt::DisplayRole) if (role != Qt::DisplayRole)
return QVariant(); return QVariant();
@ -298,39 +293,37 @@ QVariant RsGxsChannelPostFilesModel::data(const QModelIndex &index, int role) co
void RsGxsChannelPostFilesModel::setFilter(const QStringList& strings, uint32_t& count) void RsGxsChannelPostFilesModel::setFilter(const QStringList& strings, uint32_t& count)
{ {
preMods(); preMods();
beginRemoveRows(QModelIndex(),0,rowCount()-1); initEmptyHierarchy();
endRemoveRows();
if(strings.empty()) if(strings.empty())
{ {
mFilteredFiles.clear(); for(uint32_t i=0;i<mFiles.size();++i)
for(uint32_t i=0;i<mFiles.size();++i) mFilteredFiles.push_back(i);
mFilteredFiles.push_back(i); }
}
else else
{ {
mFilteredFiles.clear(); for(uint32_t i=0;i<mFiles.size();++i)
//mFilteredPosts.push_back(0); {
bool passes_strings = true;
for(uint32_t i=0;i<mFiles.size();++i)
{
bool passes_strings = true;
for(auto& s:strings) for(auto& s:strings)
passes_strings = passes_strings && QString::fromStdString(mFiles[i].mName).contains(s,Qt::CaseInsensitive); passes_strings = passes_strings && QString::fromStdString(mFiles[i].mName).contains(s,Qt::CaseInsensitive);
if(passes_strings) if(passes_strings)
mFilteredFiles.push_back(i); mFilteredFiles.push_back(i);
} }
} }
count = mFilteredFiles.size(); count = mFilteredFiles.size();
std::cerr << "After filtering: " << count << " posts remain." << std::endl; std::cerr << "After filtering: " << count << " posts remain." << std::endl;
beginInsertRows(QModelIndex(),0,rowCount()-1); if (rowCount()>0)
endInsertRows(); {
beginInsertRows(QModelIndex(),0,rowCount()-1);
endInsertRows();
}
postMods(); postMods();
} }
@ -372,7 +365,7 @@ void RsGxsChannelPostFilesModel::sort(int column, Qt::SortOrder order)
update(); update();
} }
QVariant RsGxsChannelPostFilesModel::sizeHintRole(int col) const QVariant RsGxsChannelPostFilesModel::sizeHintRole(int /*col*/) const
{ {
float factor = QFontMetricsF(QApplication::font()).height()/14.0f ; float factor = QFontMetricsF(QApplication::font()).height()/14.0f ;
@ -435,42 +428,40 @@ QVariant RsGxsChannelPostFilesModel::userRole(const ChannelPostFileInfo& fmpe,in
void RsGxsChannelPostFilesModel::clear() void RsGxsChannelPostFilesModel::clear()
{ {
preMods();
initEmptyHierarchy(); initEmptyHierarchy();
postMods();
emit channelLoaded(); emit channelLoaded();
} }
void RsGxsChannelPostFilesModel::setFiles(const std::list<ChannelPostFileInfo> &files) void RsGxsChannelPostFilesModel::setFiles(const std::list<ChannelPostFileInfo> &files)
{ {
preMods(); preMods();
beginRemoveRows(QModelIndex(),0,mFilteredFiles.size()-1); initEmptyHierarchy();
endRemoveRows();
initEmptyHierarchy(); for(auto& file:files)
mFiles.push_back(file);
for(auto& file:files) for(uint32_t i=0;i<mFiles.size();++i)
mFiles.push_back(file); mFilteredFiles.push_back(i);
for(uint32_t i=0;i<mFiles.size();++i)
mFilteredFiles.push_back(i);
#ifdef DEBUG_CHANNEL_MODEL #ifdef DEBUG_CHANNEL_MODEL
// debug_dump(); // debug_dump();
#endif #endif
beginInsertRows(QModelIndex(),0,mFilteredFiles.size()-1); if (mFilteredFiles.size()>0)
endInsertRows(); {
beginInsertRows(QModelIndex(),0,mFilteredFiles.size()-1);
postMods(); endInsertRows();
}
emit channelLoaded(); emit channelLoaded();
if(!files.empty()) if(!files.empty())
mTimer->start(5000); mTimer->start(5000);
else else
mTimer->stop(); mTimer->stop();
postMods();
} }

View File

@ -203,23 +203,22 @@ void RsGxsChannelPostsModel::handleEvent_main_thread(std::shared_ptr<const RsEve
void RsGxsChannelPostsModel::initEmptyHierarchy() void RsGxsChannelPostsModel::initEmptyHierarchy()
{ {
preMods(); beginResetModel();
mPosts.clear(); mPosts.clear();
mFilteredPosts.clear(); mFilteredPosts.clear();
postMods(); endResetModel();
} }
void RsGxsChannelPostsModel::preMods() void RsGxsChannelPostsModel::preMods()
{ {
beginResetModel(); emit layoutAboutToBeChanged();
} }
void RsGxsChannelPostsModel::postMods() void RsGxsChannelPostsModel::postMods()
{ {
endResetModel(); triggerViewUpdate();
emit layoutChanged();
triggerViewUpdate();
} }
void RsGxsChannelPostsModel::triggerViewUpdate() void RsGxsChannelPostsModel::triggerViewUpdate()
{ {
@ -244,13 +243,13 @@ void RsGxsChannelPostsModel::getFilesList(std::list<ChannelPostFileInfo>& files)
void RsGxsChannelPostsModel::setFilter(const QStringList& strings,bool only_unread, uint32_t& count) void RsGxsChannelPostsModel::setFilter(const QStringList& strings,bool only_unread, uint32_t& count)
{ {
preMods(); preMods();
beginRemoveRows(QModelIndex(),0,rowCount()-1); beginResetModel();
endRemoveRows();
mFilteredPosts.clear(); mFilteredPosts.clear();
//mFilteredPosts.push_back(0); //mFilteredPosts.push_back(0);
endResetModel();
for(size_t i=0;i<mPosts.size();++i) for(size_t i=0;i<mPosts.size();++i)
{ {
@ -268,8 +267,11 @@ void RsGxsChannelPostsModel::setFilter(const QStringList& strings,bool only_unre
count = mFilteredPosts.size(); count = mFilteredPosts.size();
beginInsertRows(QModelIndex(),0,rowCount()-1); if (rowCount()>0)
endInsertRows(); {
beginInsertRows(QModelIndex(),0,rowCount()-1);
endInsertRows();
}
postMods(); postMods();
} }
@ -321,8 +323,8 @@ bool RsGxsChannelPostsModel::getPostData(const QModelIndex& i,RsGxsChannelPost&
bool RsGxsChannelPostsModel::hasChildren(const QModelIndex &parent) const bool RsGxsChannelPostsModel::hasChildren(const QModelIndex &parent) const
{ {
if(!parent.isValid()) if(!parent.isValid())
return true; return true;
return false; // by default, no channel post has children return false; // by default, no channel post has children
} }
@ -374,45 +376,45 @@ QModelIndex RsGxsChannelPostsModel::index(int row, int column, const QModelIndex
return createIndex(row,column,ref) ; return createIndex(row,column,ref) ;
} }
QModelIndex RsGxsChannelPostsModel::parent(const QModelIndex& index) const QModelIndex RsGxsChannelPostsModel::parent(const QModelIndex& /*index*/) const
{ {
if(!index.isValid())
return QModelIndex();
return QModelIndex(); // there's no hierarchy here. So nothing to do! return QModelIndex(); // there's no hierarchy here. So nothing to do!
} }
Qt::ItemFlags RsGxsChannelPostsModel::flags(const QModelIndex& index) const Qt::ItemFlags RsGxsChannelPostsModel::flags(const QModelIndex& index) const
{ {
if (!index.isValid()) if (!index.isValid())
return 0; return Qt::ItemFlags();
return QAbstractItemModel::flags(index); return QAbstractItemModel::flags(index);
} }
bool RsGxsChannelPostsModel::setNumColumns(int n) bool RsGxsChannelPostsModel::setNumColumns(int n)
{ {
if(n < 1) if(n < 1)
{ {
RsErr() << __PRETTY_FUNCTION__ << " Attempt to set a number of column of 0. This is wrong." << std::endl; RsErr() << __PRETTY_FUNCTION__ << " Attempt to set a number of column of 0. This is wrong." << std::endl;
return false; return false;
} }
if((int)mColumns == n) if((int)mColumns == n)
return false; return false;
preMods(); preMods();
beginRemoveRows(QModelIndex(),0,rowCount()-1); beginResetModel();
endRemoveRows(); endResetModel();
mColumns = n; mColumns = n;
beginInsertRows(QModelIndex(),0,rowCount()-1); if (rowCount()>0)
endInsertRows(); {
beginInsertRows(QModelIndex(),0,rowCount()-1);
endInsertRows();
}
postMods(); postMods();
return true; return true;
} }
quintptr RsGxsChannelPostsModel::getChildRef(quintptr ref,int index) const quintptr RsGxsChannelPostsModel::getChildRef(quintptr ref,int index) const
@ -450,8 +452,8 @@ quintptr RsGxsChannelPostsModel::getParentRow(quintptr ref,int& row) const
int RsGxsChannelPostsModel::getChildrenCount(quintptr ref) const int RsGxsChannelPostsModel::getChildrenCount(quintptr ref) const
{ {
if(ref == quintptr(0)) if(ref == quintptr(0))
return rowCount()-1; return rowCount()-1;
return 0; return 0;
} }
@ -549,10 +551,9 @@ void RsGxsChannelPostsModel::updateChannel(const RsGxsGroupId& channel_group_id)
void RsGxsChannelPostsModel::clear() void RsGxsChannelPostsModel::clear()
{ {
preMods(); preMods();
mPosts.clear(); initEmptyHierarchy();
initEmptyHierarchy();
postMods(); postMods();
emit channelPostsLoaded(); emit channelPostsLoaded();
@ -565,28 +566,27 @@ bool operator<(const RsGxsChannelPost& p1,const RsGxsChannelPost& p2)
void RsGxsChannelPostsModel::setPosts(const RsGxsChannelGroup& group, std::vector<RsGxsChannelPost>& posts) void RsGxsChannelPostsModel::setPosts(const RsGxsChannelGroup& group, std::vector<RsGxsChannelPost>& posts)
{ {
preMods(); preMods();
beginRemoveRows(QModelIndex(),0,rowCount()-1); initEmptyHierarchy();
endRemoveRows(); mChannelGroup = group;
mPosts.clear(); createPostsArray(posts);
mChannelGroup = group;
createPostsArray(posts); std::sort(mPosts.begin(),mPosts.end());
std::sort(mPosts.begin(),mPosts.end()); for(uint32_t i=0;i<mPosts.size();++i)
mFilteredPosts.push_back(i);
mFilteredPosts.clear();
for(uint32_t i=0;i<mPosts.size();++i)
mFilteredPosts.push_back(i);
#ifdef DEBUG_CHANNEL_MODEL #ifdef DEBUG_CHANNEL_MODEL
// debug_dump(); // debug_dump();
#endif #endif
beginInsertRows(QModelIndex(),0,rowCount()-1); if (rowCount()>0)
endInsertRows(); {
beginInsertRows(QModelIndex(),0,rowCount()-1);
endInsertRows();
}
postMods(); postMods();
@ -595,8 +595,8 @@ void RsGxsChannelPostsModel::setPosts(const RsGxsChannelGroup& group, std::vecto
void RsGxsChannelPostsModel::update_posts(const RsGxsGroupId& group_id) void RsGxsChannelPostsModel::update_posts(const RsGxsGroupId& group_id)
{ {
if(group_id.isNull()) if(group_id.isNull())
return; return;
RsThread::async([this, group_id]() RsThread::async([this, group_id]()
{ {

View File

@ -238,7 +238,7 @@ void ChannelPostDelegate::paint(QPainter * painter, const QStyleOptionViewItem &
info_text += ", " + QString::number(post.mAttachmentCount)+ " " +((post.mAttachmentCount>1)?tr("files"):tr("file")) + " (" + misc::friendlyUnit(qulonglong(post.mSize)) + ")" ; info_text += ", " + QString::number(post.mAttachmentCount)+ " " +((post.mAttachmentCount>1)?tr("files"):tr("file")) + " (" + misc::friendlyUnit(qulonglong(post.mSize)) + ")" ;
painter->drawText(QPoint(p.x()+0.5*font_height,y),info_text); painter->drawText(QPoint(p.x()+0.5*font_height,y),info_text);
y += font_height; //y += font_height;
painter->restore(); painter->restore();
} }
@ -400,21 +400,21 @@ GxsChannelPostsWidgetWithModel::GxsChannelPostsWidgetWithModel(const RsGxsGroupI
ui->channelPostFiles_TV->setItemDelegate(new ChannelPostFilesDelegate(this)); ui->channelPostFiles_TV->setItemDelegate(new ChannelPostFilesDelegate(this));
ui->channelPostFiles_TV->setPlaceholderText(tr("No files in this post, or no post selected")); ui->channelPostFiles_TV->setPlaceholderText(tr("No files in this post, or no post selected"));
ui->channelPostFiles_TV->setSortingEnabled(true); ui->channelPostFiles_TV->setSortingEnabled(true);
ui->channelPostFiles_TV->sortByColumn(3, Qt::AscendingOrder); // sort by time ui->channelPostFiles_TV->sortByColumn(RsGxsChannelPostFilesModel::COLUMN_FILES_DATE, Qt::DescendingOrder); // sort by time
ui->channelPostFiles_TV->setAlternatingRowColors(false); ui->channelPostFiles_TV->setAlternatingRowColors(false);
ui->channelFiles_TV->setModel(mChannelFilesModel = new RsGxsChannelPostFilesModel());
ui->channelFiles_TV->setItemDelegate(mFilesDelegate = new ChannelPostFilesDelegate(this));
ui->channelFiles_TV->setPlaceholderText(tr("No files in the channel, or no channel selected"));
ui->channelFiles_TV->setSortingEnabled(true);
ui->channelFiles_TV->sortByColumn(RsGxsChannelPostFilesModel::COLUMN_FILES_DATE, Qt::DescendingOrder); // sort by time
connect(ui->channelPostFiles_TV->header(),SIGNAL(sortIndicatorChanged(int,Qt::SortOrder)), this, SLOT(sortColumnPostFiles(int,Qt::SortOrder))); connect(ui->channelPostFiles_TV->header(),SIGNAL(sortIndicatorChanged(int,Qt::SortOrder)), this, SLOT(sortColumnPostFiles(int,Qt::SortOrder)));
connect(ui->channelFiles_TV->header(),SIGNAL(sortIndicatorChanged(int,Qt::SortOrder)), this, SLOT(sortColumnFiles(int,Qt::SortOrder))); connect(ui->channelFiles_TV->header(),SIGNAL(sortIndicatorChanged(int,Qt::SortOrder)), this, SLOT(sortColumnFiles(int,Qt::SortOrder)));
connect(ui->channelPostFiles_TV,SIGNAL(customContextMenuRequested(QPoint)), this, SLOT(showChannelFilesContextMenu(QPoint))); connect(ui->channelPostFiles_TV,SIGNAL(customContextMenuRequested(QPoint)), this, SLOT(showChannelFilesContextMenu(QPoint)));
connect(ui->channelFiles_TV,SIGNAL(customContextMenuRequested(QPoint)), this, SLOT(showChannelFilesContextMenu(QPoint))); connect(ui->channelFiles_TV,SIGNAL(customContextMenuRequested(QPoint)), this, SLOT(showChannelFilesContextMenu(QPoint)));
ui->channelFiles_TV->setModel(mChannelFilesModel = new RsGxsChannelPostFilesModel());
ui->channelFiles_TV->setItemDelegate(mFilesDelegate = new ChannelPostFilesDelegate(this));
ui->channelFiles_TV->setPlaceholderText(tr("No files in the channel, or no channel selected"));
ui->channelFiles_TV->setSortingEnabled(true);
ui->channelFiles_TV->sortByColumn(3, Qt::AscendingOrder); // sort by time
connect(ui->postsTree->selectionModel(),SIGNAL(selectionChanged(const QItemSelection&,const QItemSelection&)),this,SLOT(showPostDetails())); connect(ui->postsTree->selectionModel(),SIGNAL(selectionChanged(const QItemSelection&,const QItemSelection&)),this,SLOT(showPostDetails()));
connect(ui->postsTree,SIGNAL(customContextMenuRequested(const QPoint&)),this,SLOT(postContextMenu(const QPoint&))); connect(ui->postsTree,SIGNAL(customContextMenuRequested(const QPoint&)),this,SLOT(postContextMenu(const QPoint&)));
@ -666,7 +666,7 @@ void GxsChannelPostsWidgetWithModel::download()
std::string destination; std::string destination;
rsGxsChannels->getChannelDownloadDirectory(mGroup.mMeta.mGroupId,destination); rsGxsChannels->getChannelDownloadDirectory(mGroup.mMeta.mGroupId,destination);
for(auto file:post.mFiles) for(auto& file:post.mFiles)
{ {
std::list<RsPeerId> sources; std::list<RsPeerId> sources;
@ -939,8 +939,9 @@ void GxsChannelPostsWidgetWithModel::postChannelPostLoad()
mChannelPostsModel->getFilesList(files); mChannelPostsModel->getFilesList(files);
mChannelFilesModel->setFiles(files); mChannelFilesModel->setFiles(files);
ui->channelFiles_TV->setAutoSelect(true); ui->channelFiles_TV->setAutoSelect(true);
ui->channelFiles_TV->sortByColumn(3, Qt::AscendingOrder); ui->channelFiles_TV->sortByColumn(ui->channelFiles_TV->header()->sortIndicatorSection()
,ui->channelFiles_TV->header()->sortIndicatorOrder());
ui->infoPosts->setText(QString::number(mChannelPostsModel->getNumberOfPosts()) + " / " + QString::number(mGroup.mMeta.mVisibleMsgCount)); ui->infoPosts->setText(QString::number(mChannelPostsModel->getNumberOfPosts()) + " / " + QString::number(mGroup.mMeta.mVisibleMsgCount));
@ -1206,11 +1207,11 @@ void GxsChannelPostsWidgetWithModel::insertChannelDetails(const RsGxsChannelGrou
QString distrib_string ( "[unknown]" ); QString distrib_string ( "[unknown]" );
switch(group.mMeta.mCircleType) switch((RsGxsCircleType)group.mMeta.mCircleType)
{ {
case GXS_CIRCLE_TYPE_PUBLIC: distrib_string = tr("Public") ; case RsGxsCircleType::PUBLIC: distrib_string = tr("Public") ;
break ; break ;
case GXS_CIRCLE_TYPE_EXTERNAL: case RsGxsCircleType::EXTERNAL:
{ {
RsGxsCircleDetails det ; RsGxsCircleDetails det ;
@ -1222,9 +1223,9 @@ void GxsChannelPostsWidgetWithModel::insertChannelDetails(const RsGxsChannelGrou
distrib_string = tr("Restricted to members of circle ")+QString::fromStdString(group.mMeta.mCircleId.toStdString()) ; distrib_string = tr("Restricted to members of circle ")+QString::fromStdString(group.mMeta.mCircleId.toStdString()) ;
} }
break ; break ;
case GXS_CIRCLE_TYPE_YOUR_EYES_ONLY: distrib_string = tr("Your eyes only"); case RsGxsCircleType::YOUR_EYES_ONLY: distrib_string = tr("Your eyes only");
break ; break ;
case GXS_CIRCLE_TYPE_LOCAL: distrib_string = tr("You and your friend nodes"); case RsGxsCircleType::LOCAL: distrib_string = tr("You and your friend nodes");
break ; break ;
default: default:
std::cerr << "(EE) badly initialised group distribution ID = " << group.mMeta.mCircleType << std::endl; std::cerr << "(EE) badly initialised group distribution ID = " << group.mMeta.mCircleType << std::endl;
@ -1245,7 +1246,7 @@ void GxsChannelPostsWidgetWithModel::insertChannelDetails(const RsGxsChannelGrou
showPostDetails(); showPostDetails();
} }
void GxsChannelPostsWidgetWithModel::showChannelFilesContextMenu(QPoint p) void GxsChannelPostsWidgetWithModel::showChannelFilesContextMenu(QPoint /*p*/)
{ {
QMenu contextMnu(this) ; QMenu contextMnu(this) ;
@ -1316,7 +1317,7 @@ void GxsChannelPostsWidgetWithModel::switchOnlyUnread(bool)
} }
void GxsChannelPostsWidgetWithModel::filterChanged(QString s) void GxsChannelPostsWidgetWithModel::filterChanged(QString s)
{ {
QStringList ql = s.split(' ',QString::SkipEmptyParts); QStringList ql = s.split(' ',Qt::SkipEmptyParts);
uint32_t count; uint32_t count;
mChannelPostsModel->setFilter(ql,ui->showUnread_TB->isChecked(),count); mChannelPostsModel->setFilter(ql,ui->showUnread_TB->isChecked(),count);
mChannelFilesModel->setFilter(ql,count); mChannelFilesModel->setFilter(ql,count);
@ -1419,7 +1420,7 @@ void GxsChannelPostsWidgetWithModel::toggleAutoDownload()
class GxsChannelPostsReadData class GxsChannelPostsReadData
{ {
public: public:
GxsChannelPostsReadData(bool read) explicit GxsChannelPostsReadData(bool read)
{ {
mRead = read; mRead = read;
mLastToken = 0; mLastToken = 0;

View File

@ -50,42 +50,32 @@ RsGxsForumModel::RsGxsForumModel(QObject *parent)
void RsGxsForumModel::preMods() void RsGxsForumModel::preMods()
{ {
//emit layoutAboutToBeChanged(); //Generate SIGSEGV when click on button move next/prev. emit layoutAboutToBeChanged();
beginResetModel();
} }
void RsGxsForumModel::postMods() void RsGxsForumModel::postMods()
{ {
endResetModel(); if(mTreeMode == TREE_MODE_FLAT)
if(mTreeMode == TREE_MODE_FLAT)
emit dataChanged(createIndex(0,0,(void*)NULL), createIndex(mPosts.size(),COLUMN_THREAD_NB_COLUMNS-1,(void*)NULL)); emit dataChanged(createIndex(0,0,(void*)NULL), createIndex(mPosts.size(),COLUMN_THREAD_NB_COLUMNS-1,(void*)NULL));
else else
emit dataChanged(createIndex(0,0,(void*)NULL), createIndex(mPosts[0].mChildren.size(),COLUMN_THREAD_NB_COLUMNS-1,(void*)NULL)); emit dataChanged(createIndex(0,0,(void*)NULL), createIndex(mPosts[0].mChildren.size(),COLUMN_THREAD_NB_COLUMNS-1,(void*)NULL));
emit layoutChanged();
} }
void RsGxsForumModel::setTreeMode(TreeMode mode) void RsGxsForumModel::setTreeMode(TreeMode mode)
{ {
if(mode == mTreeMode) if(mode == mTreeMode)
return; return;
preMods(); preMods();
if(mode == TREE_MODE_TREE) // means we were in FLAT mode, so the last rows are removed. beginResetModel();
{
beginRemoveRows(QModelIndex(),mPosts[0].mChildren.size(),mPosts.size()-1);
endRemoveRows();
}
mTreeMode = mode; mTreeMode = mode;
if(mode == TREE_MODE_FLAT) // means we were in tree mode, so the last rows are added. endResetModel();
{
beginInsertRows(QModelIndex(),mPosts[0].mChildren.size(),mPosts.size()-1);
endInsertRows();
}
postMods(); postMods();
} }
void RsGxsForumModel::setSortMode(SortMode mode) void RsGxsForumModel::setSortMode(SortMode mode)
@ -241,7 +231,7 @@ QModelIndex RsGxsForumModel::parent(const QModelIndex& index) const
Qt::ItemFlags RsGxsForumModel::flags(const QModelIndex& index) const Qt::ItemFlags RsGxsForumModel::flags(const QModelIndex& index) const
{ {
if (!index.isValid()) if (!index.isValid())
return 0; return Qt::ItemFlags();
return QAbstractItemModel::flags(index); return QAbstractItemModel::flags(index);
} }
@ -466,8 +456,8 @@ QVariant RsGxsForumModel::statusRole(const ForumModelPostEntry& fmpe,int column)
QVariant RsGxsForumModel::filterRole(const ForumModelPostEntry& fmpe,int /*column*/) const QVariant RsGxsForumModel::filterRole(const ForumModelPostEntry& fmpe,int /*column*/) const
{ {
if(!mFilteringEnabled || (fmpe.mPostFlags & ForumModelPostEntry::FLAG_POST_CHILDREN_PASSES_FILTER)) if(!mFilteringEnabled || (fmpe.mPostFlags & ForumModelPostEntry::FLAG_POST_CHILDREN_PASSES_FILTER))
return QVariant(FilterString); return QVariant(FilterString);
return QVariant(QString()); return QVariant(QString());
} }
@ -755,65 +745,68 @@ void RsGxsForumModel::clear()
void RsGxsForumModel::setPosts(const RsGxsForumGroup& group, const std::vector<ForumModelPostEntry>& posts,const std::map<RsGxsMessageId,std::vector<std::pair<time_t,RsGxsMessageId> > >& post_versions) void RsGxsForumModel::setPosts(const RsGxsForumGroup& group, const std::vector<ForumModelPostEntry>& posts,const std::map<RsGxsMessageId,std::vector<std::pair<time_t,RsGxsMessageId> > >& post_versions)
{ {
preMods(); preMods();
if(mTreeMode == TREE_MODE_FLAT) beginResetModel();
beginRemoveRows(QModelIndex(),0,mPosts.size()-1); endResetModel();
else
beginRemoveRows(QModelIndex(),0,mPosts[0].mChildren.size()-1);
endRemoveRows(); mForumGroup = group;
mPosts = posts;
mPostVersions = post_versions;
mForumGroup = group; // now update prow for all posts
mPosts = posts;
mPostVersions = post_versions;
// now update prow for all posts for(uint32_t i=0;i<mPosts.size();++i)
for(uint32_t j=0;j<mPosts[i].mChildren.size();++j)
mPosts[mPosts[i].mChildren[j]].prow = j;
for(uint32_t i=0;i<mPosts.size();++i) mPosts[0].prow = 0;
for(uint32_t j=0;j<mPosts[i].mChildren.size();++j)
mPosts[mPosts[i].mChildren[j]].prow = j;
mPosts[0].prow = 0; bool has_unread_below,has_read_below ;
bool has_unread_below,has_read_below ; recursUpdateReadStatusAndTimes(0,has_unread_below,has_read_below) ;
recursUpdateFilterStatus(0,0,QStringList());
recursUpdateReadStatusAndTimes(0,has_unread_below,has_read_below) ;
recursUpdateFilterStatus(0,0,QStringList());
#ifdef DEBUG_FORUMMODEL #ifdef DEBUG_FORUMMODEL
debug_dump(); debug_dump();
#endif #endif
if(mTreeMode == TREE_MODE_FLAT) int count = 0;
beginInsertRows(QModelIndex(),0,mPosts.size()-1); if(mTreeMode == TREE_MODE_FLAT)
else count = mPosts.size();
beginInsertRows(QModelIndex(),0,mPosts[0].mChildren.size()-1); else
endInsertRows(); count = mPosts[0].mChildren.size();
if(count>0)
{
beginInsertRows(QModelIndex(),0,count-1);
endInsertRows();
}
postMods(); postMods();
emit forumLoaded(); emit forumLoaded();
} }
void RsGxsForumModel::update_posts(const RsGxsGroupId& group_id) void RsGxsForumModel::update_posts(const RsGxsGroupId& group_id)
{ {
if(group_id.isNull()) if(group_id.isNull())
return; return;
RsThread::async([this, group_id]() RsThread::async([this, group_id]()
{ {
// 1 - get message data from p3GxsForums // 1 - get message data from p3GxsForums
std::list<RsGxsGroupId> forumIds; std::list<RsGxsGroupId> forumIds;
std::vector<RsMsgMetaData> msg_metas; std::vector<RsMsgMetaData> msg_metas;
std::vector<RsGxsForumGroup> groups; std::vector<RsGxsForumGroup> groups;
forumIds.push_back(group_id); forumIds.push_back(group_id);
if(!rsGxsForums->getForumsInfo(forumIds,groups) || groups.size() != 1) if(!rsGxsForums->getForumsInfo(forumIds,groups) || groups.size() != 1)
{ {
std::cerr << __PRETTY_FUNCTION__ << " failed to retrieve forum group info for forum " << group_id << std::endl; std::cerr << __PRETTY_FUNCTION__ << " failed to retrieve forum group info for forum " << group_id << std::endl;
return; return;
} }
if(!rsGxsForums->getForumMsgMetaData(group_id,msg_metas)) if(!rsGxsForums->getForumMsgMetaData(group_id,msg_metas))
{ {
@ -821,17 +814,17 @@ void RsGxsForumModel::update_posts(const RsGxsGroupId& group_id)
return; return;
} }
// 2 - sort the messages into a proper hierarchy // 2 - sort the messages into a proper hierarchy
auto post_versions = new std::map<RsGxsMessageId,std::vector<std::pair<time_t, RsGxsMessageId> > >() ; auto post_versions = new std::map<RsGxsMessageId,std::vector<std::pair<time_t, RsGxsMessageId> > >() ;
std::vector<ForumModelPostEntry> *vect = new std::vector<ForumModelPostEntry>(); std::vector<ForumModelPostEntry> *vect = new std::vector<ForumModelPostEntry>();
RsGxsForumGroup group = groups[0]; RsGxsForumGroup group = groups[0];
computeMessagesHierarchy(group,msg_metas,*vect,*post_versions); computeMessagesHierarchy(group,msg_metas,*vect,*post_versions);
// 3 - update the model in the UI thread. // 3 - update the model in the UI thread.
RsQThreadUtils::postToObject( [group,vect,post_versions,this]() RsQThreadUtils::postToObject( [group,vect,post_versions,this]()
{ {
/* Here it goes any code you want to be executed on the Qt Gui /* Here it goes any code you want to be executed on the Qt Gui
* thread, for example to update the data model with new information * thread, for example to update the data model with new information
@ -839,15 +832,15 @@ void RsGxsForumModel::update_posts(const RsGxsGroupId& group_id)
* Qt::QueuedConnection is important! * Qt::QueuedConnection is important!
*/ */
setPosts(group,*vect,*post_versions) ; setPosts(group,*vect,*post_versions) ;
delete vect; delete vect;
delete post_versions; delete post_versions;
}, this ); }, this );
}); });
} }
ForumModelIndex RsGxsForumModel::addEntry(std::vector<ForumModelPostEntry>& posts,const ForumModelPostEntry& entry,ForumModelIndex parent) ForumModelIndex RsGxsForumModel::addEntry(std::vector<ForumModelPostEntry>& posts,const ForumModelPostEntry& entry,ForumModelIndex parent)
@ -895,26 +888,25 @@ void RsGxsForumModel::convertMsgToPostEntry(const RsGxsForumGroup& mForumGroup,c
void RsGxsForumModel::computeReputationLevel(uint32_t forum_sign_flags,ForumModelPostEntry& fentry) void RsGxsForumModel::computeReputationLevel(uint32_t forum_sign_flags,ForumModelPostEntry& fentry)
{ {
uint32_t idflags =0; uint32_t idflags =0;
RsReputationLevel reputation_level = RsReputationLevel reputation_level =
rsReputations->overallReputationLevel(fentry.mAuthorId, &idflags); rsReputations->overallReputationLevel(fentry.mAuthorId, &idflags);
bool redacted = false;
if(reputation_level == RsReputationLevel::LOCALLY_NEGATIVE) if(reputation_level == RsReputationLevel::LOCALLY_NEGATIVE)
fentry.mPostFlags |= ForumModelPostEntry::FLAG_POST_IS_REDACTED; fentry.mPostFlags |= ForumModelPostEntry::FLAG_POST_IS_REDACTED;
else else
fentry.mPostFlags &= ~ForumModelPostEntry::FLAG_POST_IS_REDACTED; fentry.mPostFlags &= ~ForumModelPostEntry::FLAG_POST_IS_REDACTED;
// We use a specific item model for forums in order to handle the post pinning. // We use a specific item model for forums in order to handle the post pinning.
if(reputation_level == RsReputationLevel::UNKNOWN) if(reputation_level == RsReputationLevel::UNKNOWN)
fentry.mReputationWarningLevel = 3 ; fentry.mReputationWarningLevel = 3 ;
else if(reputation_level == RsReputationLevel::LOCALLY_NEGATIVE) else if(reputation_level == RsReputationLevel::LOCALLY_NEGATIVE)
fentry.mReputationWarningLevel = 2 ; fentry.mReputationWarningLevel = 2 ;
else if(reputation_level < rsGxsForums->minReputationForForwardingMessages(forum_sign_flags,idflags)) else if(reputation_level < rsGxsForums->minReputationForForwardingMessages(forum_sign_flags,idflags))
fentry.mReputationWarningLevel = 1 ; fentry.mReputationWarningLevel = 1 ;
else else
fentry.mReputationWarningLevel = 0 ; fentry.mReputationWarningLevel = 0 ;
} }
static bool decreasing_time_comp(const std::pair<time_t,RsGxsMessageId>& e1,const std::pair<time_t,RsGxsMessageId>& e2) { return e2.first < e1.first ; } static bool decreasing_time_comp(const std::pair<time_t,RsGxsMessageId>& e1,const std::pair<time_t,RsGxsMessageId>& e2) { return e2.first < e1.first ; }

View File

@ -1,7 +1,7 @@
<!--/**************************************************************** <!--/****************************************************************
* This file is distributed under the following license: * This file is distributed under the following license:
* *
* Copyright (c) 2008, defnax * Copyright (c) 2008, defnax
* Copyright (c) 2008, edmanm * Copyright (c) 2008, edmanm
* *
* This program is free software; you can redistribute it and/or * This program is free software; you can redistribute it and/or
@ -33,48 +33,48 @@
<td>&nbsp;&nbsp;&nbsp;</td> <td>&nbsp;&nbsp;&nbsp;</td>
<td>Homepage</td> <td>Homepage</td>
<td> <td>
<a href="http://retroshare.sourceforge.net"> <a href="https://retroshare.cc/">
http://retroshare.sourceforge.net</a> https://retroshare.cc/</a>
</td> </td>
</tr> </tr>
<tr> <tr>
<td>&nbsp;&nbsp;&nbsp;</td> <td>&nbsp;&nbsp;&nbsp;</td>
<td>RetroShare Forum</td> <td>Blog</td>
<td> <td>
<a href="http://retroshare.sourceforge.net/forum"> <a href="https://retroshareteam.wordpress.com/">
http://retroshare.sourceforge.net/forum</a> https://retroshareteam.wordpress.com/</a>
</td> </td>
</tr> </tr>
<tr> <tr>
<td>&nbsp;&nbsp;&nbsp;</td> <td>&nbsp;&nbsp;&nbsp;</td>
<td>RetroShare Wiki</td> <td>RetroShare Wiki</td>
<td> <td>
<a href="http://retroshare.sourceforge.net/wiki"> <a href="https://retroshare.readthedocs.io/en/latest/">
http://retroshare.sourceforge.net/wiki</a> https://retroshare.readthedocs.io/en/latest/</a>
</td> </td>
</tr> </tr>
<tr> <tr>
<td>&nbsp;&nbsp;&nbsp;</td> <td>&nbsp;&nbsp;&nbsp;</td>
<td>Project Page</td> <td>Project Page</td>
<td> <td>
<a href="http://sourceforge.net/projects/retroshare"> <a href="https://github.com/RetroShare/RetroShare">
http://sourceforge.net/projects/retroshare</a> https://github.com/RetroShare/RetroShare</a>
</td> </td>
</tr> </tr>
<tr> <tr>
<td>&nbsp;&nbsp;&nbsp;</td> <td>&nbsp;&nbsp;&nbsp;</td>
<td>Bugtracker</td> <td>Bugtracker</td>
<td> <td>
<a href="http://sourceforge.net/tracker/?group_id=178712&atid=886239"> <a href="https://github.com/RetroShare/RetroShare/issues">
http://sourceforge.net/tracker/?group_id=178712&atid=886239</a> https://github.com/RetroShare/RetroShare/issues</a>
</td> </td>
</tr> </tr>
<tr> <tr>
<td>&nbsp;&nbsp;&nbsp;</td> <td>&nbsp;&nbsp;&nbsp;</td>
<td>Translation</td> <td>Translation</td>
<td> <td>
<a href="http://retroshare.sourceforge.net/wiki/index.php/Translation"> <a href="https://www.transifex.com/beluga/retroshare/">
http://retroshare.sourceforge.net/wiki/index.php/Translation</a> https://www.transifex.com/beluga/retroshare/</a>
</td> </td>
</tr> </tr>
</table> </table>

View File

@ -53,6 +53,7 @@
<file>icons/gmail.png</file> <file>icons/gmail.png</file>
<file>icons/help_128.png</file> <file>icons/help_128.png</file>
<file>icons/help_64.png</file> <file>icons/help_64.png</file>
<file>icons/identities.png</file>
<file>icons/information_128.png</file> <file>icons/information_128.png</file>
<file>icons/internet_128.png</file> <file>icons/internet_128.png</file>
<file>icons/invite64.png</file> <file>icons/invite64.png</file>

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.7 KiB

View File

@ -22,6 +22,7 @@
#include <QMessageBox> #include <QMessageBox>
#include <QCloseEvent> #include <QCloseEvent>
#include <QClipboard> #include <QClipboard>
#include <QLabel>
#include <QTextCodec> #include <QTextCodec>
#include <QPrintDialog> #include <QPrintDialog>
#include <QPrinter> #include <QPrinter>
@ -94,6 +95,8 @@
#define STYLE_NORMAL "QLineEdit#%1 { border : none; }" #define STYLE_NORMAL "QLineEdit#%1 { border : none; }"
#define STYLE_FAIL "QLineEdit#%1 { border : none; color : red; }" #define STYLE_FAIL "QLineEdit#%1 { border : none; color : red; }"
static const uint32_t MAX_ALLOWED_GXS_MESSAGE_SIZE = 199000;
class MessageItemDelegate : public QItemDelegate class MessageItemDelegate : public QItemDelegate
{ {
public: public:
@ -213,6 +216,8 @@ MessageComposer::MessageComposer(QWidget *parent, Qt::WindowFlags flags)
connect(ui.friendSelectionWidget, SIGNAL(doubleClicked(int,QString)), this, SLOT(addTo())); connect(ui.friendSelectionWidget, SIGNAL(doubleClicked(int,QString)), this, SLOT(addTo()));
connect(ui.friendSelectionWidget, SIGNAL(itemSelectionChanged()), this, SLOT(friendSelectionChanged())); connect(ui.friendSelectionWidget, SIGNAL(itemSelectionChanged()), this, SLOT(friendSelectionChanged()));
connect(ui.msgText, SIGNAL(textChanged()), this, SLOT(checkLength()));
/* hide the Tree +/- */ /* hide the Tree +/- */
ui.msgFileList -> setRootIsDecorated( false ); ui.msgFileList -> setRootIsDecorated( false );
@ -352,6 +357,15 @@ MessageComposer::MessageComposer(QWidget *parent, Qt::WindowFlags flags)
/* set focus to subject */ /* set focus to subject */
ui.titleEdit->setFocus(); ui.titleEdit->setFocus();
infoLabel = new QLabel( "", this );
statusBar()->addPermanentWidget(infoLabel);
lineLabel = new QLabel( "", this );
statusBar()->addPermanentWidget(lineLabel);
lengthLabel = new QLabel( "", this );
statusBar()->addPermanentWidget(lengthLabel);
// create tag menu // create tag menu
TagsMenu *menu = new TagsMenu (tr("Tags"), this); TagsMenu *menu = new TagsMenu (tr("Tags"), this);
connect(menu, SIGNAL(aboutToShow()), this, SLOT(tagAboutToShow())); connect(menu, SIGNAL(aboutToShow()), this, SLOT(tagAboutToShow()));
@ -379,7 +393,7 @@ void MessageComposer::updateCells(int,int)
{ {
int rowCount = ui.recipientWidget->rowCount(); int rowCount = ui.recipientWidget->rowCount();
int row; int row;
bool has_gxs = false ; has_gxs = false ;
for (row = 0; row < rowCount; ++row) for (row = 0; row < rowCount; ++row)
{ {
@ -396,6 +410,7 @@ void MessageComposer::updateCells(int,int)
ui.respond_to_CB->show(); ui.respond_to_CB->show();
ui.distantFrame->show(); ui.distantFrame->show();
ui.fromLabel->show(); ui.fromLabel->show();
checkLength();
} }
else else
{ {
@ -2853,3 +2868,30 @@ void MessageComposer::sendInvite(const RsGxsId &to, bool autoSend)
/* window will destroy itself! */ /* window will destroy itself! */
} }
void MessageComposer::checkLength()
{
QString text;
RsHtml::optimizeHtml(ui.msgText, text);
std::wstring msg = text.toStdWString();
int charlength = msg.length();
int charRemains = MAX_ALLOWED_GXS_MESSAGE_SIZE - msg.length();
text = tr("Message Size: %1").arg(misc::friendlyUnit(charlength));
lengthLabel->setText(text);
lineLabel->setText("|");
if(has_gxs) {
if(charRemains >= 0) {
text = tr("It remains %1 characters after HTML conversion.").arg(charRemains);
}else{
text = tr("Warning: This message is too big of %1 characters after HTML conversion.").arg((0-charRemains));
}
ui.actionSend->setEnabled(charRemains>=0);
infoLabel->setText(text);
}
else {
infoLabel->setText("");
ui.actionSend->setEnabled(true);
}
}

View File

@ -168,6 +168,8 @@ private slots:
static QString inviteMessage(); static QString inviteMessage();
void checkLength();
private: private:
static QString buildReplyHeader(const MessageInfo &msgInfo); static QString buildReplyHeader(const MessageInfo &msgInfo);
@ -257,6 +259,12 @@ private:
RSTreeWidgetItemCompareRole *m_compareRole; RSTreeWidgetItemCompareRole *m_compareRole;
QCompleter *m_completer; QCompleter *m_completer;
QLabel *infoLabel;
QLabel *lengthLabel;
QLabel *lineLabel;
bool has_gxs;
/** Qt Designer generated object */ /** Qt Designer generated object */
Ui::MessageComposer ui; Ui::MessageComposer ui;

View File

@ -61,31 +61,32 @@ RsMessageModel::RsMessageModel(QObject *parent)
void RsMessageModel::preMods() void RsMessageModel::preMods()
{ {
emit layoutAboutToBeChanged(); emit layoutAboutToBeChanged();
} }
void RsMessageModel::postMods() void RsMessageModel::postMods()
{ {
emit dataChanged(createIndex(0,0,(void*)NULL), createIndex(mMessages.size()-1,COLUMN_THREAD_NB_COLUMNS-1,(void*)NULL)); emit dataChanged(createIndex(0,0,(void*)NULL), createIndex(mMessages.size()-1,COLUMN_THREAD_NB_COLUMNS-1,(void*)NULL));
emit layoutChanged();
} }
int RsMessageModel::rowCount(const QModelIndex& parent) const int RsMessageModel::rowCount(const QModelIndex& parent) const
{ {
if(!parent.isValid()) if(!parent.isValid())
return 0; return 0;
if(parent.column() > 0) if(parent.column() > 0)
return 0; return 0;
if(mMessages.empty()) // security. Should never happen. if(mMessages.empty()) // security. Should never happen.
return 0; return 0;
if(parent.internalPointer() == NULL) if(parent.internalPointer() == NULL)
return mMessages.size(); return mMessages.size();
return 0; return 0;
} }
int RsMessageModel::columnCount(const QModelIndex &parent) const int RsMessageModel::columnCount(const QModelIndex &/*parent*/) const
{ {
return COLUMN_THREAD_NB_COLUMNS ; return COLUMN_THREAD_NB_COLUMNS ;
} }
@ -145,8 +146,8 @@ QModelIndex RsMessageModel::index(int row, int column, const QModelIndex & paren
QModelIndex RsMessageModel::parent(const QModelIndex& index) const QModelIndex RsMessageModel::parent(const QModelIndex& index) const
{ {
if(!index.isValid()) if(!index.isValid())
return QModelIndex(); return QModelIndex();
return QModelIndex(); return QModelIndex();
} }
@ -154,12 +155,12 @@ QModelIndex RsMessageModel::parent(const QModelIndex& index) const
Qt::ItemFlags RsMessageModel::flags(const QModelIndex& index) const Qt::ItemFlags RsMessageModel::flags(const QModelIndex& index) const
{ {
if (!index.isValid()) if (!index.isValid())
return 0; return Qt::ItemFlags();
return QAbstractItemModel::flags(index); return QAbstractItemModel::flags(index);
} }
QVariant RsMessageModel::headerData(int section, Qt::Orientation orientation, int role) const QVariant RsMessageModel::headerData(int section, Qt::Orientation /*orientation*/, int role) const
{ {
if(role == Qt::DisplayRole) if(role == Qt::DisplayRole)
switch(section) switch(section)
@ -274,20 +275,20 @@ QVariant RsMessageModel::data(const QModelIndex &index, int role) const
} }
} }
QVariant RsMessageModel::textColorRole(const Rs::Msgs::MsgInfoSummary& fmpe,int column) const QVariant RsMessageModel::textColorRole(const Rs::Msgs::MsgInfoSummary& fmpe,int /*column*/) const
{ {
Rs::Msgs::MsgTagType tags; Rs::Msgs::MsgTagType tags;
rsMsgs->getMessageTagTypes(tags); rsMsgs->getMessageTagTypes(tags);
for(auto it(fmpe.msgtags.begin());it!=fmpe.msgtags.end();++it) for(auto it(fmpe.msgtags.begin());it!=fmpe.msgtags.end();++it)
for(auto it2(tags.types.begin());it2!=tags.types.end();++it2) for(auto it2(tags.types.begin());it2!=tags.types.end();++it2)
if(it2->first == *it) if(it2->first == *it)
return QColor(it2->second.second); return QColor(it2->second.second);
return QVariant(); return QVariant();
} }
QVariant RsMessageModel::statusRole(const Rs::Msgs::MsgInfoSummary& fmpe,int column) const QVariant RsMessageModel::statusRole(const Rs::Msgs::MsgInfoSummary& /*fmpe*/,int /*column*/) const
{ {
// if(column != COLUMN_THREAD_DATA) // if(column != COLUMN_THREAD_DATA)
// return QVariant(); // return QVariant();
@ -295,12 +296,12 @@ QVariant RsMessageModel::statusRole(const Rs::Msgs::MsgInfoSummary& fmpe,int col
return QVariant();//fmpe.mMsgStatus); return QVariant();//fmpe.mMsgStatus);
} }
bool RsMessageModel::passesFilter(const Rs::Msgs::MsgInfoSummary& fmpe,int column) const bool RsMessageModel::passesFilter(const Rs::Msgs::MsgInfoSummary& fmpe,int /*column*/) const
{ {
QString s ; QString s ;
bool passes_strings = true ; bool passes_strings = true ;
if(!mFilterStrings.empty()) if(!mFilterStrings.empty())
{ {
switch(mFilterType) switch(mFilterType)
{ {
@ -308,9 +309,9 @@ bool RsMessageModel::passesFilter(const Rs::Msgs::MsgInfoSummary& fmpe,int colum
break; break;
case FILTER_TYPE_FROM: s = sortRole(fmpe,COLUMN_THREAD_AUTHOR).toString(); case FILTER_TYPE_FROM: s = sortRole(fmpe,COLUMN_THREAD_AUTHOR).toString();
if(s.isNull()) if(s.isNull())
passes_strings = false; passes_strings = false;
break; break;
case FILTER_TYPE_DATE: s = displayRole(fmpe,COLUMN_THREAD_DATE).toString(); case FILTER_TYPE_DATE: s = displayRole(fmpe,COLUMN_THREAD_DATE).toString();
break; break;
case FILTER_TYPE_CONTENT: { case FILTER_TYPE_CONTENT: {
@ -330,6 +331,9 @@ bool RsMessageModel::passesFilter(const Rs::Msgs::MsgInfoSummary& fmpe,int colum
for(auto it(minfo.files.begin());it!=minfo.files.end();++it) for(auto it(minfo.files.begin());it!=minfo.files.end();++it)
s += QString::fromUtf8((*it).fname.c_str())+" "; s += QString::fromUtf8((*it).fname.c_str())+" ";
} }
break;
case FILTER_TYPE_NONE:
RS_ERR("None Type for Filter.");
}; };
} }
@ -355,18 +359,15 @@ bool RsMessageModel::passesFilter(const Rs::Msgs::MsgInfoSummary& fmpe,int colum
QVariant RsMessageModel::filterRole(const Rs::Msgs::MsgInfoSummary& fmpe,int column) const QVariant RsMessageModel::filterRole(const Rs::Msgs::MsgInfoSummary& fmpe,int column) const
{ {
if(passesFilter(fmpe,column)) if(passesFilter(fmpe,column))
return QVariant(FilterString); return QVariant(FilterString);
return QVariant(QString()); return QVariant(QString());
} }
uint32_t RsMessageModel::updateFilterStatus(ForumModelIndex i,int column,const QStringList& strings) uint32_t RsMessageModel::updateFilterStatus(ForumModelIndex /*i*/,int /*column*/,const QStringList& /*strings*/)
{ {
QString s ; return 0;
uint32_t count = 0;
return count;
} }
@ -408,7 +409,7 @@ QVariant RsMessageModel::toolTipRole(const Rs::Msgs::MsgInfoSummary& fmpe,int co
return QVariant(); return QVariant();
} }
QVariant RsMessageModel::backgroundRole(const Rs::Msgs::MsgInfoSummary &fmpe, int column) const QVariant RsMessageModel::backgroundRole(const Rs::Msgs::MsgInfoSummary &/*fmpe*/, int /*column*/) const
{ {
return QVariant(); return QVariant();
} }
@ -426,7 +427,7 @@ QVariant RsMessageModel::sizeHintRole(int col) const
} }
} }
QVariant RsMessageModel::authorRole(const Rs::Msgs::MsgInfoSummary& fmpe,int column) const QVariant RsMessageModel::authorRole(const Rs::Msgs::MsgInfoSummary& /*fmpe*/,int /*column*/) const
{ {
return QVariant(); return QVariant();
} }
@ -443,15 +444,16 @@ QVariant RsMessageModel::sortRole(const Rs::Msgs::MsgInfoSummary& fmpe,int colum
case COLUMN_THREAD_SPAM: return QVariant((fmpe.msgflags & RS_MSG_SPAM)? 1:0); case COLUMN_THREAD_SPAM: return QVariant((fmpe.msgflags & RS_MSG_SPAM)? 1:0);
case COLUMN_THREAD_AUTHOR:{ case COLUMN_THREAD_AUTHOR:{
QString name; QString name;
if(GxsIdTreeItemDelegate::computeName(RsGxsId(fmpe.srcId.toStdString()),name)) if(GxsIdTreeItemDelegate::computeName(RsGxsId(fmpe.srcId.toStdString()),name))
return name; return name;
} return ""; //Not Found
default: }
return displayRole(fmpe,column); default:
} return displayRole(fmpe,column);
}
} }
QVariant RsMessageModel::displayRole(const Rs::Msgs::MsgInfoSummary& fmpe,int col) const QVariant RsMessageModel::displayRole(const Rs::Msgs::MsgInfoSummary& fmpe,int col) const
@ -572,9 +574,12 @@ QVariant RsMessageModel::decorationRole(const Rs::Msgs::MsgInfoSummary& fmpe,int
void RsMessageModel::clear() void RsMessageModel::clear()
{ {
preMods(); preMods();
mMessages.clear(); beginResetModel();
mMessages.clear();
mMessagesMap.clear();
endResetModel();
postMods(); postMods();
@ -583,29 +588,26 @@ void RsMessageModel::clear()
void RsMessageModel::setMessages(const std::list<Rs::Msgs::MsgInfoSummary>& msgs) void RsMessageModel::setMessages(const std::list<Rs::Msgs::MsgInfoSummary>& msgs)
{ {
preMods();
beginRemoveRows(QModelIndex(),0,mMessages.size()-1); clear();
endRemoveRows();
mMessages.clear(); for(auto it(msgs.begin());it!=msgs.end();++it)
mMessagesMap.clear(); {
mMessagesMap[(*it).msgId] = mMessages.size();
mMessages.push_back(*it);
}
for(auto it(msgs.begin());it!=msgs.end();++it) // now update prow for all posts
{
mMessagesMap[(*it).msgId] = mMessages.size();
mMessages.push_back(*it);
}
// now update prow for all posts
#ifdef DEBUG_MESSAGE_MODEL #ifdef DEBUG_MESSAGE_MODEL
debug_dump(); debug_dump();
#endif #endif
beginInsertRows(QModelIndex(),0,mMessages.size()-1); if (mMessages.size()>0)
endInsertRows(); {
postMods(); beginInsertRows(QModelIndex(),0,mMessages.size()-1);
endInsertRows();
}
emit messagesLoaded(); emit messagesLoaded();
} }
@ -672,8 +674,6 @@ void RsMessageModel::updateMessages()
emit messagesLoaded(); emit messagesLoaded();
} }
static bool decreasing_time_comp(const std::pair<time_t,RsGxsMessageId>& e1,const std::pair<time_t,RsGxsMessageId>& e2) { return e2.first < e1.first ; }
void RsMessageModel::setMsgReadStatus(const QModelIndex& i,bool read_status) void RsMessageModel::setMsgReadStatus(const QModelIndex& i,bool read_status)
{ {
if(!i.isValid()) if(!i.isValid())
@ -704,12 +704,12 @@ void RsMessageModel::setMsgJunk(const QModelIndex& i,bool junk)
QModelIndex RsMessageModel::getIndexOfMessage(const std::string& mid) const QModelIndex RsMessageModel::getIndexOfMessage(const std::string& mid) const
{ {
// Brutal search. This is not so nice, so dont call that in a loop! If too costly, we'll use a map. // Brutal search. This is not so nice, so dont call that in a loop! If too costly, we'll use a map.
auto it = mMessagesMap.find(mid); auto it = mMessagesMap.find(mid);
if(it == mMessagesMap.end() || it->second >= mMessages.size()) if(it == mMessagesMap.end() || it->second >= mMessages.size())
return QModelIndex(); return QModelIndex();
quintptr ref ; quintptr ref ;
convertMsgIndexToInternalId(it->second,ref); convertMsgIndexToInternalId(it->second,ref);

View File

@ -509,6 +509,7 @@ void MessageWidget::fill(const std::string &msgId)
ui.msgText->resetImagesStatus(false); ui.msgText->resetImagesStatus(false);
clearTagLabels(); clearTagLabels();
checkLength();
ui.inviteFrame->hide(); ui.inviteFrame->hide();
ui.expandFilesButton->setChecked(false); ui.expandFilesButton->setChecked(false);
@ -690,6 +691,7 @@ void MessageWidget::fill(const std::string &msgId)
ui.filesSize->setText(QString(misc::friendlyUnit(msgInfo.size))); ui.filesSize->setText(QString(misc::friendlyUnit(msgInfo.size)));
showTagLabels(); showTagLabels();
checkLength();
currMsgFlags = msgInfo.msgflags; currMsgFlags = msgInfo.msgflags;
} }
@ -903,3 +905,15 @@ void MessageWidget::viewSource()
delete dialog; delete dialog;
} }
void MessageWidget::checkLength()
{
QString text;
RsHtml::optimizeHtml(ui.msgText, text);
std::wstring msg = text.toStdWString();
int charlength = msg.length();
text = tr("%1 (%2) ").arg(charlength).arg(misc::friendlyUnit(charlength));
ui.sizeLabel->setText(text);
}

View File

@ -86,6 +86,7 @@ private slots:
void loadImagesAlways(); void loadImagesAlways();
void buttonStyle(); void buttonStyle();
void viewSource(); void viewSource();
void checkLength();
private: private:
void clearTagLabels(); void clearTagLabels();

View File

@ -621,7 +621,7 @@
<number>0</number> <number>0</number>
</property> </property>
<property name="rightMargin"> <property name="rightMargin">
<number>0</number> <number>3</number>
</property> </property>
<property name="bottomMargin"> <property name="bottomMargin">
<number>0</number> <number>0</number>
@ -682,6 +682,27 @@
</item> </item>
</layout> </layout>
</item> </item>
<item>
<widget class="Line" name="line">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
</widget>
</item>
<item>
<widget class="QLabel" name="label">
<property name="text">
<string>Message Size:</string>
</property>
</widget>
</item>
<item>
<widget class="QLabel" name="sizeLabel">
<property name="text">
<string>Size</string>
</property>
</widget>
</item>
<item> <item>
<spacer name="filesHSpacer"> <spacer name="filesHSpacer">
<property name="orientation"> <property name="orientation">

View File

@ -18,7 +18,7 @@
</property> </property>
<widget class="QWidget" name="tabFeed"> <widget class="QWidget" name="tabFeed">
<attribute name="title"> <attribute name="title">
<string>Log</string> <string>Activity</string>
</attribute> </attribute>
<layout class="QVBoxLayout" name="tabFeedVLayout"> <layout class="QVBoxLayout" name="tabFeedVLayout">
<item> <item>

View File

@ -602,6 +602,6 @@ BWGraph::BWGraph(QWidget *parent) : RSGraphWidget(parent)
BWGraph::~BWGraph() BWGraph::~BWGraph()
{ {
delete _local_source ; //delete _local_source ;//Will be deleted by RSGraphWidget destructor
} }

View File

@ -34,10 +34,12 @@
#define SETTING_OPACITY "Opacity" #define SETTING_OPACITY "Opacity"
#define SETTING_ALWAYS_ON_TOP "AlwaysOnTop" #define SETTING_ALWAYS_ON_TOP "AlwaysOnTop"
#define SETTING_STYLE "GraphStyle" #define SETTING_STYLE "GraphStyle"
#define SETTING_GRAPHCOLOR "GraphColor"
#define DEFAULT_FILTER (BWGRAPH_LINE_SEND|BWGRAPH_LINE_RECV) #define DEFAULT_FILTER (BWGRAPH_LINE_SEND|BWGRAPH_LINE_RECV)
#define DEFAULT_ALWAYS_ON_TOP false #define DEFAULT_ALWAYS_ON_TOP false
#define DEFAULT_OPACITY 100 #define DEFAULT_OPACITY 100
#define DEFAULT_STYLE LineGraph #define DEFAULT_STYLE LineGraph
#define DEFAULT_GRAPHCOLOR DefaultColor
#define ADD_TO_FILTER(f,v,b) (f = ((b) ? ((f) | (v)) : ((f) & ~(v)))) #define ADD_TO_FILTER(f,v,b) (f = ((b) ? ((f) | (v)) : ((f) & ~(v))))
@ -132,6 +134,19 @@ BandwidthGraph::loadSettings()
ui.frmGraph->resetFlags(RSGraphWidget::RSGRAPH_FLAGS_PAINT_STYLE_PLAIN); ui.frmGraph->resetFlags(RSGraphWidget::RSGRAPH_FLAGS_PAINT_STYLE_PLAIN);
else else
ui.frmGraph->setFlags(RSGraphWidget::RSGRAPH_FLAGS_PAINT_STYLE_PLAIN); ui.frmGraph->setFlags(RSGraphWidget::RSGRAPH_FLAGS_PAINT_STYLE_PLAIN);
/* Set whether we are plotting bandwidth as area graphs or not */
int graphColor = getSetting(SETTING_GRAPHCOLOR, DEFAULT_GRAPHCOLOR).toInt();
if (graphColor < 0 || graphColor >= ui.cmbGraphColor->count()) {
graphColor = DEFAULT_GRAPHCOLOR;
}
ui.cmbGraphColor->setCurrentIndex(graphColor);
if(graphColor==0)
ui.frmGraph->resetFlags(RSGraphWidget::RSGRAPH_FLAGS_DARK_STYLE);
else
ui.frmGraph->setFlags(RSGraphWidget::RSGRAPH_FLAGS_DARK_STYLE);
/* Set graph frame settings */ /* Set graph frame settings */
ui.frmGraph->setShowEntry(0,ui.chkReceiveRate->isChecked()) ; ui.frmGraph->setShowEntry(0,ui.chkReceiveRate->isChecked()) ;
@ -158,6 +173,7 @@ void BandwidthGraph::saveChanges()
/* Save the opacity and graph style */ /* Save the opacity and graph style */
saveSetting(SETTING_OPACITY, ui.sldrOpacity->value()); saveSetting(SETTING_OPACITY, ui.sldrOpacity->value());
saveSetting(SETTING_STYLE, ui.cmbGraphStyle->currentIndex()); saveSetting(SETTING_STYLE, ui.cmbGraphStyle->currentIndex());
saveSetting(SETTING_GRAPHCOLOR, ui.cmbGraphColor->currentIndex());
/* Save the Always On Top setting */ /* Save the Always On Top setting */
saveSetting(SETTING_ALWAYS_ON_TOP, ui.chkAlwaysOnTop->isChecked()); saveSetting(SETTING_ALWAYS_ON_TOP, ui.chkAlwaysOnTop->isChecked());
@ -184,6 +200,11 @@ void BandwidthGraph::saveChanges()
else else
ui.frmGraph->setFlags(RSGraphWidget::RSGRAPH_FLAGS_PAINT_STYLE_PLAIN); ui.frmGraph->setFlags(RSGraphWidget::RSGRAPH_FLAGS_PAINT_STYLE_PLAIN);
if(ui.cmbGraphColor->currentIndex()==0)
ui.frmGraph->resetFlags(RSGraphWidget::RSGRAPH_FLAGS_DARK_STYLE);
else
ui.frmGraph->setFlags(RSGraphWidget::RSGRAPH_FLAGS_DARK_STYLE);
/* A change in window flags causes the window to disappear, so make sure /* A change in window flags causes the window to disappear, so make sure
* it's still visible. */ * it's still visible. */
showNormal(); showNormal();

View File

@ -40,6 +40,7 @@ class BandwidthGraph : public RWindow
public: public:
enum { AreaGraph=0,LineGraph=1 } ; enum { AreaGraph=0,LineGraph=1 } ;
enum { DefaultColor=0,DarkColor=1 } ;
/** Default constructor */ /** Default constructor */
BandwidthGraph(QWidget *parent = 0, Qt::WindowFlags flags = 0); BandwidthGraph(QWidget *parent = 0, Qt::WindowFlags flags = 0);

View File

@ -6,7 +6,7 @@
<rect> <rect>
<x>0</x> <x>0</x>
<y>0</y> <y>0</y>
<width>414</width> <width>418</width>
<height>305</height> <height>305</height>
</rect> </rect>
</property> </property>
@ -24,7 +24,16 @@
<property name="spacing"> <property name="spacing">
<number>6</number> <number>6</number>
</property> </property>
<property name="margin"> <property name="leftMargin">
<number>0</number>
</property>
<property name="topMargin">
<number>0</number>
</property>
<property name="rightMargin">
<number>0</number>
</property>
<property name="bottomMargin">
<number>0</number> <number>0</number>
</property> </property>
<item> <item>
@ -69,13 +78,13 @@
</property> </property>
<property name="minimumSize"> <property name="minimumSize">
<size> <size>
<width>355</width> <width>400</width>
<height>82</height> <height>82</height>
</size> </size>
</property> </property>
<property name="maximumSize"> <property name="maximumSize">
<size> <size>
<width>355</width> <width>400</width>
<height>82</height> <height>82</height>
</size> </size>
</property> </property>
@ -88,19 +97,34 @@
<property name="frameShadow"> <property name="frameShadow">
<enum>QFrame::Raised</enum> <enum>QFrame::Raised</enum>
</property> </property>
<layout class="QHBoxLayout"> <layout class="QGridLayout" name="gridLayout_2">
<property name="spacing"> <property name="leftMargin">
<number>6</number>
</property>
<property name="margin">
<number>9</number> <number>9</number>
</property> </property>
<item> <property name="topMargin">
<number>9</number>
</property>
<property name="rightMargin">
<number>9</number>
</property>
<property name="bottomMargin">
<number>9</number>
</property>
<item row="0" column="0" rowspan="2">
<layout class="QVBoxLayout" name="_2"> <layout class="QVBoxLayout" name="_2">
<property name="spacing"> <property name="spacing">
<number>6</number> <number>6</number>
</property> </property>
<property name="margin"> <property name="leftMargin">
<number>3</number>
</property>
<property name="topMargin">
<number>3</number>
</property>
<property name="rightMargin">
<number>3</number>
</property>
<property name="bottomMargin">
<number>3</number> <number>3</number>
</property> </property>
<item> <item>
@ -166,12 +190,21 @@
</item> </item>
</layout> </layout>
</item> </item>
<item> <item row="0" column="1" rowspan="2">
<layout class="QVBoxLayout" name="_3"> <layout class="QVBoxLayout" name="_3">
<property name="spacing"> <property name="spacing">
<number>1</number> <number>1</number>
</property> </property>
<property name="margin"> <property name="leftMargin">
<number>0</number>
</property>
<property name="topMargin">
<number>0</number>
</property>
<property name="rightMargin">
<number>0</number>
</property>
<property name="bottomMargin">
<number>0</number> <number>0</number>
</property> </property>
<item> <item>
@ -179,7 +212,16 @@
<property name="spacing"> <property name="spacing">
<number>6</number> <number>6</number>
</property> </property>
<property name="margin"> <property name="leftMargin">
<number>0</number>
</property>
<property name="topMargin">
<number>0</number>
</property>
<property name="rightMargin">
<number>0</number>
</property>
<property name="bottomMargin">
<number>0</number> <number>0</number>
</property> </property>
<item> <item>
@ -224,6 +266,20 @@
</item> </item>
</widget> </widget>
</item> </item>
<item>
<widget class="QComboBox" name="cmbGraphColor">
<item>
<property name="text">
<string>Default</string>
</property>
</item>
<item>
<property name="text">
<string>Dark</string>
</property>
</item>
</widget>
</item>
</layout> </layout>
</item> </item>
<item> <item>
@ -241,7 +297,16 @@
<property name="spacing"> <property name="spacing">
<number>3</number> <number>3</number>
</property> </property>
<property name="margin"> <property name="leftMargin">
<number>0</number>
</property>
<property name="topMargin">
<number>0</number>
</property>
<property name="rightMargin">
<number>0</number>
</property>
<property name="bottomMargin">
<number>0</number> <number>0</number>
</property> </property>
<item> <item>
@ -299,7 +364,16 @@
<property name="spacing"> <property name="spacing">
<number>0</number> <number>0</number>
</property> </property>
<property name="margin"> <property name="leftMargin">
<number>0</number>
</property>
<property name="topMargin">
<number>0</number>
</property>
<property name="rightMargin">
<number>0</number>
</property>
<property name="bottomMargin">
<number>0</number> <number>0</number>
</property> </property>
<item> <item>
@ -377,25 +451,21 @@
</item> </item>
</layout> </layout>
</item> </item>
<item> <item row="0" column="4" rowspan="2">
<spacer>
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>21</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
<item>
<layout class="QVBoxLayout" name="_7"> <layout class="QVBoxLayout" name="_7">
<property name="spacing"> <property name="spacing">
<number>1</number> <number>1</number>
</property> </property>
<property name="margin"> <property name="leftMargin">
<number>0</number>
</property>
<property name="topMargin">
<number>0</number>
</property>
<property name="rightMargin">
<number>0</number>
</property>
<property name="bottomMargin">
<number>0</number> <number>0</number>
</property> </property>
<item> <item>
@ -414,6 +484,19 @@
</item> </item>
</layout> </layout>
</item> </item>
<item row="0" column="3">
<spacer>
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>21</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
</layout> </layout>
</widget> </widget>
</item> </item>

View File

@ -24,6 +24,7 @@
#include "retroshare/rspeers.h" #include "retroshare/rspeers.h"
#include "retroshare/rsservicecontrol.h" #include "retroshare/rsservicecontrol.h"
#include "retroshare-gui/RsAutoUpdatePage.h" #include "retroshare-gui/RsAutoUpdatePage.h"
#include "gui/settings/rsharesettings.h"
#include "BandwidthStatsWidget.h" #include "BandwidthStatsWidget.h"
BandwidthStatsWidget::BandwidthStatsWidget(QWidget *parent) BandwidthStatsWidget::BandwidthStatsWidget(QWidget *parent)
@ -31,6 +32,8 @@ BandwidthStatsWidget::BandwidthStatsWidget(QWidget *parent)
{ {
ui.setupUi(this) ; ui.setupUi(this) ;
m_bProcessSettings = false;
// now add one button per service // now add one button per service
ui.friend_CB->addItem(tr("Sum")) ; ui.friend_CB->addItem(tr("Sum")) ;
@ -49,6 +52,9 @@ BandwidthStatsWidget::BandwidthStatsWidget(QWidget *parent)
ui.bwgraph_BW->resetFlags(RSGraphWidget::RSGRAPH_FLAGS_LEGEND_CUMULATED) ; ui.bwgraph_BW->resetFlags(RSGraphWidget::RSGRAPH_FLAGS_LEGEND_CUMULATED) ;
updateUnitSelection(0); updateUnitSelection(0);
toggleLogScale(ui.logScale_CB->checkState() == Qt::Checked);//Update bwgraph_BW with default logScale_CB state defined in ui file.
// Setup connections // Setup connections
@ -58,6 +64,7 @@ BandwidthStatsWidget::BandwidthStatsWidget(QWidget *parent)
QObject::connect(ui.service_CB ,SIGNAL(currentIndexChanged(int )),this, SLOT(updateServiceSelection(int ))) ; QObject::connect(ui.service_CB ,SIGNAL(currentIndexChanged(int )),this, SLOT(updateServiceSelection(int ))) ;
QObject::connect(ui.legend_CB ,SIGNAL(currentIndexChanged(int )),this, SLOT( updateLegendType(int ))) ; QObject::connect(ui.legend_CB ,SIGNAL(currentIndexChanged(int )),this, SLOT( updateLegendType(int ))) ;
QObject::connect(ui.logScale_CB,SIGNAL( toggled(bool)),this, SLOT( toggleLogScale(bool))) ; QObject::connect(ui.logScale_CB,SIGNAL( toggled(bool)),this, SLOT( toggleLogScale(bool))) ;
QObject::connect(ui.cmbGraphColor,SIGNAL(currentIndexChanged(int )),this, SLOT( updateGraphSelection(int))) ;
// setup one timer for auto-update // setup one timer for auto-update
@ -65,6 +72,45 @@ BandwidthStatsWidget::BandwidthStatsWidget(QWidget *parent)
connect(mTimer, SIGNAL(timeout()), this, SLOT(updateComboBoxes())) ; connect(mTimer, SIGNAL(timeout()), this, SLOT(updateComboBoxes())) ;
mTimer->setSingleShot(false) ; mTimer->setSingleShot(false) ;
mTimer->start(2000) ; mTimer->start(2000) ;
// load settings
processSettings(true);
int graphColor = ui.cmbGraphColor->currentIndex();
if(graphColor==0)
ui.bwgraph_BW->resetFlags(RSGraphWidget::RSGRAPH_FLAGS_DARK_STYLE);
else
ui.bwgraph_BW->setFlags(RSGraphWidget::RSGRAPH_FLAGS_DARK_STYLE);
}
BandwidthStatsWidget::~BandwidthStatsWidget ()
{
// save settings
processSettings(false);
}
void BandwidthStatsWidget::processSettings(bool bLoad)
{
m_bProcessSettings = true;
Settings->beginGroup(QString("BandwidthStatsWidget"));
if (bLoad) {
// load settings
// state of Graph Color combobox
int index = Settings->value("cmbGraphColor", 0).toInt();
ui.cmbGraphColor->setCurrentIndex(index);
} else {
// save settings
// state of Graph Color combobox
Settings->setValue("cmbGraphColor", ui.cmbGraphColor->currentIndex());
}
Settings->endGroup();
m_bProcessSettings = false;
} }
void BandwidthStatsWidget::toggleLogScale(bool b) void BandwidthStatsWidget::toggleLogScale(bool b)
@ -74,6 +120,7 @@ void BandwidthStatsWidget::toggleLogScale(bool b)
else else
ui.bwgraph_BW->resetFlags(RSGraphWidget::RSGRAPH_FLAGS_LOG_SCALE_Y) ; ui.bwgraph_BW->resetFlags(RSGraphWidget::RSGRAPH_FLAGS_LOG_SCALE_Y) ;
} }
void BandwidthStatsWidget::updateComboBoxes() void BandwidthStatsWidget::updateComboBoxes()
{ {
if(!isVisible()) if(!isVisible())
@ -233,3 +280,11 @@ void BandwidthStatsWidget::updateUnitSelection(int n)
ui.legend_CB->setItemText(1,tr("Total")); ui.legend_CB->setItemText(1,tr("Total"));
} }
} }
void BandwidthStatsWidget::updateGraphSelection(int n)
{
if(n==0)
ui.bwgraph_BW->resetFlags(RSGraphWidget::RSGRAPH_FLAGS_DARK_STYLE);
else
ui.bwgraph_BW->setFlags(RSGraphWidget::RSGRAPH_FLAGS_DARK_STYLE);
}

View File

@ -26,7 +26,10 @@ class BandwidthStatsWidget: public QWidget
Q_OBJECT Q_OBJECT
public: public:
/** Default Constructor */
BandwidthStatsWidget(QWidget *parent) ; BandwidthStatsWidget(QWidget *parent) ;
/** Default Destructor */
~BandwidthStatsWidget ();
protected slots: protected slots:
void updateFriendSelection(int n); void updateFriendSelection(int n);
@ -36,8 +39,12 @@ protected slots:
void updateUnitSelection(int n); void updateUnitSelection(int n);
void toggleLogScale(bool b); void toggleLogScale(bool b);
void updateLegendType(int n); void updateLegendType(int n);
void updateGraphSelection(int n);
private: private:
void processSettings(bool bLoad);
bool m_bProcessSettings;
Ui::BwStatsWidget ui; Ui::BwStatsWidget ui;
QTimer *mTimer ; QTimer *mTimer ;

View File

@ -6,7 +6,7 @@
<rect> <rect>
<x>0</x> <x>0</x>
<y>0</y> <y>0</y>
<width>1148</width> <width>800</width>
<height>385</height> <height>385</height>
</rect> </rect>
</property> </property>
@ -140,6 +140,20 @@
</property> </property>
</widget> </widget>
</item> </item>
<item>
<widget class="QComboBox" name="cmbGraphColor">
<item>
<property name="text">
<string>Default</string>
</property>
</item>
<item>
<property name="text">
<string>Dark</string>
</property>
</item>
</widget>
</item>
<item> <item>
<spacer name="horizontalSpacer"> <spacer name="horizontalSpacer">
<property name="orientation"> <property name="orientation">

View File

@ -7,7 +7,7 @@
<x>0</x> <x>0</x>
<y>0</y> <y>0</y>
<width>760</width> <width>760</width>
<height>603</height> <height>500</height>
</rect> </rect>
</property> </property>
<property name="windowTitle"> <property name="windowTitle">

View File

@ -84,6 +84,9 @@ GlobalRouterStatistics::GlobalRouterStatistics(QWidget *parent)
connect(treeWidget, SIGNAL(customContextMenuRequested(QPoint)), this, SLOT(CustomPopupMenu(QPoint))); connect(treeWidget, SIGNAL(customContextMenuRequested(QPoint)), this, SLOT(CustomPopupMenu(QPoint)));
/* Set initial size the splitter */
splitter->setStretchFactor(1, 1);
splitter->setStretchFactor(0, 0);
// load settings // load settings
processSettings(true); processSettings(true);
@ -106,12 +109,12 @@ void GlobalRouterStatistics::processSettings(bool bLoad)
// load settings // load settings
// state of splitter // state of splitter
//splitter->restoreState(Settings->value("Splitter").toByteArray()); splitter->restoreState(Settings->value("Splitter").toByteArray());
} else { } else {
// save settings // save settings
// state of splitter // state of splitter
//Settings->setValue("Splitter", splitter->saveState()); Settings->setValue("Splitter", splitter->saveState());
} }

View File

@ -6,19 +6,96 @@
<rect> <rect>
<x>0</x> <x>0</x>
<y>0</y> <y>0</y>
<width>1468</width> <width>800</width>
<height>659</height> <height>429</height>
</rect> </rect>
</property> </property>
<property name="windowTitle"> <property name="windowTitle">
<string>Router Statistics</string> <string>Router Statistics</string>
</property> </property>
<layout class="QGridLayout" name="gridLayout"> <layout class="QGridLayout" name="gridLayout">
<item row="1" column="0"> <item row="0" column="0">
<widget class="QSplitter" name="splitter"> <widget class="QSplitter" name="splitter">
<property name="orientation"> <property name="orientation">
<enum>Qt::Vertical</enum> <enum>Qt::Vertical</enum>
</property> </property>
<widget class="QGroupBox" name="groupBox">
<property name="title">
<string>GroupBox</string>
</property>
<layout class="QGridLayout" name="gridLayout_2">
<item row="0" column="0">
<widget class="QTreeWidget" name="treeWidget">
<property name="contextMenuPolicy">
<enum>Qt::CustomContextMenu</enum>
</property>
<property name="sortingEnabled">
<bool>true</bool>
</property>
<column>
<property name="text">
<string>ID</string>
</property>
</column>
<column>
<property name="text">
<string>Identity Name</string>
</property>
</column>
<column>
<property name="text">
<string>Destinaton</string>
</property>
</column>
<column>
<property name="text">
<string>Data status</string>
</property>
</column>
<column>
<property name="text">
<string>Tunnel status</string>
</property>
</column>
<column>
<property name="text">
<string>Stored data size</string>
</property>
</column>
<column>
<property name="text">
<string>Data hash</string>
</property>
</column>
<column>
<property name="text">
<string>Receive time</string>
</property>
</column>
<column>
<property name="text">
<string>Sending time</string>
</property>
</column>
<column>
<property name="text">
<string>Branching factor</string>
</property>
</column>
<column>
<property name="text">
<string>Receive time (secs ago)</string>
</property>
</column>
<column>
<property name="text">
<string>Sending time (secs ago)</string>
</property>
</column>
</widget>
</item>
</layout>
</widget>
<widget class="QScrollArea" name="_router_F"> <widget class="QScrollArea" name="_router_F">
<property name="frameShape"> <property name="frameShape">
<enum>QFrame::NoFrame</enum> <enum>QFrame::NoFrame</enum>
@ -34,93 +111,14 @@
<rect> <rect>
<x>0</x> <x>0</x>
<y>0</y> <y>0</y>
<width>1450</width> <width>782</width>
<height>317</height> <height>69</height>
</rect> </rect>
</property> </property>
</widget> </widget>
</widget> </widget>
</widget> </widget>
</item> </item>
<item row="0" column="0">
<widget class="QGroupBox" name="groupBox">
<property name="title">
<string>GroupBox</string>
</property>
<layout class="QGridLayout" name="gridLayout_2">
<item row="0" column="0">
<widget class="QTreeWidget" name="treeWidget">
<property name="contextMenuPolicy">
<enum>Qt::CustomContextMenu</enum>
</property>
<property name="sortingEnabled">
<bool>true</bool>
</property>
<column>
<property name="text">
<string>ID</string>
</property>
</column>
<column>
<property name="text">
<string>Identity Name</string>
</property>
</column>
<column>
<property name="text">
<string>Destinaton</string>
</property>
</column>
<column>
<property name="text">
<string>Data status</string>
</property>
</column>
<column>
<property name="text">
<string>Tunnel status</string>
</property>
</column>
<column>
<property name="text">
<string>Stored data size</string>
</property>
</column>
<column>
<property name="text">
<string>Data hash</string>
</property>
</column>
<column>
<property name="text">
<string>Receive time</string>
</property>
</column>
<column>
<property name="text">
<string>Sending time</string>
</property>
</column>
<column>
<property name="text">
<string>Branching factor</string>
</property>
</column>
<column>
<property name="text">
<string>Receive time (secs ago)</string>
</property>
</column>
<column>
<property name="text">
<string>Sending time (secs ago)</string>
</property>
</column>
</widget>
</item>
</layout>
</widget>
</item>
</layout> </layout>
</widget> </widget>
<resources/> <resources/>

View File

@ -6,8 +6,8 @@
<rect> <rect>
<x>0</x> <x>0</x>
<y>0</y> <y>0</y>
<width>1468</width> <width>800</width>
<height>779</height> <height>500</height>
</rect> </rect>
</property> </property>
<property name="windowTitle"> <property name="windowTitle">

View File

@ -131,4 +131,11 @@ RttStatisticsGraph::RttStatisticsGraph(QWidget *parent)
resetFlags(RSGRAPH_FLAGS_LOG_SCALE_Y) ; resetFlags(RSGRAPH_FLAGS_LOG_SCALE_Y) ;
resetFlags(RSGRAPH_FLAGS_PAINT_STYLE_PLAIN) ; resetFlags(RSGRAPH_FLAGS_PAINT_STYLE_PLAIN) ;
setFlags(RSGRAPH_FLAGS_SHOW_LEGEND) ; setFlags(RSGRAPH_FLAGS_SHOW_LEGEND) ;
int graphColor = Settings->valueFromGroup("BandwidthStatsWidget", "cmbGraphColor", 0).toInt();
if(graphColor==0)
resetFlags(RSGraphWidget::RSGraphWidget::RSGRAPH_FLAGS_DARK_STYLE);
else
setFlags(RSGraphWidget::RSGraphWidget::RSGRAPH_FLAGS_DARK_STYLE);
} }

View File

@ -54,7 +54,7 @@
#define IMAGE_DHT ":/icons/DHT128.png" #define IMAGE_DHT ":/icons/DHT128.png"
#define IMAGE_TURTLE ":/icons/turtle128.png" #define IMAGE_TURTLE ":/icons/turtle128.png"
#define IMAGE_IDENTITIES ":/icons/avatar_128.png" #define IMAGE_IDENTITIES ":/icons/identities.png"
#define IMAGE_BWGRAPH ":/icons/bandwidth128.png" #define IMAGE_BWGRAPH ":/icons/bandwidth128.png"
#define IMAGE_GLOBALROUTER ":/icons/GRouter128.png" #define IMAGE_GLOBALROUTER ":/icons/GRouter128.png"
#define IMAGE_GXSTRANSPORT ":/icons/transport128.png" #define IMAGE_GXSTRANSPORT ":/icons/transport128.png"

View File

@ -15,7 +15,16 @@
</property> </property>
<widget class="QWidget" name="centralwidget"> <widget class="QWidget" name="centralwidget">
<layout class="QGridLayout" name="gridLayout"> <layout class="QGridLayout" name="gridLayout">
<property name="margin"> <property name="leftMargin">
<number>0</number>
</property>
<property name="topMargin">
<number>0</number>
</property>
<property name="rightMargin">
<number>0</number>
</property>
<property name="bottomMargin">
<number>0</number> <number>0</number>
</property> </property>
<item row="0" column="0"> <item row="0" column="0">
@ -45,7 +54,6 @@
<attribute name="toolBarBreak"> <attribute name="toolBarBreak">
<bool>false</bool> <bool>false</bool>
</attribute> </attribute>
<addaction name="separator"/>
</widget> </widget>
<action name="actionAdd_Friend"> <action name="actionAdd_Friend">
<property name="icon"> <property name="icon">
@ -61,7 +69,7 @@
</action> </action>
<action name="actionAdd_Share"> <action name="actionAdd_Share">
<property name="icon"> <property name="icon">
<iconset resource="../images.qrc"> <iconset>
<normaloff>:/images/add-share24.png</normaloff>:/images/add-share24.png</iconset> <normaloff>:/images/add-share24.png</normaloff>:/images/add-share24.png</iconset>
</property> </property>
<property name="text"> <property name="text">
@ -79,7 +87,7 @@
</action> </action>
<action name="actionMessenger"> <action name="actionMessenger">
<property name="icon"> <property name="icon">
<iconset resource="../images.qrc"> <iconset>
<normaloff>:/images/messenger.png</normaloff>:/images/messenger.png</iconset> <normaloff>:/images/messenger.png</normaloff>:/images/messenger.png</iconset>
</property> </property>
<property name="text"> <property name="text">
@ -105,7 +113,7 @@
</action> </action>
<action name="actionQuit"> <action name="actionQuit">
<property name="icon"> <property name="icon">
<iconset resource="../images.qrc"> <iconset>
<normaloff>:/images/exit_24x24.png</normaloff>:/images/exit_24x24.png</iconset> <normaloff>:/images/exit_24x24.png</normaloff>:/images/exit_24x24.png</iconset>
</property> </property>
<property name="text"> <property name="text">

View File

@ -202,7 +202,14 @@ TurtleRouterStatistics::TurtleRouterStatistics(QWidget *parent)
float fact = fontHeight/14.0; float fact = fontHeight/14.0;
frmGraph->setMinimumHeight(200*fact); frmGraph->setMinimumHeight(200*fact);
int graphColor = Settings->valueFromGroup("BandwidthStatsWidget", "cmbGraphColor", 0).toInt();
if(graphColor==0)
frmGraph->resetFlags(RSGraphWidget::RSGRAPH_FLAGS_DARK_STYLE);
else
frmGraph->setFlags(RSGraphWidget::RSGRAPH_FLAGS_DARK_STYLE);
// load settings // load settings
processSettings(true); processSettings(true);
} }
@ -224,12 +231,12 @@ void TurtleRouterStatistics::processSettings(bool bLoad)
// load settings // load settings
// state of splitter // state of splitter
//splitter->restoreState(Settings->value("Splitter").toByteArray()); splitter->restoreState(Settings->value("Splitter").toByteArray());
} else { } else {
// save settings // save settings
// state of splitter // state of splitter
//Settings->setValue("Splitter", splitter->saveState()); Settings->setValue("Splitter", splitter->saveState());
} }

View File

@ -7,7 +7,7 @@
<x>0</x> <x>0</x>
<y>0</y> <y>0</y>
<width>680</width> <width>680</width>
<height>523</height> <height>500</height>
</rect> </rect>
</property> </property>
<property name="windowTitle"> <property name="windowTitle">
@ -29,15 +29,15 @@
<property name="orientation"> <property name="orientation">
<enum>Qt::Vertical</enum> <enum>Qt::Vertical</enum>
</property> </property>
<property name="handleWidth">
<number>5</number>
</property>
<widget class="QScrollArea" name="_tunnel_statistics_F"> <widget class="QScrollArea" name="_tunnel_statistics_F">
<property name="styleSheet"> <property name="minimumSize">
<string notr="true"/> <size>
</property> <width>0</width>
<property name="frameShape"> <height>200</height>
<enum>QFrame::NoFrame</enum> </size>
</property>
<property name="horizontalScrollBarPolicy">
<enum>Qt::ScrollBarAlwaysOff</enum>
</property> </property>
<property name="widgetResizable"> <property name="widgetResizable">
<bool>true</bool> <bool>true</bool>
@ -47,28 +47,23 @@
<rect> <rect>
<x>0</x> <x>0</x>
<y>0</y> <y>0</y>
<width>640</width> <width>636</width>
<height>248</height> <height>198</height>
</rect> </rect>
</property> </property>
<property name="autoFillBackground">
<bool>true</bool>
</property>
</widget> </widget>
</widget> </widget>
</widget> <widget class="TurtleGraph" name="frmGraph" native="true">
</item> <property name="minimumSize">
<item row="1" column="0"> <size>
<widget class="TurtleGraph" name="frmGraph" native="true"> <width>120</width>
<property name="minimumSize"> <height>200</height>
<size> </size>
<width>120</width> </property>
<height>200</height> <property name="contextMenuPolicy">
</size> <enum>Qt::NoContextMenu</enum>
</property> </property>
<property name="contextMenuPolicy"> </widget>
<enum>Qt::NoContextMenu</enum>
</property>
</widget> </widget>
</item> </item>
</layout> </layout>

View File

@ -26,6 +26,7 @@
#include <QApplication> #include <QApplication>
#include <gui/common/RSGraphWidget.h> #include <gui/common/RSGraphWidget.h>
#include "gui/settings/rsharesettings.h"
#include <retroshare/rsdht.h> #include <retroshare/rsdht.h>
#include <retroshare/rsconfig.h> #include <retroshare/rsconfig.h>
@ -74,5 +75,12 @@ class DhtGraph : public RSGraphWidget
resetFlags(RSGRAPH_FLAGS_LOG_SCALE_Y) ; resetFlags(RSGRAPH_FLAGS_LOG_SCALE_Y) ;
setFlags(RSGRAPH_FLAGS_PAINT_STYLE_PLAIN) ; setFlags(RSGRAPH_FLAGS_PAINT_STYLE_PLAIN) ;
int graphColor = Settings->valueFromGroup("BandwidthStatsWidget", "cmbGraphColor", 0).toInt();
if(graphColor==0)
resetFlags(RSGraphWidget::RSGraphWidget::RSGRAPH_FLAGS_DARK_STYLE);
else
setFlags(RSGraphWidget::RSGraphWidget::RSGRAPH_FLAGS_DARK_STYLE);
} }
}; };

View File

@ -20,6 +20,8 @@
#pragma once #pragma once
#include "gui/settings/rsharesettings.h"
#include "retroshare/rsturtle.h" #include "retroshare/rsturtle.h"
#include <gui/common/RSGraphWidget.h> #include <gui/common/RSGraphWidget.h>
@ -68,7 +70,14 @@ class TurtleGraph: public RSGraphWidget
resetFlags(RSGRAPH_FLAGS_LOG_SCALE_Y) ; resetFlags(RSGRAPH_FLAGS_LOG_SCALE_Y) ;
resetFlags(RSGRAPH_FLAGS_PAINT_STYLE_PLAIN) ; resetFlags(RSGRAPH_FLAGS_PAINT_STYLE_PLAIN) ;
setFlags(RSGRAPH_FLAGS_SHOW_LEGEND) ; setFlags(RSGRAPH_FLAGS_SHOW_LEGEND) ;
int graphColor = Settings->valueFromGroup("BandwidthStatsWidget", "cmbGraphColor", 0).toInt();
if(graphColor==0)
resetFlags(RSGraphWidget::RSGRAPH_FLAGS_DARK_STYLE);
else
setFlags(RSGraphWidget::RSGRAPH_FLAGS_DARK_STYLE);
} }
}; };

View File

@ -37,7 +37,7 @@ GroupChatToaster::GroupChatToaster(const RsPeerId &peerId, const QString &messag
/* set informations */ /* set informations */
ui.textLabel->setText(RsHtml().formatText(NULL, message, RSHTML_FORMATTEXT_EMBED_SMILEYS | RSHTML_FORMATTEXT_EMBED_LINKS | RSHTML_FORMATTEXT_CLEANSTYLE)); ui.textLabel->setText(RsHtml().formatText(NULL, message, RSHTML_FORMATTEXT_EMBED_SMILEYS | RSHTML_FORMATTEXT_EMBED_LINKS | RSHTML_FORMATTEXT_CLEANSTYLE));
ui.toasterLabel->setText(QString::fromUtf8(rsPeers->getPeerName(peerId).c_str())); ui.toasterLabel->setText(QString::fromUtf8(rsPeers->getPeerName(peerId).c_str()));
ui.avatarWidget->setFrameType(AvatarWidget::STATUS_FRAME); ui.avatarWidget->setFrameType(AvatarWidget::NO_FRAME);
ui.avatarWidget->setDefaultAvatar(":/images/user/personal64.png"); ui.avatarWidget->setDefaultAvatar(":/images/user/personal64.png");
ui.avatarWidget->setId(ChatId(peerId)); ui.avatarWidget->setId(ChatId(peerId));
} }