fixed merge with upstream/master

This commit is contained in:
csoler 2020-04-19 21:53:02 +02:00
commit 38e89d4055
No known key found for this signature in database
GPG Key ID: 7BCA522266C0804C
100 changed files with 2795 additions and 1806 deletions

49
.gitlab-ci.yml Normal file
View File

@ -0,0 +1,49 @@
image: docker:stable
services:
- docker:stable-dind
workflow:
rules:
- if: $CI_MERGE_REQUEST_ID
- if: $CI_COMMIT_BRANCH
build-and-test:
script:
- >
if [ -n "$CI_MERGE_REQUEST_ID" ]; then
MR_ARGS="--build-arg REPO_URL=$CI_MERGE_REQUEST_SOURCE_PROJECT_URL" ;
MR_ARGS="$MR_ARGS --build-arg REPO_BRANCH=$CI_MERGE_REQUEST_SOURCE_BRANCH_NAME" ;
export MR_ARGS ;
fi
- mkdir Dockercontext
- >
docker build -t retroshare:testing $MR_ARGS
--file $CI_PROJECT_DIR/build_scripts/GitlabCI/gitlabCI.Dockerfile
Dockercontext
- >
docker run --name retroshare --detach --tty retroshare:testing
retroshare-service --jsonApiPort 9092
- apk add jq
- >
docker exec retroshare
curl --verbose http://127.0.0.1:9092/rsJsonApi/version | jq
- >
docker exec retroshare
curl --verbose http://127.0.0.1:9092/rsLoginHelper/getLocations | jq
- >
docker exec retroshare
curl --verbose --data
'{ "location":{ "mLocationName":"Test 1", "mPgpName":"Test2" },
"password":"Test 3", "caller_data":"Test 5" }'
http://127.0.0.1:9092/rsLoginHelper/createLocation | jq
- >
docker exec retroshare
curl --verbose http://127.0.0.1:9092/rsLoginHelper/getLocations | jq
- >
docker exec retroshare
curl --verbose http://127.0.0.1:9092/rsLoginHelper/isLoggedIn | jq
- >
docker exec retroshare
curl --verbose http://127.0.0.1:9092/rsMsgs/getChatLobbyList | jq
- docker container stop retroshare

View File

@ -9,6 +9,7 @@ RetroShare provides file sharing, chat, messages, forums, channels and more.
.Build Status
|===============================================================================
|GNU/Linux (via Gitlab CI) | image:https://gitlab.com/RetroShare/RetroShare/badges/master/pipeline.svg[link="https://gitlab.com/RetroShare/RetroShare/-/commits/master",title="pipeline status"]
|GNU/Linux, macOS, (via Travis CI) | image:https://travis-ci.org/RetroShare/RetroShare.svg?branch=master[link="https://travis-ci.org/RetroShare/RetroShare"]
|Windows (via AppVeyor) | image:https://ci.appveyor.com/api/projects/status/github/RetroShare/RetroShare?svg=true[link="https://ci.appveyor.com/project/RetroShare58622/retroshare"]
|===============================================================================

View File

@ -0,0 +1,43 @@
## Add +--build-arg FRESHCLONE=$(date +%s)+ to docker build commandline to
## force cloning a new
## To prepare an image suitable as base for Gitlab CI use
# docker build -t "${CI_REGISTRY_IMAGE}:base" --build-arg KEEP_SOURCE=true --build-arg REPO_DEPTH="" -f base.Dockerfile .
## Now you need to tag it so you can later push it
# docker tag ${ID_OF_THE_CREATED_IMAGE} registry.gitlab.com/retroshare/${CI_REGISTRY_IMAGE}:base
## To push it to gitlab CI registry you need first to login and the to push
# docker login registry.gitlab.com
# docker push registry.gitlab.com/retroshare/${CI_REGISTRY_IMAGE}:base
## To run the container
# docker run -it -p 127.0.0.1:9092:9092 "${CI_REGISTRY_IMAGE}:base" retroshare-service --jsonApiPort 9092 --jsonApiBindAddress 0.0.0.0
FROM ubuntu
ARG CACHEBUST=0
RUN \
apt-get update -y && apt-get upgrade -y && \
apt-get install -y build-essential libssl-dev libbz2-dev libsqlite3-dev \
libsqlcipher-dev libupnp-dev pkg-config libz-dev \
qt5-default libxapian-dev qttools5-dev doxygen rapidjson-dev \
git cmake curl
ARG FRESHCLONE=0
ARG REPO_URL=https://gitlab.com/RetroShare/RetroShare.git
ARG REPO_BRANCH=master
ARG REPO_DEPTH="--depth 2000"
ARG KEEP_SOURCE=false
RUN apt-get update -y && apt-get upgrade -y
RUN git clone $REPO_DEPTH $REPO_URL -b $REPO_BRANCH && cd RetroShare && \
git fetch --tags && cd ..
RUN \
mkdir RetroShare-build && cd RetroShare-build && \
qmake ../RetroShare \
CONFIG+=no_retroshare_plugins CONFIG+=ipv6 \
CONFIG+=retroshare_service CONFIG+=no_retroshare_gui \
CONFIG+=rs_jsonapi CONFIG+=rs_deep_search && \
(make -j$(nproc) || make -j$(nproc) || make) && make install && \
cd .. && rm -rf RetroShare-build && ($KEEP_SOURCE || rm -rf RetroShare)

View File

@ -0,0 +1,17 @@
FROM registry.gitlab.com/retroshare/retroshare:base
RUN apt-get update -y && apt-get upgrade -y
ARG REPO_URL=https://gitlab.com/RetroShare/RetroShare.git
ARG REPO_BRANCH=master
RUN \
cd RetroShare && git remote add testing $REPO_URL && \
git fetch --tags testing $REPO_BRANCH && \
git reset --hard testing/$REPO_BRANCH
RUN \
mkdir RetroShare-build && cd RetroShare-build && \
qmake ../RetroShare CONFIG+=no_retroshare_gui \
CONFIG+=retroshare_service \
CONFIG+=rs_jsonapi CONFIG+=rs_deep_search && \
(make -j$(nproc) || make -j$(nproc) || make) && make install && \
cd .. && rm -rf RetroShare-build

View File

@ -37,6 +37,7 @@ RsItem *RsDiscSerialiser::create_item(
{
case RsGossipDiscoveryItemType::PGP_LIST: return new RsDiscPgpListItem();
case RsGossipDiscoveryItemType::PGP_CERT_BINARY: return new RsDiscPgpKeyItem();
case RsGossipDiscoveryItemType::PGP_CERT: return new RsDiscPgpCertItem(); // deprecated, hanlde to suppress "unkown item" warning
case RsGossipDiscoveryItemType::CONTACT: return new RsDiscContactItem();
case RsGossipDiscoveryItemType::IDENTITY_LIST: return new RsDiscIdentityListItem();
default:

View File

@ -97,6 +97,27 @@ public:
uint32_t bin_len;
};
class RS_DEPRECATED_FOR(RsDiscPgpKeyItem) RsDiscPgpCertItem: public RsDiscItem
{
public:
RsDiscPgpCertItem() : RsDiscItem(RsGossipDiscoveryItemType::PGP_CERT)
{ setPriorityLevel(QOS_PRIORITY_RS_DISC_PGP_CERT); }
void clear() override
{
pgpId.clear();
pgpCert.clear();
}
void serial_process(RsGenericSerializer::SerializeJob j, RsGenericSerializer::SerializeContext& ctx) override
{
RsTypeSerializer::serial_process(j,ctx,pgpId,"pgpId") ;
RsTypeSerializer::serial_process(j,ctx,TLV_TYPE_STR_PGPCERT,pgpCert,"pgpCert") ;
}
RsPgpId pgpId;
std::string pgpCert;
};
class RsDiscContactItem: public RsDiscItem
{
public:

View File

@ -260,6 +260,7 @@ int p3discovery2::handleIncoming()
{
RsDiscPgpListItem* pgplist = nullptr;
RsDiscPgpKeyItem* pgpkey = nullptr;
RsDiscPgpCertItem* pgpcert = nullptr; // deprecated, hanlde for retro compability
RsDiscContactItem* contact = nullptr;
RsDiscIdentityListItem* gxsidlst = nullptr;
@ -282,6 +283,9 @@ int p3discovery2::handleIncoming()
}
else if((pgpkey = dynamic_cast<RsDiscPgpKeyItem *>(item)) != nullptr)
recvPGPCertificate(item->PeerId(), pgpkey);
else if((pgpcert = dynamic_cast<RsDiscPgpCertItem *>(item)) != nullptr)
// sink
delete pgpcert;
else if((pgplist = dynamic_cast<RsDiscPgpListItem *>(item)) != nullptr)
{
if (pgplist->mode == RsGossipDiscoveryPgpListMode::FRIENDS)

View File

@ -1193,7 +1193,7 @@ bool RsGenExchange::getGroupList(const uint32_t &token, std::list<RsGxsGroupId>
bool RsGenExchange::getMsgList(const uint32_t &token,
GxsMsgIdResult &msgIds)
{
return mDataAccess->getMsgList(token, msgIds);
return mDataAccess->getMsgIdList(token, msgIds);
}
bool RsGenExchange::getMsgRelatedList(const uint32_t &token, MsgRelatedIdResult &msgIds)
@ -1692,7 +1692,7 @@ void RsGenExchange::notifyChangedGroupStats(const RsGxsGroupId &grpId)
{
RS_STACK_MUTEX(mGenMtx);
RsGxsGroupChange* gc = new RsGxsGroupChange(RsGxsNotify::TYPE_PROCESSED, false);
RsGxsGroupChange* gc = new RsGxsGroupChange(RsGxsNotify::TYPE_STATISTICS_CHANGED, false);
gc->mGrpIdList.push_back(grpId);
mNotifications.push_back(gc);
}

File diff suppressed because it is too large Load Diff

View File

@ -22,6 +22,7 @@
#ifndef RSGXSDATAACCESS_H
#define RSGXSDATAACCESS_H
#include <queue>
#include "retroshare/rstokenservice.h"
#include "rsgxsrequesttypes.h"
#include "rsgds.h"
@ -30,6 +31,8 @@
typedef std::map< RsGxsGroupId, std::map<RsGxsMessageId, RsGxsMsgMetaData*> > MsgMetaFilter;
typedef std::map< RsGxsGroupId, RsGxsGrpMetaData* > GrpMetaFilter;
bool operator<(const std::pair<uint32_t,GxsRequest*>& p1,const std::pair<uint32_t,GxsRequest*>& p2);
class RsGxsDataAccess : public RsTokenService
{
public:
@ -56,7 +59,7 @@ public:
* @param groupIds group id to request info for
* @return
*/
bool requestGroupInfo(uint32_t &token, uint32_t ansType, const RsTokReqOptions &opts, const std::list<RsGxsGroupId> &groupIds);
bool requestGroupInfo(uint32_t &token, uint32_t ansType, const RsTokReqOptions &opts, const std::list<RsGxsGroupId> &groupIds) override;
/*!
* Use this to request all group related info
@ -65,7 +68,7 @@ public:
* @param opts Additional option that affect outcome of request. Please see specific services, for valid values
* @return
*/
bool requestGroupInfo(uint32_t &token, uint32_t ansType, const RsTokReqOptions &opts);
bool requestGroupInfo(uint32_t &token, uint32_t ansType, const RsTokReqOptions &opts) override;
/*!
* Use this to get msg information (id, meta, or data), store token value to poll for request completion
@ -75,7 +78,7 @@ public:
* @param groupIds The ids of the groups to get, second entry of map empty to query for all msgs
* @return true if request successful false otherwise
*/
bool requestMsgInfo(uint32_t &token, uint32_t ansType, const RsTokReqOptions &opts, const GxsMsgReq& msgIds);
bool requestMsgInfo(uint32_t &token, uint32_t ansType, const RsTokReqOptions &opts, const GxsMsgReq& msgIds) override;
/*!
* Use this to get message information (id, meta, or data), store token value to poll for request completion
@ -86,7 +89,7 @@ public:
* all messages for all groups are retrieved
* @return true if request successful false otherwise
*/
bool requestMsgInfo(uint32_t &token, uint32_t ansType, const RsTokReqOptions &opts, const std::list<RsGxsGroupId>& grpIds);
bool requestMsgInfo(uint32_t &token, uint32_t ansType, const RsTokReqOptions &opts, const std::list<RsGxsGroupId>& grpIds) override;
/*!
* For requesting msgs related to a given msg id within a group
@ -96,7 +99,7 @@ public:
* @param groupIds The ids of the groups to get, second entry of map empty to query for all msgs
* @return true if request successful false otherwise
*/
bool requestMsgRelatedInfo(uint32_t &token, uint32_t ansType, const RsTokReqOptions &opts, const std::vector<RsGxsGrpMsgIdPair> &msgIds);
bool requestMsgRelatedInfo(uint32_t &token, uint32_t ansType, const RsTokReqOptions &opts, const std::vector<RsGxsGrpMsgIdPair> &msgIds) override;
/*!
* This request statistics on amount of data held
@ -107,19 +110,20 @@ public:
* total size of messages
* total size of groups
* @param token
* @param opts Additional option that affect outcome of request. Please see specific services, for valid values
*/
void requestServiceStatistic(uint32_t& token);
void requestServiceStatistic(uint32_t& token, const RsTokReqOptions &opts) override;
/*!
* To request statistic on a group
* @param token set to value to be redeemed to get statistic
* @param grpId the id of the group
* @param opts Additional option that affect outcome of request. Please see specific services, for valid values
*/
void requestGroupStatistic(uint32_t& token, const RsGxsGroupId& grpId);
void requestGroupStatistic(uint32_t& token, const RsGxsGroupId& grpId, const RsTokReqOptions &opts) override;
/* Poll */
GxsRequestStatus requestStatus(const uint32_t token);
GxsRequestStatus requestStatus(uint32_t token);
/* Cancel Request */
bool cancelRequest(const uint32_t &token);
@ -200,7 +204,8 @@ public:
* @param token request token to be redeemed
* @param msgIds
*/
bool getMsgList(const uint32_t &token, GxsMsgIdResult &msgIds);
bool getMsgIdList(const uint32_t &token, GxsMsgIdResult &msgIds);
/*!
* Retrieve msg list for a given token for message related info
@ -271,7 +276,7 @@ private:
* @param token the value of the token for the request object handle wanted
* @return the request associated to this token
*/
GxsRequest* locked_retrieveRequest(const uint32_t& token);
GxsRequest* locked_retrieveCompetedRequest(const uint32_t& token);
/*!
* Add a gxs request to queue
@ -378,8 +383,18 @@ private:
* @param req
* @return false if unsuccessful, true otherwise
*/
bool getMsgList(MsgIdReq* req);
bool getMsgIdList(MsgIdReq* req);
/*!
* Attempts to retrieve msg Meta list from data store
* Computationally/CPU-Bandwidth expensive
*
* @param msgIds List of message Ids for the Message Metas to retrieve
* @param opts GxsRequest options
* @param result Map of Meta information for messages
*
*/
bool getMsgMetaDataList( const GxsMsgReq& msgIds, const RsTokReqOptions& opts, GxsMsgMetaResult& result );
/*!
* Attempts to retrieve group meta data from data store
@ -445,7 +460,7 @@ private:
* @param opts the request options set by user
* @param meta The accompanying meta information for msg, ids
*/
void filterMsgList(GxsMsgIdResult& msgIds, const RsTokReqOptions& opts, const MsgMetaFilter& meta) const;
void filterMsgIdList(GxsMsgIdResult& msgIds, const RsTokReqOptions& opts, const MsgMetaFilter& meta) const;
/*!
* This filter msgs based of options supplied (at the moment just status masks)
@ -482,9 +497,10 @@ private:
* @param opts the options used to parameterise the id filter
* @param msgIdsOut the left overs ids after filter is applied to msgIds
*/
bool getMsgList(const GxsMsgReq& msgIds, const RsTokReqOptions& opts, GxsMsgReq& msgIdsOut);
bool getMsgIdList(const GxsMsgReq& msgIds, const RsTokReqOptions& opts, GxsMsgReq& msgIdsOut);
private:
bool locked_clearRequest(const uint32_t &token);
RsGeneralDataService* mDataStore;
@ -492,10 +508,9 @@ private:
uint32_t mNextToken;
std::map<uint32_t, GxsRequestStatus> mPublicToken;
std::map<uint32_t, GxsRequest*> mRequests;
std::set<std::pair<uint32_t,GxsRequest*> > mRequestQueue;
std::map<uint32_t, GxsRequest*> mCompletedRequests;
};
#endif // RSGXSDATAACCESS_H

View File

@ -23,6 +23,128 @@
#include "rsgxsrequesttypes.h"
#include "util/rsstd.h"
std::ostream& operator<<(std::ostream& o,const GxsRequest& g)
{
return g.print(o);
}
std::ostream& GroupMetaReq::print(std::ostream& o) const
{
o << "[Request type=GroupMeta groupIds (size=" << mGroupIds.size() << "): " ;
if(!mGroupIds.empty())
{
o << *mGroupIds.begin() ;
if(mGroupIds.size() > 1)
o << " ..." ;
}
o << "]" ;
return o;
}
std::ostream& GroupIdReq::print(std::ostream& o) const
{
return o << "[Request type=GroupIdReq" << "]" ;
}
std::ostream& GroupSerializedDataReq::print(std::ostream& o) const
{
return o << "[Request type=GroupSerializedData" << "]" ;
}
std::ostream& GroupDataReq::print(std::ostream& o) const
{
o << "[Request type=GroupDataReq groupIds (size=" << mGroupIds.size() << "): " ;
if(!mGroupIds.empty())
{
o << *mGroupIds.begin() ;
if(mGroupIds.size() > 1)
o << " ..." ;
}
o << "]" ;
return o;
}
std::ostream& MsgIdReq::print(std::ostream& o) const
{
return o << "[Request type=MsgId" << "]" ;
}
std::ostream& MsgMetaReq::print(std::ostream& o) const
{
o << "[Request type=MsgMetaReq groups (size=" << mMsgIds.size() << "): " ;
if(!mMsgIds.empty())
{
o << mMsgIds.begin()->first << " (" << mMsgIds.begin()->second.size() << " messages)";
if(mMsgIds.size() > 1)
o << " ..." ;
}
o << "]" ;
return o;
}
std::ostream& MsgDataReq::print(std::ostream& o) const
{
o << "[Request type=MsgDataReq groups (size=" << mMsgIds.size() << "): " ;
if(!mMsgIds.empty())
{
o << mMsgIds.begin()->first << " (" << mMsgIds.begin()->second.size() << " messages)";
if(mMsgIds.size() > 1)
o << " ..." ;
}
o << "]" ;
return o;
}
std::ostream& MsgRelatedInfoReq::print(std::ostream& o) const
{
o << "[Request type=MsgRelatedInfo msgIds (size=" << mMsgIds.size() << "): " ;
if(!mMsgIds.empty())
{
o << mMsgIds.begin()->first ;
if(mMsgIds.size() > 1)
o << " ..." ;
}
o << "]" ;
return o;
}
std::ostream& GroupSetFlagReq::print(std::ostream& o) const
{
return o << "[Request type=GroupFlagSet grpId=" << grpId << "]" ;
}
std::ostream& ServiceStatisticRequest::print(std::ostream& o) const
{
return o << "[Request type=ServiceStatistics" << "]" ;
}
std::ostream& GroupStatisticRequest::print(std::ostream& o) const
{
return o << "[Request type=GroupStatistics grpId=" << mGrpId << "]" ;
}
GroupMetaReq::~GroupMetaReq()
{
//rsstd::delete_all(mGroupMetaData.begin(), mGroupMetaData.end()); // now memory ownership is kept by the cache.
@ -57,3 +179,8 @@ MsgRelatedInfoReq::~MsgRelatedInfoReq()
rsstd::delete_all(dataIt->second.begin(), dataIt->second.end());
}
}
std::ostream& MessageSetFlagReq::print(std::ostream& o) const
{
return o << "[Request type=MsgFlagSet" << "]" ;
}

View File

@ -29,25 +29,30 @@
struct GxsRequest
{
GxsRequest() :
token(0), reqTime(0), ansType(0), reqType(0),
token(0), reqTime(0), clientAnswerType(0), reqType(0),
status(RsTokenService::FAILED) {}
virtual ~GxsRequest() {}
uint32_t token;
uint32_t reqTime;
RS_DEPRECATED uint32_t ansType; /// G10h4ck: This is of no use
uint32_t clientAnswerType; /// This is made available to the clients in order to keep track of why specific requests where sent..
uint32_t reqType;
RsTokReqOptions Options;
RsTokenService::GxsRequestStatus status;
virtual std::ostream& print(std::ostream& o) const = 0;
};
std::ostream& operator<<(std::ostream& o,const GxsRequest& g);
class GroupMetaReq : public GxsRequest
{
public:
virtual ~GroupMetaReq();
virtual std::ostream& print(std::ostream& o) const override;
public:
std::list<RsGxsGroupId> mGroupIds;
std::list<const RsGxsGrpMetaData*> mGroupMetaData;
@ -56,12 +61,16 @@ public:
class GroupIdReq : public GxsRequest
{
public:
virtual std::ostream& print(std::ostream& o) const override ;
std::list<RsGxsGroupId> mGroupIds;
std::list<RsGxsGroupId> mGroupIdResult;
};
class GroupSerializedDataReq : public GxsRequest
{
public:
virtual std::ostream& print(std::ostream& o) const override ;
std::list<RsGxsGroupId> mGroupIds;
std::list<RsNxsGrp*> mGroupData;
};
@ -71,6 +80,7 @@ class GroupDataReq : public GxsRequest
public:
virtual ~GroupDataReq();
virtual std::ostream& print(std::ostream& o) const override;
public:
std::list<RsGxsGroupId> mGroupIds;
std::list<RsNxsGrp*> mGroupData;
@ -79,6 +89,8 @@ public:
class MsgIdReq : public GxsRequest
{
public:
virtual std::ostream& print(std::ostream& o) const override ;
GxsMsgReq mMsgIds;
GxsMsgIdResult mMsgIdResult;
};
@ -88,6 +100,8 @@ class MsgMetaReq : public GxsRequest
public:
virtual ~MsgMetaReq();
virtual std::ostream& print(std::ostream& o) const override;
public:
GxsMsgReq mMsgIds;
GxsMsgMetaResult mMsgMetaData;
@ -98,6 +112,7 @@ class MsgDataReq : public GxsRequest
public:
virtual ~MsgDataReq();
virtual std::ostream& print(std::ostream& o) const override;
public:
GxsMsgReq mMsgIds;
NxsMsgDataResult mMsgData;
@ -106,12 +121,15 @@ public:
class ServiceStatisticRequest: public GxsRequest
{
public:
virtual std::ostream& print(std::ostream& o) const override ;
GxsServiceStatistic mServiceStatistic;
};
struct GroupStatisticRequest: public GxsRequest
{
public:
virtual std::ostream& print(std::ostream& o) const override ;
RsGxsGroupId mGrpId;
GxsGroupStatistic mGroupStatistic;
};
@ -121,6 +139,7 @@ class MsgRelatedInfoReq : public GxsRequest
public:
virtual ~MsgRelatedInfoReq();
std::ostream& print(std::ostream& o) const override;
public:
std::vector<RsGxsGrpMsgIdPair> mMsgIds;
MsgRelatedIdResult mMsgIdResult;
@ -131,6 +150,8 @@ public:
class GroupSetFlagReq : public GxsRequest
{
public:
virtual std::ostream& print(std::ostream& o) const override ;
const static uint32_t FLAG_SUBSCRIBE;
const static uint32_t FLAG_STATUS;
@ -145,6 +166,7 @@ class MessageSetFlagReq : public GxsRequest
public:
const static uint32_t FLAG_STATUS;
virtual std::ostream& print(std::ostream& o) const override ;
uint8_t type;
uint32_t flag;
uint32_t flagMask;

View File

@ -43,7 +43,7 @@ p3GxsTrans::~p3GxsTrans()
}
}
bool p3GxsTrans::getStatistics(GxsTransStatistics& stats)
bool p3GxsTrans::getDataStatistics(GxsTransStatistics& stats)
{
{
RS_STACK_MUTEX(mDataMutex);
@ -1335,4 +1335,53 @@ bool p3GxsTrans::acceptNewMessage(const RsGxsMsgMetaData *msgMeta,uint32_t msg_s
}
bool p3GxsTrans::getGroupStatistics(std::map<RsGxsGroupId,RsGxsTransGroupStatistics>& stats)
{
uint32_t token1;
RsTokReqOptions opts1;
opts1.mReqType = GXS_REQUEST_TYPE_GROUP_META;
if( !requestGroupInfo(token1, opts1) || waitToken(token1) != RsTokenService::COMPLETE )
return false;
std::list<RsGroupMetaData> group_metas;
getGroupSummary(token1,group_metas);
for(auto& group_meta:group_metas)
{
RsGxsTransGroupStatistics& stat(stats[group_meta.mGroupId]);
uint32_t token2;
if(!RsGxsIfaceHelper::requestGroupStatistic(token2,group_meta.mGroupId) || waitToken(token2) != RsTokenService::COMPLETE)
continue;
RsGenExchange::getGroupStatistic(token2,stat);
stat.popularity = group_meta.mPop ;
stat.subscribed = IS_GROUP_SUBSCRIBED(group_meta.mSubscribeFlags) ;
stat.mGrpId = group_meta.mGroupId ;
std::vector<RsMsgMetaData> metas;
uint32_t token3;
RsTokReqOptions opts;
opts.mReqType = GXS_REQUEST_TYPE_MSG_META;
std::list<RsGxsGroupId> groupIds;
groupIds.push_back(group_meta.mGroupId);
if( !requestMsgInfo(token3, opts, groupIds) || waitToken(token3, std::chrono::seconds(5)) != RsTokenService::COMPLETE )
continue;
GxsMsgMetaMap metaMap;
if(!RsGenExchange::getMsgMeta(token3, metaMap) || metaMap.size() != 1)
continue;
for(auto& meta: metaMap.begin()->second)
stat.addMessageMeta(group_meta.mGroupId,meta) ;
}
return true;
}

View File

@ -113,13 +113,21 @@ public:
/*!
* \brief getStatistics
* Gathers all sorts of statistics about the internals of p3GxsTrans, in order to display info about the running status,
* message transport, etc.
* Gathers all sorts of statistics about the data transported by p3GxsTrans, in order to display info about the running status,
* message transport, etc. This is a blocking call. Use it in a thread.
* \param stats This structure contains all statistics information.
* \return true is the call succeeds.
*/
virtual bool getStatistics(GxsTransStatistics& stats);
virtual bool getDataStatistics(GxsTransStatistics& stats) override;
/*!
* \brief getGroupStatistics
* Gathers statistics about GXS groups and messages used by GxsTrans to transport data. This is a blocking call. Use it in a thread.
* \param stats
* \return true if the data collection succeeds.
*/
virtual bool getGroupStatistics(std::map<RsGxsGroupId,RsGxsTransGroupStatistics>& stats) override;
/**
* Send an email to recipient, in the process author of the email is

View File

@ -362,6 +362,7 @@ bool RsPluginManager::loadPlugin(const std::string& plugin_name,bool first_time)
dlclose(handle);
return false ;
}
#ifdef TO_REMOVE
if(pinfo.svn_revision == 0)
{
std::cerr << " -> No svn revision number." << std::endl;
@ -370,6 +371,7 @@ bool RsPluginManager::loadPlugin(const std::string& plugin_name,bool first_time)
dlclose(handle);
return false ;
}
#endif
// Now look for the plugin class symbol.
//

View File

@ -111,6 +111,7 @@ enum class RsChannelEventCode: uint8_t
SUBSCRIBE_STATUS_CHANGED = 0x06, // subscription for channel mChannelGroupId changed.
READ_STATUS_CHANGED = 0x07, // existing message has been read or set to unread
RECEIVED_DISTANT_SEARCH_RESULT = 0x08, // result for the given group id available for the given turtle request id
STATISTICS_CHANGED = 0x09, // stats (nb of supplier friends, how many msgs they have etc) has changed
};
struct RsGxsChannelEvent: RsEvent
@ -409,6 +410,14 @@ public:
virtual bool subscribeToChannel( const RsGxsGroupId& channelId,
bool subscribe ) = 0;
/**
* \brief Retrieve statistics about the channel service
* @jsonapi{development}
* \param[out] stat Statistics structure
* \return
*/
virtual bool getChannelServiceStatistics(GxsServiceStatistic& stat) =0;
/**
* \brief Retrieve statistics about the given channel
* @jsonapi{development}
@ -418,6 +427,7 @@ public:
*/
virtual bool getChannelStatistics(const RsGxsGroupId& channelId,GxsGroupStatistic& stat) =0;
/**
* @brief Request remote channels search
* @jsonapi{development}

View File

@ -111,6 +111,7 @@ enum class RsForumEventCode: uint8_t
UPDATED_MESSAGE = 0x04, /// existing message has been updated in a particular forum
SUBSCRIBE_STATUS_CHANGED = 0x05, /// forum was subscribed or unsubscribed
READ_STATUS_CHANGED = 0x06, /// msg was read or marked unread
STATISTICS_CHANGED = 0x07, /// suppliers and how many messages they have changed
};
struct RsGxsForumEvent: RsEvent
@ -219,6 +220,14 @@ public:
*/
virtual bool getForumsSummaries(std::list<RsGroupMetaData>& forums) = 0;
/**
* @brief returns statistics for the forum service
* @jsonapi{development}
* @param[out] stat statistics struct
* @return false if the call fails
*/
virtual bool getForumServiceStatistics(GxsServiceStatistic& stat) =0;
/**
* @brief returns statistics about a particular forum
* @jsonapi{development}
@ -228,6 +237,7 @@ public:
*/
virtual bool getForumStatistics(const RsGxsGroupId& forumId,GxsGroupStatistic& stat)=0;
/**
* @brief Get forums information (description, thumbnail...).
* Blocking API.

View File

@ -40,7 +40,9 @@
* are necessary, so at this point this workaround seems acceptable.
*/
//#define DEBUG_GXSIFACEHELPER 1
//==================================
// #define DEBUG_GXSIFACEHELPER 1
//==================================
enum class TokenRequestType: uint8_t
{
@ -85,8 +87,7 @@ public:
* @param groupIds the ids return for given request token
* @return false if request token is invalid, check token status for error report
*/
bool getGroupList(const uint32_t &token,
std::list<RsGxsGroupId> &groupIds)
bool getGroupList(const uint32_t &token, std::list<RsGxsGroupId> &groupIds)
{
return mGxs.getGroupList(token, groupIds);
}
@ -119,8 +120,7 @@ public:
* @param groupInfo the ids returned for given request token
* @return false if request token is invalid, check token status for error report
*/
bool getGroupSummary(const uint32_t &token,
std::list<RsGroupMetaData> &groupInfo)
bool getGroupSummary(const uint32_t &token, std::list<RsGroupMetaData> &groupInfo)
{
return mGxs.getGroupMeta(token, groupInfo);
}
@ -130,8 +130,7 @@ public:
* @param msgInfo the message metadata returned for given request token
* @return false if request token is invalid, check token status for error report
*/
bool getMsgSummary(const uint32_t &token,
GxsMsgMetaMap &msgInfo)
bool getMsgSummary(const uint32_t &token, GxsMsgMetaMap &msgInfo)
{
return mGxs.getMsgMeta(token, msgInfo);
}
@ -368,9 +367,12 @@ public:
{ return mTokenService.requestStatus(token); }
/// @see RsTokenService::requestServiceStatistic
void requestServiceStatistic(uint32_t& token)
bool requestServiceStatistic(uint32_t& token)
{
mTokenService.requestServiceStatistic(token);
RsTokReqOptions opts;
opts.mReqType = GXS_REQUEST_TYPE_SERVICE_STATS;
mTokenService.requestServiceStatistic(token,opts);
RS_STACK_MUTEX(mMtx);
mActiveTokens[token]=TokenRequestType::SERVICE_STATISTICS;
@ -378,12 +380,16 @@ public:
#ifdef DEBUG_GXSIFACEHELPER
locked_dumpTokens();
#endif
return true;
}
/// @see RsTokenService::requestGroupStatistic
bool requestGroupStatistic(uint32_t& token, const RsGxsGroupId& grpId)
{
mTokenService.requestGroupStatistic(token, grpId);
RsTokReqOptions opts;
opts.mReqType = GXS_REQUEST_TYPE_GROUP_STATS;
mTokenService.requestGroupStatistic(token, grpId,opts);
RS_STACK_MUTEX(mMtx);
mActiveTokens[token]=TokenRequestType::GROUP_STATISTICS;
@ -501,7 +507,7 @@ private:
uint32_t count[7] = {0};
std::cerr << "Service " << std::hex << service_id << std::dec
RsDbg() << "Service " << std::hex << service_id << std::dec
<< " (" << rsServiceControl->getServiceName(RsServiceInfo::RsServiceInfoUIn16ToFullServiceId(service_id))
<< ") this=" << std::hex << (void*)this << std::dec << ") Active tokens (per type): " ;

View File

@ -45,6 +45,13 @@ struct RsMsgMetaData;
typedef std::map<RsGxsGroupId, std::vector<RsMsgMetaData> > MsgMetaResult;
enum class GxsRequestPriority {
VERY_HIGH = 0x00,
HIGH = 0x01,
NORMAL = 0x02,
LOW = 0x03,
VERY_LOW = 0x04,
};
class RsGxsGrpMetaData;
class RsGxsMsgMetaData;
@ -232,7 +239,7 @@ public:
mNumChildMsgsNew = 0;
mNumChildMsgsUnread = 0;
mSizeStore = 0;
}
}
public:
uint32_t mNumMsgs;

View File

@ -46,7 +46,8 @@ struct RsGxsNotify
TYPE_RECEIVED_NEW = 0x02,
TYPE_PROCESSED = 0x03,
TYPE_RECEIVED_PUBLISHKEY = 0x04,
TYPE_RECEIVED_DISTANT_SEARCH_RESULTS = 0x05
TYPE_RECEIVED_DISTANT_SEARCH_RESULTS = 0x05,
TYPE_STATISTICS_CHANGED = 0x06
};
virtual ~RsGxsNotify() {}

View File

@ -70,10 +70,8 @@ enum class GxsTransSendStatus : uint8_t
typedef uint64_t RsGxsTransId;
class RsGxsTransGroup
class RsGxsTransGroup: public RsGxsGenericGroupData
{
public:
RsGroupMetaData mMeta;
};
class RsGxsTransMsg
@ -103,7 +101,34 @@ struct RsGxsTransOutgoingRecord
RsGxsGroupId group_id ;
};
class RsGxsTransGroupStatistics: public GxsGroupStatistic
{
public:
RsGxsTransGroupStatistics()
{
last_publish_TS = 0;
popularity = 0;
subscribed = false;
}
void addMessageMeta(const RsGxsGroupId& grp,const RsMsgMetaData& meta)
{
messages_metas[meta.mMsgId] = meta ;
last_publish_TS = std::max(last_publish_TS,meta.mPublishTs) ;
mGrpId = grp ;
}
bool subscribed ;
int popularity ;
rstime_t last_publish_TS;
std::map<RsGxsMessageId,RsMsgMetaData> messages_metas ;
};
/// RetroShare GxsTrans asyncronous redundant small mail trasport on top of GXS
///
class RsGxsTrans: public RsGxsIfaceHelper
{
public:
@ -120,10 +145,8 @@ public:
virtual ~RsGxsTrans() {}
virtual bool getStatistics(GxsTransStatistics& stats)=0;
// virtual bool getGroupData(const uint32_t &token, std::vector<RsGxsTransGroup> &groups) = 0;
// virtual bool getPostData(const uint32_t &token, std::vector<RsGxsTransMsg> &posts) = 0;
virtual bool getDataStatistics(GxsTransStatistics& stats)=0;
virtual bool getGroupStatistics(std::map<RsGxsGroupId,RsGxsTransGroupStatistics>& stats) =0;
};
extern RsGxsTrans *rsGxsTrans ;

View File

@ -313,7 +313,8 @@ extern RsAccounts* rsAccounts;
class RsLoginHelper
{
public:
RsLoginHelper() {}
RsLoginHelper() = default;
/**
* @brief Normal way to attempt login
* @jsonapi{development,manualwrapper}

View File

@ -988,7 +988,17 @@ virtual void getOwnAvatarData(unsigned char *& data,int& size) = 0 ;
virtual uint32_t getDistantChatPermissionFlags()=0 ;
virtual bool setDistantChatPermissionFlags(uint32_t flags)=0 ;
virtual bool initiateDistantChatConnexion(
/**
* @brief initiateDistantChatConnexion initiate a connexion for a distant chat
* @jsonapi{development}
* @param[in] to_pid RsGxsId to start the connection
* @param[in] from_pid owned RsGxsId who start the connection
* @param[out] pid distant chat id
* @param[out] error_code if the connection can't be stablished
* @param[in] notify notify remote that the connection is stablished
* @return true on success
*/
virtual bool initiateDistantChatConnexion(
const RsGxsId& to_pid, const RsGxsId& from_pid,
DistantChatPeerId& pid, uint32_t& error_code,
bool notify = true ) = 0;
@ -1001,7 +1011,14 @@ virtual bool initiateDistantChatConnexion(
* @return true on success
*/
virtual bool getDistantChatStatus(const DistantChatPeerId& pid, DistantChatPeerInfo& info)=0;
virtual bool closeDistantChatConnexion(const DistantChatPeerId& pid)=0;
/**
* @brief closeDistantChatConnexion
* @jsonapi{development}
* @param[in] pid distant chat id to close the connection
* @return true on success
*/
virtual bool closeDistantChatConnexion(const DistantChatPeerId& pid)=0;
/**
* @brief MessageSend

View File

@ -114,6 +114,7 @@ enum class RsPostedEventCode: uint8_t
UPDATED_POSTED_GROUP = 0x04,
UPDATED_MESSAGE = 0x05,
READ_STATUS_CHANGED = 0x06,
STATISTICS_CHANGED = 0x07,
};
@ -167,6 +168,8 @@ public:
virtual bool getBoardStatistics(const RsGxsGroupId& boardId,GxsGroupStatistic& stat) =0;
virtual bool getBoardsServiceStatistics(GxsServiceStatistic& stat) =0;
enum RS_DEPRECATED RankType {TopRankType, HotRankType, NewRankType };
RS_DEPRECATED_FOR(getBoardsInfo)

View File

@ -80,7 +80,7 @@ struct RsTokReqOptions
{
RsTokReqOptions() : mOptions(0), mStatusFilter(0), mStatusMask(0),
mMsgFlagMask(0), mMsgFlagFilter(0), mReqType(0), mSubscribeFilter(0),
mSubscribeMask(0), mBefore(0), mAfter(0) {}
mSubscribeMask(0), mBefore(0), mAfter(0),mPriority(GxsRequestPriority::NORMAL) {}
/**
* Can be one or multiple RS_TOKREQOPT_*
@ -107,6 +107,8 @@ struct RsTokReqOptions
// Time range... again applied after Options.
rstime_t mBefore;
rstime_t mAfter;
GxsRequestPriority mPriority;
};
/*!
@ -181,6 +183,25 @@ public:
*/
virtual bool requestMsgRelatedInfo(uint32_t &token, uint32_t ansType, const RsTokReqOptions &opts, const std::vector<RsGxsGrpMsgIdPair>& msgIds) = 0;
/*!
* This request statistics on amount of data held
* number of groups
* number of groups subscribed
* number of messages
* size of db store
* total size of messages
* total size of groups
* @param token
*/
virtual void requestServiceStatistic(uint32_t& token, const RsTokReqOptions &opts) = 0;
/*!
* To request statistic on a group
* @param token set to value to be redeemed to get statistic
* @param grpId the id of the group
*/
virtual void requestGroupStatistic(uint32_t& token, const RsGxsGroupId& grpId, const RsTokReqOptions &opts) = 0;
/* Poll */
@ -194,25 +215,6 @@ public:
*/
virtual GxsRequestStatus requestStatus(const uint32_t token) = 0;
/*!
* This request statistics on amount of data held
* number of groups
* number of groups subscribed
* number of messages
* size of db store
* total size of messages
* total size of groups
* @param token
*/
virtual void requestServiceStatistic(uint32_t& token) = 0;
/*!
* To request statistic on a group
* @param token set to value to be redeemed to get statistic
* @param grpId the id of the group
*/
virtual void requestGroupStatistic(uint32_t& token, const RsGxsGroupId& grpId) = 0;
/*!
* @brief Cancel Request
* If this function returns false, it may be that the request has completed

View File

@ -28,6 +28,7 @@
#include "retroshare/rstokenservice.h"
#include "retroshare/rsgxsifacehelper.h"
#include "retroshare/rsgxscommon.h"
/* The Main Interface Class - for information about your Peers */
@ -38,6 +39,7 @@ struct RsWireGroup: RsGxsGenericGroupData
{
public:
std::string mDescription;
RsGxsImage mIcon;
};
@ -93,9 +95,10 @@ class RsWirePlace
#define WIRE_PULSE_TYPE_REPLY_MSG (0x0002)
#define WIRE_PULSE_TYPE_REPLY_REFERENCE (0x0004)
#define WIRE_PULSE_TYPE_SENTIMENT_POSITIVE (0x0010)
#define WIRE_PULSE_TYPE_SENTIMENT_NEUTRAL (0x0020)
#define WIRE_PULSE_TYPE_SENTIMENT_NEGATIVE (0x0040)
#define WIRE_PULSE_SENTIMENT_NO_SENTIMENT (0x0000)
#define WIRE_PULSE_SENTIMENT_POSITIVE (0x0001)
#define WIRE_PULSE_SENTIMENT_NEUTRAL (0x0002)
#define WIRE_PULSE_SENTIMENT_NEGATIVE (0x0003)
class RsWirePulse
{
@ -107,6 +110,7 @@ class RsWirePulse
std::string mPulseText;
uint32_t mPulseType;
uint32_t mReplySentiment; // only relevant if a reply.
// These Ref to the related (parent or reply) if reply (MODE_REPLY_MSG set)
// Mode REPLY_MSG only REPLY_REFERENCE

View File

@ -44,17 +44,20 @@ RsItem *RsGxsWireSerialiser::create_item(uint16_t service,uint8_t item_subtype)
void RsGxsWireGroupItem::clear()
{
group.mDescription.clear();
group.mIcon.clear();
}
void RsGxsWireGroupItem::serial_process(RsGenericSerializer::SerializeJob j,RsGenericSerializer::SerializeContext& ctx)
{
RsTypeSerializer::serial_process(j,ctx,TLV_TYPE_STR_DESCR,group.mDescription,"group.mDescription") ;
group.mIcon.serial_process(j, ctx);
}
void RsGxsWirePulseItem::clear()
{
pulse.mPulseText.clear();
pulse.mPulseType = 0;
pulse.mReplySentiment = 0;
pulse.mRefGroupId.clear();
pulse.mRefGroupName.clear();
pulse.mRefOrigMsgId.clear();
@ -66,6 +69,7 @@ void RsGxsWirePulseItem::serial_process(RsGenericSerializer::SerializeJob j,RsGe
{
RsTypeSerializer::serial_process(j,ctx,TLV_TYPE_STR_MSG,pulse.mPulseText,"pulse.mPulseText") ;
RsTypeSerializer::serial_process(j,ctx,TLV_TYPE_UINT32_PARAM,pulse.mPulseType,"pulse.mPulseType") ;
RsTypeSerializer::serial_process(j,ctx,TLV_TYPE_UINT32_PARAM,pulse.mReplySentiment,"pulse.mReplySentiment") ;
RsTypeSerializer::serial_process(j,ctx,pulse.mRefGroupId,"pulse.mRefGroupId") ;
RsTypeSerializer::serial_process(j,ctx,TLV_TYPE_STR_NAME,pulse.mRefGroupName,"pulse.mRefGroupName") ;
RsTypeSerializer::serial_process(j,ctx,pulse.mRefOrigMsgId,"pulse.mRefOrigMsgId") ;

View File

@ -302,7 +302,6 @@ void p3GxsChannels::notifyChanges(std::vector<RsGxsNotify *> &changes)
{
switch (grpChange->getType())
{
default:
case RsGxsNotify::TYPE_PROCESSED: // happens when the group is subscribed
{
std::list<RsGxsGroupId> &grpList = grpChange->mGrpIdList;
@ -318,6 +317,20 @@ void p3GxsChannels::notifyChanges(std::vector<RsGxsNotify *> &changes)
}
break;
case RsGxsNotify::TYPE_STATISTICS_CHANGED:
{
std::list<RsGxsGroupId> &grpList = grpChange->mGrpIdList;
std::list<RsGxsGroupId>::iterator git;
for (git = grpList.begin(); git != grpList.end(); ++git)
{
auto ev = std::make_shared<RsGxsChannelEvent>();
ev->mChannelGroupId = *git;
ev->mChannelEventCode = RsChannelEventCode::STATISTICS_CHANGED;
rsEvents->postEvent(ev);
}
}
break;
case RsGxsNotify::TYPE_PUBLISHED:
case RsGxsNotify::TYPE_RECEIVED_NEW:
{
@ -356,9 +369,14 @@ void p3GxsChannels::notifyChanges(std::vector<RsGxsNotify *> &changes)
rsEvents->postEvent(ev);
}
}
break;
default:
RsErr() << " Got a GXS event of type " << grpChange->getType() << " Currently not handled." << std::endl;
break;
}
}
}
RsGxsDistantSearchResultChange *dsrChange = dynamic_cast<RsGxsDistantSearchResultChange*>(*it);
@ -1062,6 +1080,15 @@ bool p3GxsChannels::getChannelStatistics(const RsGxsGroupId& channelId,GxsGroupS
return RsGenExchange::getGroupStatistic(token,stat);
}
bool p3GxsChannels::getChannelServiceStatistics(GxsServiceStatistic& stat)
{
uint32_t token;
if(!RsGxsIfaceHelper::requestServiceStatistic(token) || waitToken(token) != RsTokenService::COMPLETE)
return false;
return RsGenExchange::getServiceStatistic(token,stat);
}
bool p3GxsChannels::getContentSummaries(
const RsGxsGroupId& channelId, std::vector<RsMsgMetaData>& summaries )
{

View File

@ -204,6 +204,9 @@ virtual bool ExtraFileRemove(const RsFileHash &hash);
/// Implementation of @see RsGxsChannels::getChannelStatistics
bool getChannelStatistics(const RsGxsGroupId& channelId,GxsGroupStatistic& stat) override;
/// Iplementation of @see RsGxsChannels::getChannelServiceStatistics
bool getChannelServiceStatistics(GxsServiceStatistic& stat) override;
/// Implementation of @see RsGxsChannels::createChannelV2
bool createChannelV2(
const std::string& name, const std::string& description,

View File

@ -246,7 +246,6 @@ void p3GxsForums::notifyChanges(std::vector<RsGxsNotify *> &changes)
{
switch (grpChange->getType())
{
default:
case RsGxsNotify::TYPE_PROCESSED: // happens when the group is subscribed
{
std::list<RsGxsGroupId> &grpList = grpChange->mGrpIdList;
@ -260,7 +259,7 @@ void p3GxsForums::notifyChanges(std::vector<RsGxsNotify *> &changes)
}
}
break;
break;
case RsGxsNotify::TYPE_PUBLISHED:
case RsGxsNotify::TYPE_RECEIVED_NEW:
@ -288,8 +287,26 @@ void p3GxsForums::notifyChanges(std::vector<RsGxsNotify *> &changes)
<< " Not notifying already known forum "
<< *git << std::endl;
}
break;
}
break;
case RsGxsNotify::TYPE_STATISTICS_CHANGED:
{
std::list<RsGxsGroupId> &grpList = grpChange->mGrpIdList;
std::list<RsGxsGroupId>::iterator git;
for (git = grpList.begin(); git != grpList.end(); ++git)
{
auto ev = std::make_shared<RsGxsForumEvent>();
ev->mForumGroupId = *git;
ev->mForumEventCode = RsForumEventCode::STATISTICS_CHANGED;
rsEvents->postEvent(ev);
}
}
break;
default:
RsErr() << " Got a GXS event of type " << grpChange->getType() << " Currently not handled." << std::endl;
break;
#ifdef NOT_USED_YET
case RsGxsNotify::TYPE_RECEIVED_PUBLISHKEY:
@ -819,6 +836,15 @@ bool p3GxsForums::createGroup(uint32_t &token, RsGxsForumGroup &group)
return true;
}
bool p3GxsForums::getForumServiceStatistics(GxsServiceStatistic& stat)
{
uint32_t token;
if(!RsGxsIfaceHelper::requestServiceStatistic(token) || waitToken(token) != RsTokenService::COMPLETE)
return false;
return RsGenExchange::getServiceStatistic(token,stat);
}
bool p3GxsForums::getForumStatistics(const RsGxsGroupId& ForumId,GxsGroupStatistic& stat)
{
uint32_t token;

View File

@ -97,6 +97,9 @@ public:
/// Implementation of @see RsGxsForums::getForumStatistics
bool getForumStatistics(const RsGxsGroupId& ForumId,GxsGroupStatistic& stat) override;
/// Implementation of @see RsGxsForums::getForumServiceStatistics
bool getForumServiceStatistics(GxsServiceStatistic& stat) override;
/// @see RsGxsForums::getForumMsgMetaData
virtual bool getForumMsgMetaData(const RsGxsGroupId& forumId, std::vector<RsMsgMetaData>& msg_metas) ;

View File

@ -133,8 +133,7 @@ void p3PostBase::notifyChanges(std::vector<RsGxsNotify *> &changes)
#endif
switch(grpChange->getType())
{
default:
{
case RsGxsNotify::TYPE_PROCESSED: // happens when the group is subscribed
{
std::list<RsGxsGroupId> &grpList = grpChange->mGrpIdList;
@ -148,15 +147,30 @@ void p3PostBase::notifyChanges(std::vector<RsGxsNotify *> &changes)
}
}
break;
break;
case RsGxsNotify::TYPE_PUBLISHED:
case RsGxsNotify::TYPE_RECEIVED_NEW:
{
/* group received */
const std::list<RsGxsGroupId>& grpList = grpChange->mGrpIdList;
case RsGxsNotify::TYPE_STATISTICS_CHANGED:
{
std::list<RsGxsGroupId> &grpList = grpChange->mGrpIdList;
std::list<RsGxsGroupId>::iterator git;
for (auto git = grpList.begin(); git != grpList.end(); ++git)
for (git = grpList.begin(); git != grpList.end(); ++git)
{
auto ev = std::make_shared<RsGxsPostedEvent>();
ev->mPostedGroupId = *git;
ev->mPostedEventCode = RsPostedEventCode::STATISTICS_CHANGED;
rsEvents->postEvent(ev);
}
}
break;
case RsGxsNotify::TYPE_PUBLISHED:
case RsGxsNotify::TYPE_RECEIVED_NEW:
{
/* group received */
const std::list<RsGxsGroupId>& grpList = grpChange->mGrpIdList;
for (auto git = grpList.begin(); git != grpList.end(); ++git)
{
if(mKnownPosted.find(*git) == mKnownPosted.end())
{
@ -178,9 +192,13 @@ void p3PostBase::notifyChanges(std::vector<RsGxsNotify *> &changes)
<< " Not notifying already known forum "
<< *git << std::endl;
}
}
}
break;
}
default:
RsErr() << " Got a GXS event of type " << grpChange->getType() << " Currently not handled." << std::endl;
break;
}
}
delete *it;

View File

@ -364,6 +364,16 @@ bool p3Posted::getBoardsSummaries(std::list<RsGroupMetaData>& boards )
return getGroupSummary(token, boards);
}
bool p3Posted::getBoardsServiceStatistics(GxsServiceStatistic& stat)
{
uint32_t token;
if(!RsGxsIfaceHelper::requestServiceStatistic(token) || waitToken(token) != RsTokenService::COMPLETE)
return false;
return RsGenExchange::getServiceStatistic(token,stat);
}
bool p3Posted::getBoardStatistics(const RsGxsGroupId& boardId,GxsGroupStatistic& stat)
{
uint32_t token;

View File

@ -74,6 +74,8 @@ virtual void receiveHelperChanges(std::vector<RsGxsNotify*>& changes)
bool getBoardStatistics(const RsGxsGroupId& boardId,GxsGroupStatistic& stat) override;
bool getBoardsServiceStatistics(GxsServiceStatistic& stat) override;
bool editBoard(RsPostedGroup& board) override;
bool createBoard(RsPostedGroup& board) override;

View File

@ -75,7 +75,8 @@ private:
#else // def __ANDROID__
#include <iostream>
#include <ctime>
#include <chrono>
#include <iomanip>
enum class RsLoggerCategories
{
@ -96,8 +97,15 @@ struct t_RsLogger
template<typename T>
inline stream_type& operator<<(const T& val)
{
return std::cerr << static_cast<char>(CATEGORY) << " " << time(nullptr)
<< " " << val;
using namespace std::chrono;
const auto now = system_clock::now();
const auto sec = time_point_cast<seconds>(now);
const auto msec = duration_cast<milliseconds>(now - sec);
const auto tFill = std::cerr.fill();
return std::cerr << static_cast<char>(CATEGORY) << " "
<< sec.time_since_epoch().count() << "."
<< std::setfill('0') << std::setw(3) << msec.count()
<< std::setfill(tFill) << " " << val;
}
};
#endif // def __ANDROID__

View File

@ -418,9 +418,7 @@ void ChatLobbyWidget::addChatPage(ChatLobbyDialog *d)
if(_lobby_infos.find(d->id()) == _lobby_infos.end())
{
ui.stackedWidget->addWidget(d) ;
connect(d,SIGNAL(lobbyLeave(ChatLobbyId)),this,SLOT(unsubscribeChatLobby(ChatLobbyId))) ;
connect(d,SIGNAL(dialogClose(ChatDialog*)),this,SLOT(dialogClose(ChatDialog*)));
connect(d,SIGNAL(typingEventReceived(ChatLobbyId)),this,SLOT(updateTypingStatus(ChatLobbyId))) ;
connect(d,SIGNAL(messageReceived(bool,ChatLobbyId,QDateTime,QString,QString)),this,SLOT(updateMessageChanged(bool,ChatLobbyId,QDateTime,QString,QString))) ;
connect(d,SIGNAL(peerJoined(ChatLobbyId)),this,SLOT(updatePeerEntering(ChatLobbyId))) ;
@ -429,14 +427,33 @@ void ChatLobbyWidget::addChatPage(ChatLobbyDialog *d)
ChatLobbyId id = d->id();
_lobby_infos[id].dialog = d ;
_lobby_infos[id].default_icon = QIcon() ;
_lobby_infos[id].last_typing_event = time(NULL) ;
_lobby_infos[id].last_typing_event = time(nullptr) ;
ChatLobbyInfo linfo ;
if(rsMsgs->getChatLobbyInfo(id,linfo))
_lobby_infos[id].default_icon = (linfo.lobby_flags & RS_CHAT_LOBBY_FLAGS_PUBLIC) ? QIcon(IMAGE_PUBLIC):QIcon(IMAGE_PRIVATE) ;
else
std::cerr << "(EE) cannot find info for room " << std::hex << id << std::dec << std::endl;
ChatLobbyInfo linfo ;
if(rsMsgs->getChatLobbyInfo(id,linfo))
_lobby_infos[id].default_icon = (linfo.lobby_flags & RS_CHAT_LOBBY_FLAGS_PUBLIC) ? QIcon(IMAGE_PUBLIC):QIcon(IMAGE_PRIVATE) ;
else
std::cerr << "(EE) cannot find info for room " << std::hex << id << std::dec << std::endl;
}
ui.stackedWidget->addWidget(d) ;
}
void ChatLobbyWidget::removeChatPage(ChatLobbyDialog *d)
{
// check that the page already exist.
if(_lobby_infos.find(d->id()) != _lobby_infos.end())
{
ui.stackedWidget->removeWidget(d) ;
}
}
void ChatLobbyWidget::dialogClose(ChatDialog* cd)
{
ChatLobbyDialog* d = dynamic_cast<ChatLobbyDialog*>(cd);
if(_lobby_infos.find(d->id()) != _lobby_infos.end())
unsubscribeChatLobby(d->id());
}
void ChatLobbyWidget::setCurrentChatPage(ChatLobbyDialog *d)
@ -708,7 +725,7 @@ void ChatLobbyWidget::createChatLobby()
void ChatLobbyWidget::showLobby(QTreeWidgetItem *item)
{
if (item == NULL || item->type() != TYPE_LOBBY) {
if (item == nullptr || item->type() != TYPE_LOBBY) {
showBlankPage(0) ;
return;
}
@ -718,7 +735,11 @@ void ChatLobbyWidget::showLobby(QTreeWidgetItem *item)
if(_lobby_infos.find(id) == _lobby_infos.end())
showBlankPage(id) ;
else
ui.stackedWidget->setCurrentWidget(_lobby_infos[id].dialog) ;
{
_lobby_infos[id].dialog->showDialog(RS_CHAT_FOCUS);
if (_lobby_infos[id].dialog->isWindowed())
showBlankPage(id, true);
}
}
// this function is for the case where we don't have any identity yet
@ -772,17 +793,17 @@ bool ChatLobbyWidget::showLobbyAnchor(ChatLobbyId id, QString anchor)
{
QTreeWidgetItem *item = getTreeWidgetItem(id) ;
if(item != NULL) {
if(item != nullptr) {
if(item->type() == TYPE_LOBBY) {
if(_lobby_infos.find(id) == _lobby_infos.end()) {
showBlankPage(id) ;
} else {
//ChatLobbyDialog cldChatLobby =_lobby_infos[id].dialog;
ui.stackedWidget->setCurrentWidget(_lobby_infos[id].dialog) ;
ChatLobbyDialog *cldCW=NULL ;
if (NULL != (cldCW = dynamic_cast<ChatLobbyDialog *>(ui.stackedWidget->currentWidget())))
cldCW->getChatWidget()->scrollToAnchor(anchor);
_lobby_infos[id].dialog->showDialog(RS_CHAT_FOCUS);
if (_lobby_infos[id].dialog->isWindowed())
showBlankPage(id, true);
_lobby_infos[id].dialog->getChatWidget()->scrollToAnchor(anchor);
}
ui.lobbyTreeWidget->setCurrentItem(item);
@ -857,19 +878,19 @@ void ChatLobbyWidget::autoSubscribeLobby(QTreeWidgetItem *item)
subscribeChatLobbyAtItem(item);
}
void ChatLobbyWidget::showBlankPage(ChatLobbyId id)
void ChatLobbyWidget::showBlankPage(ChatLobbyId id, bool subscribed /*= false*/)
{
// show the default blank page.
ui.stackedWidget->setCurrentWidget(ui._lobby_blank_page) ;
// Update information
std::vector<VisibleChatLobbyRecord> lobbies;
rsMsgs->getListOfNearbyChatLobbies(lobbies);
rsMsgs->getListOfNearbyChatLobbies(lobbies);
std::list<RsGxsId> my_ids ;
rsIdentity->getOwnIds(my_ids) ;
std::list<RsGxsId> my_ids ;
rsIdentity->getOwnIds(my_ids) ;
trimAnonIds(my_ids) ;
trimAnonIds(my_ids) ;
for(std::vector<VisibleChatLobbyRecord>::const_iterator it(lobbies.begin());it!=lobbies.end();++it)
if( (*it).lobby_id == id)
@ -881,8 +902,10 @@ void ChatLobbyWidget::showBlankPage(ChatLobbyId id)
ui.lobbysec_lineEdit->setText( (( (*it).lobby_flags & RS_CHAT_LOBBY_FLAGS_PGP_SIGNED)?tr("No anonymous IDs"):tr("Anonymous IDs accepted")) );
ui.lobbypeers_lineEdit->setText( QString::number((*it).total_number_of_peers) );
QString text = tr("You're not subscribed to this chat room; Double click-it to enter and chat.") ;
QString text = tr("You're subscribed to this chat room; Double click to show window and chat.") ;
if (!subscribed)
{
text = tr("You're not subscribed to this chat room; Double click-it to enter and chat.") ;
if(my_ids.empty())
{
if( (*it).lobby_flags & RS_CHAT_LOBBY_FLAGS_PGP_SIGNED)
@ -890,8 +913,9 @@ void ChatLobbyWidget::showBlankPage(ChatLobbyId id)
else
text += "\n\n"+tr("You will need to create an identity in order to join chat rooms.") ;
}
}
ui.lobbyInfoLabel->setText(text);
ui.lobbyInfoLabel->setText(text);
return ;
}
@ -1037,6 +1061,8 @@ void ChatLobbyWidget::unsubscribeChatLobby(ChatLobbyId id)
}
ui.stackedWidget->removeWidget(it->second.dialog) ;
disconnect(it->second.dialog,SIGNAL(dialogClose(ChatDialog*)),this,SLOT(dialogClose(ChatDialog*)));
it->second.dialog->leaveLobby();
_lobby_infos.erase(it) ;
}

View File

@ -38,6 +38,7 @@
class RSTreeWidgetItemCompareRole;
class ChatTabWidget ;
class ChatDialog ;
class ChatLobbyDialog ;
class QTextBrowser ;
@ -69,6 +70,7 @@ public:
void setCurrentChatPage(ChatLobbyDialog *) ; // used by ChatLobbyDialog to raise.
void addChatPage(ChatLobbyDialog *) ;
void removeChatPage(ChatLobbyDialog *) ;
bool showLobbyAnchor(ChatLobbyId id, QString anchor) ;
uint unreadCount();
@ -77,6 +79,7 @@ signals:
void unreadCountChanged(uint unreadCount);
protected slots:
void dialogClose(ChatDialog*);
void lobbyChanged();
void lobbyTreeWidgetCustomPopupMenu(QPoint);
void createChatLobby();
@ -87,7 +90,7 @@ protected slots:
void displayChatLobbyEvent(qulonglong lobby_id, int event_type, const RsGxsId& gxs_id, const QString& str);
void readChatLobbyInvites();
void showLobby(QTreeWidgetItem *lobby_item) ;
void showBlankPage(ChatLobbyId id) ;
void showBlankPage(ChatLobbyId id, bool subscribed = false) ;
void unsubscribeChatLobby(ChatLobbyId id) ;
void createIdentityAndSubscribe();
void subscribeChatLobbyAs() ;

View File

@ -6,8 +6,8 @@
<rect>
<x>0</x>
<y>0</y>
<width>1531</width>
<height>889</height>
<width>793</width>
<height>511</height>
</rect>
</property>
<property name="sizePolicy">
@ -26,28 +26,28 @@
</sizepolicy>
</property>
<property name="frameShape">
<enum>QFrame::Box</enum>
<enum>QFrame::NoFrame</enum>
</property>
<property name="frameShadow">
<enum>QFrame::Sunken</enum>
<enum>QFrame::Plain</enum>
</property>
<layout class="QHBoxLayout" name="horizontalLayout_4">
<property name="leftMargin">
<number>2</number>
<number>3</number>
</property>
<property name="topMargin">
<number>2</number>
<number>3</number>
</property>
<property name="rightMargin">
<number>2</number>
<number>3</number>
</property>
<property name="bottomMargin">
<number>2</number>
<number>3</number>
</property>
<item>
<layout class="QHBoxLayout" name="horizontalLayout">
<property name="spacing">
<number>0</number>
<number>2</number>
</property>
<item>
<widget class="QFrame" name="searchLineFrame">
@ -414,7 +414,7 @@
<string>Directory</string>
</property>
<property name="icon">
<iconset resource="../images.qrc">
<iconset>
<normaloff>:/images/folder16.png</normaloff>:/images/folder16.png</iconset>
</property>
</item>

View File

@ -62,13 +62,18 @@ void PostedDialog::handleEvent_main_thread(std::shared_ptr<const RsEvent> event)
case RsPostedEventCode::NEW_MESSAGE:
case RsPostedEventCode::UPDATED_MESSAGE: // [[fallthrough]];
case RsPostedEventCode::READ_STATUS_CHANGED: // [[fallthrough]];
updateMessageSummaryList(e->mPostedGroupId);
updateGroupStatisticsReal(e->mPostedGroupId); // update the list immediately
break;
case RsPostedEventCode::NEW_POSTED_GROUP: // [[fallthrough]];
case RsPostedEventCode::SUBSCRIBE_STATUS_CHANGED: // [[fallthrough]];
updateDisplay(true);
break;
case RsPostedEventCode::STATISTICS_CHANGED:
updateGroupStatistics(e->mPostedGroupId);
break;
default: break;
}
}
@ -82,7 +87,7 @@ PostedDialog::~PostedDialog()
UserNotify *PostedDialog::createUserNotify(QObject *parent)
{
return new PostedUserNotify(rsPosted, parent);
return new PostedUserNotify(rsPosted, this, parent);
}
QString PostedDialog::getHelpString() const

View File

@ -18,18 +18,19 @@
* *
*******************************************************************************/
#include "retroshare/rsposted.h"
#include "PostedUserNotify.h"
#include "gui/MainWindow.h"
PostedUserNotify::PostedUserNotify(RsGxsIfaceHelper *ifaceImpl, QObject *parent) :
GxsUserNotify(ifaceImpl, parent)
PostedUserNotify::PostedUserNotify(RsGxsIfaceHelper *ifaceImpl, const GxsGroupFrameDialog *g, QObject *parent) :
GxsUserNotify(ifaceImpl, g, parent)
{
}
bool PostedUserNotify::hasSetting(QString *name, QString *group)
{
if (name) *name = tr("Posted");
if (group) *group = "Posted";
if (name) *name = tr("Board Post");
if (group) *group = "Board";
return true;
}

View File

@ -28,7 +28,7 @@ class PostedUserNotify : public GxsUserNotify
Q_OBJECT
public:
PostedUserNotify(RsGxsIfaceHelper *ifaceImpl, QObject *parent = 0);
PostedUserNotify(RsGxsIfaceHelper *ifaceImpl, const GxsGroupFrameDialog *g, QObject *parent = 0);
virtual bool hasSetting(QString *name, QString *group);

View File

@ -24,6 +24,7 @@
#include "PulseAddDialog.h"
const uint32_t PULSE_MAX_SIZE = 1000; // 1k char.
/** Constructor */
PulseAddDialog::PulseAddDialog(QWidget *parent)
@ -35,8 +36,9 @@ PulseAddDialog::PulseAddDialog(QWidget *parent)
connect(ui.pushButton_Post, SIGNAL( clicked( void ) ), this, SLOT( postPulse( void ) ) );
connect(ui.pushButton_AddURL, SIGNAL( clicked( void ) ), this, SLOT( addURL( void ) ) );
connect(ui.pushButton_AddTo, SIGNAL( clicked( void ) ), this, SLOT( addTo( void ) ) );
connect(ui.pushButton_ClearDisplayAs, SIGNAL( clicked( void ) ), this, SLOT( clearDisplayAs( void ) ) );
connect(ui.pushButton_Cancel, SIGNAL( clicked( void ) ), this, SLOT( cancelPulse( void ) ) );
connect(ui.textEdit_Pulse, SIGNAL( textChanged( void ) ), this, SLOT( pulseTextChanged( void ) ) );
}
void PulseAddDialog::setGroup(RsWireGroup &group)
@ -47,11 +49,59 @@ void PulseAddDialog::setGroup(RsWireGroup &group)
}
void PulseAddDialog::cleanup()
{
if (mIsReply)
{
std::cerr << "PulseAddDialog::setReplyTo() cleaning up old replyto";
std::cerr << std::endl;
QLayout *layout = ui.widget_replyto->layout();
// completely delete layout and sublayouts
QLayoutItem * item;
QWidget * widget;
while ((item = layout->takeAt(0)))
{
if ((widget = item->widget()) != 0)
{
std::cerr << "PulseAddDialog::setReplyTo() removing widget";
std::cerr << std::endl;
widget->hide();
delete widget;
}
else
{
std::cerr << "PulseAddDialog::setReplyTo() removing item";
std::cerr << std::endl;
delete item;
}
}
// then finally
delete layout;
mIsReply = false;
}
ui.frame_reply->setVisible(false);
ui.comboBox_sentiment->setCurrentIndex(0);
ui.lineEdit_URL->setText("");
ui.lineEdit_DisplayAs->setText("");
ui.textEdit_Pulse->setPlainText("");
ui.pushButton_Post->setEnabled(false);
// disable URL until functionality finished.
ui.frame_URL->setEnabled(false);
}
void PulseAddDialog::pulseTextChanged()
{
std::string pulseText = ui.textEdit_Pulse->toPlainText().toStdString();
bool enable = (pulseText.size() > 0) && (pulseText.size() < PULSE_MAX_SIZE);
ui.pushButton_Post->setEnabled(enable);
}
void PulseAddDialog::setReplyTo(RsWirePulse &pulse, std::string &groupName)
{
mIsReply = true;
mReplyToPulse = pulse;
mReplyGroupName = groupName;
ui.frame_reply->setVisible(true);
{
std::map<rstime_t, RsWirePulse *> replies;
@ -75,12 +125,10 @@ void PulseAddDialog::addURL()
return;
}
void PulseAddDialog::addTo()
void PulseAddDialog::clearDisplayAs()
{
std::cerr << "PulseAddDialog::addTo()";
std::cerr << "PulseAddDialog::clearDisplayAs()";
std::cerr << std::endl;
return;
}
@ -96,7 +144,6 @@ void PulseAddDialog::cancelPulse()
return;
}
void PulseAddDialog::postPulse()
{
std::cerr << "PulseAddDialog::postPulse()";
@ -126,6 +173,7 @@ void PulseAddDialog::postOriginalPulse()
pulse.mMeta.mOrigMsgId.clear();
pulse.mPulseType = WIRE_PULSE_TYPE_ORIGINAL_MSG;
pulse.mReplySentiment = WIRE_PULSE_SENTIMENT_NO_SENTIMENT;
pulse.mPulseText = ui.textEdit_Pulse->toPlainText().toStdString();
// all mRefs should empty.
@ -136,6 +184,27 @@ void PulseAddDialog::postOriginalPulse()
hide();
}
uint32_t PulseAddDialog::toPulseSentiment(int index)
{
switch(index)
{
case 1:
return WIRE_PULSE_SENTIMENT_POSITIVE;
break;
case 2:
return WIRE_PULSE_SENTIMENT_NEUTRAL;
break;
case 3:
return WIRE_PULSE_SENTIMENT_NEGATIVE;
break;
case -1:
case 0:
default:
return WIRE_PULSE_SENTIMENT_NO_SENTIMENT;
break;
}
return 0;
}
void PulseAddDialog::postReplyPulse()
{
@ -151,6 +220,7 @@ void PulseAddDialog::postReplyPulse()
pulse.mMeta.mOrigMsgId.clear();
pulse.mPulseType = WIRE_PULSE_TYPE_REPLY_MSG;
pulse.mReplySentiment = toPulseSentiment(ui.comboBox_sentiment->currentIndex());
pulse.mPulseText = ui.textEdit_Pulse->toPlainText().toStdString();
// mRefs refer to parent post.
@ -185,6 +255,8 @@ void PulseAddDialog::postRefPulse(RsWirePulse &pulse)
refPulse.mMeta.mOrigMsgId.clear();
refPulse.mPulseType = WIRE_PULSE_TYPE_REPLY_REFERENCE;
refPulse.mReplySentiment = toPulseSentiment(ui.comboBox_sentiment->currentIndex());
// Dont put parent PulseText into refPulse - it is available on Thread Msg.
// otherwise gives impression it is correctly setup Parent / Reply...
// when in fact the parent PublishTS, and AuthorId are wrong.

View File

@ -33,15 +33,17 @@ class PulseAddDialog : public QWidget, public TokenResponse
public:
PulseAddDialog(QWidget *parent = 0);
void cleanup();
void setGroup(RsWireGroup &group);
void setReplyTo(RsWirePulse &pulse, std::string &groupName);
private slots:
void addURL();
void addTo();
void clearDisplayAs();
void postPulse();
void cancelPulse();
void clearDialog();
void pulseTextChanged();
private:
void postOriginalPulse();
@ -51,6 +53,7 @@ private:
void acknowledgeMessage(const uint32_t &token);
void loadPulseData(const uint32_t &token);
void loadRequest(const TokenQueue *queue, const TokenRequest &req);
uint32_t toPulseSentiment(int index);
protected:

View File

@ -13,9 +13,67 @@
<property name="windowTitle">
<string/>
</property>
<layout class="QGridLayout" name="gridLayout_2">
<item row="0" column="1" colspan="3">
<widget class="QFrame" name="frame_2">
<layout class="QVBoxLayout" name="verticalLayout">
<item>
<widget class="QFrame" name="frame">
<property name="sizePolicy">
<sizepolicy hsizetype="Expanding" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="maximumSize">
<size>
<width>16777215</width>
<height>16777215</height>
</size>
</property>
<property name="frameShape">
<enum>QFrame::StyledPanel</enum>
</property>
<property name="frameShadow">
<enum>QFrame::Raised</enum>
</property>
<layout class="QHBoxLayout" name="horizontalLayout_3">
<item>
<widget class="QLabel" name="label">
<property name="maximumSize">
<size>
<width>100</width>
<height>16777215</height>
</size>
</property>
<property name="font">
<font>
<pointsize>12</pointsize>
<weight>75</weight>
<bold>true</bold>
</font>
</property>
<property name="text">
<string>Post From:</string>
</property>
</widget>
</item>
<item>
<widget class="QLabel" name="label_groupName">
<property name="text">
<string>GroupLabel</string>
</property>
</widget>
</item>
<item>
<widget class="GxsIdLabel" name="label_idName">
<property name="text">
<string>IDLabel</string>
</property>
</widget>
</item>
</layout>
</widget>
</item>
<item>
<widget class="QFrame" name="frame_reply">
<property name="frameShape">
<enum>QFrame::StyledPanel</enum>
</property>
@ -24,50 +82,74 @@
</property>
<layout class="QVBoxLayout" name="verticalLayout_3">
<item>
<layout class="QHBoxLayout" name="horizontalLayout">
<item>
<widget class="QLabel" name="label_4">
<property name="text">
<string>In Reply to:</string>
</property>
</widget>
</item>
<item>
<widget class="QLabel" name="label_5">
<property name="font">
<font>
<pointsize>11</pointsize>
<weight>75</weight>
<bold>true</bold>
</font>
</property>
<property name="text">
<string>Positive / Neutral / Negative</string>
</property>
</widget>
</item>
<item>
<spacer name="horizontalSpacer_3">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>238</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
</layout>
<widget class="QWidget" name="widget_replyto" native="true"/>
</item>
<item>
<widget class="QWidget" name="widget_replyto" native="true"/>
<widget class="QWidget" name="widget_sentiment" native="true">
<layout class="QHBoxLayout" name="horizontalLayout">
<item>
<widget class="QLabel" name="label_4">
<property name="text">
<string>Response Sentiment: </string>
</property>
</widget>
</item>
<item>
<widget class="QComboBox" name="comboBox_sentiment">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="minimumSize">
<size>
<width>150</width>
<height>0</height>
</size>
</property>
<item>
<property name="text">
<string>No Sentiment</string>
</property>
</item>
<item>
<property name="text">
<string>Positive</string>
</property>
</item>
<item>
<property name="text">
<string>Neutral</string>
</property>
</item>
<item>
<property name="text">
<string>Negative</string>
</property>
</item>
</widget>
</item>
<item>
<spacer name="horizontalSpacer_3">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>238</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
</layout>
</widget>
</item>
</layout>
</widget>
</item>
<item row="1" column="1" colspan="3">
<item>
<widget class="QFrame" name="frame_3">
<property name="frameShape">
<enum>QFrame::StyledPanel</enum>
@ -79,220 +161,80 @@
<item>
<widget class="QTextEdit" name="textEdit_Pulse"/>
</item>
</layout>
</widget>
</item>
<item row="2" column="1" colspan="3">
<widget class="QGroupBox" name="groupBox">
<property name="title">
<string>URL Adder</string>
</property>
<layout class="QGridLayout" name="gridLayout">
<item row="0" column="1">
<spacer name="horizontalSpacer">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>331</width>
<height>24</height>
</size>
</property>
</spacer>
</item>
<item row="0" column="2">
<widget class="QPushButton" name="pushButton_AddURL">
<property name="text">
<string>Add to Pulse</string>
</property>
</widget>
</item>
<item row="1" column="0">
<widget class="QLabel" name="label_3">
<property name="text">
<string>Display As</string>
</property>
</widget>
</item>
<item row="1" column="1" colspan="2">
<widget class="QLineEdit" name="lineEdit_2"/>
</item>
<item row="2" column="0">
<widget class="QLabel" name="label_2">
<property name="text">
<string>URL</string>
</property>
</widget>
</item>
<item row="2" column="1" colspan="2">
<widget class="QLineEdit" name="lineEdit"/>
</item>
</layout>
</widget>
</item>
<item row="3" column="1">
<widget class="QPushButton" name="pushButton_Cancel">
<property name="text">
<string>Cancel</string>
</property>
</widget>
</item>
<item row="3" column="2">
<spacer name="horizontalSpacer_2">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>298</width>
<height>24</height>
</size>
</property>
</spacer>
</item>
<item row="3" column="3">
<widget class="QPushButton" name="pushButton_Post">
<property name="text">
<string>Post Pulse to Wire</string>
</property>
</widget>
</item>
<item row="0" column="0" rowspan="4">
<widget class="QSplitter" name="splitter">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<widget class="QFrame" name="frame">
<property name="maximumSize">
<size>
<width>160</width>
<height>16777215</height>
</size>
</property>
<property name="frameShape">
<enum>QFrame::StyledPanel</enum>
</property>
<property name="frameShadow">
<enum>QFrame::Raised</enum>
</property>
<layout class="QVBoxLayout" name="verticalLayout_4">
<item>
<widget class="QLabel" name="label">
<property name="font">
<font>
<pointsize>12</pointsize>
<weight>75</weight>
<bold>true</bold>
</font>
</property>
<property name="text">
<string>Post From:</string>
</property>
</widget>
</item>
<item>
<widget class="QLabel" name="label_groupName">
<property name="text">
<string>GroupLabel</string>
</property>
</widget>
</item>
<item>
<widget class="GxsIdLabel" name="label_idName">
<property name="text">
<string>IDLabel</string>
</property>
</widget>
</item>
</layout>
</widget>
<widget class="QScrollArea" name="scrollArea_3">
<property name="widgetResizable">
<bool>true</bool>
</property>
<widget class="QWidget" name="scrollAreaWidgetContents_3">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>150</width>
<height>423</height>
</rect>
</property>
<layout class="QVBoxLayout" name="verticalLayout">
<item>
<widget class="QPushButton" name="pushButton_AddTo">
<property name="text">
<string>Add to Pulse</string>
</property>
</widget>
</item>
<item>
<widget class="QLineEdit" name="lineEdit_3">
<property name="text">
<string>filter</string>
</property>
</widget>
</item>
<item>
<widget class="QScrollArea" name="scrollArea">
<property name="widgetResizable">
<bool>true</bool>
</property>
<widget class="QWidget" name="scrollAreaWidgetContents">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>130</width>
<height>341</height>
</rect>
<item>
<widget class="QFrame" name="frame_URL">
<layout class="QGridLayout" name="gridLayout">
<item row="0" column="0">
<widget class="QLabel" name="label_3">
<property name="text">
<string>URL</string>
</property>
<layout class="QVBoxLayout" name="verticalLayout_2">
<item>
<widget class="QCheckBox" name="checkBox_5">
<property name="text">
<string>Account 1</string>
</property>
</widget>
</item>
<item>
<widget class="QCheckBox" name="checkBox_6">
<property name="text">
<string>Account 2</string>
</property>
</widget>
</item>
<item>
<widget class="QCheckBox" name="checkBox_7">
<property name="text">
<string>Account 3</string>
</property>
</widget>
</item>
<item>
<spacer name="verticalSpacer_3">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
<height>70</height>
</size>
</property>
</spacer>
</item>
</layout>
</widget>
</widget>
</item>
</layout>
</widget>
</widget>
</item>
<item row="0" column="1">
<widget class="QLineEdit" name="lineEdit_URL"/>
</item>
<item row="0" column="2">
<widget class="QPushButton" name="pushButton_AddURL">
<property name="text">
<string>Add to Pulse</string>
</property>
</widget>
</item>
<item row="1" column="0">
<widget class="QLabel" name="label_2">
<property name="text">
<string>Display As</string>
</property>
</widget>
</item>
<item row="1" column="1">
<widget class="QLineEdit" name="lineEdit_DisplayAs"/>
</item>
<item row="1" column="2">
<widget class="QPushButton" name="pushButton_ClearDisplayAs">
<property name="text">
<string>Clear Display As</string>
</property>
</widget>
</item>
</layout>
</widget>
</item>
</layout>
</widget>
</item>
<item>
<layout class="QHBoxLayout" name="horizontalLayout_2">
<item>
<widget class="QPushButton" name="pushButton_Cancel">
<property name="text">
<string>Cancel</string>
</property>
</widget>
</item>
<item>
<spacer name="horizontalSpacer_2">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>298</width>
<height>24</height>
</size>
</property>
</spacer>
</item>
<item>
<widget class="QPushButton" name="pushButton_Post">
<property name="text">
<string>Post Pulse to Wire</string>
</property>
</widget>
</item>
</layout>
</item>
</layout>
</widget>
<customwidgets>

View File

@ -92,6 +92,10 @@ void PulseDetails::setup()
label_replies->setText("");
frame_replies->setVisible(false);
mHasReplies = false;
toolButton_follow->setEnabled(false); // TODO
toolButton_rate->setEnabled(false); // TODO
toolButton_reply->setEnabled(mActions != NULL);
}
void PulseDetails::addReplies(std::map<rstime_t, RsWirePulse *> replies)
@ -183,18 +187,28 @@ QString PulseDetails::getSummary()
void PulseDetails::follow()
{
// follow group.
mActions->follow(mPulse.mMeta.mGroupId);
if (mActions)
{
mActions->follow(mPulse.mMeta.mGroupId);
}
}
void PulseDetails::rate()
{
// rate author
mActions->rate(mPulse.mMeta.mAuthorId);
if (mActions)
{
mActions->rate(mPulse.mMeta.mAuthorId);
}
}
void PulseDetails::reply()
{
mActions->reply(mPulse, mGroupName);
// reply
if (mActions)
{
mActions->reply(mPulse, mGroupName);
}
}

View File

@ -1,15 +1,5 @@
<RCC>
<qresource prefix="/" >
<file>images/kuickshow.png</file>
<file>images/kview_24.png</file>
<file>images/kview_64.png</file>
<file>images/album_64.png</file>
<file>images/album_subscribe.png</file>
<file>images/album_unsubscribe.png</file>
<file>images/album_create_64.png</file>
<file>images/album_default_128.png</file>
<file>images/my_album_48.png</file>
<file>images/subscribed_album_48.png</file>
<file>images/friends_album_48.png</file>
<file>images/compose.png</file>
</qresource>
</RCC>

View File

@ -40,9 +40,10 @@
#define GROUP_SET_ALL (0)
#define GROUP_SET_OWN (1)
#define GROUP_SET_SUBSCRIBED (2)
#define GROUP_SET_AUTO (3)
#define GROUP_SET_RECOMMENDED (4)
#define GROUP_SET_OTHERS (5)
#define GROUP_SET_OTHERS (3)
// Future Extensions.
// #define GROUP_SET_AUTO (4)
// #define GROUP_SET_RECOMMENDED (5)
#define WIRE_TOKEN_TYPE_SUBSCRIBE_CHANGE 1
@ -56,13 +57,14 @@ WireDialog::WireDialog(QWidget *parent)
mAddDialog = NULL;
mPulseSelected = NULL;
mGroupSelected = NULL;
connect( ui.toolButton_createAccount, SIGNAL(clicked()), this, SLOT(createGroup()));
connect( ui.toolButton_createPulse, SIGNAL(clicked()), this, SLOT(createPulse()));
connect( ui.pushButton_Post, SIGNAL(clicked()), this, SLOT(createPulse()));
connect( ui.toolButton_refresh, SIGNAL(clicked()), this, SLOT(refreshGroups()));
connect(ui.comboBox_groupSet, SIGNAL(currentIndexChanged(int)), this, SLOT(selectGroupSet(int)));
connect(ui.comboBox_filterTime, SIGNAL(currentIndexChanged(int)), this, SLOT(selectFilterTime(int)));
QTimer *timer = new QTimer(this);
timer->connect(timer, SIGNAL(timeout()), this, SLOT(checkUpdate()));
@ -136,6 +138,7 @@ void WireDialog::reply(RsWirePulse &pulse, std::string &groupName)
// publishing group.
RsWireGroup group = mOwnGroups[idx];
mAddDialog->cleanup();
mAddDialog->setGroup(group);
// establish replyTo.
@ -177,15 +180,31 @@ void WireDialog::notifyGroupSelection(WireGroupItem *item)
std::cerr << "WireDialog::notifyGroupSelection() from : " << item;
std::cerr << std::endl;
bool doSelection = true;
if (mGroupSelected)
{
std::cerr << "WireDialog::notifyGroupSelection() unselecting old one : " << mGroupSelected;
std::cerr << std::endl;
mGroupSelected->setSelected(false);
if (mGroupSelected == item)
{
std::cerr << "WireDialog::notifyGroupSelection() current -> unselect";
std::cerr << std::endl;
/* de-selection of current item */
mGroupSelected = NULL;
doSelection = false;
}
}
mGroupSelected = item;
if (doSelection)
{
item->setSelected(true);
mGroupSelected = item;
}
/* update display */
showSelectedGroups();
}
@ -229,6 +248,7 @@ void WireDialog::createPulse()
RsWireGroup group = mOwnGroups[idx];
mAddDialog->cleanup();
mAddDialog->setGroup(group);
mAddDialog->show();
}
@ -320,6 +340,8 @@ void WireDialog::deleteGroups()
std::cerr << "WireDialog::deleteGroups()";
std::cerr << std::endl;
mGroupSelected = NULL;
QLayout *alayout = ui.scrollAreaWidgetContents_groups->layout();
QLayoutItem *item;
int i = 0;
@ -380,11 +402,39 @@ void WireDialog::selectGroupSet(int index)
showGroups();
}
void WireDialog::selectFilterTime(int index)
{
std::cerr << "WireDialog::selectFilterTime(" << index << ")";
std::cerr << std::endl;
showSelectedGroups();
}
void WireDialog::showSelectedGroups()
{
ui.comboBox_filterTime->setEnabled(false);
if (mGroupSelected)
{
deletePulses();
// request data.
std::list<RsGxsGroupId> grpIds;
grpIds.push_back(mGroupSelected->groupId());
requestPulseData(grpIds);
}
else
{
showGroups();
}
}
void WireDialog::showGroups()
{
ui.comboBox_filterTime->setEnabled(false);
deleteGroups();
deletePulses();
/* depends on the comboBox */
std::map<RsGxsGroupId, RsWireGroup>::const_iterator it;
for (it = mAllGroups.begin(); it != mAllGroups.end(); it++)
@ -399,12 +449,6 @@ void WireDialog::showGroups()
if (mGroupSet == GROUP_SET_SUBSCRIBED) {
add = true;
}
if (mGroupSet == GROUP_SET_AUTO) {
add = true;
}
if (mGroupSet == GROUP_SET_RECOMMENDED) {
add = true;
}
}
else {
if (mGroupSet == GROUP_SET_OTHERS) {
@ -506,6 +550,29 @@ public:
std::map<rstime_t, RsWirePulse *> replies; // publish -> replies.
};
rstime_t WireDialog::getFilterTimestamp()
{
rstime_t filterTimestamp = time(NULL);
switch(ui.comboBox_filterTime->currentIndex())
{
case 1: // Last 24 Hours.
filterTimestamp -= (3600 * 24);
break;
case 2: // Last 7 Days.
filterTimestamp -= (3600 * 24 * 7);
break;
case 3: // Last 30 Days.
filterTimestamp -= (3600 * 24 * 30);
break;
case 0: // All Time.
case -1: // no index.
default:
filterTimestamp = 0; // back to Epoch! effectively all.
break;
}
return filterTimestamp;
}
bool WireDialog::loadPulseData(const uint32_t &token)
{
std::cerr << "WireDialog::loadPulseData()";
@ -517,6 +584,14 @@ bool WireDialog::loadPulseData(const uint32_t &token)
std::list<RsWirePulse *> references;
std::map<RsGxsMessageId, PulseReplySet> pulseGrouping;
// setup time filtering.
uint32_t filterTimestamp;
bool filterTime = (ui.comboBox_filterTime->currentIndex() > 0);
if (filterTime)
{
filterTimestamp = getFilterTimestamp();
}
std::vector<RsWirePulse>::iterator vit = pulses.begin();
for(; vit != pulses.end(); vit++)
{
@ -531,6 +606,15 @@ bool WireDialog::loadPulseData(const uint32_t &token)
}
else
{
// Filter timestamp now. (as soon as possible).
if (filterTime && (pulse.mMeta.mPublishTs < filterTimestamp))
{
std::cerr << "WireDialog::loadPulseData() SKipping OLD MSG: GroupId: " << pulse.mMeta.mGroupId;
std::cerr << " PulseId: " << pulse.mMeta.mMsgId;
std::cerr << std::endl;
continue;
}
RsGxsGroupId &gid = pulse.mMeta.mGroupId;
std::map<RsGxsGroupId, RsWireGroup>::iterator git = mAllGroups.find(gid);
if (git != mAllGroups.end())
@ -591,6 +675,7 @@ bool WireDialog::loadPulseData(const uint32_t &token)
std::map<RsGxsMessageId, PulseReplySet>::iterator pgit;
for(pgit = pulseGrouping.begin(); pgit != pulseGrouping.end(); pgit++)
{
PulseOrderedReply &msg = pulseOrdering[pgit->second.msg->mMeta.mPublishTs] =
PulseOrderedReply(pgit->second.msg, pgit->second.group);
std::map<RsGxsMessageId, RsWirePulse *>::iterator rmit;
@ -609,6 +694,8 @@ bool WireDialog::loadPulseData(const uint32_t &token)
addPulse(poit->second.msg, poit->second.group, poit->second.replies);
}
// allow filterTime to be changed again
ui.comboBox_filterTime->setEnabled(true);
return true;
}

View File

@ -68,6 +68,7 @@ private slots:
void checkUpdate();
void refreshGroups();
void selectGroupSet(int index);
void selectFilterTime(int index);
private:
@ -81,8 +82,12 @@ private:
void deletePulses();
void deleteGroups();
void showGroups();
void showSelectedGroups();
void updateGroups(std::vector<RsWireGroup> &groups);
// utils.
rstime_t getFilterTimestamp();
// Loading Data.
void requestGroupData();
bool loadGroupData(const uint32_t &token);

View File

@ -19,13 +19,13 @@
<property name="windowTitle">
<string/>
</property>
<layout class="QGridLayout" name="gridLayout_2">
<item row="0" column="0" colspan="2">
<widget class="QFrame" name="frame_2">
<layout class="QVBoxLayout" name="verticalLayout_5">
<item>
<widget class="QFrame" name="frame_toolbar">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
<verstretch>1</verstretch>
</sizepolicy>
</property>
<property name="frameShape">
@ -40,6 +40,13 @@
<property name="text">
<string>Create Account</string>
</property>
<property name="icon">
<iconset resource="../icons.qrc">
<normaloff>:/icons/png/add.png</normaloff>:/icons/png/add.png</iconset>
</property>
<property name="toolButtonStyle">
<enum>Qt::ToolButtonTextBesideIcon</enum>
</property>
</widget>
</item>
<item>
@ -47,19 +54,12 @@
<property name="text">
<string>Post Pulse</string>
</property>
</widget>
</item>
<item>
<widget class="QToolButton" name="toolButton_3">
<property name="text">
<string>...</string>
<property name="icon">
<iconset resource="TheWire_images.qrc">
<normaloff>:/images/compose.png</normaloff>:/images/compose.png</iconset>
</property>
</widget>
</item>
<item>
<widget class="QToolButton" name="toolButton_4">
<property name="text">
<string>...</string>
<property name="toolButtonStyle">
<enum>Qt::ToolButtonTextBesideIcon</enum>
</property>
</widget>
</item>
@ -95,6 +95,9 @@
</item>
<item>
<widget class="QToolButton" name="toolButton_Settings">
<property name="enabled">
<bool>false</bool>
</property>
<property name="text">
<string>Settings</string>
</property>
@ -103,243 +106,268 @@
</layout>
</widget>
</item>
<item row="6" column="0">
<widget class="QScrollArea" name="scrollArea">
<property name="widgetResizable">
<bool>true</bool>
<item>
<widget class="QSplitter" name="splitter">
<property name="sizePolicy">
<sizepolicy hsizetype="Expanding" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>100</verstretch>
</sizepolicy>
</property>
<property name="alignment">
<set>Qt::AlignBottom|Qt::AlignLeading|Qt::AlignLeft</set>
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<widget class="QWidget" name="scrollAreaWidgetContents">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>434</width>
<height>412</height>
</rect>
<widget class="QFrame" name="frame">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Preferred">
<horstretch>1</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="styleSheet">
<string notr="true">QWidget#scrollAreaWidgetContents{border: none;}</string>
<property name="minimumSize">
<size>
<width>250</width>
<height>0</height>
</size>
</property>
<layout class="QVBoxLayout" name="verticalLayout_2">
<property name="spacing">
<number>0</number>
</property>
<property name="leftMargin">
<number>0</number>
</property>
<property name="topMargin">
<number>0</number>
</property>
<property name="rightMargin">
<number>0</number>
</property>
<property name="bottomMargin">
<number>0</number>
</property>
<property name="maximumSize">
<size>
<width>400</width>
<height>16777215</height>
</size>
</property>
<property name="frameShape">
<enum>QFrame::StyledPanel</enum>
</property>
<property name="frameShadow">
<enum>QFrame::Raised</enum>
</property>
<layout class="QVBoxLayout" name="verticalLayout">
<item>
<spacer name="verticalSpacer">
<property name="orientation">
<enum>Qt::Vertical</enum>
<widget class="QComboBox" name="comboBox_groupSet">
<item>
<property name="text">
<string>All</string>
</property>
</item>
<item>
<property name="text">
<string>Yourself</string>
</property>
</item>
<item>
<property name="text">
<string>Following</string>
</property>
</item>
<item>
<property name="text">
<string>Others</string>
</property>
</item>
</widget>
</item>
<item>
<widget class="QLabel" name="followLabel">
<property name="font">
<font>
<pointsize>10</pointsize>
<weight>75</weight>
<bold>true</bold>
</font>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
<height>40</height>
</size>
<property name="text">
<string>Who to Follow</string>
</property>
</spacer>
</widget>
</item>
<item>
<widget class="QScrollArea" name="scrollArea_2">
<property name="widgetResizable">
<bool>true</bool>
</property>
<widget class="QWidget" name="scrollAreaWidgetContents_groups">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>228</width>
<height>421</height>
</rect>
</property>
<layout class="QVBoxLayout" name="verticalLayout_4">
<item>
<spacer name="verticalSpacer_2">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
<height>116</height>
</size>
</property>
</spacer>
</item>
</layout>
</widget>
</widget>
</item>
</layout>
</widget>
</widget>
</item>
<item row="1" column="0" rowspan="5">
<layout class="QGridLayout" name="gridLayout">
<item row="0" column="3" colspan="2">
<widget class="QDateTimeEdit" name="dateTimeEdit"/>
</item>
<item row="1" column="0">
<widget class="QLabel" name="label_2">
<property name="text">
<string>Search/Filter</string>
</property>
</widget>
</item>
<item row="1" column="4">
<widget class="QCheckBox" name="checkBox_9">
<property name="text">
<string>Network Wide</string>
</property>
</widget>
</item>
<item row="0" column="1">
<widget class="QComboBox" name="comboBox">
<item>
<property name="text">
<string>All</string>
</property>
</item>
<item>
<property name="text">
<string>Last Month</string>
</property>
</item>
<item>
<property name="text">
<string>Last Week</string>
</property>
</item>
<item>
<property name="text">
<string>Today</string>
</property>
</item>
<item>
<property name="text">
<string>New</string>
</property>
</item>
</widget>
</item>
<item row="0" column="2">
<widget class="QComboBox" name="comboBox_2">
<item>
<property name="text">
<string>from</string>
</property>
</item>
<item>
<property name="text">
<string>until</string>
</property>
</item>
</widget>
</item>
<item row="0" column="0">
<widget class="QLabel" name="label_3">
<property name="text">
<string>TimeRange</string>
</property>
</widget>
</item>
<item row="1" column="1" colspan="3">
<widget class="QLineEdit" name="lineEdit"/>
</item>
</layout>
</item>
<item row="5" column="1" rowspan="2">
<widget class="QFrame" name="frame">
<property name="maximumSize">
<size>
<width>400</width>
<height>16777215</height>
</size>
</property>
<property name="frameShape">
<enum>QFrame::StyledPanel</enum>
</property>
<property name="frameShadow">
<enum>QFrame::Raised</enum>
</property>
<layout class="QVBoxLayout" name="verticalLayout_5">
<property name="spacing">
<number>0</number>
<widget class="QFrame" name="frame_2">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Preferred">
<horstretch>3</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="leftMargin">
<number>0</number>
<property name="frameShape">
<enum>QFrame::StyledPanel</enum>
</property>
<property name="topMargin">
<number>0</number>
<property name="frameShadow">
<enum>QFrame::Raised</enum>
</property>
<property name="rightMargin">
<number>0</number>
</property>
<property name="bottomMargin">
<number>0</number>
</property>
<item>
<widget class="QScrollArea" name="scrollArea_2">
<property name="widgetResizable">
<bool>true</bool>
</property>
<widget class="QWidget" name="scrollAreaWidgetContents_groups">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>262</width>
<height>416</height>
</rect>
</property>
<layout class="QVBoxLayout" name="verticalLayout_4">
<layout class="QVBoxLayout" name="verticalLayout_3">
<item>
<widget class="QWidget" name="widget_range" native="true">
<layout class="QHBoxLayout" name="horizontalLayout_2">
<property name="spacing">
<number>0</number>
</property>
<property name="leftMargin">
<number>0</number>
</property>
<property name="topMargin">
<number>0</number>
</property>
<property name="rightMargin">
<number>0</number>
</property>
<property name="bottomMargin">
<number>0</number>
</property>
<item>
<spacer name="verticalSpacer_2">
<spacer name="horizontalSpacer_2">
<property name="orientation">
<enum>Qt::Vertical</enum>
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
<height>116</height>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
<item>
<widget class="QLabel" name="label_3">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="text">
<string>Show Posts from </string>
</property>
</widget>
</item>
<item>
<widget class="QComboBox" name="comboBox_filterTime">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<item>
<property name="text">
<string> All Time</string>
</property>
</item>
<item>
<property name="text">
<string>Last 24 hours</string>
</property>
</item>
<item>
<property name="text">
<string>Last 7 days</string>
</property>
</item>
<item>
<property name="text">
<string>Last 30 days</string>
</property>
</item>
</widget>
</item>
</layout>
</widget>
</widget>
</item>
</layout>
</widget>
</item>
<item row="3" column="1">
<widget class="QComboBox" name="comboBox_groupSet">
<item>
<property name="text">
<string>All</string>
</property>
</item>
<item>
<property name="text">
<string>Yourself</string>
</property>
</item>
<item>
<property name="text">
<string>Subscribed</string>
</property>
</item>
<item>
<property name="text">
<string>Auto</string>
</property>
</item>
<item>
<property name="text">
<string>Recommended</string>
</property>
</item>
<item>
<property name="text">
<string>Others</string>
</property>
</item>
</widget>
</item>
<item row="2" column="1">
<widget class="QPushButton" name="pushButton_Post">
<property name="text">
<string>Post Pulse to Wire</string>
</property>
</item>
<item>
<widget class="QScrollArea" name="scrollArea">
<property name="widgetResizable">
<bool>true</bool>
</property>
<property name="alignment">
<set>Qt::AlignBottom|Qt::AlignLeading|Qt::AlignLeft</set>
</property>
<widget class="QWidget" name="scrollAreaWidgetContents">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>431</width>
<height>443</height>
</rect>
</property>
<property name="styleSheet">
<string notr="true">QWidget#scrollAreaWidgetContents{border: none;}</string>
</property>
<layout class="QVBoxLayout" name="verticalLayout_2">
<property name="spacing">
<number>0</number>
</property>
<property name="leftMargin">
<number>0</number>
</property>
<property name="topMargin">
<number>0</number>
</property>
<property name="rightMargin">
<number>0</number>
</property>
<property name="bottomMargin">
<number>0</number>
</property>
<item>
<spacer name="verticalSpacer">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
<height>40</height>
</size>
</property>
</spacer>
</item>
</layout>
</widget>
</widget>
</item>
</layout>
</widget>
</widget>
</item>
</layout>
</widget>
<resources>
<include location="TheWire_images.qrc"/>
<include location="../icons.qrc"/>
</resources>
<connections/>
</ui>

View File

@ -24,6 +24,7 @@
#include <QBuffer>
#include "WireGroupItem.h"
#include "gui/gxs/GxsIdDetails.h"
#include <algorithm>
#include <iostream>
@ -39,12 +40,27 @@ WireGroupItem::WireGroupItem(WireGroupHolder *holder, const RsWireGroup &grp)
}
RsGxsGroupId &WireGroupItem::groupId()
{
return mGroup.mMeta.mGroupId;
}
void WireGroupItem::setup()
{
label_groupName->setText(QString::fromStdString(mGroup.mMeta.mGroupName));
label_authorId->setId(mGroup.mMeta.mAuthorId);
frame_details->setVisible(false);
RsIdentityDetails idDetails ;
rsIdentity->getIdDetails(mGroup.mMeta.mAuthorId,idDetails);
QPixmap pixmap ;
if(idDetails.mAvatar.mSize == 0 || !GxsIdDetails::loadPixmapFromData(idDetails.mAvatar.mData, idDetails.mAvatar.mSize, pixmap,GxsIdDetails::SMALL))
pixmap = GxsIdDetails::makeDefaultIcon(mGroup.mMeta.mAuthorId,GxsIdDetails::SMALL);
label_avatar->setPixmap(pixmap);
connect(toolButton_show, SIGNAL(clicked()), this, SLOT(show()));
connect(toolButton_subscribe, SIGNAL(clicked()), this, SLOT(subscribe()));
setGroupSet();
@ -59,13 +75,13 @@ void WireGroupItem::setGroupSet()
}
else if (mGroup.mMeta.mSubscribeFlags & GXS_SERV::GROUP_SUBSCRIBE_SUBSCRIBED)
{
toolButton_type->setText("Subcribed");
toolButton_subscribe->setText("Unsubcribe");
toolButton_type->setText("Following");
toolButton_subscribe->setText("Unfollow");
}
else
{
toolButton_type->setText("Other");
toolButton_subscribe->setText("Subcribe");
toolButton_subscribe->setText("Follow");
}
}
@ -91,8 +107,28 @@ void WireGroupItem::removeItem()
{
}
void WireGroupItem::setSelected(bool /* on */)
void WireGroupItem::setSelected(bool on)
{
mSelected = on;
// set color too
if (mSelected)
{
setBackground("red");
}
else
{
setBackground("gray");
}
}
void WireGroupItem::setBackground(QString color)
{
QWidget *tocolor = this;
QPalette p = tocolor->palette();
p.setColor(tocolor->backgroundRole(), QColor(color));
tocolor->setPalette(p);
tocolor->setAutoFillBackground(true);
}
bool WireGroupItem::isSelected()
@ -102,20 +138,14 @@ bool WireGroupItem::isSelected()
void WireGroupItem::mousePressEvent(QMouseEvent *event)
{
/* We can be very cunning here?
* grab out position.
* flag ourselves as selected.
* then pass the mousePressEvent up for handling by the parent
*/
QPoint pos = event->pos();
std::cerr << "WireGroupItem::mousePressEvent(" << pos.x() << ", " << pos.y() << ")";
std::cerr << std::endl;
setSelected(true);
QWidget::mousePressEvent(event);
// notify of selection.
// Holder will setSelected() flag.
mHolder->notifyGroupSelection(this);
}
const QPixmap *WireGroupItem::getPixmap()

View File

@ -50,6 +50,7 @@ public:
bool isSelected();
const QPixmap *getPixmap();
RsGxsGroupId &groupId();
private slots:
void show();
@ -61,6 +62,7 @@ protected:
private:
void setup();
void setGroupSet();
void setBackground(QString color);
WireGroupHolder *mHolder;
RsWireGroup mGroup;

View File

@ -25,6 +25,22 @@
<layout class="QVBoxLayout" name="verticalLayout">
<item>
<layout class="QHBoxLayout" name="horizontalLayout_2">
<item>
<widget class="QLabel" name="label_avatar">
<property name="maximumSize">
<size>
<width>32</width>
<height>32</height>
</size>
</property>
<property name="text">
<string>Avatar</string>
</property>
<property name="scaledContents">
<bool>true</bool>
</property>
</widget>
</item>
<item>
<widget class="QLabel" name="label_groupName">
<property name="text">

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.6 KiB

View File

@ -87,7 +87,6 @@ WikiDialog::WikiDialog(QWidget *parent) : RsGxsUpdateBroadcastPage(rsWiki, paren
mAddGroupDialog = NULL;
mEditDialog = NULL;
connect( ui.toolButton_NewGroup, SIGNAL(clicked()), this, SLOT(OpenOrShowAddGroupDialog()));
connect( ui.toolButton_NewPage, SIGNAL(clicked()), this, SLOT(OpenOrShowAddPageDialog()));
connect( ui.toolButton_Edit, SIGNAL(clicked()), this, SLOT(OpenOrShowEditDialog()));
connect( ui.toolButton_Republish, SIGNAL(clicked()), this, SLOT(OpenOrShowRepublishDialog()));
@ -105,9 +104,9 @@ WikiDialog::WikiDialog(QWidget *parent) : RsGxsUpdateBroadcastPage(rsWiki, paren
/* setup TokenQueue */
mWikiQueue = new TokenQueue(rsWiki->getTokenService(), this);
// Set initial size of the splitter
ui.listSplitter->setStretchFactor(0, 0);
ui.listSplitter->setStretchFactor(1, 1);
// Set initial size of the splitter
ui.listSplitter->setStretchFactor(0, 0);
ui.listSplitter->setStretchFactor(1, 1);
/* Setup Group Tree */
mYourGroups = ui.groupTreeWidget->addCategoryItem(tr("My Groups"), QIcon(), true);
@ -115,6 +114,13 @@ WikiDialog::WikiDialog(QWidget *parent) : RsGxsUpdateBroadcastPage(rsWiki, paren
mPopularGroups = ui.groupTreeWidget->addCategoryItem(tr("Popular Groups"), QIcon(), false);
mOtherGroups = ui.groupTreeWidget->addCategoryItem(tr("Other Groups"), QIcon(), false);
/* Add the New Group button */
QToolButton *newGroupButton = new QToolButton(this);
newGroupButton->setIcon(QIcon(":/icons/png/add.png"));
newGroupButton->setToolTip(tr("Create Group"));
connect(newGroupButton, SIGNAL(clicked()), this, SLOT(OpenOrShowAddGroupDialog()));
ui.groupTreeWidget->addToolButton(newGroupButton);
// load settings
processSettings(true);
}

View File

@ -36,92 +36,6 @@
<property name="spacing">
<number>0</number>
</property>
<item>
<widget class="QFrame" name="toolBarFrameTop">
<property name="maximumSize">
<size>
<width>16777215</width>
<height>30</height>
</size>
</property>
<property name="frameShape">
<enum>QFrame::Box</enum>
</property>
<property name="frameShadow">
<enum>QFrame::Sunken</enum>
</property>
<layout class="QHBoxLayout" name="horizontalLayout_2">
<property name="leftMargin">
<number>2</number>
</property>
<property name="topMargin">
<number>2</number>
</property>
<property name="rightMargin">
<number>2</number>
</property>
<property name="bottomMargin">
<number>2</number>
</property>
<item>
<widget class="QLabel" name="label">
<property name="maximumSize">
<size>
<width>24</width>
<height>24</height>
</size>
</property>
<property name="text">
<string/>
</property>
<property name="pixmap">
<pixmap resource="../icons.qrc">:/icons/png/wiki.png</pixmap>
</property>
<property name="scaledContents">
<bool>true</bool>
</property>
</widget>
</item>
<item>
<widget class="QLabel" name="label_2">
<property name="font">
<font>
<pointsize>10</pointsize>
<weight>75</weight>
<bold>true</bold>
</font>
</property>
<property name="text">
<string>Wiki Pages</string>
</property>
</widget>
</item>
<item>
<widget class="QToolButton" name="toolButton_NewGroup">
<property name="text">
<string>New Group</string>
</property>
<property name="icon">
<iconset resource="../icons.qrc">
<normaloff>:/icons/png/add.png</normaloff>:/icons/png/add.png</iconset>
</property>
<property name="iconSize">
<size>
<width>24</width>
<height>24</height>
</size>
</property>
<property name="toolButtonStyle">
<enum>Qt::ToolButtonIconOnly</enum>
</property>
<property name="autoRaise">
<bool>true</bool>
</property>
</widget>
</item>
</layout>
</widget>
</item>
<item>
<widget class="QScrollArea" name="scrollArea_2">
<property name="widgetResizable">
@ -133,7 +47,7 @@
<x>0</x>
<y>0</y>
<width>241</width>
<height>480</height>
<height>510</height>
</rect>
</property>
<layout class="QVBoxLayout" name="verticalLayout_2">

View File

@ -62,7 +62,7 @@ const static uint32_t timeToInactivity = 60 * 10; // in seconds
/** Default constructor */
ChatLobbyDialog::ChatLobbyDialog(const ChatLobbyId& lid, QWidget *parent, Qt::WindowFlags flags)
: ChatDialog(parent, flags), lobbyId(lid),
: ChatDialog(parent, flags), lobbyId(lid), mWindowedSetted(false), mPCWindow(nullptr),
bullet_red_128(":/icons/bullet_red_128.png"), bullet_grey_128(":/icons/bullet_grey_128.png"),
bullet_green_128(":/icons/bullet_green_128.png"), bullet_yellow_128(":/icons/bullet_yellow_128.png")
{
@ -129,6 +129,15 @@ ChatLobbyDialog::ChatLobbyDialog(const ChatLobbyId& lid, QWidget *parent, Qt::Wi
double scaler_factor = S > 25 ? 2.4 : 1.8;
QSize icon_size(scaler_factor * S, scaler_factor * S);
// Add a button to undock dialog.
//
undockButton = new QToolButton;
undockButton->setText(QString());
undockButton->setAutoRaise(true);
connect(undockButton, SIGNAL(clicked()), this , SLOT(toggleWindowed()));
getChatWidget()->addTitleBarWidget(undockButton) ;
// Add a button to invite friends.
//
inviteFriendsButton = new QToolButton ;
@ -201,8 +210,12 @@ ChatLobbyDialog::ChatLobbyDialog(const ChatLobbyId& lid, QWidget *parent, Qt::Wi
void ChatLobbyDialog::leaveLobby()
{
emit lobbyLeave(id()) ;
emit dialogClose(this);
if (mPCWindow)
mPCWindow = nullptr;// Windows deleted by events just before.
}
void ChatLobbyDialog::inviteFriends()
{
std::cerr << "Inviting friends" << std::endl;
@ -404,12 +417,8 @@ void ChatLobbyDialog::init(const ChatId &/*id*/, const QString &/*title*/)
lastUpdateListTime = 0;
// add to window
ChatLobbyWidget *chatLobbyPage = dynamic_cast<ChatLobbyWidget*>(MainWindow::getPage(MainWindow::ChatLobby));
if (chatLobbyPage) {
chatLobbyPage->addChatPage(this) ;
}
// add to stacked lobby list
setWindowed(false);
/** List of muted Participants */
mutedParticipants.clear() ;
@ -421,11 +430,15 @@ void ChatLobbyDialog::init(const ChatId &/*id*/, const QString &/*title*/)
/** Destructor. */
ChatLobbyDialog::~ChatLobbyDialog()
{
// announce leaving of lobby
if (mPCWindow)
{
mPCWindow->removeDialog(this);
mPCWindow = nullptr;
}
// check that the lobby still exists.
if (mChatId.isLobbyId())
rsMsgs->sendLobbyStatusPeerLeaving(mChatId.toLobbyId());
// announce leaving of lobby
if (mChatId.isLobbyId())
rsMsgs->sendLobbyStatusPeerLeaving(mChatId.toLobbyId());
// save settings
processSettings(false);
@ -910,11 +923,17 @@ void ChatLobbyDialog::showDialog(uint chatflags)
{
if (chatflags & RS_CHAT_FOCUS)
{
MainWindow::showWindow(MainWindow::ChatLobby);
MainPage *p = MainWindow::getPage(MainWindow::ChatLobby);
if (isWindowed() && mPCWindow) {
mPCWindow->showDialog(this, chatflags);
}
else
{
MainWindow::showWindow(MainWindow::ChatLobby);
MainPage *p = MainWindow::getPage(MainWindow::ChatLobby);
if(p != NULL)
dynamic_cast<ChatLobbyWidget*>(p)->setCurrentChatPage(this) ;
if(p)
dynamic_cast<ChatLobbyWidget*>(p)->setCurrentChatPage(this) ;
}
}
}
@ -941,3 +960,54 @@ void ChatLobbyDialog::filterIds()
ui.participantsList->filterItems(filterColumn, text);
}
void ChatLobbyDialog::setWindowed(bool windowed)
{
if (mWindowedSetted && (windowed == isWindowed()) )
{
RsErr() << __PRETTY_FUNCTION__ << " Attempt to set windowed same as last state." << std::endl;
return;
}
mWindowedSetted = true;
// just empiric values
qreal S = QFontMetricsF(font()).height();
int size = static_cast<int>(S > 25.0 ? 2.4 * S : 1.8 * S);
QSize icon_size(size, size);
QIcon icon ;
// chatLobbyPage could be NULL for first autosubscribe lobby as Dialog is created before main widget
ChatLobbyWidget *chatLobbyPage = dynamic_cast<ChatLobbyWidget*>(MainWindow::getPage(MainWindow::ChatLobby));
if (!mPCWindow)
mPCWindow = PopupChatWindow::getWindow(true);
if (windowed)
{
if (chatLobbyPage)
chatLobbyPage->removeChatPage(this);
if (mPCWindow)
mPCWindow->addDialog(this);
undockButton->setToolTip(tr("Redock to Main window"));
icon.addPixmap(QPixmap(":/icons/png/dock.png")) ;
undockButton->setIcon(icon) ;
undockButton->setIconSize(icon_size);
}
else
{
if (mPCWindow)
{
mPCWindow->removeDialog(this);
mPCWindow = nullptr;
}
if (chatLobbyPage)
chatLobbyPage->addChatPage(this);
undockButton->setToolTip(tr("Undock to a new window"));
icon.addPixmap(QPixmap(":/icons/png/undock.png")) ;
undockButton->setIcon(icon) ;
undockButton->setIconSize(icon_size);
}
show();
if (chatLobbyPage)// If not defined, we are on autosubscribe loop of lobby widget constructor. So don't recall it.
showDialog(RS_CHAT_FOCUS);
}

View File

@ -25,6 +25,7 @@
#include "ui_ChatLobbyDialog.h"
#include "gui/common/RSTreeWidgetItem.h"
#include "ChatDialog.h"
#include "PopupChatWindow.h"
Q_DECLARE_METATYPE(RsGxsId)
Q_DECLARE_METATYPE(QList<RsGxsId>)
@ -51,16 +52,20 @@ public:
ChatLobbyId id() const { return lobbyId ;}
void sortParcipants();
inline bool isWindowed() const { return dynamic_cast<PopupChatWindow*>(this->window()) != nullptr; }
public slots:
void leaveLobby() ;
private slots:
void participantsTreeWidgetCustomPopupMenu( QPoint point );
void textBrowserAskContextMenu(QMenu* contextMnu, QString anchorForPosition, const QPoint point);
void inviteFriends() ;
void leaveLobby() ;
void filterChanged(const QString &text);
void showInPeopleTab();
void showInPeopleTab();
void toggleWindowed(){setWindowed(!isWindowed());}
void setWindowed(bool windowed);
signals:
void lobbyLeave(ChatLobbyId) ;
void typingEventReceived(ChatLobbyId) ;
void messageReceived(bool incoming, ChatLobbyId lobby_id, QDateTime time, QString senderName, QString msg) ;
void peerJoined(ChatLobbyId) ;
@ -103,9 +108,13 @@ private:
RSTreeWidgetItemCompareRole *mParticipantCompareRole ;
QToolButton *inviteFriendsButton ;
QToolButton *undockButton ;
QToolButton *inviteFriendsButton ;
QToolButton *unsubscribeButton ;
bool mWindowedSetted;
PopupChatWindow* mPCWindow;
/** Qt Designer generated object */
Ui::ChatLobbyDialog ui;

View File

@ -324,12 +324,12 @@ border-image: url(:/images/closepressed.png)
</widget>
</item>
<item>
<widget class="QFrame" name="toolBarFrameTop">
<widget class="QFrame" name="toolBar">
<property name="frameShape">
<enum>QFrame::Box</enum>
<enum>QFrame::NoFrame</enum>
</property>
<property name="frameShadow">
<enum>QFrame::Sunken</enum>
<enum>QFrame::Plain</enum>
</property>
<layout class="QHBoxLayout" name="toolBarFrameHLayout">
<property name="spacing">
@ -412,7 +412,7 @@ border-image: url(:/images/closepressed.png)
</property>
<property name="icon">
<iconset resource="../icons.qrc">
<normaloff>:/icons/png/attach-image.png</normaloff>:/icons/png/attach-image.png</iconset>
<normaloff>:/icons/png/add-image.png</normaloff>:/icons/png/add-image.png</iconset>
</property>
<property name="iconSize">
<size>
@ -435,7 +435,7 @@ border-image: url(:/images/closepressed.png)
</property>
<property name="icon">
<iconset resource="../icons.qrc">
<normaloff>:/icons/png/attach.png</normaloff>:/icons/png/attach.png</iconset>
<normaloff>:/icons/png/attachements.png</normaloff>:/icons/png/attachements.png</iconset>
</property>
<property name="iconSize">
<size>
@ -455,7 +455,7 @@ border-image: url(:/images/closepressed.png)
</property>
<property name="icon">
<iconset resource="../icons.qrc">
<normaloff>:/icons/png/settings.png</normaloff>:/icons/png/settings.png</iconset>
<normaloff>:/icons/png/options2.png</normaloff>:/icons/png/options2.png</iconset>
</property>
<property name="iconSize">
<size>
@ -537,24 +537,18 @@ border-image: url(:/images/closepressed.png)
</item>
<item>
<widget class="QToolButton" name="searchBefore">
<property name="minimumSize">
<size>
<width>14</width>
<height>28</height>
</size>
</property>
<property name="maximumSize">
<size>
<width>14</width>
<height>28</height>
</size>
</property>
<property name="focusPolicy">
<enum>Qt::NoFocus</enum>
</property>
<property name="icon">
<iconset resource="../WikiPoos/Wiki_images.qrc">
<normaloff>:/images/arrow-left.png</normaloff>:/images/arrow-left.png</iconset>
<iconset resource="../icons.qrc">
<normaloff>:/icons/png/arrow-left.png</normaloff>:/icons/png/arrow-left.png</iconset>
</property>
<property name="iconSize">
<size>
<width>28</width>
<height>28</height>
</size>
</property>
<property name="autoRaise">
<bool>true</bool>
@ -563,24 +557,18 @@ border-image: url(:/images/closepressed.png)
</item>
<item>
<widget class="QToolButton" name="searchAfter">
<property name="minimumSize">
<size>
<width>14</width>
<height>28</height>
</size>
</property>
<property name="maximumSize">
<size>
<width>14</width>
<height>28</height>
</size>
</property>
<property name="focusPolicy">
<enum>Qt::NoFocus</enum>
</property>
<property name="icon">
<iconset resource="../WikiPoos/Wiki_images.qrc">
<normaloff>:/images/arrow-right.png</normaloff>:/images/arrow-right.png</iconset>
<iconset resource="../icons.qrc">
<normaloff>:/icons/png/arrow-right.png</normaloff>:/icons/png/arrow-right.png</iconset>
</property>
<property name="iconSize">
<size>
<width>28</width>
<height>28</height>
</size>
</property>
<property name="autoRaise">
<bool>true</bool>
@ -711,10 +699,10 @@ border-image: url(:/images/closepressed.png)
</size>
</property>
<property name="frameShape">
<enum>QFrame::Box</enum>
<enum>QFrame::NoFrame</enum>
</property>
<property name="frameShadow">
<enum>QFrame::Sunken</enum>
<enum>QFrame::Plain</enum>
</property>
<layout class="QHBoxLayout" name="titleBarFrameHLayout">
<property name="leftMargin">
@ -983,7 +971,7 @@ border-image: url(:/images/closepressed.png)
</action>
<action name="actionImport_sticker">
<property name="icon">
<iconset resource="../images.qrc">
<iconset resource="../icons.qrc">
<normaloff>:/icons/png/addstickers.png</normaloff>:/icons/png/addstickers.png</iconset>
</property>
<property name="text">

View File

@ -64,15 +64,13 @@ static PopupChatWindow *instance = NULL;
}
/** Default constructor */
PopupChatWindow::PopupChatWindow(bool tabbed, QWidget *parent, Qt::WindowFlags flags) : QMainWindow(parent, flags)
PopupChatWindow::PopupChatWindow(bool tabbed, QWidget *parent, Qt::WindowFlags flags)
: QMainWindow(parent, flags),tabbedWindow(tabbed),firstShow(true)
, chatDialog(nullptr),mEmptyIcon(nullptr)
{
/* Invoke Qt Designer generated QObject setup routine */
ui.setupUi(this);
tabbedWindow = tabbed;
firstShow = true;
chatDialog = NULL;
mEmptyIcon = NULL;
setAttribute(Qt::WA_DeleteOnClose);
ui.tabWidget->setVisible(tabbedWindow);
@ -204,15 +202,16 @@ void PopupChatWindow::addDialog(ChatDialog *dialog)
if (tabbedWindow) {
ui.tabWidget->addDialog(dialog);
} else {
ui.horizontalLayout->addWidget(dialog);
ui.chatcentralLayout->addWidget(dialog);
dialog->addToParent(this);
ui.horizontalLayout->setContentsMargins(0, 0, 0, 0);
chatId = dialog->getChatId();
ui.chatcentralLayout->setContentsMargins(0, 0, 0, 0);
chatId = dialog->getChatId();
chatDialog = dialog;
calculateStyle(dialog);
calculateTitle(dialog);
/* signal toggled is called */
ui.actionSetOnTop->setChecked(PeerSettings->getPrivateChatOnTop(chatId));
ui.actionSetOnTop->setChecked(PeerSettings->getPrivateChatOnTop(chatId));
QObject::connect(dialog, SIGNAL(dialogClose(ChatDialog*)), this, SLOT(dialogClose(ChatDialog*)));
}
@ -233,14 +232,15 @@ void PopupChatWindow::removeDialog(ChatDialog *dialog)
deleteLater();
}
} else {
QObject::disconnect(dialog, SIGNAL(dialogClose(ChatDialog*)), this, SLOT(dialogClose(ChatDialog*)));
if (chatDialog == dialog) {
QObject::disconnect(dialog, SIGNAL(dialogClose(ChatDialog*)), this, SLOT(dialogClose(ChatDialog*)));
saveSettings();
dialog->removeFromParent(this);
ui.horizontalLayout->removeWidget(dialog);
chatDialog = NULL;
chatId = ChatId();
ui.chatcentralLayout->removeWidget(dialog);
chatDialog = nullptr;
chatId = ChatId();
close();
deleteLater();
}
}

View File

@ -17,7 +17,7 @@
<string notr="true">MainWindow</string>
</property>
<widget class="QWidget" name="chatcentralwidget">
<layout class="QHBoxLayout" name="horizontalLayout">
<layout class="QHBoxLayout" name="chatcentralLayout">
<property name="leftMargin">
<number>5</number>
</property>

View File

@ -59,6 +59,8 @@
#define MAX_COMMENT_TITLE 32
static const uint32_t DELAY_BETWEEN_GROUP_STATISTICS_UPDATE = 120; // do not update group statistics more often than once every 2 mins
/*
* Transformation Notes:
* there are still a couple of things that the new groups differ from Old version.
@ -76,6 +78,9 @@ GxsGroupFrameDialog::GxsGroupFrameDialog(RsGxsIfaceHelper *ifaceImpl, QWidget *p
ui = new Ui::GxsGroupFrameDialog();
ui->setupUi(this);
mShouldUpdateMessageSummaryList = true;
mShouldUpdateGroupStatistics = false;
mLastGroupStatisticsUpdateTs=0;
mInitialized = false;
mDistSyncAllowed = allow_dist_sync;
mInFill = false;
@ -182,7 +187,43 @@ void GxsGroupFrameDialog::showEvent(QShowEvent *event)
initUi();
}
updateDisplay( mCachedGroupMetas.empty() );
uint32_t children = mYourGroups->childCount() + mSubscribedGroups->childCount() + mPopularGroups->childCount() + mOtherGroups->childCount();
bool empty = mCachedGroupMetas.empty() || children==0;
updateDisplay( empty );
}
void GxsGroupFrameDialog::paintEvent(QPaintEvent *pe)
{
if(mShouldUpdateMessageSummaryList)
{
if(!mGroupIdsSummaryToUpdate.empty())
for(auto& group_id: mGroupIdsSummaryToUpdate)
updateMessageSummaryListReal(group_id);
else
updateMessageSummaryListReal(RsGxsGroupId());
mShouldUpdateMessageSummaryList = false;
mGroupIdsSummaryToUpdate.clear();
}
rstime_t now = time(nullptr);
if(mShouldUpdateGroupStatistics && now > DELAY_BETWEEN_GROUP_STATISTICS_UPDATE + mLastGroupStatisticsUpdateTs)
{
// This mechanism allows to gather multiple updateGroupStatistics events at once and not send too many of them at the same time.
// it avoids re-loadign all the group everytime a friend sends new statistics.
for(auto& groupId: mGroupStatisticsToUpdate)
updateGroupStatisticsReal(groupId);
mShouldUpdateGroupStatistics = false;
mLastGroupStatisticsUpdateTs = time(nullptr);
mGroupStatisticsToUpdate.clear();
}
MainPage::paintEvent(pe);
}
void GxsGroupFrameDialog::processSettings(bool load)
@ -988,6 +1029,18 @@ void GxsGroupFrameDialog::insertGroupsData(const std::list<RsGxsGenericGroupData
}
void GxsGroupFrameDialog::updateMessageSummaryList(RsGxsGroupId groupId)
{
// groupId.isNull() means that we need to update all groups so we clear up the list of groups to update.
if(!groupId.isNull())
mGroupIdsSummaryToUpdate.insert(groupId);
else
mGroupIdsSummaryToUpdate.clear();
mShouldUpdateMessageSummaryList = true;
}
void GxsGroupFrameDialog::updateMessageSummaryListReal(RsGxsGroupId groupId)
{
if (!mInitialized) {
return;
@ -1072,6 +1125,12 @@ void GxsGroupFrameDialog::updateGroupSummary()
/*********************** **** **** **** ***********************/
void GxsGroupFrameDialog::updateGroupStatistics(const RsGxsGroupId &groupId)
{
mGroupStatisticsToUpdate.insert(groupId);
mShouldUpdateGroupStatistics = true;
}
void GxsGroupFrameDialog::updateGroupStatisticsReal(const RsGxsGroupId &groupId)
{
RsThread::async([this,groupId]()
{
@ -1083,7 +1142,7 @@ void GxsGroupFrameDialog::updateGroupStatistics(const RsGxsGroupId &groupId)
return;
}
RsQThreadUtils::postToObject( [this,stats]()
RsQThreadUtils::postToObject( [this,stats, groupId]()
{
/* 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
@ -1096,6 +1155,7 @@ void GxsGroupFrameDialog::updateGroupStatistics(const RsGxsGroupId &groupId)
return;
ui->groupTreeWidget->setUnreadCount(item, mCountChildMsgs ? (stats.mNumThreadMsgsUnread + stats.mNumChildMsgsUnread) : stats.mNumThreadMsgsUnread);
mCachedGroupStats[groupId] = stats;
getUserNotify()->updateIcon();
@ -1103,6 +1163,23 @@ void GxsGroupFrameDialog::updateGroupStatistics(const RsGxsGroupId &groupId)
});
}
void GxsGroupFrameDialog::getServiceStatistics(GxsServiceStatistic& stats) const
{
stats = GxsServiceStatistic(); // clears everything
for(auto it: mCachedGroupStats)
{
const GxsGroupStatistic& s(it.second);
stats.mNumMsgs += s.mNumMsgs;
stats.mNumGrps += 1;
stats.mSizeOfMsgs += s.mTotalSizeOfMsgs;
stats.mNumThreadMsgsNew += s.mNumThreadMsgsNew;
stats.mNumThreadMsgsUnread += s.mNumThreadMsgsUnread;
stats.mNumChildMsgsNew += s.mNumChildMsgsNew ;
stats.mNumChildMsgsUnread += s.mNumChildMsgsUnread ;
}
}
TurtleRequestId GxsGroupFrameDialog::distantSearch(const QString& search_string) // this should be overloaded in the child class
{

View File

@ -29,7 +29,6 @@
#include <inttypes.h>
#include "util/TokenQueue.h"
#include "GxsIdTreeWidgetItem.h"
#include "GxsGroupDialog.h"
@ -80,8 +79,11 @@ public:
virtual void getGroupList(std::map<RsGxsGroupId,RsGroupMetaData> &groups) ;
void getServiceStatistics(GxsServiceStatistic& stats) const ;
protected:
virtual void showEvent(QShowEvent *event);
virtual void showEvent(QShowEvent *event) override;
virtual void paintEvent(QPaintEvent *pe) override;
virtual void updateDisplay(bool complete);
const RsGxsGroupId &groupId() { return mGroupId; }
@ -102,6 +104,10 @@ protected:
virtual bool getGroupData(std::list<RsGxsGenericGroupData*>& groupInfo) =0;
virtual bool getGroupStatistics(const RsGxsGroupId& groupId,GxsGroupStatistic& stat) =0;
void updateGroupStatisticsReal(const RsGxsGroupId &groupId);
void updateMessageSummaryListReal(RsGxsGroupId groupId);
private slots:
void todo();
@ -173,20 +179,13 @@ private:
virtual uint32_t requestGroupSummaryType() { return GXS_REQUEST_TYPE_GROUP_META; } // request only meta data
void requestGroupStatistics(const RsGxsGroupId &groupId);
void loadGroupStatistics(const uint32_t &token);
// subscribe/unsubscribe ack.
// void acknowledgeSubscribeChange(const uint32_t &token);
GxsMessageFrameWidget *messageWidget(const RsGxsGroupId &groupId, bool ownTab);
GxsMessageFrameWidget *createMessageWidget(const RsGxsGroupId &groupId);
GxsCommentDialog *commentWidget(const RsGxsMessageId &msgId);
// void requestGroupSummary_CurrentGroup(const RsGxsGroupId &groupId);
// void loadGroupSummary_CurrentGroup(const uint32_t &token);
protected:
void updateSearchResults();
@ -209,12 +208,23 @@ private:
RsGxsGroupId mNavigatePendingGroupId;
RsGxsMessageId mNavigatePendingMsgId;
// Message summary list update
bool mShouldUpdateMessageSummaryList ; // whether we should update the counting for groups. This takes some CPU so we only do it when needed.
std::set<RsGxsGroupId> mGroupIdsSummaryToUpdate;
// GroupStatistics update
bool mShouldUpdateGroupStatistics;
rstime_t mLastGroupStatisticsUpdateTs;
std::set<RsGxsGroupId> mGroupStatisticsToUpdate;
UIStateHelper *mStateHelper;
/** Qt Designer generated object */
Ui::GxsGroupFrameDialog *ui;
std::map<RsGxsGroupId,RsGroupMetaData> mCachedGroupMetas;
std::map<RsGxsGroupId,GxsGroupStatistic> mCachedGroupStats;
std::map<uint32_t,QTreeWidgetItem*> mSearchGroupsItems ;
std::map<uint32_t,std::set<RsGxsGroupId> > mKnownGroups;

View File

@ -22,60 +22,35 @@
//#include "gui/gxs/RsGxsUpdateBroadcastBase.h"
#include "retroshare/rsgxsifacehelper.h"
#include "util/qtthreadsutils.h"
#define TOKEN_TYPE_STATISTICS 1
GxsUserNotify::GxsUserNotify(RsGxsIfaceHelper *ifaceImpl, QObject *parent) :
UserNotify(parent), TokenResponse()
GxsUserNotify::GxsUserNotify(RsGxsIfaceHelper *ifaceImpl, const GxsGroupFrameDialog *g,QObject *parent) : UserNotify(parent), mGroupFrameDialog(g)
{
mNewThreadMessageCount = 0;
mNewChildMessageCount = 0;
mCountChildMsgs = false;
mInterface = ifaceImpl;
mTokenService = mInterface->getTokenService();
mTokenQueue = new TokenQueue(mInterface->getTokenService(), this);
//mBase = new RsGxsUpdateBroadcastBase(ifaceImpl);
//connect(mBase, SIGNAL(fillDisplay(bool)), this, SLOT(updateIcon()));
}
GxsUserNotify::~GxsUserNotify()
{
if (mTokenQueue) {
delete(mTokenQueue);
}
//if (mBase) {
//delete(mBase);
//}
}
GxsUserNotify::~GxsUserNotify() {}
void GxsUserNotify::startUpdate()
{
mNewThreadMessageCount = 0;
mNewChildMessageCount = 0;
uint32_t token;
mTokenService->requestServiceStatistic(token);
mTokenQueue->queueRequest(token, 0, RS_TOKREQ_ANSTYPE_ACK, TOKEN_TYPE_STATISTICS);
GxsServiceStatistic stats;
mGroupFrameDialog->getServiceStatistics(stats);
/* 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
* after a blocking call to RetroShare API complete */
mNewThreadMessageCount = stats.mNumThreadMsgsNew;
mNewChildMessageCount = stats.mNumChildMsgsNew;
update();
}
void GxsUserNotify::loadRequest(const TokenQueue *queue, const TokenRequest &req)
{
if (queue == mTokenQueue) {
/* now switch on req */
switch(req.mUserType) {
case TOKEN_TYPE_STATISTICS:
{
GxsServiceStatistic stats;
mInterface->getServiceStatistic(req.mToken, stats);
mNewThreadMessageCount = stats.mNumThreadMsgsNew;
mNewChildMessageCount = stats.mNumChildMsgsNew;
update();
}
break;
}
}
}

View File

@ -23,22 +23,20 @@
#include <QObject>
#include "gui/common/UserNotify.h"
#include "gui/gxs/GxsGroupFrameDialog.h"
#include "util/TokenQueue.h"
struct RsGxsIfaceHelper;
class RsGxsUpdateBroadcastBase;
class GxsUserNotify : public UserNotify, public TokenResponse
class GxsUserNotify : public UserNotify
{
Q_OBJECT
public:
GxsUserNotify(RsGxsIfaceHelper *ifaceImpl, QObject *parent = 0);
GxsUserNotify(RsGxsIfaceHelper *ifaceImpl, const GxsGroupFrameDialog *g, QObject *parent = 0);
virtual ~GxsUserNotify();
/* TokenResponse */
virtual void loadRequest(const TokenQueue *queue, const TokenRequest &req);
protected:
virtual void startUpdate();
@ -49,10 +47,9 @@ protected:
bool mCountChildMsgs; // Count new child messages?
private:
RsGxsIfaceHelper *mInterface;
RsTokenService *mTokenService;
TokenQueue *mTokenQueue;
RsGxsUpdateBroadcastBase *mBase;
const GxsGroupFrameDialog *mGroupFrameDialog;
unsigned int mNewThreadMessageCount;
unsigned int mNewChildMessageCount;
};

View File

@ -24,32 +24,32 @@
#include <iostream>
const uint32_t WikiCreateEnabledFlags = (
GXS_GROUP_FLAGS_NAME |
// GXS_GROUP_FLAGS_ICON |
GXS_GROUP_FLAGS_DESCRIPTION |
GXS_GROUP_FLAGS_DISTRIBUTION |
// GXS_GROUP_FLAGS_PUBLISHSIGN |
GXS_GROUP_FLAGS_SHAREKEYS |
// GXS_GROUP_FLAGS_PERSONALSIGN |
// GXS_GROUP_FLAGS_COMMENTS |
0);
GXS_GROUP_FLAGS_NAME |
// GXS_GROUP_FLAGS_ICON |
GXS_GROUP_FLAGS_DESCRIPTION |
GXS_GROUP_FLAGS_DISTRIBUTION |
// GXS_GROUP_FLAGS_PUBLISHSIGN |
GXS_GROUP_FLAGS_SHAREKEYS |
// GXS_GROUP_FLAGS_PERSONALSIGN |
// GXS_GROUP_FLAGS_COMMENTS |
0);
uint32_t WikiCreateDefaultsFlags = ( GXS_GROUP_DEFAULTS_DISTRIB_PUBLIC |
//GXS_GROUP_DEFAULTS_DISTRIB_GROUP |
//GXS_GROUP_DEFAULTS_DISTRIB_LOCAL |
//GXS_GROUP_DEFAULTS_DISTRIB_GROUP |
//GXS_GROUP_DEFAULTS_DISTRIB_LOCAL |
GXS_GROUP_DEFAULTS_PUBLISH_OPEN |
//GXS_GROUP_DEFAULTS_PUBLISH_THREADS |
//GXS_GROUP_DEFAULTS_PUBLISH_REQUIRED |
//GXS_GROUP_DEFAULTS_PUBLISH_ENCRYPTED |
GXS_GROUP_DEFAULTS_PUBLISH_OPEN |
//GXS_GROUP_DEFAULTS_PUBLISH_THREADS |
//GXS_GROUP_DEFAULTS_PUBLISH_REQUIRED |
//GXS_GROUP_DEFAULTS_PUBLISH_ENCRYPTED |
//GXS_GROUP_DEFAULTS_PERSONAL_GPG |
GXS_GROUP_DEFAULTS_PERSONAL_REQUIRED |
//GXS_GROUP_DEFAULTS_PERSONAL_IFNOPUB |
//GXS_GROUP_DEFAULTS_PERSONAL_GPG |
GXS_GROUP_DEFAULTS_PERSONAL_REQUIRED |
//GXS_GROUP_DEFAULTS_PERSONAL_IFNOPUB |
//GXS_GROUP_DEFAULTS_COMMENTS_YES |
GXS_GROUP_DEFAULTS_COMMENTS_NO |
0);
//GXS_GROUP_DEFAULTS_COMMENTS_YES |
GXS_GROUP_DEFAULTS_COMMENTS_NO |
0);
uint32_t WikiEditDefaultsFlags = WikiCreateDefaultsFlags;
uint32_t WikiEditEnabledFlags = WikiCreateEnabledFlags;

View File

@ -64,10 +64,10 @@ void GxsChannelDialog::handleEvent_main_thread(std::shared_ptr<const RsEvent> ev
switch(e->mChannelEventCode)
{
case RsChannelEventCode::NEW_MESSAGE:
case RsChannelEventCode::UPDATED_MESSAGE: // [[fallthrough]];
case RsChannelEventCode::READ_STATUS_CHANGED:
updateMessageSummaryList(e->mChannelGroupId);
case RsChannelEventCode::NEW_MESSAGE: // [[fallthrough]];
case RsChannelEventCode::UPDATED_MESSAGE: // [[fallthrough]];
case RsChannelEventCode::READ_STATUS_CHANGED: // [[fallthrough]];
updateGroupStatisticsReal(e->mChannelGroupId); // update the list immediately
break;
case RsChannelEventCode::RECEIVED_DISTANT_SEARCH_RESULT:
@ -80,6 +80,10 @@ void GxsChannelDialog::handleEvent_main_thread(std::shared_ptr<const RsEvent> ev
updateDisplay(true);
break;
case RsChannelEventCode::STATISTICS_CHANGED:
updateGroupStatistics(e->mChannelGroupId);
break;
default:
break;
}
@ -109,7 +113,7 @@ QString GxsChannelDialog::getHelpString() const
UserNotify *GxsChannelDialog::createUserNotify(QObject *parent)
{
return new GxsChannelUserNotify(rsGxsChannels, parent);
return new GxsChannelUserNotify(rsGxsChannels,this, parent);
}
void GxsChannelDialog::shareOnChannel(const RsGxsGroupId& channel_id,const QList<RetroShareLink>& file_links)

View File

@ -18,11 +18,12 @@
* *
*******************************************************************************/
#include "retroshare/rsgxschannels.h"
#include "GxsChannelUserNotify.h"
#include "gui/MainWindow.h"
GxsChannelUserNotify::GxsChannelUserNotify(RsGxsIfaceHelper *ifaceImpl, QObject *parent) :
GxsUserNotify(ifaceImpl, parent)
GxsChannelUserNotify::GxsChannelUserNotify(RsGxsIfaceHelper *ifaceImpl, const GxsGroupFrameDialog *g, QObject *parent) :
GxsUserNotify(ifaceImpl, g, parent)
{
}

View File

@ -22,13 +22,14 @@
#define GXSCHANNELUSERNOTIFY_H
#include "gui/gxs/GxsUserNotify.h"
#include "gui/gxs/GxsGroupFrameDialog.h"
class GxsChannelUserNotify : public GxsUserNotify
{
Q_OBJECT
public:
GxsChannelUserNotify(RsGxsIfaceHelper *ifaceImpl, QObject *parent = 0);
GxsChannelUserNotify(RsGxsIfaceHelper *ifaceImpl, const GxsGroupFrameDialog *g, QObject *parent = 0);
virtual bool hasSetting(QString *name, QString *group);

View File

@ -1214,7 +1214,7 @@ void RsGxsForumModel::setMsgReadStatus(const QModelIndex& i,bool read_status,boo
if(!i.isValid())
return ;
preMods();
// no need to call preMods()/postMods() here because we'renot changing the model
void *ref = i.internalPointer();
uint32_t entry = 0;
@ -1226,34 +1226,46 @@ void RsGxsForumModel::setMsgReadStatus(const QModelIndex& i,bool read_status,boo
recursSetMsgReadStatus(entry,read_status,with_children) ;
recursUpdateReadStatusAndTimes(0,has_unread_below,has_read_below);
postMods();
// Normally we should only update the parents up to the top of the tree, but it's complicated and the update here doesn't really cost,
// so we blindly update the whole widget.
if(mTreeMode == TREE_MODE_FLAT)
emit dataChanged(createIndex(0,0,(void*)NULL), createIndex(mPosts.size(),COLUMN_THREAD_NB_COLUMNS-1,(void*)NULL));
else
emit dataChanged(createIndex(0,0,(void*)NULL), createIndex(mPosts[0].mChildren.size(),COLUMN_THREAD_NB_COLUMNS-1,(void*)NULL));
}
void RsGxsForumModel::recursSetMsgReadStatus(ForumModelIndex i,bool read_status,bool with_children)
{
if(read_status)
mPosts[i].mMsgStatus = 0;
else
mPosts[i].mMsgStatus = GXS_SERV::GXS_MSG_STATUS_GUI_UNREAD;
int newStatus = (read_status ? mPosts[i].mMsgStatus & ~static_cast<int>(GXS_SERV::GXS_MSG_STATUS_GUI_UNREAD)
: mPosts[i].mMsgStatus | static_cast<int>(GXS_SERV::GXS_MSG_STATUS_GUI_UNREAD));
bool bChanged = (mPosts[i].mMsgStatus != newStatus);
mPosts[i].mMsgStatus = newStatus;
//Remove Unprocessed and New flags
mPosts[i].mMsgStatus &= ~(GXS_SERV::GXS_MSG_STATUS_UNPROCESSED | GXS_SERV::GXS_MSG_STATUS_GUI_NEW);
uint32_t token;
if (bChanged)
{
//Don't recurs post versions as this should be done before, if no change.
uint32_t token;
auto s = getPostVersions(mPosts[i].mMsgId) ;
auto s = getPostVersions(mPosts[i].mMsgId) ;
if(!s.empty())
for(auto it(s.begin());it!=s.end();++it)
{
rsGxsForums->setMessageReadStatus(token,std::make_pair( mForumGroup.mMeta.mGroupId, it->second ), read_status);
std::cerr << "Setting version " << it->second << " of post " << mPosts[i].mMsgId << " as read." << std::endl;
}
else
rsGxsForums->setMessageReadStatus(token,std::make_pair( mForumGroup.mMeta.mGroupId, mPosts[i].mMsgId ), read_status);
}
if(!s.empty())
for(auto it(s.begin());it!=s.end();++it)
{
rsGxsForums->setMessageReadStatus(token,std::make_pair( mForumGroup.mMeta.mGroupId, it->second ), read_status);
std::cerr << "Setting version " << it->second << " of post " << mPosts[i].mMsgId << " as read." << std::endl;
}
else
rsGxsForums->setMessageReadStatus(token,std::make_pair( mForumGroup.mMeta.mGroupId, mPosts[i].mMsgId ), read_status);
if(!with_children)
return;
if(!with_children)
return;
for(uint32_t j=0;j<mPosts[i].mChildren.size();++j)
recursSetMsgReadStatus(mPosts[i].mChildren[j],read_status,with_children);
for(uint32_t j=0;j<mPosts[i].mChildren.size();++j)
recursSetMsgReadStatus(mPosts[i].mChildren[j],read_status,with_children);
}
void RsGxsForumModel::recursUpdateReadStatusAndTimes(ForumModelIndex i,bool& has_unread_below,bool& has_read_below)

View File

@ -1054,6 +1054,8 @@ void GxsForumThreadWidget::insertMessage()
ui->lineLeft->hide();
ui->by_text_label->hide();
ui->by_label->hide();
ui->postText->setImageBlockWidget(ui->imageBlockWidget) ;
ui->postText->resetImagesStatus(Settings->getForumLoadEmbeddedImages());
// add/show combobox for versions, if applicable, and enable it. If no older versions of the post available, hide the combobox.
@ -1726,6 +1728,7 @@ void GxsForumThreadWidget::postForumLoading()
recursRestoreExpandedItems(mThreadProxyModel->mapFromSource(mThreadModel->root()),mSavedExpandedMessages);
//mUpdating = false;
}
void GxsForumThreadWidget::updateGroupData()
{
if(groupId().isNull())

View File

@ -18,11 +18,12 @@
* *
*******************************************************************************/
#include "retroshare/rsgxsforums.h"
#include "GxsForumUserNotify.h"
#include "gui/MainWindow.h"
GxsForumUserNotify::GxsForumUserNotify(RsGxsIfaceHelper *ifaceImpl, QObject *parent) :
GxsUserNotify(ifaceImpl, parent)
GxsForumUserNotify::GxsForumUserNotify(RsGxsIfaceHelper *ifaceImpl, const GxsGroupFrameDialog *g, QObject *parent) :
GxsUserNotify(ifaceImpl, g, parent)
{
mCountChildMsgs = true;
}

View File

@ -28,7 +28,7 @@ class GxsForumUserNotify : public GxsUserNotify
Q_OBJECT
public:
GxsForumUserNotify(RsGxsIfaceHelper *ifaceImpl, QObject *parent = 0);
GxsForumUserNotify(RsGxsIfaceHelper *ifaceImpl, const GxsGroupFrameDialog *g, QObject *parent = 0);
virtual bool hasSetting(QString *name, QString *group);

View File

@ -62,13 +62,18 @@ void GxsForumsDialog::handleEvent_main_thread(std::shared_ptr<const RsEvent> eve
case RsForumEventCode::NEW_MESSAGE:
case RsForumEventCode::UPDATED_MESSAGE: // [[fallthrough]];
case RsForumEventCode::READ_STATUS_CHANGED:
updateMessageSummaryList(e->mForumGroupId);
updateGroupStatisticsReal(e->mForumGroupId); // update the list immediately
break;
case RsForumEventCode::NEW_FORUM: // [[fallthrough]];
case RsForumEventCode::SUBSCRIBE_STATUS_CHANGED:
updateDisplay(true);
break;
case RsForumEventCode::STATISTICS_CHANGED:
updateGroupStatistics(e->mForumGroupId); // update the list when redraw less often than once every 2 mins
break;
default:
break;
}
@ -133,7 +138,7 @@ void GxsForumsDialog::shareInMessage(const RsGxsGroupId& forum_id,const QList<Re
UserNotify *GxsForumsDialog::createUserNotify(QObject *parent)
{
return new GxsForumUserNotify(rsGxsForums, parent);
return new GxsForumUserNotify(rsGxsForums,this, parent);
}
QString GxsForumsDialog::text(TextType type)

View File

@ -69,6 +69,7 @@
<file>icons/png/chat-lobbies.png</file>
<file>icons/png/circles.png</file>
<file>icons/png/digital-key.png</file>
<file>icons/png/dock.png</file>
<file>icons/png/empty-circle.png</file>
<file>icons/png/enter.png</file>
<file>icons/png/exit.png</file>
@ -121,6 +122,7 @@
<file>icons/png/thumbs-neutral.png</file>
<file>icons/png/thumbs-up.png</file>
<file>icons/png/typing.png</file>
<file>icons/png/undock.png</file>
<file>icons/png/video.png</file>
<file>icons/quit_128.png</file>
<file>icons/search_red_128.png</file>

Binary file not shown.

Before

Width:  |  Height:  |  Size: 9.3 KiB

After

Width:  |  Height:  |  Size: 4.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.8 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.6 KiB

After

Width:  |  Height:  |  Size: 4.5 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.8 KiB

After

Width:  |  Height:  |  Size: 2.6 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.3 KiB

After

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.3 KiB

After

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 6.6 KiB

After

Width:  |  Height:  |  Size: 3.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.8 KiB

View File

@ -0,0 +1,95 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Created with Inkscape (http://www.inkscape.org/) -->
<svg
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
id="svg4823"
version="1.1"
inkscape:version="0.92.5 (2060ec1f9f, 2020-04-08)"
xml:space="preserve"
width="80"
height="80"
viewBox="0 0 80 80"
sodipodi:docname="dock.svg"
inkscape:export-filename="/home/phenom/GIT/RetroShare/trunk/retroshare-gui/src/gui/icons/png/dock.png"
inkscape:export-xdpi="153.60001"
inkscape:export-ydpi="153.60001"><metadata
id="metadata4829"><rdf:RDF><cc:Work
rdf:about=""><dc:format>image/svg+xml</dc:format><dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" /><dc:title /></cc:Work></rdf:RDF></metadata><defs
id="defs4827" /><sodipodi:namedview
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1"
objecttolerance="10"
gridtolerance="10"
guidetolerance="10"
inkscape:pageopacity="0"
inkscape:pageshadow="2"
inkscape:window-width="1920"
inkscape:window-height="1015"
id="namedview4825"
showgrid="false"
showguides="true"
inkscape:guide-bbox="true"
inkscape:zoom="8.34386"
inkscape:cx="-8.1326614"
inkscape:cy="38.591301"
inkscape:window-x="0"
inkscape:window-y="0"
inkscape:window-maximized="1"
inkscape:current-layer="g4831" /><g
id="g4831"
inkscape:groupmode="layer"
inkscape:label="ink_ext_XXXXXX"
transform="matrix(1.25,0,0,-1.25,0,80)"><path
inkscape:connector-curvature="0"
id="path4835"
style="fill:#039bd5;fill-opacity:1;fill-rule:nonzero;stroke:none"
d="M 64,32 C 64,14.327 49.673,0 32,0 14.327,0 0,14.327 0,32 0,49.673 14.327,64 32,64 49.673,64 64,49.673 64,32" /><path
inkscape:connector-curvature="0"
id="path5452-3"
style="fill:#000000;fill-opacity:0.15686275;fill-rule:nonzero;stroke:none;stroke-width:2.16372085"
d="M 48,17.599999 C 48,15.3906 46.2094,13.6 44.000001,13.6 h -24 C 17.7906,13.6 16,15.3906 16,17.599999 16,19.809401 17.7906,21.6 20.000001,21.6 h 24 C 46.2094,21.6 48,19.809401 48,17.599999" /><path
inkscape:connector-curvature="0"
id="path5452"
style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:2.16372061"
d="M 48,19.999999 C 48,17.7906 46.2094,16 44.000001,16 h -24 C 17.7906,16 16,17.7906 16,19.999999 16,22.209401 17.7906,24 20.000001,24 h 24 C 46.2094,24 48,22.209401 48,19.999999" /><path
sodipodi:type="star"
style="fill:#000000;fill-opacity:0.15686275;stroke-width:0.80000001"
id="path4575-7"
sodipodi:sides="3"
sodipodi:cx="32.203388"
sodipodi:cy="-39.322033"
sodipodi:r1="18.807909"
sodipodi:r2="9.4039545"
sodipodi:arg1="2.6179939"
sodipodi:arg2="3.6651914"
inkscape:flatsided="false"
inkscape:rounded="0"
inkscape:randomized="0"
d="m 15.915261,-29.918079 8.144064,-14.105931 8.144064,-14.105932 8.144063,14.105932 8.144063,14.105932 -16.288127,0 z"
transform="matrix(0.98231064,0,0,0.85070592,0.36626977,79.051486)"
inkscape:transform-center-y="5.0000002" /><path
sodipodi:type="star"
style="fill:#ffffff;fill-opacity:1;stroke-width:0.80000001"
id="path4575"
sodipodi:sides="3"
sodipodi:cx="32.203388"
sodipodi:cy="-39.322033"
sodipodi:r1="18.807909"
sodipodi:r2="9.4039545"
sodipodi:arg1="2.6179939"
sodipodi:arg2="3.6651914"
inkscape:flatsided="false"
inkscape:rounded="0"
inkscape:randomized="0"
d="m 15.915261,-29.918079 8.144064,-14.105931 8.144064,-14.105932 8.144063,14.105932 8.144063,14.105932 -16.288127,0 z"
transform="matrix(0.98231061,0,0,0.85070593,0.36627025,81.451486)"
inkscape:transform-center-y="5.0000009" /></g></svg>

After

Width:  |  Height:  |  Size: 4.1 KiB

View File

@ -11,7 +11,7 @@
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
id="svg4155"
version="1.1"
inkscape:version="0.91 r13725"
inkscape:version="0.92.4 (5da689c313, 2019-01-14)"
xml:space="preserve"
width="80"
height="80"
@ -19,7 +19,7 @@
sodipodi:docname="highlight.svg"><metadata
id="metadata4161"><rdf:RDF><cc:Work
rdf:about=""><dc:format>image/svg+xml</dc:format><dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" /><dc:title></dc:title></cc:Work></rdf:RDF></metadata><defs
rdf:resource="http://purl.org/dc/dcmitype/StillImage" /><dc:title /></cc:Work></rdf:RDF></metadata><defs
id="defs4159" /><sodipodi:namedview
pagecolor="#ffffff"
bordercolor="#666666"
@ -29,53 +29,49 @@
guidetolerance="10"
inkscape:pageopacity="0"
inkscape:pageshadow="2"
inkscape:window-width="1920"
inkscape:window-height="1009"
inkscape:window-width="1366"
inkscape:window-height="705"
id="namedview4157"
showgrid="false"
inkscape:zoom="4"
inkscape:cx="-24.259002"
inkscape:cx="36.287037"
inkscape:cy="43.832174"
inkscape:window-x="0"
inkscape:window-y="0"
inkscape:window-x="-8"
inkscape:window-y="-8"
inkscape:window-maximized="1"
inkscape:current-layer="g4163" /><g
id="g4163"
inkscape:groupmode="layer"
inkscape:label="ink_ext_XXXXXX"
transform="matrix(1.25,0,0,-1.25,0,80)"><path
inkscape:connector-curvature="0"
id="path4167"
style="fill:#039bd5;fill-opacity:1;fill-rule:nonzero;stroke:none"
d="M 64,32 C 64,14.327 49.673,0 32,0 14.327,0 0,14.327 0,32 0,49.673 14.327,64 32,64 49.673,64 64,49.673 64,32" /><rect
style="opacity:1;fill:#7db6d8;fill-opacity:1;stroke:none;stroke-width:1.70078743;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
transform="matrix(1.25,0,0,-1.25,0,80)"><rect
style="opacity:1;fill:#7db6d8;fill-opacity:1;stroke:none;stroke-width:2.52538538;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
id="rect6133"
width="28.011572"
height="7.7652335"
x="33.391724"
y="-4.4962573"
width="41.59251"
height="11.530078"
x="28.414354"
y="-6.3301339"
transform="matrix(0.70401372,0.71018637,0.71018637,-0.70401372,0,0)"
ry="0.97251195" /><rect
style="opacity:1;fill:#7db6d8;fill-opacity:1;stroke:none;stroke-width:1.70078743;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
ry="1.444018" /><rect
style="opacity:1;fill:#7db6d8;fill-opacity:1;stroke:none;stroke-width:2.52538538;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
id="rect6700"
width="27.207941"
height="1.5130339"
x="14.804393"
y="-17.282293"
width="40.399254"
height="2.2466028"
x="7.3261099"
y="-10.385328"
transform="scale(1,-1)"
ry="0.75651693" /><g
ry="1.1233014" /><g
id="use6704"
transform="matrix(0.01400435,0,0,0.01400435,13.445216,13.067276)"
transform="matrix(0.02079413,0,0,0.02079413,5.3079594,4.1267317)"
style="fill:#000000;fill-opacity:0.15686275;stroke:none"><path
style="fill:#000000;fill-opacity:0.15686275"
id="path6708"
d="M 872.51523,639.00498 C 767.99202,553.02724 168.10038,323.38141 131.10038,279.38141 99.655615,245.36096 96.853397,228.23591 111.76852,212.8463 c 13.92096,-14.36384 20.42554,-20.16439 41.43987,-19.84206 52.92372,0.81176 155.27561,7.0021 215.71714,65.06553 14.56004,13.98717 38.5512,28.7708 57.42621,22.4754 14.11853,-4.70897 74.39937,17.6523 213.06827,75.04468 C 879.26642,454.85764 942.53887,449.38714 1039,529 c 182.987,151.02574 806,793 990,1001 345,388 431,511 431,618 -1.8807,10.2331 -6.5386,50.5991 -21.4516,44.1496 C 2267.6724,2118.2502 1295.6545,987.06701 872.51523,639.00498 Z"
inkscape:connector-curvature="0"
sodipodi:nodetypes="scssssssccss" /></g><g
style="fill:#ffffff;stroke:none;fill-opacity:1"
transform="matrix(0.01400435,0,0,0.01400435,13.445216,14.667276)"
style="fill:#039bd5;fill-opacity:1;stroke:none"
transform="matrix(0.02079413,0,0,0.02079413,5.3079594,6.5024647)"
id="g4"><path
inkscape:connector-curvature="0"
d="m 2067,2455 c -49,-18 -114,-62 -207,-141 -41,-35 -132,-108 -201,-163 C 1389,1937 992,1562 674,1219 462,990 432,951 376,825 349,764 302,666 272,605 189,439 169,379 184,349 195,327 193,321 156,277 75,181 61,139 100,100 c 39,-39 98,-19 192,66 31,27 41,31 65,25 37,-10 55,-4 288,106 289,135 278,129 394,232 177,158 806,793 990,1001 345,388 431,511 431,618 0,51 -2,54 -79,140 -43,48 -101,108 -129,135 -47,43 -55,47 -99,46 -26,0 -65,-7 -86,-14 z m 5,-339 c 88,-75 148,-149 148,-182 0,-25 -95,-133 -380,-432 -91,-95 -190,-201 -220,-234 -87,-97 -731,-718 -744,-718 -6,0 -27,25 -46,56 -52,86 -117,153 -208,211 -69,45 -81,56 -73,71 13,24 146,167 385,415 260,270 719,700 914,858 l 73,59 37,-19 c 20,-11 72,-49 114,-85 z"
id="path6"
style="fill:#ffffff;fill-opacity:1" /></g></g></svg>
style="fill:#039bd5;fill-opacity:1" /></g></g></svg>

Before

Width:  |  Height:  |  Size: 4.4 KiB

After

Width:  |  Height:  |  Size: 4.2 KiB

View File

@ -11,12 +11,15 @@
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
id="svg4925"
version="1.1"
inkscape:version="0.91 r13725"
inkscape:version="0.92.4 (5da689c313, 2019-01-14)"
xml:space="preserve"
width="80"
height="80"
viewBox="0 0 80 80"
sodipodi:docname="search.svg"><metadata
sodipodi:docname="search.svg"
inkscape:export-filename="C:\Users\ProBook\Documents\GitHub\RetroShare\retroshare-gui\src\gui\icons\png\search.png"
inkscape:export-xdpi="153.60001"
inkscape:export-ydpi="153.60001"><metadata
id="metadata4931"><rdf:RDF><cc:Work
rdf:about=""><dc:format>image/svg+xml</dc:format><dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" /><dc:title /></cc:Work></rdf:RDF></metadata><defs
@ -29,50 +32,46 @@
guidetolerance="10"
inkscape:pageopacity="0"
inkscape:pageshadow="2"
inkscape:window-width="1920"
inkscape:window-height="1009"
inkscape:window-width="1366"
inkscape:window-height="705"
id="namedview4927"
showgrid="false"
inkscape:zoom="5.9"
inkscape:cx="-34.973275"
inkscape:cy="31.754347"
inkscape:window-x="0"
inkscape:window-y="0"
inkscape:cx="29.491525"
inkscape:cy="41.249684"
inkscape:window-x="-8"
inkscape:window-y="-8"
inkscape:window-maximized="1"
inkscape:current-layer="g4933" /><g
id="g4933"
inkscape:groupmode="layer"
inkscape:label="ink_ext_XXXXXX"
transform="matrix(1.25,0,0,-1.25,0,80)"><path
inkscape:connector-curvature="0"
id="path4937"
style="fill:#039bd5;fill-opacity:1;fill-rule:nonzero;stroke:none"
d="M 64,32 C 64,14.327 49.673,0 32,0 14.327,0 0,14.327 0,32 0,49.673 14.327,64 32,64 49.673,64 64,49.673 64,32" /><path
inkscape:connector-curvature="0"
id="path4939"
style="fill:#000000;fill-opacity:0.15686275;fill-rule:nonzero;stroke:none"
d="m 48,11.5 c -0.6395,0 -1.2797,0.2441 -1.7676,0.7324 l -9.4636,9.4637 c 0.3863,0.273 0.7605,0.5656 1.1218,0.8777 l 8.3418,-8.3414 C 46.7203,13.7441 47.3605,13.5 48,13.5 c 0.6395,0 1.2797,0.2441 1.7676,0.7324 0.2281,0.2281 0.4027,0.4891 0.5242,0.7676 C 50.691,14.0852 50.516,12.9809 49.7676,12.2324 49.2797,11.7441 48.6395,11.5 48,11.5 M 33.9215,24.6102 c -0.3543,0.5289 -0.4856,1.1632 -0.3926,1.7699 0.132,0.0734 0.2633,0.1504 0.3926,0.2301 0.0894,-0.1332 0.193,-0.2598 0.3109,-0.3778 l 0.8192,-0.8191 C 34.6891,25.118 34.3113,24.8504 33.9215,24.6102" /><path
style="fill:#000000;fill-opacity:0.15686275;fill-rule:nonzero;stroke:none;stroke-width:1.43466902"
d="m 54.804592,3.9067797 c -0.91747,0 -1.835946,0.350203 -2.535922,1.050752 L 38.691538,18.534808 c 0.554213,0.391665 1.091066,0.811448 1.609411,1.25921 L 52.26867,7.8268693 c 0.699976,-0.7005489 1.618452,-1.050752 2.535922,-1.050752 0.917471,0 1.835945,0.3502031 2.53592,1.050752 0.327248,0.3272473 0.577742,0.7016964 0.752054,1.1012519 0.572721,-1.3124356 0.321653,-2.89674 -0.752054,-3.9705895 -0.699975,-0.700549 -1.618449,-1.050752 -2.53592,-1.050752 M 34.606606,22.715577 c -0.508304,0.758796 -0.696677,1.668807 -0.563251,2.539221 0.189375,0.105304 0.377747,0.215773 0.563251,0.330117 0.128259,-0.191097 0.27689,-0.372727 0.446038,-0.542018 l 1.175281,-1.175138 c -0.520067,-0.423658 -1.062086,-0.807576 -1.621319,-1.152182" /><path
inkscape:connector-curvature="0"
id="path4941"
style="fill:#495672;fill-opacity:1;fill-rule:nonzero;stroke:none"
d="m 48,13.5 c -0.6395,0 -1.2797,0.2441 -1.7676,0.7324 l -12,12 c -0.9765,0.9766 -0.9765,2.5586 0,3.5352 0.9754,0.9765 2.5598,0.9765 3.5352,0 l 12,-12 c 0.9765,-0.9766 0.9765,-2.5586 0,-3.5352 C 49.2797,13.7441 48.6395,13.5 48,13.5" /><path
style="fill:#495672;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.43466902"
d="m 54.804592,6.7761173 c -0.91747,0 -1.835946,0.3502031 -2.535922,1.050752 L 35.052644,25.042897 c -1.400955,1.401097 -1.400955,3.670743 0,5.071841 1.399375,1.400955 3.672465,1.400955 5.071842,0 L 57.340512,12.898711 c 1.400954,-1.401097 1.400954,-3.6707434 0,-5.0718417 -0.699975,-0.7005489 -1.618449,-1.050752 -2.53592,-1.050752" /><path
inkscape:connector-curvature="0"
id="path4943"
style="fill:#7db6d8;fill-opacity:1;fill-rule:nonzero;stroke:none"
d="m 35.8578,43.0859 c 4.127,-4.1265 4.127,-10.8171 0,-14.9437 -4.1265,-4.127 -10.8172,-4.127 -14.9437,0 -4.127,4.1266 -4.127,10.8172 0,14.9437 4.1265,4.127 10.8172,4.127 14.9437,0" /><path
style="fill:#7db6d8;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.43466902"
d="m 37.384554,49.22209 c 5.920879,-5.920162 5.920879,-15.518958 0,-21.439263 -5.92016,-5.920879 -15.5191,-5.920879 -21.439261,0 -5.920879,5.920305 -5.920879,15.519101 0,21.439263 5.920161,5.920878 15.519101,5.920878 21.439261,0" /><path
inkscape:connector-curvature="0"
id="path4945"
style="fill:#000000;fill-opacity:0.15686275;fill-rule:nonzero;stroke:none"
d="m 28.3859,19.0469 c -3.891,0 -7.5492,1.5152 -10.3004,4.2668 -5.6796,5.6797 -5.6796,14.9211 0,20.6008 2.7512,2.7511 6.4094,4.2668 10.3004,4.2668 3.8911,0 7.5493,-1.5157 10.3004,-4.2668 4.7211,-4.7211 5.518,-11.904 2.3903,-17.4555 l -2.9801,2.9801 c 0.7051,1.641 0.9746,3.4246 0.8094,5.175 0.2859,3.0269 -0.7297,6.1539 -3.0481,8.4718 -2.0633,2.0633 -4.7676,3.0954 -7.4719,3.0954 -2.7043,0 -5.4086,-1.0321 -7.4718,-3.0954 -2.318,-2.3179 -3.334,-5.4449 -3.0481,-8.4718 -0.2859,-3.0274 0.7301,-6.1539 3.0481,-8.4719 2.0632,-2.0637 4.7675,-3.0953 7.4718,-3.0953 1.9219,0 3.8438,0.5211 5.5356,1.5633 0.0894,-0.1332 0.193,-0.2598 0.3109,-0.3778 l 2.5364,-2.5363 C 34.332,19.9746 31.4305,19.0469 28.3859,19.0469" /><path
style="fill:#000000;fill-opacity:0.15686275;fill-rule:nonzero;stroke:none;stroke-width:1.43466902"
d="m 26.664851,14.734082 c -5.582296,0 -10.830601,2.173812 -14.777662,6.121447 -8.1483473,8.148488 -8.1483473,21.406839 0,29.555328 3.947061,3.946917 9.195366,6.121444 14.777662,6.121444 5.582441,0 10.830747,-2.174527 14.777665,-6.121444 6.773214,-6.773215 7.916503,-17.0783 3.429289,-25.042864 l -4.275457,4.275457 c 1.011585,2.354291 1.398228,4.913167 1.161221,7.424412 0.410171,4.342598 -1.046878,8.828808 -4.373015,12.154228 -2.960152,2.960153 -6.839927,4.440874 -10.719703,4.440874 -3.879774,0 -7.75955,-1.480721 -10.719558,-4.440874 -3.325563,-3.32542 -4.783187,-7.81163 -4.373015,-12.154228 -0.410172,-4.343317 1.047452,-8.828809 4.373015,-12.154373 2.960008,-2.960726 6.839784,-4.44073 10.719558,-4.44073 2.757291,0 5.514582,0.747605 7.941755,2.242818 0.128259,-0.191099 0.27689,-0.372726 0.446038,-0.542018 l 3.638894,-3.638751 C 35.195536,16.065025 31.032845,14.734082 26.664851,14.734082" /><path
inkscape:connector-curvature="0"
id="path4947"
style="fill:#000000;fill-opacity:0.15686275;fill-rule:nonzero;stroke:none"
d="m 36.7688,21.6961 -2.5364,2.5363 c -0.1179,0.118 -0.2215,0.2446 -0.3109,0.3778 0.3898,0.2402 0.7676,0.5078 1.1301,0.8031 l 2.839,-2.8395 c -0.3613,-0.3121 -0.7355,-0.6047 -1.1218,-0.8777" /><path
style="fill:#000000;fill-opacity:0.15686275;fill-rule:nonzero;stroke:none;stroke-width:1.43466902"
d="m 38.691538,18.534808 -3.638894,3.638751 c -0.169148,0.169292 -0.317779,0.350919 -0.446038,0.542018 0.559233,0.344606 1.101252,0.728524 1.621319,1.152182 l 4.073024,-4.073741 c -0.518345,-0.447762 -1.055198,-0.867545 -1.609411,-1.25921" /><path
inkscape:connector-curvature="0"
id="path4951"
style="fill:#000000;fill-opacity:0.15686275;fill-rule:nonzero;stroke:none"
d="m 17.866,34.6141 c -0.2859,3.0269 0.7301,6.1539 3.0481,8.4718 2.0632,2.0633 4.7675,3.0954 7.4718,3.0954 2.7043,0 5.4086,-1.0321 7.4719,-3.0954 2.3184,-2.3179 3.334,-5.4449 3.0481,-8.4718 -0.2235,2.3621 -1.2391,4.6632 -3.0481,6.4718 -2.0633,2.0633 -4.7676,3.0954 -7.4719,3.0954 -2.7043,0 -5.4086,-1.0321 -7.4718,-3.0954 -1.8086,-1.8086 -2.8246,-4.1097 -3.0481,-6.4718" /><path
style="fill:#000000;fill-opacity:0.15686275;fill-rule:nonzero;stroke:none;stroke-width:1.43466902"
d="m 11.572278,37.067862 c -0.410172,4.342598 1.047452,8.828808 4.373015,12.154228 2.960008,2.960153 6.839784,4.440874 10.719558,4.440874 3.879776,0 7.759551,-1.480721 10.719703,-4.440874 3.326137,-3.32542 4.783186,-7.81163 4.373015,-12.154228 -0.320649,3.38883 -1.777698,6.690147 -4.373015,9.28489 -2.960152,2.960152 -6.839927,4.440874 -10.719703,4.440874 -3.879774,0 -7.75955,-1.480722 -10.719558,-4.440874 -2.594743,-2.594743 -4.052366,-5.89606 -4.373015,-9.28489" /><path
inkscape:connector-curvature="0"
id="path4953"
style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none"
d="m 28.3859,50.1813 c -3.891,0 -7.5492,-1.5157 -10.3004,-4.2668 -5.6796,-5.6797 -5.6796,-14.9211 0,-20.6008 2.7512,-2.7516 6.4094,-4.2668 10.3004,-4.2668 3.8911,0 7.5493,1.5152 10.3004,4.2668 5.6797,5.6797 5.6797,14.9211 0,20.6008 -2.7511,2.7511 -6.4093,4.2668 -10.3004,4.2668 z m 0,-4 c 2.7043,0 5.4086,-1.0321 7.4719,-3.0954 4.127,-4.1265 4.127,-10.8171 0,-14.9437 -2.0633,-2.0637 -4.7676,-3.0953 -7.4719,-3.0953 -2.7043,0 -5.4086,1.0316 -7.4718,3.0953 -4.127,4.1266 -4.127,10.8172 0,14.9437 2.0632,2.0633 4.7675,3.0954 7.4718,3.0954" /></g></svg>
style="fill:#039bd5;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.43466902"
d="m 26.664851,59.401639 c -5.582296,0 -10.830601,-2.174527 -14.777662,-6.121445 -8.1483473,-8.148489 -8.1483473,-21.406839 0,-29.555327 3.947061,-3.947635 9.195366,-6.121446 14.777662,-6.121446 5.582441,0 10.830747,2.173811 14.777665,6.121446 8.148488,8.148488 8.148488,21.406838 0,29.555327 -3.946918,3.946918 -9.195224,6.121445 -14.777665,6.121445 z m 0,-5.738675 c 3.879776,0 7.759551,-1.480721 10.719703,-4.440874 5.920879,-5.920162 5.920879,-15.518958 0,-21.439263 -2.960152,-2.960726 -6.839927,-4.440731 -10.719703,-4.440731 -3.879774,0 -7.75955,1.480005 -10.719558,4.440731 -5.920879,5.920305 -5.920879,15.519101 0,21.439263 2.960008,2.960153 6.839784,4.440874 10.719558,4.440874" /></g></svg>

Before

Width:  |  Height:  |  Size: 5.6 KiB

After

Width:  |  Height:  |  Size: 6.5 KiB

View File

@ -0,0 +1,95 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Created with Inkscape (http://www.inkscape.org/) -->
<svg
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
id="svg4823"
version="1.1"
inkscape:version="0.92.5 (2060ec1f9f, 2020-04-08)"
xml:space="preserve"
width="80"
height="80"
viewBox="0 0 80 80"
sodipodi:docname="undock.svg"
inkscape:export-filename="/home/phenom/GIT/RetroShare/trunk/retroshare-gui/src/gui/icons/png/undock.png"
inkscape:export-xdpi="153.60001"
inkscape:export-ydpi="153.60001"><metadata
id="metadata4829"><rdf:RDF><cc:Work
rdf:about=""><dc:format>image/svg+xml</dc:format><dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" /><dc:title /></cc:Work></rdf:RDF></metadata><defs
id="defs4827" /><sodipodi:namedview
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1"
objecttolerance="10"
gridtolerance="10"
guidetolerance="10"
inkscape:pageopacity="0"
inkscape:pageshadow="2"
inkscape:window-width="1920"
inkscape:window-height="1015"
id="namedview4825"
showgrid="false"
showguides="true"
inkscape:guide-bbox="true"
inkscape:zoom="8.34386"
inkscape:cx="-8.1326614"
inkscape:cy="38.591301"
inkscape:window-x="0"
inkscape:window-y="0"
inkscape:window-maximized="1"
inkscape:current-layer="g4831" /><g
id="g4831"
inkscape:groupmode="layer"
inkscape:label="ink_ext_XXXXXX"
transform="matrix(1.25,0,0,-1.25,0,80)"><path
inkscape:connector-curvature="0"
id="path4835"
style="fill:#039bd5;fill-opacity:1;fill-rule:nonzero;stroke:none"
d="M 64,32 C 64,14.327 49.673,0 32,0 14.327,0 0,14.327 0,32 0,49.673 14.327,64 32,64 49.673,64 64,49.673 64,32" /><path
inkscape:connector-curvature="0"
id="path5452-3"
style="fill:#000000;fill-opacity:0.15686275;fill-rule:nonzero;stroke:none;stroke-width:2.16372085"
d="M 48,17.599999 C 48,15.3906 46.2094,13.6 44.000001,13.6 h -24 C 17.7906,13.6 16,15.3906 16,17.599999 16,19.809401 17.7906,21.6 20.000001,21.6 h 24 C 46.2094,21.6 48,19.809401 48,17.599999" /><path
inkscape:connector-curvature="0"
id="path5452"
style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:2.16372061"
d="M 48,19.999999 C 48,17.7906 46.2094,16 44.000001,16 h -24 C 17.7906,16 16,17.7906 16,19.999999 16,22.209401 17.7906,24 20.000001,24 h 24 C 46.2094,24 48,22.209401 48,19.999999" /><path
sodipodi:type="star"
style="fill:#000000;fill-opacity:0.15686275;stroke-width:0.80000001"
id="path4575-7"
sodipodi:sides="3"
sodipodi:cx="32.203388"
sodipodi:cy="-39.322033"
sodipodi:r1="18.807909"
sodipodi:r2="9.4039545"
sodipodi:arg1="2.6179939"
sodipodi:arg2="3.6651914"
inkscape:flatsided="false"
inkscape:rounded="0"
inkscape:randomized="0"
d="m 15.915261,-29.918079 8.144064,-14.105931 8.144064,-14.105932 8.144063,14.105932 8.144063,14.105932 -16.288127,0 z"
transform="matrix(0.98231064,0,0,-0.85070592,0.36626977,4.1485139)"
inkscape:transform-center-y="-5.0000005" /><path
sodipodi:type="star"
style="fill:#ffffff;fill-opacity:1;stroke-width:0.80000001"
id="path4575"
sodipodi:sides="3"
sodipodi:cx="32.203388"
sodipodi:cy="-39.322033"
sodipodi:r1="18.807909"
sodipodi:r2="9.4039545"
sodipodi:arg1="2.6179939"
sodipodi:arg2="3.6651914"
inkscape:flatsided="false"
inkscape:rounded="0"
inkscape:randomized="0"
d="m 15.915261,-29.918079 8.144064,-14.105931 8.144064,-14.105932 8.144063,14.105932 8.144063,14.105932 -16.288127,0 z"
transform="matrix(0.98231061,0,0,-0.85070593,0.36627025,6.5485136)"
inkscape:transform-center-y="-5.0000005" /></g></svg>

After

Width:  |  Height:  |  Size: 4.1 KiB

View File

@ -331,7 +331,6 @@
<file>images/mimetypes/source_c.png</file>
<file>images/mimetypes/source_cpp.png</file>
<file>images/mimetypes/source_h.png</file>
<file>images/toaster/backgroundtoaster.png</file>
<file>images/thumb-default-video.png</file>
<file>images/user/add_user24.png</file>
<file>images/user/add_user48.png</file>

Binary file not shown.

Before

Width:  |  Height:  |  Size: 30 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 34 KiB

View File

@ -132,6 +132,7 @@ MessageWidget::MessageWidget(bool controlled, QWidget *parent, Qt::WindowFlags f
isControlled = controlled;
isWindow = false;
currMsgFlags = 0;
expandFiles = false;
ui.actionTextBesideIcon->setData(Qt::ToolButtonTextBesideIcon);
ui.actionIconOnly->setData(Qt::ToolButtonIconOnly);
@ -281,10 +282,7 @@ void MessageWidget::processSettings(const QString &settingsGroup, bool load)
// load settings
// expandFiles
bool value = Settings->value("expandFiles", false).toBool();
ui.expandFilesButton->setChecked(value);
ui.msgList->setVisible(value);
togglefileview();
expandFiles = Settings->value("expandFiles", false).toBool();
// toolbar button style
Qt::ToolButtonStyle style = (Qt::ToolButtonStyle) Settings->value("ToolButon_Style", Qt::ToolButtonTextBesideIcon).toInt();
@ -293,7 +291,7 @@ void MessageWidget::processSettings(const QString &settingsGroup, bool load)
// save settings
// expandFiles
Settings->setValue("expandFiles", ui.expandFilesButton->isChecked());
Settings->setValue("expandFiles", expandFiles);
//toolbar button style
Settings->setValue("ToolButon_Style", ui.replyButton->toolButtonStyle());
@ -322,7 +320,7 @@ void MessageWidget::msgfilelistWidgetCostumPopupMenu( QPoint /*point*/ )
contextMnu.exec(QCursor::pos());
}
void MessageWidget::togglefileview()
void MessageWidget::togglefileview(bool noUpdate/*=false*/)
{
/* if msg header visible -> change icon and tooltip
* three widgets...
@ -335,6 +333,10 @@ void MessageWidget::togglefileview()
ui.expandFilesButton->setIcon(QIcon(QString(":/icons/png/up-arrow.png")));
ui.expandFilesButton->setToolTip(tr("Show the attachment pane"));
}
if (!noUpdate)
expandFiles = ui.expandFilesButton->isChecked();
ui.msgList->setVisible(ui.expandFilesButton->isChecked());
}
/* download the recommendations... */
@ -426,13 +428,10 @@ void MessageWidget::messagesChanged()
void MessageWidget::clearTagLabels()
{
/* clear all tags */
while (tagLabels.size()) {
delete tagLabels.front();
tagLabels.pop_front();
}
while (ui.tagLayout->count()) {
delete ui.tagLayout->takeAt(0);
}
qDeleteAll(tagLabels);
tagLabels.clear();
misc::clearLayout(ui.tagLayout);
ui.tagsLabel->setVisible(false);
}
@ -510,6 +509,16 @@ void MessageWidget::fill(const std::string &msgId)
clearTagLabels();
ui.inviteFrame->hide();
ui.expandFilesButton->setChecked(false);
togglefileview(true);
ui.replyButton->setEnabled(false);
ui.replyallButton->setEnabled(false);
ui.forwardButton->setEnabled(false);
ui.deleteButton->setEnabled(false);
ui.moreButton->setEnabled(false);
currMsgFlags = 0;
return;
@ -517,6 +526,13 @@ void MessageWidget::fill(const std::string &msgId)
clearTagLabels();
ui.replyButton->setEnabled(true);
ui.replyallButton->setEnabled(true);
ui.forwardButton->setEnabled(true);
ui.deleteButton->setEnabled(true);
ui.moreButton->setEnabled(true);
MessageInfo msgInfo;
if (rsMail->getMessage(currMsgId, msgInfo) == false) {
std::cerr << "MessageWidget::fill() Couldn't find Msg" << std::endl;
@ -549,6 +565,8 @@ void MessageWidget::fill(const std::string &msgId)
/* add the items in! */
ui.msgList->insertTopLevelItems(0, items);
ui.expandFilesButton->setChecked(expandFiles && (items.count()>0) );
togglefileview(true);
/* iterate through the sources */
RetroShareLink link;
@ -688,8 +706,15 @@ void MessageWidget::remove()
if (isWindow) {
window()->close();
} else {
deleteLater();
if (isControlled) {
currMsgId.clear();
fill(currMsgId);
} else {
deleteLater();
}
}
emit messageRemoved();
}
void MessageWidget::print()

View File

@ -58,6 +58,8 @@ public:
QString subject(bool noEmpty);
signals:
void messageRemoved();
private slots:
void reply();
@ -75,7 +77,7 @@ private slots:
void messagesTagsChanged();
void messagesChanged();
void togglefileview();
void togglefileview(bool noUpdate = false);
void getcurrentrecommended();
void getallrecommended();
@ -94,6 +96,7 @@ private:
bool isWindow;
std::string currMsgId;
unsigned int currMsgFlags;
bool expandFiles;
QList<QLabel*> tagLabels;

View File

@ -124,9 +124,11 @@ MessagesDialog::MessagesDialog(QWidget *parent)
inProcessSettings = false;
inChange = false;
lockUpdate = 0;
lastSelectedIndex = QModelIndex();
msgWidget = new MessageWidget(true, this);
ui.msgLayout->addWidget(msgWidget);
connect(msgWidget, SIGNAL(messageRemoved()), this, SLOT(messageRemoved()));
connectActions();
@ -695,6 +697,7 @@ void MessagesDialog::openAsWindow()
}
msgWidget->activateWindow();
connect(msgWidget, SIGNAL(messageRemoved()), this, SLOT(messageRemoved()));
/* window will destroy itself! */
}
@ -714,6 +717,7 @@ void MessagesDialog::openAsTab()
ui.tabWidget->addTab(msgWidget, msgWidget->subject(true));
ui.tabWidget->setCurrentWidget(msgWidget);
connect(msgWidget, SIGNAL(messageRemoved()), this, SLOT(messageRemoved()));
/* window will destroy itself! */
}
@ -860,7 +864,8 @@ void MessagesDialog::clicked(const QModelIndex& proxy_index)
case RsMessageModel::COLUMN_THREAD_READ:
{
mMessageModel->setMsgReadStatus(real_index, !isMessageRead(proxy_index));
insertMsgTxtAndFiles(proxy_index);
//Already updated by currentChanged
//insertMsgTxtAndFiles(proxy_index);
updateMessageSummaryList();
return;
}
@ -871,8 +876,9 @@ void MessagesDialog::clicked(const QModelIndex& proxy_index)
}
}
// show current message directly
insertMsgTxtAndFiles(proxy_index);
// show current message directly
//Already updated by currentChanged
//insertMsgTxtAndFiles(proxy_index);
}
// double click in messageTreeWidget
@ -953,14 +959,20 @@ void MessagesDialog::insertMsgTxtAndFiles(const QModelIndex& proxy_index)
QModelIndex real_index = mMessageProxyModel->mapToSource(proxy_index);
if(!real_index.isValid())
if(!real_index.isValid())
{
mCurrMsgId.clear();
msgWidget->fill(mCurrMsgId);
updateInterface();
lastSelectedIndex = QModelIndex();
return;
}
mid = real_index.data(RsMessageModel::MsgIdRole).toString().toStdString();
lastSelectedIndex = proxy_index;
if (!ui.messageTreeWidget->indexBelow(proxy_index).isValid())
lastSelectedIndex = ui.messageTreeWidget->indexAbove(proxy_index);
mid = real_index.data(RsMessageModel::MsgIdRole).toString().toStdString();
/* Save the Data.... for later */
@ -1025,6 +1037,12 @@ void MessagesDialog::removemessage()
mMessageModel->updateMessages();
updateMessageSummaryList();
messageRemoved();
}
void MessagesDialog::messageRemoved()
{
ui.messageTreeWidget->setCurrentIndex(lastSelectedIndex);
}
void MessagesDialog::undeletemessage()

View File

@ -57,10 +57,6 @@ public:
void setTextColorInbox(QColor color) { mTextColorInbox = color; }
signals:
void messagesAboutToLoad();
void messagesLoaded();
protected:
virtual UserNotify *createUserNotify(QObject *parent) override;
bool eventFilter(QObject *obj, QEvent *ev);
@ -69,6 +65,7 @@ protected:
public slots:
//void insertMessages();
void messagesTagsChanged();
void messageRemoved();
void preModelUpdate();
void postModelUpdate();
@ -156,6 +153,7 @@ private:
Ui::MessagesDialog ui;
QList<QString> mTmpSavedSelectedIds;
QModelIndex lastSelectedIndex;
};
#endif

View File

@ -225,9 +225,8 @@ ChatWidget QFrame#infoFrame {
background-color: qlineargradient(x1:0, y1:0, x2:0, y2:1, stop:0 #FFFFD7, stop:1 #FFFFB2);
}
ChatWidget QFrame#titleBarFrame {
background-color: qlineargradient(x1:0, y1:0, x2:0, y2:1, stop:0 #FEFEFE, stop:1 #E8E8E8);
border: 1px solid #CCCCCC;
ChatWidget QFrame#titleBarFrame, QFrame#toolBarFrameTop {
}
PopupChatWindow QToolBar#chattoolBar{
@ -242,8 +241,8 @@ MessageComposer QToolBar#toolBar {
}
MessagesDialog QFrame#folderFrame, MessagesDialog QFrame#quickViewFrame {
background-color: qlineargradient(x1:0, y1:0, x2:0, y2:1, stop:0 #FEFEFE, stop:1 #E8E8E8);
border: 1px solid #CCCCCC;
background: transparent;
}
/* Profile */

View File

@ -75,7 +75,7 @@
<item>
<widget class="QCheckBox" name="notify_Posted">
<property name="text">
<string>Links</string>
<string>Boards</string>
</property>
</widget>
</item>
@ -103,7 +103,7 @@
<item>
<widget class="QCheckBox" name="notify_Security">
<property name="text">
<string>Security</string>
<string>Friend Requests</string>
</property>
</widget>
</item>
@ -155,7 +155,7 @@
<item>
<widget class="QCheckBox" name="message_ConnectAttempt">
<property name="text">
<string>Connect attempt</string>
<string>Friend Requests</string>
</property>
</widget>
</item>
@ -256,7 +256,7 @@
<item>
<widget class="QCheckBox" name="popup_ConnectAttempt">
<property name="text">
<string>Connect attempt</string>
<string>Friend Requests</string>
</property>
</widget>
</item>

View File

@ -45,6 +45,7 @@
#include "util/QtVersion.h"
#include "gui/common/UIStateHelper.h"
#include "util/misc.h"
#include "util/qtthreadsutils.h"
#include "gui/gxs/GxsIdLabel.h"
#include "gui/gxs/GxsIdDetails.h"
#include "gui/gxs/GxsIdTreeWidgetItem.h"
@ -85,8 +86,6 @@ GxsTransportStatistics::GxsTransportStatistics(QWidget *parent)
mStateHelper = new UIStateHelper(this);
mStateHelper->addWidget(GXSTRANS_GROUP_META, treeWidget);
mTransQueue = new TokenQueue(rsGxsTrans->getTokenService(), this);
m_bProcessSettings = false;
mLastGroupReqTS = 0 ;
@ -154,7 +153,8 @@ void GxsTransportStatistics::updateDisplay(bool)
std::cerr << "GxsTransportStatistics::updateDisplay()" << std::endl;
#endif
requestGroupMeta();
loadGroups();
mLastGroupReqTS = now ;
}
@ -201,7 +201,7 @@ void GxsTransportStatistics::updateContent()
{
RsGxsTrans::GxsTransStatistics transinfo ;
rsGxsTrans->getStatistics(transinfo) ;
rsGxsTrans->getDataStatistics(transinfo) ;
// clear
@ -333,92 +333,8 @@ void GxsTransportStatistics::personDetails()
dialog->show();
}
void GxsTransportStatistics::loadRequest(const TokenQueue *queue, const TokenRequest &req)
{
#ifdef DEBUG_GXSTRANS_STATS
std::cerr << "GxsTransportStatistics::loadRequest() UserType: " << req.mUserType << std::endl;
#endif
if (queue != mTransQueue)
{
std::cerr << "Wrong queue!" << std::endl;
return ;
}
/* now switch on req */
switch(req.mUserType)
{
case GXSTRANS_GROUP_META: loadGroupMeta(req.mToken);
break;
case GXSTRANS_GROUP_STAT: loadGroupStat(req.mToken);
break;
case GXSTRANS_MSG_META: loadMsgMeta(req.mToken);
break;
default:
std::cerr << "GxsTransportStatistics::loadRequest() ERROR: INVALID TYPE";
std::cerr << std::endl;
break;
}
updateContent();
}
void GxsTransportStatistics::requestGroupMeta()
{
mStateHelper->setLoading(GXSTRANS_GROUP_META, true);
#ifdef DEBUG_GXSTRANS_STATS
std::cerr << "GxsTransportStatisticsWidget::requestGroupMeta()";
std::cerr << std::endl;
#endif
RsTokReqOptions opts;
opts.mReqType = GXS_REQUEST_TYPE_GROUP_META;
uint32_t token;
mTransQueue->requestGroupInfo(token, RS_TOKREQ_ANSTYPE_SUMMARY, opts, GXSTRANS_GROUP_META);
}
void GxsTransportStatistics::requestGroupStat(const RsGxsGroupId &groupId)
{
uint32_t token;
rsGxsTrans->getTokenService()->requestGroupStatistic(token, groupId);
mTransQueue->queueRequest(token, 0, RS_TOKREQ_ANSTYPE_ACK, GXSTRANS_GROUP_STAT);
}
void GxsTransportStatistics::requestMsgMeta(const RsGxsGroupId& grpId)
{
mStateHelper->setLoading(GXSTRANS_MSG_META, true);
#ifdef DEBUG_GXSTRANS_STATS
std::cerr << "GxsTransportStatisticsWidget::requestGroupMeta()";
std::cerr << std::endl;
#endif
RsTokReqOptions opts;
opts.mReqType = GXS_REQUEST_TYPE_MSG_META;
std::list<RsGxsGroupId> grouplist ;
grouplist.push_back(grpId) ;
uint32_t token;
rsGxsTrans->getTokenService()->requestMsgInfo(token, RS_TOKREQ_ANSTYPE_SUMMARY, opts, grouplist);
mTransQueue->queueRequest(token, 0, RS_TOKREQ_ANSTYPE_ACK, GXSTRANS_MSG_META);
}
void GxsTransportStatistics::loadGroupStat(const uint32_t &token)
{
GxsGroupStatistic stats;
rsGxsTrans->getGroupStatistic(token, stats);
#ifdef DEBUG_GXSTRANS_STATS
std::cerr << "Loading group stats: " << stats.mGrpId << ", num msgs=" << stats.mNumMsgs << ", total size=" << stats.mTotalSizeOfMsgs << std::endl;
#endif
dynamic_cast<GxsGroupStatistic&>(mGroupStats[stats.mGrpId]) = stats ;
}
void GxsTransportStatistics::loadGroupMeta(const uint32_t& token)
#ifdef TO_REMOVE
void GxsTransportStatistics::loadGroupMeta(const std::vector<RsGroupMetaData>& groupInfo)
{
mStateHelper->setLoading(GXSTRANS_GROUP_META, false);
@ -427,22 +343,11 @@ void GxsTransportStatistics::loadGroupMeta(const uint32_t& token)
std::cerr << std::endl;
#endif
std::list<RsGroupMetaData> groupInfo;
std::list<RsGroupMetaData>::iterator vit;
if (!rsGxsTrans->getGroupSummary(token,groupInfo))
{
std::cerr << "GxsTransportStatistics::loadGroupMeta() Error getting GroupMeta";
std::cerr << std::endl;
mStateHelper->setActive(GXSTRANS_GROUP_META, false);
return;
}
mStateHelper->setActive(GXSTRANS_GROUP_META, true);
std::set<RsGxsGroupId> existing_groups ;
for(vit = groupInfo.begin(); vit != groupInfo.end(); ++vit)
for(auto vit = groupInfo.begin(); vit != groupInfo.end(); ++vit)
{
existing_groups.insert(vit->mGroupId) ;
@ -451,8 +356,8 @@ void GxsTransportStatistics::loadGroupMeta(const uint32_t& token)
std::cerr << "GxsTransportStatisticsWidget::loadGroupMeta() GroupId: " << vit->mGroupId << " Group: " << vit->mGroupName << std::endl;
#endif
requestGroupStat(vit->mGroupId) ;
requestMsgMeta(vit->mGroupId) ;
loadGroupStats(vit->mGroupId) ;
loadMsgMetas(vit->mGroupId) ;
RsGxsTransGroupStatistics& s(mGroupStats[vit->mGroupId]);
s.popularity = vit->mPop ;
@ -469,17 +374,74 @@ void GxsTransportStatistics::loadGroupMeta(const uint32_t& token)
++it;
}
void GxsTransportStatistics::loadMsgMeta(const uint32_t& token)
void GxsTransportStatistics::loadGroupStats(const RsGxsGroupId& groupId)
{
mStateHelper->setLoading(GXSTRANS_MSG_META, false);
#ifdef DEBUG_GXSTRANS_STATS
std::cerr << "Loading group stats: " << stats.mGrpId << ", num msgs=" << stats.mNumMsgs << ", total size=" << stats.mTotalSizeOfMsgs << std::endl;
#endif
GxsMsgMetaMap m ;
RsThread::async([this]()
{
// 1 - get message data from p3GxsForums
if (!rsGxsTrans->getMsgSummary(token,m))
return ;
#ifdef DEBUG_FORUMS
std::cerr << "Retrieving post data for post " << mThreadId << std::endl;
#endif
GxsGroupStatistic stats;
rsGxsTrans->getGroupStatistic(groupId,stats);
for(GxsMsgMetaMap::const_iterator it(m.begin());it!=m.end();++it)
for(uint32_t i=0;i<it->second.size();++i)
mGroupStats[it->first].addMessageMeta(it->first,it->second[i]) ;
RsQThreadUtils::postToObject( [stats,this]()
{
/* 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
* after a blocking call to RetroShare API complete */
dynamic_cast<GxsGroupStatistic&>(mGroupStats[stats.mGrpId]) = stats ;
mStateHelper->setLoading(GXSTRANS_GROUP_STAT, false);
}, this );
});
}
#endif
void GxsTransportStatistics::loadGroups()
{
mStateHelper->setLoading(GXSTRANS_GROUP_META, true);
RsThread::async([this]()
{
// 1 - get message data from p3GxsForums
#ifdef DEBUG_FORUMS
std::cerr << "Retrieving post data for post " << mThreadId << std::endl;
#endif
std::map<RsGxsGroupId,RsGxsTransGroupStatistics> stats;
if(!rsGxsTrans->getGroupStatistics(stats))
{
RsErr() << "Cannot retrieve group statistics in GxsTransportStatistics" << std::endl;
return;
}
RsQThreadUtils::postToObject( [stats,this]()
{
/* 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
* after a blocking call to RetroShare API complete */
mGroupStats = stats;
updateContent();
mStateHelper->setLoading(GXSTRANS_GROUP_META, false);
}, this );
});
}

View File

@ -25,8 +25,8 @@
#include <QPoint>
#include <retroshare/rsgrouter.h>
#include <retroshare/rstypes.h>
#include <retroshare/rsgxstrans.h>
#include "util/TokenQueue.h"
#include "RsAutoUpdatePage.h"
#include "ui_GxsTransportStatistics.h"
#include "gui/gxs/RsGxsUpdateBroadcastPage.h"
@ -35,32 +35,7 @@
class GxsTransportStatisticsWidget ;
class UIStateHelper;
class RsGxsTransGroupStatistics: public GxsGroupStatistic
{
public:
RsGxsTransGroupStatistics()
{
last_publish_TS = 0;
popularity = 0;
subscribed = false;
}
void addMessageMeta(const RsGxsGroupId& grp,const RsMsgMetaData& meta)
{
messages_metas[meta.mMsgId] = meta ;
last_publish_TS = std::max(last_publish_TS,meta.mPublishTs) ;
mGrpId = grp ;
}
bool subscribed ;
int popularity ;
rstime_t last_publish_TS;
std::map<RsGxsMessageId,RsMsgMetaData> messages_metas ;
};
class GxsTransportStatistics: public MainPage, public TokenResponse, public Ui::GxsTransportStatistics
class GxsTransportStatistics: public MainPage, public Ui::GxsTransportStatistics
{
Q_OBJECT
@ -71,8 +46,6 @@ public:
// Cache for peer names.
static QString getPeerName(const RsPeerId& peer_id) ;
virtual void loadRequest(const TokenQueue *queue, const TokenRequest &req) ;
void updateContent() ;
private slots:
@ -82,19 +55,12 @@ private slots:
private:
void updateDisplay(bool complete) ;
void loadGroupMeta(const uint32_t& token);
void loadGroupStat(const uint32_t& token);
void loadMsgMeta(const uint32_t& token);
void requestGroupMeta();
void requestMsgMeta(const RsGxsGroupId& groupId);
void requestGroupStat(const RsGxsGroupId &groupId);
void loadGroups();
void processSettings(bool bLoad);
bool m_bProcessSettings;
GxsTransportStatisticsWidget *_tst_CW ;
TokenQueue *mTransQueue ;
UIStateHelper *mStateHelper;
uint32_t mLastGroupReqTS ;

View File

@ -1241,6 +1241,7 @@ gxsthewire {
gui/TheWire/WireGroupDialog.cpp \
gui/TheWire/PulseAddDialog.cpp \
RESOURCES += gui/TheWire/TheWire_images.qrc
}
identities {

View File

@ -405,3 +405,23 @@ QString misc::getExistingDirectory(QWidget *parent, const QString &caption, cons
return QFileDialog::getExistingDirectory(parent, caption, dir, QFileDialog::DontUseNativeDialog | QFileDialog::ShowDirsOnly | QFileDialog::DontResolveSymlinks);
#endif
}
/*!
* Clear a Layout content
* \param layout: Layout to Clear
*/
void misc::clearLayout(QLayout * layout) {
if (! layout)
return;
while (auto item = layout->takeAt(0))
{
if (auto *widget = item->widget())
widget->deleteLater();
if (auto *spacer = item->spacerItem())
delete spacer;
clearLayout(item->layout());
delete item;
}
}

View File

@ -27,6 +27,7 @@
#include <QPair>
#include <QThread>
#include <QFileDialog>
#include <QLayout>
#include "gui/settings/rsharesettings.h"
@ -182,6 +183,10 @@ class misc : public QObject
static QString getExistingDirectory(QWidget *parent = nullptr
, const QString &caption = QString()
, const QString &dir = QString());
//Clear QLayout
static void clearLayout(QLayout *layout);
};
// Trick to get a portable sleep() function