merged upstream/master

This commit is contained in:
csoler 2020-03-06 22:12:06 +01:00
commit 1f0678075f
No known key found for this signature in database
GPG Key ID: 7BCA522266C0804C
111 changed files with 3722 additions and 2428 deletions

View File

@ -465,14 +465,17 @@ void JsonApiServer::registerHandler(
const std::shared_ptr<rb::Session> session,
const std::function<void (const std::shared_ptr<rb::Session>)>& callback )
{
/* Declare outside the lambda to avoid returning a dangling
* reference on Android */
RsWarn tWarn;
const auto authFail =
[&path, &session](int status) -> RsWarn::stream_type&
[&](int status) -> RsWarn::stream_type&
{
/* Capture session by reference as it is cheaper then copying
* shared_ptr by value which is not needed in this case */
session->close(status, corsOptionsHeaders);
return RsWarn() << "JsonApiServer authentication handler "
return tWarn << "JsonApiServer authentication handler "
"blocked an attempt to call JSON API "
"authenticated method: " << path;
};

View File

@ -404,10 +404,16 @@ int AuthSSLimpl::InitAuth(
std::cout.flush() ;
#ifndef RS_DISABLE_DIFFIE_HELLMAN_INIT_CHECK
if(DH_check(dh, &codes) && codes == 0)
SSL_CTX_set_tmp_dh(sslctx, dh);
else
pfs_enabled = false ;
pfs_enabled = false;
#else // ndef RS_DISABLE_DIFFIE_HELLMAN_INIT_CHECK
/* DH_check(...) is not strictly necessary and on Android devices it
* takes at least one minute which is untolerable there */
SSL_CTX_set_tmp_dh(sslctx, dh);
#endif // ndef RS_DISABLE_DIFFIE_HELLMAN_INIT_CHECK
}
else
pfs_enabled = false ;

View File

@ -245,7 +245,7 @@ public:
std::vector<RsMsgMetaData>& msgMetas) = 0;
/**
* @brief Get specific list of messages from a single forums. Blocking API
* @brief Get specific list of messages from a single forum. Blocking API
* @jsonapi{development}
* @param[in] forumId id of the forum of which the content is requested
* @param[in] msgsIds list of message ids to request

View File

@ -3,7 +3,7 @@
* *
* libretroshare: retroshare core library *
* *
* Copyright 2012-2012 by Robert Fernie <retroshare@lunamutt.com> *
* Copyright 2012-2020 by Robert Fernie <retroshare@lunamutt.com> *
* *
* This program is free software: you can redistribute it and/or modify *
* it under the terms of the GNU Lesser General Public License as *
@ -45,11 +45,7 @@ class RsWireGroup
/***********************************************************************
* So pulses operate in the following modes.
*
* => Standard, a post to your own group.
* => @User, gets duplicated on each user's group.
* => RT, duplicated as child of original post.
* RsWire - is intended to be a Twitter clone - but fully decentralised.
*
* From Twitter:
* twitter can be: embedded, replied to, favourited, unfavourited,
@ -73,6 +69,36 @@ class RsWirePlace
};
/************************************************************************
* Pulse comes in three flavours.
*
*
* Original Msg Pulse
* - Spontaneous msg, on your own group.
* - mPulseType = WIRE_PULSE_TYPE_ORIGINAL_MSG
* - Ref fields are empty.
*
* Reply to a Pulse (i.e Retweet), has two parts.
* as we want the retweet to reference the original, and the original to know about reply.
* This info will be duplicated in two msgs - but allow data to spread easier.
*
* Reply Msg Pulse, will be Top-Level Msg on Publisher's Group.
* - mPulseMode = WIRE_PULSE_TYPE_REPLY_MSG
* - Ref fields refer to Parent (InReplyTo) Msg.
*
* Reply Reference, is Child Msg of Parent Msg, on Parent Publisher's Group.
* - mPulseMode = WIRE_PULSE_TYPE_REPLY_REFERENCE
* - Ref fields refer to Reply Msg.
* - NB: This Msg requires Parent Msg for complete info, while other two are self-contained.
***********************************************************************/
#define WIRE_PULSE_TYPE_ORIGINAL_MSG (0x0001)
#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)
class RsWirePulse
{
@ -80,19 +106,26 @@ class RsWirePulse
RsMsgMetaData mMeta;
std::string mPulseText; // all the text is stored here.
std::string mHashTags;
// Store actual Pulse here.
std::string mPulseText;
// These will be added at some point.
// std::string mInReplyPulse;
uint32_t mPulseType;
// uint32_t mPulseFlags;
// These Ref to the related (parent or reply) if reply (MODE_REPLY_MSG set)
// Mode REPLY_MSG only REPLY_REFERENCE
RsGxsGroupId mRefGroupId; // PARENT_GrpId REPLY_GrpId
std::string mRefGroupName; // PARENT_GrpName REPLY_GrpName
RsGxsMessageId mRefOrigMsgId; // PARENT_OrigMsgId REPLY_OrigMsgId
RsGxsId mRefAuthorId; // PARENT_AuthorId REPLY_AuthorId
rstime_t mRefPublishTs; // PARENT_PublishTs REPLY_PublishTs
std::string mRefPulseText; // PARENT_PulseText REPLY_PulseText
// std::list<std::string> mMentions;
// std::list<std::string> mHashTags;
// std::list<std::string> mUrls;
// RsWirePlace mPlace;
// Open Question. Do we want these additional fields?
// These can potentially be added at some point.
// std::list<std::string> mMentions;
// std::list<std::string> mHashTags;
// std::list<std::string> mUrls;
// RsWirePlace mPlace;
};
@ -107,6 +140,13 @@ class RsWire: public RsGxsIfaceHelper
explicit RsWire(RsGxsIface& gxs) : RsGxsIfaceHelper(gxs) {}
virtual ~RsWire() {}
/*!
* To acquire a handle to token service handler
* needed to make requests to the service
* @return handle to token service for this gxs service
*/
virtual RsTokenService* getTokenService() = 0;
/* Specific Service Data */
virtual bool getGroupData(const uint32_t &token, std::vector<RsWireGroup> &groups) = 0;
virtual bool getPulseData(const uint32_t &token, std::vector<RsWirePulse> &pulses) = 0;

View File

@ -64,6 +64,7 @@ enum class RsServiceType : uint16_t
GXS_TRANS = 0x0230,
JSONAPI = 0x0240,
FORUMS_CONFIG = 0x0315,
POSTED_CONFIG = 0x0316,
CHANNELS_CONFIG = 0x0317,
RTT = 0x1011, /// Round Trip Time
@ -123,7 +124,9 @@ RS_DEPRECATED_FOR(RsServiceType) const uint16_t RS_SERVICE_GXS_TYPE_REPUTATION
RS_DEPRECATED_FOR(RsServiceType) const uint16_t RS_SERVICE_TYPE_GXS_RECOGN = 0x0220;
RS_DEPRECATED_FOR(RsServiceType) const uint16_t RS_SERVICE_TYPE_GXS_TRANS = 0x0230;
RS_DEPRECATED_FOR(RsServiceType) const uint16_t RS_SERVICE_TYPE_JSONAPI = 0x0240;
/// used to save notification records in GXS and possible other service-based configuration
RS_DEPRECATED_FOR(RsServiceType) const uint16_t RS_SERVICE_GXS_TYPE_FORUMS_CONFIG = 0x0315;
RS_DEPRECATED_FOR(RsServiceType) const uint16_t RS_SERVICE_GXS_TYPE_POSTED_CONFIG = 0x0316;
RS_DEPRECATED_FOR(RsServiceType) const uint16_t RS_SERVICE_GXS_TYPE_CHANNELS_CONFIG = 0x0317;
// Experimental Services.

View File

@ -29,16 +29,16 @@
RsItem *RsGxsWireSerialiser::create_item(uint16_t service,uint8_t item_subtype) const
{
if(service != RS_SERVICE_GXS_TYPE_WIRE)
return NULL ;
if(service != RS_SERVICE_GXS_TYPE_WIRE)
return NULL ;
switch(item_subtype)
{
case RS_PKT_SUBTYPE_WIRE_GROUP_ITEM: return new RsGxsWireGroupItem();
case RS_PKT_SUBTYPE_WIRE_PULSE_ITEM: return new RsGxsWirePulseItem();
default:
return NULL ;
}
switch(item_subtype)
{
case RS_PKT_SUBTYPE_WIRE_GROUP_ITEM: return new RsGxsWireGroupItem();
case RS_PKT_SUBTYPE_WIRE_PULSE_ITEM: return new RsGxsWirePulseItem();
default:
return NULL ;
}
}
void RsGxsWireGroupItem::clear()
@ -48,18 +48,30 @@ void RsGxsWireGroupItem::clear()
void RsGxsWireGroupItem::serial_process(RsGenericSerializer::SerializeJob j,RsGenericSerializer::SerializeContext& ctx)
{
RsTypeSerializer::serial_process(j,ctx,TLV_TYPE_STR_DESCR,group.mDescription,"group.mDescription") ;
RsTypeSerializer::serial_process(j,ctx,TLV_TYPE_STR_DESCR,group.mDescription,"group.mDescription") ;
}
void RsGxsWirePulseItem::clear()
{
pulse.mPulseText.clear();
pulse.mHashTags.clear();
pulse.mPulseType = 0;
pulse.mRefGroupId.clear();
pulse.mRefGroupName.clear();
pulse.mRefOrigMsgId.clear();
pulse.mRefAuthorId.clear();
pulse.mRefPulseText.clear();
}
void RsGxsWirePulseItem::serial_process(RsGenericSerializer::SerializeJob j,RsGenericSerializer::SerializeContext& ctx)
{
RsTypeSerializer::serial_process(j,ctx,TLV_TYPE_STR_MSG,pulse.mPulseText,"pulse.mPulseText") ;
RsTypeSerializer::serial_process(j,ctx,TLV_TYPE_STR_HASH_TAG,pulse.mHashTags,"pulse.mHashTags") ;
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,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") ;
RsTypeSerializer::serial_process(j,ctx,pulse.mRefAuthorId,"pulse.mRefAuthorId") ;
RsTypeSerializer::serial_process(j,ctx,pulse.mRefPublishTs,"pulse.mRefPublishTs") ;
RsTypeSerializer::serial_process(j,ctx,TLV_TYPE_STR_MSG,pulse.mRefPulseText,"pulse.mRefPulseText") ;
}

View File

@ -1381,8 +1381,7 @@ int RsServer::StartupRetroShare()
#ifdef RS_USE_WIRE
/**** Wire GXS service ****/
RsGeneralDataService* wire_ds = new RsDataService(currGxsDir + "/", "wire_db",
RS_SERVICE_GXS_TYPE_WIRE,
NULL, rsInitConfig->gxs_passwd);
RS_SERVICE_GXS_TYPE_WIRE, NULL, rsInitConfig->gxs_passwd);
p3Wire *mWire = new p3Wire(wire_ds, NULL, mGxsIdService);
@ -1633,6 +1632,7 @@ int RsServer::StartupRetroShare()
mConfigMgr->addConfiguration("gxschannels_srv.cfg", mGxsChannels);
mConfigMgr->addConfiguration("gxscircles.cfg" , gxscircles_ns);
mConfigMgr->addConfiguration("posted.cfg" , posted_ns);
mConfigMgr->addConfiguration("gxsposted_srv.cfg", mPosted);
#ifdef RS_USE_WIKI
mConfigMgr->addConfiguration("wiki.cfg", wiki_ns);
#endif
@ -1826,7 +1826,7 @@ int RsServer::StartupRetroShare()
startServiceThread(mPhoto, "gxs photo");
#endif
#if RS_USE_WIRE
startServiceThread(mPhoto, "gxs wire");
startServiceThread(mWire, "gxs wire");
#endif
// cores ready start up GXS net servers
@ -1843,7 +1843,7 @@ int RsServer::StartupRetroShare()
startServiceThread(photo_ns, "gxs photo ns");
#endif
#if RS_USE_WIRE
startServiceThread(photo_ns, "gxs wire ns");
startServiceThread(wire_ns, "gxs wire ns");
#endif
# ifdef RS_GXS_TRANS

View File

@ -136,14 +136,14 @@ uint32_t p3GxsChannels::channelsAuthenPolicy()
static const uint32_t GXS_CHANNELS_CONFIG_MAX_TIME_NOTIFY_STORAGE = 86400*30*2 ; // ignore notifications for 2 months
static const uint8_t GXS_CHANNELS_CONFIG_SUBTYPE_NOTIFY_RECORD = 0x01 ;
struct RsGxsGroupNotifyRecordsItem: public RsItem
struct RsGxsChannelNotifyRecordsItem: public RsItem
{
RsGxsGroupNotifyRecordsItem()
RsGxsChannelNotifyRecordsItem()
: RsItem(RS_PKT_VERSION_SERVICE,RS_SERVICE_GXS_TYPE_CHANNELS_CONFIG,GXS_CHANNELS_CONFIG_SUBTYPE_NOTIFY_RECORD)
{}
virtual ~RsGxsGroupNotifyRecordsItem() {}
virtual ~RsGxsChannelNotifyRecordsItem() {}
void serial_process( RsGenericSerializer::SerializeJob j,
RsGenericSerializer::SerializeContext& ctx )
@ -167,7 +167,7 @@ public:
switch(item_sub_id)
{
case GXS_CHANNELS_CONFIG_SUBTYPE_NOTIFY_RECORD: return new RsGxsGroupNotifyRecordsItem();
case GXS_CHANNELS_CONFIG_SUBTYPE_NOTIFY_RECORD: return new RsGxsChannelNotifyRecordsItem();
default:
return NULL;
}
@ -178,7 +178,7 @@ bool p3GxsChannels::saveList(bool &cleanup, std::list<RsItem *>&saveList)
{
cleanup = true ;
RsGxsGroupNotifyRecordsItem *item = new RsGxsGroupNotifyRecordsItem ;
RsGxsChannelNotifyRecordsItem *item = new RsGxsChannelNotifyRecordsItem ;
{
RS_STACK_MUTEX(mKnownChannelsMutex);
@ -198,7 +198,7 @@ bool p3GxsChannels::loadList(std::list<RsItem *>& loadList)
rstime_t now = time(NULL);
RsGxsGroupNotifyRecordsItem *fnr = dynamic_cast<RsGxsGroupNotifyRecordsItem*>(item) ;
RsGxsChannelNotifyRecordsItem *fnr = dynamic_cast<RsGxsChannelNotifyRecordsItem*>(item) ;
if(fnr)
{
@ -206,7 +206,7 @@ bool p3GxsChannels::loadList(std::list<RsItem *>& loadList)
mKnownChannels.clear();
for(auto it(fnr->records.begin());it!=fnr->records.end();++it)
if( it->second + GXS_CHANNELS_CONFIG_MAX_TIME_NOTIFY_STORAGE < now)
if( now < it->second + GXS_CHANNELS_CONFIG_MAX_TIME_NOTIFY_STORAGE)
mKnownChannels.insert(*it) ;
}

View File

@ -96,14 +96,14 @@ uint32_t p3GxsForums::forumsAuthenPolicy()
static const uint32_t GXS_FORUMS_CONFIG_MAX_TIME_NOTIFY_STORAGE = 86400*30*2 ; // ignore notifications for 2 months
static const uint8_t GXS_FORUMS_CONFIG_SUBTYPE_NOTIFY_RECORD = 0x01 ;
struct RsGxsGroupNotifyRecordsItem: public RsItem
struct RsGxsForumNotifyRecordsItem: public RsItem
{
RsGxsGroupNotifyRecordsItem()
RsGxsForumNotifyRecordsItem()
: RsItem(RS_PKT_VERSION_SERVICE,RS_SERVICE_GXS_TYPE_FORUMS_CONFIG,GXS_FORUMS_CONFIG_SUBTYPE_NOTIFY_RECORD)
{}
virtual ~RsGxsGroupNotifyRecordsItem() {}
virtual ~RsGxsForumNotifyRecordsItem() {}
void serial_process( RsGenericSerializer::SerializeJob j,
RsGenericSerializer::SerializeContext& ctx )
@ -127,7 +127,7 @@ public:
switch(item_sub_id)
{
case GXS_FORUMS_CONFIG_SUBTYPE_NOTIFY_RECORD: return new RsGxsGroupNotifyRecordsItem();
case GXS_FORUMS_CONFIG_SUBTYPE_NOTIFY_RECORD: return new RsGxsForumNotifyRecordsItem();
default:
return NULL;
}
@ -138,7 +138,7 @@ bool p3GxsForums::saveList(bool &cleanup, std::list<RsItem *>&saveList)
{
cleanup = true ;
RsGxsGroupNotifyRecordsItem *item = new RsGxsGroupNotifyRecordsItem ;
RsGxsForumNotifyRecordsItem *item = new RsGxsForumNotifyRecordsItem ;
item->records = mKnownForums ;
@ -155,14 +155,14 @@ bool p3GxsForums::loadList(std::list<RsItem *>& loadList)
rstime_t now = time(NULL);
RsGxsGroupNotifyRecordsItem *fnr = dynamic_cast<RsGxsGroupNotifyRecordsItem*>(item) ;
RsGxsForumNotifyRecordsItem *fnr = dynamic_cast<RsGxsForumNotifyRecordsItem*>(item) ;
if(fnr != NULL)
{
mKnownForums.clear();
for(auto it(fnr->records.begin());it!=fnr->records.end();++it)
if( it->second + GXS_FORUMS_CONFIG_MAX_TIME_NOTIFY_STORAGE < now)
if( now < it->second + GXS_FORUMS_CONFIG_MAX_TIME_NOTIFY_STORAGE)
mKnownForums.insert(*it) ;
}

View File

@ -157,15 +157,26 @@ void p3PostBase::notifyChanges(std::vector<RsGxsNotify *> &changes)
const std::list<RsGxsGroupId>& grpList = grpChange->mGrpIdList;
for (auto git = grpList.begin(); git != grpList.end(); ++git)
{
{
if(mKnownPosted.find(*git) == mKnownPosted.end())
{
mKnownPosted.insert(std::make_pair(*git, time(nullptr)));
IndicateConfigChanged();
auto ev = std::make_shared<RsGxsPostedEvent>();
ev->mPostedGroupId = *git;
ev->mPostedEventCode = RsPostedEventCode::NEW_POSTED_GROUP;
rsEvents->postEvent(ev);
#ifdef POSTBASE_DEBUG
std::cerr << "p3PostBase::notifyChanges() Incoming Group: " << *git;
std::cerr << std::endl;
std::cerr << "p3PostBase::notifyChanges() Incoming Group: " << *git;
std::cerr << std::endl;
#endif
auto ev = std::make_shared<RsGxsPostedEvent>();
ev->mPostedGroupId = *git;
ev->mPostedEventCode = RsPostedEventCode::NEW_POSTED_GROUP;
rsEvents->postEvent(ev);
}
else
RsInfo() << __PRETTY_FUNCTION__
<< " Not notifying already known forum "
<< *git << std::endl;
}
}
break;
@ -828,3 +839,89 @@ void p3PostBase::handleResponse(uint32_t token, uint32_t req_type)
}
}
static const uint32_t GXS_POSTED_CONFIG_MAX_TIME_NOTIFY_STORAGE = 86400*30*2 ; // ignore notifications for 2 months
static const uint8_t GXS_POSTED_CONFIG_SUBTYPE_NOTIFY_RECORD = 0x01 ;
struct RsGxsPostedNotifyRecordsItem: public RsItem
{
RsGxsPostedNotifyRecordsItem()
: RsItem(RS_PKT_VERSION_SERVICE,RS_SERVICE_GXS_TYPE_POSTED_CONFIG,GXS_POSTED_CONFIG_SUBTYPE_NOTIFY_RECORD)
{}
virtual ~RsGxsPostedNotifyRecordsItem() {}
void serial_process( RsGenericSerializer::SerializeJob j,
RsGenericSerializer::SerializeContext& ctx )
{ RS_SERIAL_PROCESS(records); }
void clear() {}
std::map<RsGxsGroupId,rstime_t> records;
};
class GxsPostedConfigSerializer : public RsServiceSerializer
{
public:
GxsPostedConfigSerializer() : RsServiceSerializer(RS_SERVICE_GXS_TYPE_POSTED_CONFIG) {}
virtual ~GxsPostedConfigSerializer() {}
RsItem* create_item(uint16_t service_id, uint8_t item_sub_id) const
{
if(service_id != RS_SERVICE_GXS_TYPE_POSTED_CONFIG)
return NULL;
switch(item_sub_id)
{
case GXS_POSTED_CONFIG_SUBTYPE_NOTIFY_RECORD: return new RsGxsPostedNotifyRecordsItem();
default:
return NULL;
}
}
};
bool p3PostBase::saveList(bool &cleanup, std::list<RsItem *>&saveList)
{
cleanup = true ;
RsGxsPostedNotifyRecordsItem *item = new RsGxsPostedNotifyRecordsItem ;
item->records = mKnownPosted ;
saveList.push_back(item) ;
return true;
}
bool p3PostBase::loadList(std::list<RsItem *>& loadList)
{
while(!loadList.empty())
{
RsItem *item = loadList.front();
loadList.pop_front();
rstime_t now = time(NULL);
RsGxsPostedNotifyRecordsItem *fnr = dynamic_cast<RsGxsPostedNotifyRecordsItem*>(item) ;
if(fnr != NULL)
{
mKnownPosted.clear();
for(auto it(fnr->records.begin());it!=fnr->records.end();++it)
if( now < it->second + GXS_POSTED_CONFIG_MAX_TIME_NOTIFY_STORAGE)
mKnownPosted.insert(*it) ;
}
delete item ;
}
return true;
}
RsSerialiser* p3PostBase::setupSerialiser()
{
RsSerialiser* rss = new RsSerialiser;
rss->addSerialType(new GxsPostedConfigSerializer());
return rss;
}

View File

@ -63,39 +63,44 @@ bool encodePostCache(std::string &str, const PostStats &s);
bool extractPostCache(const std::string &str, PostStats &s);
class p3PostBase: public RsGenExchange, public GxsTokenQueue, public RsTickEvent
class p3PostBase: public RsGenExchange, public GxsTokenQueue, public RsTickEvent, public p3Config
{
public:
public:
p3PostBase(RsGeneralDataService *gds, RsNetworkExchangeService *nes, RsGixs* gixs,
RsSerialType* serviceSerialiser, uint16_t serviceType);
RsSerialType* serviceSerialiser, uint16_t serviceType);
virtual void service_tick();
virtual void service_tick();
protected:
protected:
virtual void notifyChanges(std::vector<RsGxsNotify*>& changes);
virtual void notifyChanges(std::vector<RsGxsNotify*>& changes);
// Overloaded from GxsTokenQueue for Request callbacks.
virtual void handleResponse(uint32_t token, uint32_t req_type);
// Overloaded from GxsTokenQueue for Request callbacks.
virtual void handleResponse(uint32_t token, uint32_t req_type);
// Overloaded from RsTickEvent.
virtual void handle_event(uint32_t event_type, const std::string &elabel);
// Overloaded from RsTickEvent.
virtual void handle_event(uint32_t event_type, const std::string &elabel);
public:
// overloads p3Config
virtual RsSerialiser* setupSerialiser() override; // @see p3Config::setupSerialiser()
virtual bool saveList(bool &cleanup, std::list<RsItem *>&saveList) override; // @see p3Config::saveList(bool &cleanup, std::list<RsItem *>&)
virtual bool loadList(std::list<RsItem *>& loadList) override; // @see p3Config::loadList(std::list<RsItem *>&)
//////////////////////////////////////////////////////////////////////////////
public:
virtual void setMessageReadStatus(uint32_t& token, const RsGxsGrpMsgIdPair& msgId, bool read);
//////////////////////////////////////////////////////////////////////////////
virtual void setMessageReadStatus(uint32_t& token, const RsGxsGrpMsgIdPair& msgId, bool read);
protected:
protected:
p3GxsCommentService *mCommentService;
private:
private:
static uint32_t postBaseAuthenPolicy();
static uint32_t postBaseAuthenPolicy();
// Background processing.
void background_tick();
@ -120,9 +125,10 @@ static uint32_t postBaseAuthenPolicy();
bool mBgProcessing;
bool mBgIncremental;
std::list<RsGxsGroupId> mBgGroupList;
std::map<RsGxsMessageId, PostStats> mBgStatsMap;
std::list<RsGxsGroupId> mBgGroupList;
std::map<RsGxsMessageId, PostStats> mBgStatsMap;
std::map<RsGxsGroupId,rstime_t> mKnownPosted;
};
#endif

View File

@ -3,7 +3,7 @@
* *
* libretroshare: retroshare core library *
* *
* Copyright 2012-2012 by Robert Fernie <retroshare@lunamutt.com> *
* Copyright 2012-2020 by Robert Fernie <retroshare@lunamutt.com> *
* *
* This program is free software: you can redistribute it and/or modify *
* it under the terms of the GNU Lesser General Public License as *
@ -83,6 +83,10 @@ void p3Wire::service_tick()
return;
}
RsTokenService* p3Wire::getTokenService() {
return RsGenExchange::getTokenService();
}
void p3Wire::notifyChanges(std::vector<RsGxsNotify*>& changes)
{
@ -175,12 +179,12 @@ bool p3Wire::createGroup(uint32_t &token, RsWireGroup &group)
groupItem->group = group;
groupItem->meta = group.mMeta;
std::cerr << "p3Wire::createGroup(): ";
std::cerr << "p3Wire::createGroup(): ";
std::cerr << std::endl;
std::cerr << group;
std::cerr << std::endl;
std::cerr << "p3Wire::createGroup() pushing to RsGenExchange";
std::cerr << "p3Wire::createGroup() pushing to RsGenExchange";
std::cerr << std::endl;
RsGenExchange::publishGroup(token, groupItem);
@ -193,11 +197,11 @@ bool p3Wire::createPulse(uint32_t &token, RsWirePulse &pulse)
std::cerr << "p3Wire::createPulse(): " << pulse;
std::cerr << std::endl;
RsGxsWirePulseItem* pulseItem = new RsGxsWirePulseItem();
pulseItem->pulse = pulse;
pulseItem->meta = pulse.mMeta;
RsGxsWirePulseItem* pulseItem = new RsGxsWirePulseItem();
pulseItem->pulse = pulse;
pulseItem->meta = pulse.mMeta;
RsGenExchange::publishMsg(token, pulseItem);
RsGenExchange::publishMsg(token, pulseItem);
return true;
}

View File

@ -3,7 +3,7 @@
* *
* libretroshare: retroshare core library *
* *
* Copyright 2012-2012 by Robert Fernie <retroshare@lunamutt.com> *
* Copyright 2012-2020 by Robert Fernie <retroshare@lunamutt.com> *
* *
* This program is free software: you can redistribute it and/or modify *
* it under the terms of the GNU Lesser General Public License as *
@ -34,37 +34,33 @@
*
*/
class p3Wire: public RsGenExchange, public RsWire
{
public:
p3Wire(RsGeneralDataService* gds, RsNetworkExchangeService* nes, RsGixs *gixs);
virtual RsServiceInfo getServiceInfo();
static uint32_t wireAuthenPolicy();
p3Wire(RsGeneralDataService* gds, RsNetworkExchangeService* nes, RsGixs *gixs);
virtual RsServiceInfo getServiceInfo();
static uint32_t wireAuthenPolicy();
protected:
virtual void notifyChanges(std::vector<RsGxsNotify*>& changes) ;
virtual void notifyChanges(std::vector<RsGxsNotify*>& changes) ;
public:
virtual void service_tick();
virtual void service_tick();
virtual RsTokenService* getTokenService();
/* Specific Service Data */
virtual bool getGroupData(const uint32_t &token, std::vector<RsWireGroup> &groups);
virtual bool getPulseData(const uint32_t &token, std::vector<RsWirePulse> &pulses);
/* Specific Service Data */
virtual bool getGroupData(const uint32_t &token, std::vector<RsWireGroup> &groups);
virtual bool getPulseData(const uint32_t &token, std::vector<RsWirePulse> &pulses);
virtual bool createGroup(uint32_t &token, RsWireGroup &group);
virtual bool createPulse(uint32_t &token, RsWirePulse &pulse);
virtual bool createGroup(uint32_t &token, RsWireGroup &group);
virtual bool createPulse(uint32_t &token, RsWirePulse &pulse);
private:
virtual void generateDummyData();
std::string genRandomId();
private:
virtual void generateDummyData();
std::string genRandomId();
RsMutex mWireMtx;
};
#endif

View File

@ -421,7 +421,6 @@ void MainWindow::initStackedPage()
PeopleDialog *peopleDialog = NULL;
addPage(peopleDialog = new PeopleDialog(ui->stackPages), grp, &notify);
#endif
addPage(newsFeed = new NewsFeed(ui->stackPages), grp, &notify);
#ifdef RS_USE_WIKI
WikiDialog *wikiDialog = NULL;
addPage(wikiDialog = new WikiDialog(ui->stackPages), grp, &notify);
@ -492,6 +491,7 @@ void MainWindow::initStackedPage()
}
}
addPage(newsFeed = new NewsFeed(ui->stackPages), grp, &notify);
addPage(settingsDialog = new SettingsPage(ui->stackPages),grp,&notify);
/* Create the toolbar */

View File

@ -27,7 +27,7 @@
#include "util/TokenQueue.h"
#include <retroshare-gui/RsAutoUpdatePage.h>
#define IMAGE_NEWSFEED ":/icons/plugins_128.png"
#define IMAGE_NEWSFEED ":/icons/png/newsfeed.png"
const uint32_t NEWSFEED_PEERLIST = 0x0001;

View File

@ -16,262 +16,259 @@
<property name="sizeGripEnabled">
<bool>true</bool>
</property>
<layout class="QVBoxLayout" name="verticalLayout_4">
<item>
<layout class="QGridLayout" name="gridLayout_5">
<item row="0" column="0" colspan="2">
<widget class="HeaderFrame" name="headerFrame">
<property name="frameShape">
<enum>QFrame::StyledPanel</enum>
<enum>QFrame::NoFrame</enum>
</property>
<property name="frameShadow">
<enum>QFrame::Raised</enum>
<enum>QFrame::Plain</enum>
</property>
</widget>
</item>
<item>
<item row="1" column="0">
<layout class="QGridLayout" name="gridLayout_3">
<item row="0" column="0">
<widget class="QLabel" name="label_thumbNail">
<property name="minimumSize">
<size>
<width>64</width>
<height>64</height>
</size>
</property>
<property name="text">
<string>TextLabel</string>
</property>
</widget>
</item>
<item row="1" column="0">
<spacer name="verticalSpacer">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
<height>12</height>
</size>
</property>
</spacer>
</item>
</layout>
</item>
<item row="1" column="1">
<layout class="QGridLayout" name="gridLayout_4">
<property name="topMargin">
<number>6</number>
</property>
<item row="1" column="1">
<widget class="QLineEdit" name="lineEdit_Category">
<property name="enabled">
<bool>false</bool>
</property>
<property name="sizePolicy">
<sizepolicy hsizetype="MinimumExpanding" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
</widget>
</item>
<item row="2" column="1">
<widget class="QLineEdit" name="lineEdit_Caption">
<property name="enabled">
<bool>false</bool>
</property>
<property name="sizePolicy">
<sizepolicy hsizetype="MinimumExpanding" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
</widget>
</item>
<item row="1" column="0">
<widget class="QLabel" name="label_7">
<property name="text">
<string>Category:</string>
</property>
</widget>
</item>
<item row="2" column="0">
<widget class="QLabel" name="label_8">
<property name="text">
<string>Caption</string>
</property>
</widget>
</item>
<item row="0" column="0">
<widget class="QLabel" name="label_9">
<property name="text">
<string>Album Title:</string>
</property>
</widget>
</item>
<item row="0" column="1">
<widget class="QLineEdit" name="lineEdit_Title">
<property name="enabled">
<bool>false</bool>
</property>
<property name="sizePolicy">
<sizepolicy hsizetype="MinimumExpanding" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
</widget>
</item>
<item row="3" column="1">
<spacer name="verticalSpacer_2">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>568</width>
<height>6</height>
</size>
</property>
</spacer>
</item>
</layout>
</item>
<item row="2" column="0" colspan="2">
<widget class="QFrame" name="frame">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Minimum">
<sizepolicy hsizetype="Preferred" vsizetype="Expanding">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
<verstretch>1</verstretch>
</sizepolicy>
</property>
<property name="frameShape">
<enum>QFrame::StyledPanel</enum>
</property>
<property name="frameShadow">
<enum>QFrame::Raised</enum>
</property>
<layout class="QVBoxLayout" name="verticalLayout_3" stretch="0,10,0">
<item>
<widget class="QFrame" name="frame_2">
<property name="sizePolicy">
<sizepolicy hsizetype="MinimumExpanding" vsizetype="Preferred">
<horstretch>10</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<layout class="QGridLayout" name="gridLayout">
<property name="horizontalSpacing">
<number>6</number>
</property>
<property name="verticalSpacing">
<number>2</number>
</property>
<item row="0" column="2">
<widget class="QLineEdit" name="lineEdit_Title">
<property name="enabled">
<bool>false</bool>
</property>
<property name="sizePolicy">
<sizepolicy hsizetype="MinimumExpanding" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
</widget>
</item>
<item row="1" column="1">
<widget class="QLabel" name="label_7">
<property name="text">
<string>Category:</string>
</property>
</widget>
</item>
<item row="1" column="2">
<widget class="QLineEdit" name="lineEdit_Category">
<property name="enabled">
<bool>false</bool>
</property>
<property name="sizePolicy">
<sizepolicy hsizetype="MinimumExpanding" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
</widget>
</item>
<item row="0" column="0" rowspan="3">
<widget class="QFrame" name="albumGroup">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Minimum">
<horstretch>0</horstretch>
<verstretch>1</verstretch>
</sizepolicy>
</property>
<layout class="QVBoxLayout" name="verticalLayout_2">
<item>
<widget class="QLabel" name="label_thumbNail">
<property name="minimumSize">
<size>
<width>64</width>
<height>64</height>
</size>
</property>
<property name="text">
<string>TextLabel</string>
</property>
</widget>
</item>
<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>
</item>
<item row="2" column="2">
<widget class="QLineEdit" name="lineEdit_Caption">
<property name="enabled">
<bool>false</bool>
</property>
<property name="sizePolicy">
<sizepolicy hsizetype="MinimumExpanding" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
</widget>
</item>
<item row="2" column="1">
<widget class="QLabel" name="label_8">
<property name="text">
<string>Caption</string>
</property>
</widget>
</item>
<item row="0" column="1">
<widget class="QLabel" name="label_9">
<property name="text">
<string>Album Title:</string>
</property>
</widget>
</item>
</layout>
</widget>
</item>
<item>
<widget class="QWidget" name="widget" native="true">
<layout class="QVBoxLayout" name="verticalLayout">
<item>
<widget class="QLabel" name="label_10">
<property name="text">
<string>&lt;!DOCTYPE HTML PUBLIC &quot;-//W3C//DTD HTML 4.0//EN&quot; &quot;http://www.w3.org/TR/REC-html40/strict.dtd&quot;&gt;
<layout class="QGridLayout" name="gridLayout">
<property name="topMargin">
<number>0</number>
</property>
<item row="0" column="0">
<widget class="QLabel" name="label_10">
<property name="text">
<string>&lt;!DOCTYPE HTML PUBLIC &quot;-//W3C//DTD HTML 4.0//EN&quot; &quot;http://www.w3.org/TR/REC-html40/strict.dtd&quot;&gt;
&lt;html&gt;&lt;head&gt;&lt;meta name=&quot;qrichtext&quot; content=&quot;1&quot; /&gt;&lt;style type=&quot;text/css&quot;&gt;
p, li { white-space: pre-wrap; }
&lt;/style&gt;&lt;/head&gt;&lt;body style=&quot; font-family:'MS Shell Dlg 2'; font-size:8.25pt; font-weight:400; font-style:normal;&quot;&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;&lt;span style=&quot; font-size:8pt; font-weight:600;&quot;&gt; Drag &amp;amp; Drop to insert pictures. Click on a picture to edit details below.&lt;/span&gt;&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
</property>
</widget>
</item>
<item>
<widget class="QScrollArea" name="scrollAreaPhotos">
<property name="sizePolicy">
<sizepolicy hsizetype="Expanding" vsizetype="Expanding">
<horstretch>0</horstretch>
<verstretch>10</verstretch>
</sizepolicy>
</property>
<property name="acceptDrops">
<bool>true</bool>
</property>
<property name="horizontalScrollBarPolicy">
<enum>Qt::ScrollBarAsNeeded</enum>
</property>
<property name="widgetResizable">
<bool>true</bool>
</property>
<property name="alignment">
<set>Qt::AlignBottom|Qt::AlignLeading|Qt::AlignLeft</set>
</property>
<widget class="PhotoDrop" name="scrollAreaWidgetContents">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>737</width>
<height>315</height>
</rect>
</property>
<property name="sizePolicy">
<sizepolicy hsizetype="Expanding" vsizetype="Expanding">
<horstretch>0</horstretch>
<verstretch>10</verstretch>
</sizepolicy>
</property>
<property name="styleSheet">
<string notr="true">QWidget#scrollAreaWidgetContents{border: none;}</string>
</property>
<layout class="QGridLayout" name="gridLayout_2"/>
</widget>
</widget>
</item>
</layout>
</property>
</widget>
</item>
<item>
<layout class="QHBoxLayout" name="horizontalLayout">
<item>
<widget class="QPushButton" name="pushButton_AddPhoto">
<property name="text">
<string>Add Photo</string>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="pushButton_EditPhoto">
<property name="text">
<string>Edit Photo</string>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="pushButton_DeletePhoto">
<property name="text">
<string>Delete Photo</string>
</property>
</widget>
</item>
<item>
<spacer name="horizontalSpacer_2">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>68</width>
<height>17</height>
</size>
</property>
</spacer>
</item>
<item>
<widget class="QDialogButtonBox" name="buttonBox">
<property name="standardButtons">
<set>QDialogButtonBox::Cancel</set>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="pushButton_PublishPhotos">
<property name="text">
<string>Publish Photos</string>
</property>
</widget>
</item>
</layout>
<item row="1" column="0">
<widget class="QScrollArea" name="scrollAreaPhotos">
<property name="sizePolicy">
<sizepolicy hsizetype="Expanding" vsizetype="Expanding">
<horstretch>0</horstretch>
<verstretch>10</verstretch>
</sizepolicy>
</property>
<property name="acceptDrops">
<bool>true</bool>
</property>
<property name="horizontalScrollBarPolicy">
<enum>Qt::ScrollBarAsNeeded</enum>
</property>
<property name="widgetResizable">
<bool>true</bool>
</property>
<property name="alignment">
<set>Qt::AlignBottom|Qt::AlignLeading|Qt::AlignLeft</set>
</property>
<widget class="PhotoDrop" name="scrollAreaWidgetContents">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>757</width>
<height>395</height>
</rect>
</property>
<property name="sizePolicy">
<sizepolicy hsizetype="Expanding" vsizetype="Expanding">
<horstretch>0</horstretch>
<verstretch>10</verstretch>
</sizepolicy>
</property>
<property name="styleSheet">
<string notr="true">QWidget#scrollAreaWidgetContents{border: none;}</string>
</property>
<layout class="QGridLayout" name="gridLayout_2"/>
</widget>
</widget>
</item>
</layout>
</widget>
</item>
<item row="3" column="0" colspan="2">
<layout class="QHBoxLayout" name="horizontalLayout">
<property name="leftMargin">
<number>6</number>
</property>
<property name="topMargin">
<number>6</number>
</property>
<property name="rightMargin">
<number>6</number>
</property>
<property name="bottomMargin">
<number>6</number>
</property>
<item>
<widget class="QPushButton" name="pushButton_AddPhoto">
<property name="text">
<string>Add Photo</string>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="pushButton_EditPhoto">
<property name="text">
<string>Edit Photo</string>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="pushButton_DeletePhoto">
<property name="text">
<string>Delete Photo</string>
</property>
</widget>
</item>
<item>
<spacer name="horizontalSpacer_2">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>68</width>
<height>17</height>
</size>
</property>
</spacer>
</item>
<item>
<widget class="QDialogButtonBox" name="buttonBox">
<property name="standardButtons">
<set>QDialogButtonBox::Cancel</set>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="pushButton_PublishPhotos">
<property name="text">
<string>Publish Photos</string>
</property>
</widget>
</item>
</layout>
</item>
</layout>
</widget>
<customwidgets>

View File

@ -6,8 +6,8 @@
<rect>
<x>0</x>
<y>0</y>
<width>229</width>
<height>234</height>
<width>230</width>
<height>217</height>
</rect>
</property>
<property name="windowTitle">
@ -28,15 +28,51 @@ border-radius: 10px}</string>
<property name="frameShadow">
<enum>QFrame::Raised</enum>
</property>
<layout class="QVBoxLayout" name="verticalLayout_4">
<item>
<widget class="QLabel" name="label_Thumbnail">
<property name="text">
<string>TextLabel</string>
</property>
</widget>
<layout class="QGridLayout" name="gridLayout">
<item row="0" column="0">
<layout class="QHBoxLayout" name="horizontalLayout_3">
<item>
<spacer name="horizontalSpacer">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeType">
<enum>QSizePolicy::Preferred</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>18</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
<item>
<widget class="QLabel" name="label_Thumbnail">
<property name="text">
<string>TextLabel</string>
</property>
</widget>
</item>
<item>
<spacer name="horizontalSpacer_2">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeType">
<enum>QSizePolicy::Preferred</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>18</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
</layout>
</item>
<item>
<item row="1" column="0">
<layout class="QHBoxLayout" name="horizontalLayout_2">
<item>
<layout class="QHBoxLayout" name="horizontalLayout">
@ -91,7 +127,7 @@ p, li { white-space: pre-wrap; }
</item>
</layout>
</item>
<item>
<item row="2" column="0">
<spacer name="verticalSpacer">
<property name="orientation">
<enum>Qt::Vertical</enum>

View File

@ -25,6 +25,11 @@
#include "retroshare/rsidentity.h"
#include "gui/gxs/GxsCommentDialog.h"
#define IMAGE_FULLSCREEN ":/icons/fullscreen.png"
#define IMAGE_FULLSCREENEXIT ":/icons/fullscreen-exit.png"
#define IMAGE_SHOW ":/icons/png/down-arrow.png"
#define IMAGE_HIDE ":/icons/png/up-arrow.png"
PhotoDialog::PhotoDialog(RsPhoto *rs_photo, const RsPhotoPhoto &photo, QWidget *parent) :
QDialog(parent, Qt::WindowSystemMenuHint | Qt::WindowTitleHint | Qt::WindowMinMaxButtonsHint | Qt::WindowCloseButtonHint),
ui(new Ui::PhotoDialog), mRsPhoto(rs_photo), mPhotoQueue(new TokenQueue(mRsPhoto->getTokenService(), this)),
@ -76,8 +81,10 @@ void PhotoDialog::toggleDetails()
{
if (ui->frame_details->isVisible()) {
ui->frame_details->setVisible(false);
ui->detailsButton->setIcon(QIcon(IMAGE_SHOW));
} else {
ui->frame_details->setVisible(true);
ui->detailsButton->setIcon(QIcon(IMAGE_HIDE));
}
}
@ -182,9 +189,11 @@ void PhotoDialog::setFullScreen()
show();
raise();
#endif
ui->fullscreenButton->setIcon(QIcon(IMAGE_FULLSCREENEXIT));
} else {
setWindowState( windowState() ^ Qt::WindowFullScreen );
show();
ui->fullscreenButton->setIcon(QIcon(IMAGE_FULLSCREEN));
}
}

View File

@ -7,7 +7,7 @@
<x>0</x>
<y>0</y>
<width>790</width>
<height>824</height>
<height>509</height>
</rect>
</property>
<property name="windowTitle">
@ -52,11 +52,24 @@
<rect>
<x>0</x>
<y>0</y>
<width>558</width>
<height>551</height>
<width>540</width>
<height>318</height>
</rect>
</property>
<layout class="QHBoxLayout" name="horizontalLayout_2">
<item>
<spacer name="horizontalSpacer">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
<item>
<widget class="QLabel" name="label_Photo">
<property name="sizePolicy">
@ -74,8 +87,24 @@
<property name="text">
<string>TextLabel</string>
</property>
<property name="alignment">
<set>Qt::AlignCenter</set>
</property>
</widget>
</item>
<item>
<spacer name="horizontalSpacer_2">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
</layout>
</widget>
</widget>
@ -92,8 +121,8 @@
<string>...</string>
</property>
<property name="icon">
<iconset resource="../images.qrc">
<normaloff>:/images/window_fullscreen.png</normaloff>:/images/window_fullscreen.png</iconset>
<iconset resource="../icons.qrc">
<normaloff>:/icons/fullscreen.png</normaloff>:/icons/fullscreen.png</iconset>
</property>
<property name="autoRaise">
<bool>true</bool>
@ -103,7 +132,11 @@
<item>
<widget class="QPushButton" name="detailsButton">
<property name="text">
<string>Details \/</string>
<string>Details</string>
</property>
<property name="icon">
<iconset resource="../icons.qrc">
<normaloff>:/icons/png/down-arrow.png</normaloff>:/icons/png/down-arrow.png</iconset>
</property>
</widget>
</item>
@ -136,6 +169,10 @@
<property name="text">
<string>&lt;N&gt; Comments &gt;&gt;</string>
</property>
<property name="icon">
<iconset resource="../icons.qrc">
<normaloff>:/icons/png/comment.png</normaloff>:/icons/png/comment.png</iconset>
</property>
</widget>
</item>
</layout>
@ -255,6 +292,7 @@
</widget>
<resources>
<include location="../images.qrc"/>
<include location="../icons.qrc"/>
</resources>
<connections/>
</ui>

View File

@ -38,8 +38,8 @@
<string>Create Album</string>
</property>
<property name="icon">
<iconset resource="../images.qrc">
<normaloff>:/images/add_image24.png</normaloff>:/images/add_image24.png</iconset>
<iconset resource="Photo_images.qrc">
<normaloff>:/images/album_create_64.png</normaloff>:/images/album_create_64.png</iconset>
</property>
<property name="iconSize">
<size>
@ -62,7 +62,7 @@
</property>
<property name="icon">
<iconset resource="../images.qrc">
<normaloff>:/images/add_image24.png</normaloff>:/images/add_image24.png</iconset>
<normaloff>:/images/edit_16.png</normaloff>:/images/edit_16.png</iconset>
</property>
<property name="iconSize">
<size>
@ -73,6 +73,9 @@
<property name="toolButtonStyle">
<enum>Qt::ToolButtonTextBesideIcon</enum>
</property>
<property name="autoRaise">
<bool>true</bool>
</property>
</widget>
</item>
<item>
@ -283,7 +286,7 @@
<x>0</x>
<y>0</y>
<width>804</width>
<height>197</height>
<height>208</height>
</rect>
</property>
<property name="styleSheet">
@ -319,7 +322,7 @@
<x>0</x>
<y>0</y>
<width>804</width>
<height>196</height>
<height>208</height>
</rect>
</property>
<property name="styleSheet">

View File

@ -22,6 +22,9 @@
#include "gui/PhotoShare/PhotoDrop.h"
#include "gui/gxs/GxsIdDetails.h"
#define IMAGE_FULLSCREEN ":/icons/fullscreen.png"
#define IMAGE_FULLSCREENEXIT ":/icons/fullscreen-exit.png"
#include <iostream>
/** Constructor */
@ -300,10 +303,12 @@ void PhotoSlideShow::setFullScreen()
show();
raise();
#endif
ui.fullscreenButton->setIcon(QIcon(IMAGE_FULLSCREENEXIT));
} else {
setWindowState( windowState() ^ Qt::WindowFullScreen );
show();
ui.fullscreenButton->setIcon(QIcon(IMAGE_FULLSCREEN));
}
}

View File

@ -98,8 +98,8 @@
<string/>
</property>
<property name="icon">
<iconset resource="../images.qrc">
<normaloff>:/images/window_fullscreen.png</normaloff>:/images/window_fullscreen.png</iconset>
<iconset resource="../icons.qrc">
<normaloff>:/icons/fullscreen.png</normaloff>:/icons/fullscreen.png</iconset>
</property>
<property name="autoRaise">
<bool>false</bool>
@ -157,6 +157,7 @@
<resources>
<include location="Photo_images.qrc"/>
<include location="../images.qrc"/>
<include location="../icons.qrc"/>
</resources>
<connections/>
</ui>

View File

@ -1,7 +1,7 @@
/*******************************************************************************
* gui/TheWire/PulseAddDialog.cpp *
* *
* Copyright (c) 2012 Robert Fernie <retroshare.project@gmail.com> *
* Copyright (c) 2012-2020 Robert Fernie <retroshare.project@gmail.com> *
* *
* This program is free software: you can redistribute it and/or modify *
* it under the terms of the GNU Affero General Public License as *
@ -18,39 +18,58 @@
* *
*******************************************************************************/
#include "gui/TheWire/PulseAddDialog.h"
#include "gui/PhotoShare/PhotoDrop.h"
#include <iostream>
#include "PulseDetails.h"
#include "PulseAddDialog.h"
/** Constructor */
PulseAddDialog::PulseAddDialog(QWidget *parent)
: QWidget(parent)
: QWidget(parent), mIsReply(false), mWaitingRefMsg(false)
{
ui.setupUi(this);
mWireQueue = new TokenQueue(rsWire->getTokenService(), this);
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_Cancel, SIGNAL( clicked( void ) ), this, SLOT( cancelPulse( void ) ) );
#if 0
connect(ui.scrollAreaWidgetContents, SIGNAL( buttonStatus( uint32_t ) ), this, SLOT( updateMoveButtons( uint32_t ) ) );
connect(ui.pushButton_ShiftRight, SIGNAL( clicked( void ) ), ui.scrollAreaWidgetContents, SLOT( moveRight( void ) ) );
connect(ui.pushButton_EditPhotoDetails, SIGNAL( clicked( void ) ), this, SLOT( showPhotoDetails( void ) ) );
}
connect(ui.pushButton_Publish, SIGNAL( clicked( void ) ), this, SLOT( publishAlbum( void ) ) );
#endif
void PulseAddDialog::setGroup(RsWireGroup &group)
{
ui.label_groupName->setText(QString::fromStdString(group.mMeta.mGroupName));
ui.label_idName->setText(QString::fromStdString(group.mMeta.mAuthorId.toStdString()));
mGroup = group;
}
mPhotoDetails = NULL;
void PulseAddDialog::setReplyTo(RsWirePulse &pulse, std::string &groupName)
{
mIsReply = true;
mReplyToPulse = pulse;
mReplyGroupName = groupName;
{
PulseDetails *details = new PulseDetails(NULL, pulse, groupName, true);
// add extra widget into layout.
QVBoxLayout *vbox = new QVBoxLayout();
vbox->addWidget(details);
vbox->setSpacing(1);
vbox->setContentsMargins(0,0,0,0);
ui.widget_replyto->setLayout(vbox);
ui.widget_replyto->setVisible(true);
}
}
void PulseAddDialog::addURL()
{
std::cerr << "PulseAddDialog::addURL()";
std::cerr << std::endl;
std::cerr << "PulseAddDialog::addURL()";
std::cerr << std::endl;
return;
}
@ -58,8 +77,8 @@ void PulseAddDialog::addURL()
void PulseAddDialog::addTo()
{
std::cerr << "PulseAddDialog::addTo()";
std::cerr << std::endl;
std::cerr << "PulseAddDialog::addTo()";
std::cerr << std::endl;
return;
}
@ -67,8 +86,8 @@ void PulseAddDialog::addTo()
void PulseAddDialog::cancelPulse()
{
std::cerr << "PulseAddDialog::cancelPulse()";
std::cerr << std::endl;
std::cerr << "PulseAddDialog::cancelPulse()";
std::cerr << std::endl;
clearDialog();
hide();
@ -77,130 +96,203 @@ void PulseAddDialog::cancelPulse()
}
void PulseAddDialog::updateMoveButtons(uint32_t status)
{
std::cerr << "PulseAddDialog::updateMoveButtons(" << status << ")";
std::cerr << std::endl;
#if 0
switch(status)
{
case PHOTO_SHIFT_NO_BUTTONS:
ui.pushButton_ShiftLeft->setEnabled(false);
ui.pushButton_ShiftRight->setEnabled(false);
break;
case PHOTO_SHIFT_LEFT_ONLY:
ui.pushButton_ShiftLeft->setEnabled(true);
ui.pushButton_ShiftRight->setEnabled(false);
break;
case PHOTO_SHIFT_RIGHT_ONLY:
ui.pushButton_ShiftLeft->setEnabled(false);
ui.pushButton_ShiftRight->setEnabled(true);
break;
case PHOTO_SHIFT_BOTH:
ui.pushButton_ShiftLeft->setEnabled(true);
ui.pushButton_ShiftRight->setEnabled(true);
break;
}
#endif
}
void PulseAddDialog::showPhotoDetails()
{
#if 0
std::cerr << "PulseAddDialog::showPhotoDetails()";
std::cerr << std::endl;
if (!mPhotoDetails)
{
mPhotoDetails = new PhotoDetailsDialog(NULL);
}
PhotoItem *item = ui.scrollAreaWidgetContents->getSelectedPhotoItem();
mPhotoDetails->setPhotoItem(item);
mPhotoDetails->show();
#endif
}
void PulseAddDialog::postPulse()
{
std::cerr << "PulseAddDialog::postPulse()";
std::cerr << std::endl;
#if 0
/* we need to iterate through each photoItem, and extract the details */
RsPhotoAlbum album;
RsPhotoThumbnail albumThumb;
album.mShareOptions.mShareType = 0;
album.mShareOptions.mShareGroupId = "unknown";
album.mShareOptions.mPublishKey = "unknown";
album.mShareOptions.mCommentMode = 0;
album.mShareOptions.mResizeMode = 0;
album.mTitle = ui.lineEdit_Title->text().toStdString();
album.mCategory = "Unknown";
album.mCaption = ui.lineEdit_Caption->text().toStdString();
album.mWhere = ui.lineEdit_Where->text().toStdString();
album.mWhen = ui.lineEdit_When->text().toStdString();
if (rsPhoto->submitAlbumDetails(album, albumThumb))
std::cerr << "PulseAddDialog::postPulse()";
std::cerr << std::endl;
if (mIsReply)
{
/* now have path and album id */
int photoCount = ui.scrollAreaWidgetContents->getPhotoCount();
for(int i = 0; i < photoCount; ++i)
{
RsPhotoPhoto photo;
RsPhotoThumbnail thumbnail;
PhotoItem *item = ui.scrollAreaWidgetContents->getPhotoIdx(i);
photo = item->mDetails;
item->getPhotoThumbnail(thumbnail);
photo.mAlbumId = album.mAlbumId;
photo.mOrder = i;
/* scale photo if needed */
if (album.mShareOptions.mResizeMode)
{
/* */
}
/* save image to album path */
photo.path = "unknown";
rsPhoto->submitPhoto(photo, thumbnail);
}
postReplyPulse();
}
else
{
postOriginalPulse();
}
}
void PulseAddDialog::postOriginalPulse()
{
std::cerr << "PulseAddDialog::postOriginalPulse()";
std::cerr << std::endl;
RsWirePulse pulse;
pulse.mMeta.mGroupId = mGroup.mMeta.mGroupId;
pulse.mMeta.mAuthorId = mGroup.mMeta.mAuthorId;
pulse.mMeta.mThreadId.clear();
pulse.mMeta.mParentId.clear();
pulse.mMeta.mOrigMsgId.clear();
pulse.mPulseType = WIRE_PULSE_TYPE_ORIGINAL_MSG;
pulse.mPulseText = ui.textEdit_Pulse->toPlainText().toStdString();
// all mRefs should empty.
uint32_t token;
rsWire->createPulse(token, pulse);
#endif
clearDialog();
hide();
}
void PulseAddDialog::clearDialog()
void PulseAddDialog::postReplyPulse()
{
std::cerr << "PulseAddDialog::postReplyPulse()";
std::cerr << std::endl;
ui.textEdit_Pulse->setPlainText("");
#if 0
ui.lineEdit_Title->setText(QString("title"));
ui.lineEdit_Caption->setText(QString("Caption"));
ui.lineEdit_Where->setText(QString("Where"));
ui.lineEdit_When->setText(QString("When"));
RsWirePulse pulse;
ui.scrollAreaWidgetContents->clearPhotos();
#endif
pulse.mMeta.mGroupId = mGroup.mMeta.mGroupId;
pulse.mMeta.mAuthorId = mGroup.mMeta.mAuthorId;
pulse.mMeta.mThreadId.clear();
pulse.mMeta.mParentId.clear();
pulse.mMeta.mOrigMsgId.clear();
pulse.mPulseType = WIRE_PULSE_TYPE_REPLY_MSG;
pulse.mPulseText = ui.textEdit_Pulse->toPlainText().toStdString();
// mRefs refer to parent post.
pulse.mRefGroupId = mReplyToPulse.mMeta.mGroupId;
pulse.mRefGroupName = mReplyGroupName;
pulse.mRefOrigMsgId = mReplyToPulse.mMeta.mOrigMsgId;
pulse.mRefAuthorId = mReplyToPulse.mMeta.mAuthorId;
pulse.mRefPublishTs = mReplyToPulse.mMeta.mPublishTs;
pulse.mRefPulseText = mReplyToPulse.mPulseText;
// Need Pulse MsgID before we can create associated Reference.
mWaitingRefMsg = true;
uint32_t token;
rsWire->createPulse(token, pulse);
mWireQueue->queueRequest(token, TOKENREQ_MSGINFO, RS_TOKREQ_ANSTYPE_ACK, 0);
}
void PulseAddDialog::postRefPulse(RsWirePulse &pulse)
{
std::cerr << "PulseAddDialog::postRefPulse() create Reference!";
std::cerr << std::endl;
// Reference Pulse. posted on Parent's Group.
RsWirePulse refPulse;
refPulse.mMeta.mGroupId = mReplyToPulse.mMeta.mGroupId;
refPulse.mMeta.mAuthorId = mGroup.mMeta.mAuthorId; // own author Id.
refPulse.mMeta.mThreadId = mReplyToPulse.mMeta.mOrigMsgId;
refPulse.mMeta.mParentId = mReplyToPulse.mMeta.mOrigMsgId;
refPulse.mMeta.mOrigMsgId.clear();
refPulse.mPulseType = WIRE_PULSE_TYPE_REPLY_REFERENCE;
// 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.
refPulse.mPulseText = "";
// refs refer back to own Post.
refPulse.mRefGroupId = mGroup.mMeta.mGroupId;
refPulse.mRefGroupName = mGroup.mMeta.mGroupName;
refPulse.mRefOrigMsgId = pulse.mMeta.mOrigMsgId;
refPulse.mRefAuthorId = mGroup.mMeta.mAuthorId;
refPulse.mRefPublishTs = pulse.mMeta.mPublishTs;
refPulse.mRefPulseText = pulse.mPulseText;
uint32_t token;
rsWire->createPulse(token, refPulse);
clearDialog();
hide();
}
void PulseAddDialog::clearDialog()
{
ui.textEdit_Pulse->setPlainText("");
}
void PulseAddDialog::acknowledgeMessage(const uint32_t &token)
{
std::cerr << "PulseAddDialog::acknowledgeMessage()";
std::cerr << std::endl;
std::pair<RsGxsGroupId, RsGxsMessageId> p;
rsWire->acknowledgeMsg(token, p);
if (mWaitingRefMsg)
{
std::cerr << "PulseAddDialog::acknowledgeMessage() Waiting Ref Msg";
std::cerr << std::endl;
mWaitingRefMsg = false;
// request photo data.
GxsMsgReq req;
std::set<RsGxsMessageId> msgIds;
msgIds.insert(p.second);
req[p.first] = msgIds;
RsTokReqOptions opts;
opts.mReqType = GXS_REQUEST_TYPE_MSG_DATA;
uint32_t token;
mWireQueue->requestMsgInfo(token, RS_TOKREQ_ANSTYPE_DATA, opts, req, 0);
}
else
{
std::cerr << "PulseAddDialog::acknowledgeMessage() Not Waiting Ref Msg";
std::cerr << std::endl;
}
}
void PulseAddDialog::loadPulseData(const uint32_t &token)
{
std::cerr << "PulseAddDialog::loadPulseData()";
std::cerr << std::endl;
std::vector<RsWirePulse> pulses;
rsWire->getPulseData(token, pulses);
if (pulses.size() != 1)
{
std::cerr << "PulseAddDialog::loadPulseData() Error Too many pulses";
std::cerr << std::endl;
return;
}
std::cerr << "PulseAddDialog::loadPulseData() calling postRefMsg";
std::cerr << std::endl;
RsWirePulse& pulse = pulses[0];
postRefPulse(pulse);
}
/**************************** Request / Response Filling of Data ************************/
void PulseAddDialog::loadRequest(const TokenQueue *queue, const TokenRequest &req)
{
if (queue == mWireQueue)
{
/* now switch on req */
switch(req.mType)
{
case TOKENREQ_MSGINFO:
switch(req.mAnsType)
{
case RS_TOKREQ_ANSTYPE_ACK:
acknowledgeMessage(req.mToken);
break;
case RS_TOKREQ_ANSTYPE_DATA:
loadPulseData(req.mToken);
break;
default:
std::cerr << "PulseAddDialog::loadRequest() ERROR: MSG: INVALID ANS TYPE";
std::cerr << std::endl;
break;
}
break;
default:
std::cerr << "PulseAddDialog::loadRequest() ERROR: INVALID TYPE";
std::cerr << std::endl;
break;
}
}
}

View File

@ -1,7 +1,7 @@
/*******************************************************************************
* gui/TheWire/PulseAddDialog.h *
* *
* Copyright (c) 2012 Robert Fernie <retroshare.project@gmail.com> *
* Copyright (c) 2012-2020 Robert Fernie <retroshare.project@gmail.com> *
* *
* This program is free software: you can redistribute it and/or modify *
* it under the terms of the GNU Affero General Public License as *
@ -23,30 +23,46 @@
#include "ui_PulseAddDialog.h"
#include <inttypes.h>
#include <retroshare/rswire.h>
#include "util/TokenQueue.h"
class PhotoDetailsDialog;
class PulseAddDialog : public QWidget
class PulseAddDialog : public QWidget, public TokenResponse
{
Q_OBJECT
public:
PulseAddDialog(QWidget *parent = 0);
private slots:
void showPhotoDetails();
void updateMoveButtons(uint32_t status);
void setGroup(RsWireGroup &group);
void setReplyTo(RsWirePulse &pulse, std::string &groupName);
private slots:
void addURL();
void addTo();
void postPulse();
void cancelPulse();
void clearDialog();
private:
void postOriginalPulse();
void postReplyPulse();
void postRefPulse(RsWirePulse &pulse);
void acknowledgeMessage(const uint32_t &token);
void loadPulseData(const uint32_t &token);
void loadRequest(const TokenQueue *queue, const TokenRequest &req);
protected:
PhotoDetailsDialog *mPhotoDetails;
RsWireGroup mGroup; // where we want to post from.
// if this is a reply
bool mIsReply;
std::string mReplyGroupName;
RsWirePulse mReplyToPulse;
bool mWaitingRefMsg;
TokenQueue* mWireQueue;
Ui::PulseAddDialog ui;
};

View File

@ -14,196 +14,75 @@
<string/>
</property>
<layout class="QGridLayout" name="gridLayout_2">
<item row="0" column="0" rowspan="3">
<widget class="QSplitter" name="splitter">
<property name="orientation">
<enum>Qt::Vertical</enum>
<item row="0" column="1" colspan="3">
<widget class="QFrame" name="frame_2">
<property name="frameShape">
<enum>QFrame::StyledPanel</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_5">
<property name="spacing">
<number>0</number>
</property>
<property name="margin">
<number>0</number>
</property>
<item>
<widget class="QScrollArea" name="scrollArea_2">
<property name="sizePolicy">
<sizepolicy hsizetype="Expanding" vsizetype="Minimum">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="widgetResizable">
<bool>true</bool>
</property>
<widget class="QWidget" name="scrollAreaWidgetContents_2">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>156</width>
<height>184</height>
</rect>
</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="QCheckBox" name="checkBox">
<property name="text">
<string>Account 1</string>
</property>
</widget>
</item>
<item>
<widget class="QCheckBox" name="checkBox_2">
<property name="text">
<string>Account 2</string>
</property>
</widget>
</item>
<item>
<widget class="QCheckBox" name="checkBox_3">
<property name="text">
<string>Account 3</string>
</property>
</widget>
</item>
<item>
<spacer name="verticalSpacer_2">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
<height>0</height>
</size>
</property>
</spacer>
</item>
</layout>
</widget>
</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>158</width>
<height>372</height>
</rect>
</property>
<layout class="QVBoxLayout" name="verticalLayout">
<property name="frameShadow">
<enum>QFrame::Raised</enum>
</property>
<layout class="QVBoxLayout" name="verticalLayout_3">
<item>
<layout class="QHBoxLayout" name="horizontalLayout">
<item>
<widget class="QPushButton" name="pushButton_AddTo">
<widget class="QLabel" name="label_4">
<property name="text">
<string>Add to Pulse</string>
<string>In Reply to:</string>
</property>
</widget>
</item>
<item>
<widget class="QLineEdit" name="lineEdit_3">
<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>filter</string>
<string>Positive / Neutral / Negative</string>
</property>
</widget>
</item>
<item>
<widget class="QScrollArea" name="scrollArea">
<property name="widgetResizable">
<bool>true</bool>
<spacer name="horizontalSpacer_3">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<widget class="QWidget" name="scrollAreaWidgetContents">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>138</width>
<height>286</height>
</rect>
</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>
<property name="sizeHint" stdset="0">
<size>
<width>238</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
</layout>
</widget>
</widget>
</item>
<item>
<widget class="QWidget" name="widget_replyto" native="true"/>
</item>
</layout>
</widget>
</item>
<item row="0" column="1" colspan="3">
<widget class="QTextEdit" name="textEdit_Pulse"/>
</item>
<item row="1" column="1" colspan="3">
<widget class="QFrame" name="frame_3">
<property name="frameShape">
<enum>QFrame::StyledPanel</enum>
</property>
<property name="frameShadow">
<enum>QFrame::Raised</enum>
</property>
<layout class="QVBoxLayout" name="verticalLayout_5">
<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>
@ -252,14 +131,14 @@
</layout>
</widget>
</item>
<item row="2" column="1">
<item row="3" column="1">
<widget class="QPushButton" name="pushButton_Cancel">
<property name="text">
<string>Cancel</string>
</property>
</widget>
</item>
<item row="2" column="2">
<item row="3" column="2">
<spacer name="horizontalSpacer_2">
<property name="orientation">
<enum>Qt::Horizontal</enum>
@ -272,17 +151,159 @@
</property>
</spacer>
</item>
<item row="2" column="3">
<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>
</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>
</widget>
</item>
</layout>
</widget>
<customwidgets>
<customwidget>
<class>GxsIdLabel</class>
<extends>QLabel</extends>
<header>gui/gxs/GxsIdLabel.h</header>
</customwidget>
</customwidgets>
<resources>
<include location="../LinksCloud/images.qrc"/>
<include location="TheWire_images.qrc"/>
</resources>
<connections/>
</ui>

View File

@ -0,0 +1,144 @@
/*******************************************************************************
* gui/TheWire/PulseDetails.cpp *
* *
* Copyright (c) 2020 Robert Fernie <retroshare.project@gmail.com> *
* *
* This program is free software: you can redistribute it and/or modify *
* it under the terms of the GNU Affero General Public License as *
* published by the Free Software Foundation, either version 3 of the *
* License, or (at your option) any later version. *
* *
* This program is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU Affero General Public License for more details. *
* *
* You should have received a copy of the GNU Affero General Public License *
* along with this program. If not, see <https://www.gnu.org/licenses/>. *
* *
*******************************************************************************/
#include <QDateTime>
#include <QMessageBox>
#include <QMouseEvent>
#include <QBuffer>
#include "PulseDetails.h"
#include "util/DateTime.h"
#include <algorithm>
#include <iostream>
/** Constructor */
PulseDetails::PulseDetails(PulseHolder *actions, RsWirePulse &pulse, std::string &groupName, bool is_original)
:QWidget(NULL), mActions(actions), mPulse(pulse), mGroupName(groupName), mIsOriginal(is_original)
{
setupUi(this);
setAttribute ( Qt::WA_DeleteOnClose, true );
setup();
}
PulseDetails::PulseDetails(PulseHolder *actions,
RsGxsGroupId &parentGroupId,
std::string &parentGroupName,
RsGxsMessageId &parentOrigMsgId,
RsGxsId &parentAuthorId,
rstime_t &parentPublishTs,
std::string &parentPulseText)
:QWidget(NULL), mActions(actions), mPulse(), mGroupName(parentGroupName), mIsOriginal(false)
{
setupUi(this);
setAttribute ( Qt::WA_DeleteOnClose, true );
// reuse Meta data structure.
mPulse.mMeta.mGroupId = parentGroupId;
mPulse.mMeta.mOrigMsgId = parentOrigMsgId;
mPulse.mMeta.mAuthorId = parentAuthorId;
mPulse.mMeta.mPublishTs = parentPublishTs;
mPulse.mPulseText = parentPulseText;
setup();
}
void PulseDetails::setup()
{
connect(toolButton_expand, SIGNAL(clicked()), this, SLOT(toggle()));
connect(toolButton_follow, SIGNAL(clicked()), this, SLOT(follow()));
connect(toolButton_rate, SIGNAL(clicked()), this, SLOT(rate()));
connect(toolButton_reply, SIGNAL(clicked()), this, SLOT(reply()));
label_wireName->setText(QString::fromStdString(mGroupName));
label_idName->setId(mPulse.mMeta.mAuthorId);
label_date->setText(DateTime::formatDateTime(mPulse.mMeta.mPublishTs));
label_summary->setText(getSummary());
// label_icon->setText();
textBrowser->setPlainText(QString::fromStdString(mPulse.mPulseText));
frame_expand->setVisible(false);
}
void PulseDetails::toggle()
{
if (frame_expand->isVisible()) {
// switch to minimal view.
label_summary->setVisible(true);
frame_expand->setVisible(false);
} else {
// switch to expanded view.
label_summary->setVisible(false);
frame_expand->setVisible(true);
}
}
QString PulseDetails::getSummary()
{
std::string summary = mPulse.mPulseText;
std::cerr << "PulseDetails::getSummary() orig: " << summary;
std::cerr << std::endl;
int len = summary.size();
bool in_whitespace = false;
for (int i = 0; i < len; i++)
{
if (isspace(summary[i])) {
if (in_whitespace) {
// trim
summary.erase(i, 1);
// rollback index / len.
--i;
--len;
} else {
// replace whitespace with space.
summary[i] = ' ';
in_whitespace = true;
}
} else {
in_whitespace = false;
}
}
std::cerr << "PulseDetails::getSummary() summary: " << summary;
std::cerr << std::endl;
return QString::fromStdString(summary);
}
void PulseDetails::follow()
{
// follow group.
mActions->follow(mPulse.mMeta.mGroupId);
}
void PulseDetails::rate()
{
// rate author
mActions->rate(mPulse.mMeta.mAuthorId);
}
void PulseDetails::reply()
{
mActions->reply(mPulse, mGroupName);
}

View File

@ -0,0 +1,62 @@
/*******************************************************************************
* gui/TheWire/PulseDetails.h *
* *
* Copyright (c) 2020 Robert Fernie <retroshare.project@gmail.com> *
* *
* This program is free software: you can redistribute it and/or modify *
* it under the terms of the GNU Affero General Public License as *
* published by the Free Software Foundation, either version 3 of the *
* License, or (at your option) any later version. *
* *
* This program is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU Affero General Public License for more details. *
* *
* You should have received a copy of the GNU Affero General Public License *
* along with this program. If not, see <https://www.gnu.org/licenses/>. *
* *
*******************************************************************************/
#ifndef MRK_PULSE_DETAILS_H
#define MRK_PULSE_DETAILS_H
#include "ui_PulseDetails.h"
#include "PulseItem.h"
#include <retroshare/rswire.h>
class PulseDetails : public QWidget, private Ui::PulseDetails
{
Q_OBJECT
public:
PulseDetails(PulseHolder *actions, RsWirePulse &pulse, std::string &groupName, bool is_original);
// when Reply parent....
PulseDetails(PulseHolder *actions,
RsGxsGroupId &parentGroupId,
std::string &parentGroupName,
RsGxsMessageId &parentOrigMsgId,
RsGxsId &parentAuthorId,
rstime_t &parentPublishTs,
std::string &parentPulseText);
void setup();
private slots:
void toggle();
void follow();
void rate();
void reply();
private:
QString getSummary();
PulseHolder *mActions;
RsWirePulse mPulse;
std::string mGroupName;
bool mIsOriginal;
};
#endif

View File

@ -0,0 +1,185 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>PulseDetails</class>
<widget class="QWidget" name="PulseDetails">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>750</width>
<height>166</height>
</rect>
</property>
<property name="windowTitle">
<string>Form</string>
</property>
<layout class="QVBoxLayout" name="verticalLayout_2">
<item>
<layout class="QHBoxLayout" name="horizontalLayout">
<item>
<widget class="QToolButton" name="toolButton_expand">
<property name="text">
<string>\/</string>
</property>
</widget>
</item>
<item>
<widget class="QLabel" name="label_wireName">
<property name="text">
<string>WireGroupName</string>
</property>
</widget>
</item>
<item>
<spacer name="horizontalSpacer_3">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeType">
<enum>QSizePolicy::Preferred</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
<item>
<widget class="GxsIdLabel" name="label_idName">
<property name="text">
<string>idLabel</string>
</property>
</widget>
</item>
<item>
<spacer name="horizontalSpacer">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>128</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
<item>
<widget class="QLabel" name="label_summary">
<property name="text">
<string>Summary Text/ date</string>
</property>
</widget>
</item>
<item>
<spacer name="horizontalSpacer_2">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeType">
<enum>QSizePolicy::Preferred</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
<item>
<widget class="QLabel" name="label_date">
<property name="text">
<string>TextLabel</string>
</property>
</widget>
</item>
</layout>
</item>
<item>
<widget class="QFrame" name="frame_expand">
<property name="frameShape">
<enum>QFrame::StyledPanel</enum>
</property>
<property name="frameShadow">
<enum>QFrame::Raised</enum>
</property>
<layout class="QHBoxLayout" name="horizontalLayout_2">
<item>
<layout class="QVBoxLayout" name="verticalLayout_3">
<item>
<widget class="QToolButton" name="toolButton_follow">
<property name="text">
<string>follow</string>
</property>
</widget>
</item>
<item>
<widget class="QToolButton" name="toolButton_reply">
<property name="text">
<string>reply</string>
</property>
</widget>
</item>
<item>
<widget class="QToolButton" name="toolButton_rate">
<property name="text">
<string>rate</string>
</property>
</widget>
</item>
</layout>
</item>
<item>
<layout class="QVBoxLayout" name="verticalLayout">
<item>
<widget class="QLabel" name="label_icon">
<property name="minimumSize">
<size>
<width>80</width>
<height>80</height>
</size>
</property>
<property name="text">
<string>Image</string>
</property>
</widget>
</item>
<item>
<spacer name="verticalSpacer">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<property name="sizeType">
<enum>QSizePolicy::Expanding</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
<height>5</height>
</size>
</property>
</spacer>
</item>
</layout>
</item>
<item>
<widget class="QTextBrowser" name="textBrowser"/>
</item>
</layout>
</widget>
</item>
</layout>
</widget>
<customwidgets>
<customwidget>
<class>GxsIdLabel</class>
<extends>QLabel</extends>
<header>gui/gxs/GxsIdLabel.h</header>
</customwidget>
</customwidgets>
<resources/>
<connections/>
</ui>

View File

@ -1,7 +1,7 @@
/*******************************************************************************
* gui/TheWire/PulseItem.cpp *
* *
* Copyright (c) 2012 Robert Fernie <retroshare.project@gmail.com> *
* Copyright (c) 2012-2020 Robert Fernie <retroshare.project@gmail.com> *
* *
* This program is free software: you can redistribute it and/or modify *
* it under the terms of the GNU Affero General Public License as *
@ -25,6 +25,8 @@
#include "PulseItem.h"
#include "PulseDetails.h"
#include <algorithm>
#include <iostream>
@ -34,14 +36,119 @@
/** Constructor */
PulseItem::PulseItem(PulseHolder *parent, std::string path)
:QWidget(NULL), mParent(parent), mType(0)
PulseItem::PulseItem(PulseHolder *holder, std::string path)
:QWidget(NULL), mHolder(holder), mType(0)
{
setupUi(this);
setAttribute ( Qt::WA_DeleteOnClose, true );
setupUi(this);
setAttribute ( Qt::WA_DeleteOnClose, true );
}
PulseItem::PulseItem(PulseHolder *holder, RsWirePulse &pulse, RsWireGroup &group)
:QWidget(NULL), mHolder(holder), mType(0)
{
setupUi(this);
setAttribute ( Qt::WA_DeleteOnClose, true );
QWidget *pulse_widget = widget_parent; // default msg goes into widget_parent.
/* if it is a reply */
if (pulse.mPulseType & WIRE_PULSE_TYPE_REPLY_MSG) {
std::cerr << "Installing Reply Msg";
std::cerr << std::endl;
std::cerr << "GroupID: " << pulse.mRefGroupId;
std::cerr << std::endl;
std::cerr << "GroupName: " << pulse.mRefGroupName;
std::cerr << std::endl;
std::cerr << "OrigMsgId: " << pulse.mRefOrigMsgId;
std::cerr << std::endl;
std::cerr << "AuthorId: " << pulse.mRefAuthorId;
std::cerr << std::endl;
std::cerr << "PublishTs: " << pulse.mRefPublishTs;
std::cerr << std::endl;
std::cerr << "PulseText: " << pulse.mRefPulseText;
std::cerr << std::endl;
// fill in the parent.
PulseDetails *parent = new PulseDetails(
mHolder,
pulse.mRefGroupId,
pulse.mRefGroupName,
pulse.mRefOrigMsgId,
pulse.mRefAuthorId,
pulse.mRefPublishTs,
pulse.mRefPulseText);
// add extra widget into layout.
QVBoxLayout *vbox = new QVBoxLayout();
vbox->addWidget(parent);
vbox->setContentsMargins(0,0,0,0);
widget_parent->setLayout(vbox);
// if its a reply, the real msg goes into reply slot.
pulse_widget = widget_reply;
}
else if (pulse.mPulseType & WIRE_PULSE_TYPE_REPLY_REFERENCE)
{
// THIS IS A FAKE ONE... LEAVE IN UNTIL ITS HANDLED ELSEWHERE.
// NB: PARENT PublishTS and AuthorID appear wrong...
std::cerr << "Installing Ref Msg";
std::cerr << std::endl;
std::cerr << "GroupID: " << pulse.mRefGroupId;
std::cerr << std::endl;
std::cerr << "GroupName: " << pulse.mRefGroupName;
std::cerr << std::endl;
std::cerr << "OrigMsgId: " << pulse.mRefOrigMsgId;
std::cerr << std::endl;
std::cerr << "AuthorId: " << pulse.mRefAuthorId;
std::cerr << std::endl;
std::cerr << "PublishTs: " << pulse.mRefPublishTs;
std::cerr << std::endl;
std::cerr << "PulseText: " << pulse.mRefPulseText;
std::cerr << std::endl;
// fill in the parent.
PulseDetails *parent = new PulseDetails(
mHolder,
pulse.mRefGroupId,
pulse.mRefGroupName,
pulse.mRefOrigMsgId,
pulse.mRefAuthorId,
pulse.mRefPublishTs,
pulse.mRefPulseText);
// add extra widget into layout.
QVBoxLayout *vbox = new QVBoxLayout();
vbox->addWidget(parent);
vbox->setContentsMargins(0,0,0,0);
widget_reply->setLayout(vbox);
// if its a REF, the real msg goes into parent slot.
pulse_widget = widget_parent;
} else {
// ORIGINAL PULSE.
// hide widget_reply, as it will be empty.
widget_reply->setVisible(false);
}
{
std::cerr << "Adding Main Message";
std::cerr << std::endl;
PulseDetails *details = new PulseDetails(mHolder, pulse, group.mMeta.mGroupName, true);
// add extra widget into layout.
QVBoxLayout *vbox = new QVBoxLayout();
vbox->addWidget(details);
vbox->setSpacing(1);
vbox->setContentsMargins(0,0,0,0);
pulse_widget->setLayout(vbox);
pulse_widget->setVisible(true);
// details->toggle();
}
}
void PulseItem::removeItem()
{
}
@ -52,29 +159,29 @@ void PulseItem::setSelected(bool on)
bool PulseItem::isSelected()
{
return mSelected;
return mSelected;
}
void PulseItem::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
*/
/* 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();
QPoint pos = event->pos();
std::cerr << "PulseItem::mousePressEvent(" << pos.x() << ", " << pos.y() << ")";
std::cerr << std::endl;
std::cerr << "PulseItem::mousePressEvent(" << pos.x() << ", " << pos.y() << ")";
std::cerr << std::endl;
setSelected(true);
setSelected(true);
QWidget::mousePressEvent(event);
QWidget::mousePressEvent(event);
}
const QPixmap *PulseItem::getPixmap()
{
return NULL;
return NULL;
}

View File

@ -1,7 +1,7 @@
/*******************************************************************************
* gui/TheWire/PulseItem.h *
* *
* Copyright (c) 2012 Robert Fernie <retroshare.project@gmail.com> *
* Copyright (c) 2012-2020 Robert Fernie <retroshare.project@gmail.com> *
* *
* This program is free software: you can redistribute it and/or modify *
* it under the terms of the GNU Affero General Public License as *
@ -23,37 +23,48 @@
#include "ui_PulseItem.h"
#include <retroshare/rswire.h>
class PulseItem;
class PulseHolder
{
public:
virtual void deletePulseItem(PulseItem *, uint32_t ptype) = 0;
virtual void notifySelection(PulseItem *item, int ptype) = 0;
public:
virtual ~PulseHolder() {}
virtual void deletePulseItem(PulseItem *, uint32_t ptype) = 0;
virtual void notifySelection(PulseItem *item, int ptype) = 0;
// Actions.
virtual void follow(RsGxsGroupId &groupId) = 0;
virtual void rate(RsGxsId &authorId) = 0;
virtual void reply(RsWirePulse &pulse, std::string &groupName) = 0;
};
class PulseItem : public QWidget, private Ui::PulseItem
{
Q_OBJECT
public:
PulseItem(PulseHolder *parent, std::string url);
PulseItem(PulseHolder *holder, std::string url);
PulseItem(PulseHolder *holder, RsWirePulse &pulse, RsWireGroup &group);
void removeItem();
void removeItem();
void setSelected(bool on);
bool isSelected();
void setSelected(bool on);
bool isSelected();
const QPixmap *getPixmap();
const QPixmap *getPixmap();
protected:
void mousePressEvent(QMouseEvent *event);
void mousePressEvent(QMouseEvent *event);
private:
PulseHolder *mParent;
uint32_t mType;
bool mSelected;
PulseHolder *mHolder;
RsWirePulse mPulse;
uint32_t mType;
bool mSelected;
};
#endif

View File

@ -6,10 +6,16 @@
<rect>
<x>0</x>
<y>0</y>
<width>615</width>
<height>232</height>
<width>802</width>
<height>322</height>
</rect>
</property>
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="font">
<font>
<pointsize>9</pointsize>
@ -18,7 +24,7 @@
<property name="windowTitle">
<string notr="true"/>
</property>
<layout class="QHBoxLayout" name="horizontalLayout">
<layout class="QVBoxLayout" name="verticalLayout">
<item>
<widget class="QFrame" name="frame">
<property name="sizePolicy">
@ -27,6 +33,12 @@
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="minimumSize">
<size>
<width>0</width>
<height>0</height>
</size>
</property>
<property name="styleSheet">
<string notr="true">QFrame#frame{border: 2px solid #CCCCCC;
background: qlineargradient(x1: 0, y1: 0, x2: 0, y2: 1,
@ -39,164 +51,103 @@ border-radius: 10px}</string>
<property name="frameShadow">
<enum>QFrame::Raised</enum>
</property>
<layout class="QGridLayout" name="gridLayout">
<item row="0" column="0" rowspan="2">
<widget class="QLabel" name="imgLabel">
<property name="minimumSize">
<size>
<width>75</width>
<height>75</height>
</size>
</property>
<property name="maximumSize">
<size>
<width>75</width>
<height>75</height>
</size>
</property>
<property name="styleSheet">
<string notr="true">QLabel#label{border: 2px solid black;
background: qlineargradient(x1: 0, y1: 0, x2: 0, y2: 1,
stop: 0 #EEEEEE, stop: 1 #CCCCCC);
border-radius: 10px}</string>
</property>
<property name="text">
<string/>
</property>
<property name="pixmap">
<pixmap>:/images/konversation.png</pixmap>
</property>
<property name="alignment">
<set>Qt::AlignCenter</set>
</property>
</widget>
</item>
<item row="0" column="1">
<layout class="QHBoxLayout" name="_3">
<item>
<widget class="QLabel" name="fromBoldLabel">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="font">
<font>
<pointsize>9</pointsize>
<weight>75</weight>
<bold>true</bold>
</font>
</property>
<property name="text">
<string>From</string>
</property>
</widget>
</item>
<item>
<widget class="QLabel" name="fromLabel">
<property name="sizePolicy">
<sizepolicy hsizetype="Expanding" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="font">
<font>
<pointsize>9</pointsize>
</font>
</property>
<property name="text">
<string notr="true">Signed by</string>
</property>
<property name="openExternalLinks">
<bool>true</bool>
</property>
</widget>
</item>
</layout>
</item>
<item row="0" column="2">
<layout class="QHBoxLayout" name="_4">
<item>
<widget class="QLabel" name="dateBoldLabel">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="font">
<font>
<pointsize>9</pointsize>
<weight>75</weight>
<bold>true</bold>
</font>
</property>
<property name="text">
<string>Date</string>
</property>
</widget>
</item>
<item>
<widget class="QLabel" name="dateLabel">
<property name="sizePolicy">
<sizepolicy hsizetype="Expanding" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="font">
<font>
<pointsize>9</pointsize>
</font>
</property>
<property name="text">
<string notr="true">You eyes only</string>
</property>
<property name="openExternalLinks">
<bool>true</bool>
</property>
</widget>
</item>
</layout>
</item>
<item row="1" column="1" rowspan="3" colspan="2">
<widget class="QTextBrowser" name="textBrowser"/>
</item>
<item row="2" column="0">
<spacer name="verticalSpacer">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>48</width>
<height>75</height>
</size>
</property>
</spacer>
</item>
<item row="3" column="0">
<layout class="QVBoxLayout" name="verticalLayout_2">
<item>
<layout class="QHBoxLayout" name="horizontalLayout_2">
<item>
<widget class="QToolButton" name="toolButton">
<property name="text">
<string>...</string>
<widget class="QFrame" name="widget_parent">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Preferred">
<horstretch>20</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="minimumSize">
<size>
<width>0</width>
<height>0</height>
</size>
</property>
<property name="frameShape">
<enum>QFrame::StyledPanel</enum>
</property>
</widget>
</item>
<item>
<widget class="QToolButton" name="toolButton_2">
<property name="text">
<string>...</string>
<spacer name="verticalSpacer_2">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
</widget>
<property name="sizeHint" stdset="0">
<size>
<width>10</width>
<height>40</height>
</size>
</property>
</spacer>
</item>
<item>
<widget class="QToolButton" name="toolButton_3">
<property name="text">
<string>...</string>
<spacer name="horizontalSpacer_2">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>50</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
</layout>
</item>
<item>
<layout class="QHBoxLayout" name="horizontalLayout">
<item>
<spacer name="horizontalSpacer">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeType">
<enum>QSizePolicy::Preferred</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>50</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
<item>
<spacer name="verticalSpacer">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>10</width>
<height>40</height>
</size>
</property>
</spacer>
</item>
<item>
<widget class="QFrame" name="widget_reply">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Preferred">
<horstretch>20</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="minimumSize">
<size>
<width>0</width>
<height>0</height>
</size>
</property>
<property name="frameShape">
<enum>QFrame::StyledPanel</enum>
</property>
</widget>
</item>
@ -208,7 +159,7 @@ border-radius: 10px}</string>
</layout>
</widget>
<resources>
<include location="../../retroshare-gui/src/gui/images.qrc"/>
<include location="TheWire_images.qrc"/>
</resources>
<connections/>
</ui>

View File

@ -0,0 +1,15 @@
<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>
</qresource>
</RCC>

View File

@ -1,7 +1,7 @@
/*******************************************************************************
* gui/TheWire/WireDialog.cpp *
* *
* Copyright (c) 2012 Robert Fernie <retroshare.project@gmail.com> *
* Copyright (c) 2012-2020 Robert Fernie <retroshare.project@gmail.com> *
* *
* This program is free software: you can redistribute it and/or modify *
* it under the terms of the GNU Affero General Public License as *
@ -20,40 +20,24 @@
#include "WireDialog.h"
#include "WireGroupDialog.h"
#include "WireGroupItem.h"
#include <retroshare/rspeers.h>
#include <retroshare/rsphoto.h>
#include <retroshare/rswire.h>
#include <iostream>
#include <sstream>
#include <QTimer>
/******
* #define PHOTO_DEBUG 1
*****/
#include <QMessageBox>
/****************************************************************
* New Photo Display Widget.
* TheWire Display Widget.
*
* This has two 'lists'.
* Top list shows Albums.
* Lower list is photos from the selected Album.
*
* Notes:
* Each Item will be an AlbumItem, which contains a thumbnail & random details.
* We will limit Items to < 100. With a 'Filter to see more message.
*
* Thumbnails will come from Service.
* Option to Share albums / pictures onward (if permissions allow).
* Option to Download the albums to a specified directory. (is this required if sharing an album?)
*
* Will introduce a FullScreen SlideShow later... first get basics happening.
*/
/** Constructor */
WireDialog::WireDialog(QWidget *parent)
: MainPage(parent)
@ -63,36 +47,103 @@ WireDialog::WireDialog(QWidget *parent)
mAddDialog = NULL;
mPulseSelected = NULL;
connect( ui.pushButton_Post, SIGNAL(clicked()), this, SLOT(OpenOrShowPulseAddDialog()));
//connect( ui.pushButton_Accounts, SIGNAL(clicked()), this, SLOT(OpenOrShowAccountDialog()));
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()));
QTimer *timer = new QTimer(this);
timer->connect(timer, SIGNAL(timeout()), this, SLOT(checkUpdate()));
timer->start(1000);
/* setup TokenQueue */
mWireQueue = new TokenQueue(rsWire->getTokenService(), this);
requestGroupData();
}
void WireDialog::refreshGroups()
{
requestGroupData();
}
void WireDialog::addItem(QWidget *item)
{
QLayout *alayout = ui.scrollAreaWidgetContents->layout();
alayout->addWidget(item);
}
void WireDialog::addGroup(QWidget *item)
{
QLayout *alayout = ui.scrollAreaWidgetContents_groups->layout();
alayout->addWidget(item);
}
// PulseHolder interface.
void WireDialog::deletePulseItem(PulseItem *item, uint32_t type)
{
return;
}
void WireDialog::notifySelection(PulseItem *item, int ptype)
{
std::cerr << "WireDialog::notifySelection() from : " << ptype << " " << item;
std::cerr << std::endl;
std::cerr << "WireDialog::notifySelection() from : " << ptype << " " << item;
std::cerr << std::endl;
notifyPulseSelection(item);
}
#if 0
switch(ptype)
// Actions from PulseHolder.
void WireDialog::follow(RsGxsGroupId &groupId)
{
std::cerr << "WireDialog::follow(";
std::cerr << groupId.toStdString();
std::cerr << ")";
std::cerr << std::endl;
}
void WireDialog::rate(RsGxsId &authorId)
{
std::cerr << "WireDialog::rate(";
std::cerr << authorId.toStdString();
std::cerr << ")";
std::cerr << std::endl;
}
void WireDialog::reply(RsWirePulse &pulse, std::string &groupName)
{
std::cerr << "WireDialog::reply(";
std::cerr << pulse.mMeta.mGroupId.toStdString();
std::cerr << ",";
std::cerr << pulse.mMeta.mOrigMsgId.toStdString();
std::cerr << ")";
std::cerr << std::endl;
if (!mAddDialog)
{
default:
case PHOTO_ITEM_TYPE_ALBUM:
notifyAlbumSelection(item);
break;
case PHOTO_ITEM_TYPE_PHOTO:
notifyPhotoSelection(item);
break;
mAddDialog = new PulseAddDialog(NULL);
mAddDialog->hide();
}
#endif
int idx = ui.groupChooser->currentIndex();
if (idx < 0) {
std::cerr << "WireDialog::reply() ERROR GETTING AuthorId!";
std::cerr << std::endl;
QMessageBox::warning(this, tr("RetroShare"),tr("Please create or choose Wire Groupd first"), QMessageBox::Ok, QMessageBox::Ok);
return;
}
// publishing group.
RsWireGroup group = mOwnGroups[idx];
mAddDialog->setGroup(group);
// establish replyTo.
mAddDialog->setReplyTo(pulse, groupName);
mAddDialog->show();
}
void WireDialog::notifyPulseSelection(PulseItem *item)
@ -127,331 +178,305 @@ void WireDialog::checkUpdate()
return;
}
/*************** New Photo Dialog ***************/
void WireDialog::OpenOrShowPulseAddDialog()
void WireDialog::createGroup()
{
if (mAddDialog)
{
mAddDialog->show();
}
else
WireGroupDialog wireCreate(mWireQueue, this);
wireCreate.exec();
}
void WireDialog::createPulse()
{
if (!mAddDialog)
{
mAddDialog = new PulseAddDialog(NULL);
mAddDialog->show();
}
}
bool WireDialog::matchesAlbumFilter(const RsPhotoAlbum &album)
{
return true;
}
double WireDialog::AlbumScore(const RsPhotoAlbum &album)
{
return 1;
}
bool WireDialog::matchesPhotoFilter(const RsPhotoPhoto &photo)
{
return true;
}
double WireDialog::PhotoScore(const RsPhotoPhoto &photo)
{
return 1;
}
bool WireDialog::FilterNSortAlbums(const std::list<std::string> &albumIds, std::list<std::string> &filteredAlbumIds, int count)
{
#if 0
std::multimap<double, std::string> sortedAlbums;
std::multimap<double, std::string>::iterator sit;
std::list<std::string>::const_iterator it;
for(it = albumIds.begin(); it != albumIds.end(); ++it)
{
RsPhotoAlbum album;
rsPhoto->getAlbum(*it, album);
if (matchesAlbumFilter(album))
{
double score = AlbumScore(album);
sortedAlbums.insert(std::make_pair(score, *it));
}
mAddDialog->hide();
}
int i;
for (sit = sortedAlbums.begin(), i = 0; (sit != sortedAlbums.end()) && (i < count); ++sit, ++i)
{
filteredAlbumIds.push_back(sit->second);
}
#endif
return true;
}
bool WireDialog::FilterNSortPhotos(const std::list<std::string> &photoIds, std::list<std::string> &filteredPhotoIds, int count)
{
#if 0
std::multimap<double, std::string> sortedPhotos;
std::multimap<double, std::string>::iterator sit;
std::list<std::string>::const_iterator it;
int i = 0;
for(it = photoIds.begin(); it != photoIds.end(); ++it, ++i)
{
RsPhotoPhoto photo;
rsPhoto->getPhoto(*it, photo);
if (matchesPhotoFilter(photo))
{
double score = i; //PhotoScore(album);
sortedPhotos.insert(std::make_pair(score, *it));
}
}
for (sit = sortedPhotos.begin(), i = 0; (sit != sortedPhotos.end()) && (i < count); ++sit, ++i)
{
filteredPhotoIds.push_back(sit->second);
}
#endif
return true;
}
void WireDialog::insertAlbums()
{
#if 0
/* clear it all */
clearAlbums();
//ui.albumLayout->clear();
/* create a list of albums */
std::list<std::string> albumIds;
std::list<std::string> filteredAlbumIds;
std::list<std::string>::iterator it;
rsPhoto->getAlbumList(albumIds);
/* Filter Albums */ /* Sort Albums */
#define MAX_ALBUMS 50
int count = MAX_ALBUMS;
FilterNSortAlbums(albumIds, filteredAlbumIds, count);
for(it = filteredAlbumIds.begin(); it != filteredAlbumIds.end(); ++it)
{
addAlbum(*it);
}
insertPhotosForAlbum(filteredAlbumIds);
#endif
}
void WireDialog::insertPhotosForSelectedAlbum()
{
#if 0
std::cerr << "WireDialog::insertPhotosForSelectedAlbum()";
std::cerr << std::endl;
clearPhotos();
std::list<std::string> albumIds;
if (mAlbumSelected)
{
albumIds.push_back(mAlbumSelected->mDetails.mAlbumId);
std::cerr << "WireDialog::insertPhotosForSelectedAlbum() AlbumId: " << mAlbumSelected->mDetails.mAlbumId;
int idx = ui.groupChooser->currentIndex();
if (idx < 0) {
std::cerr << "WireDialog::createPulse() ERROR GETTING AuthorId!";
std::cerr << std::endl;
QMessageBox::warning(this, tr("RetroShare"),tr("Please create or choose Wire Groupd first"), QMessageBox::Ok, QMessageBox::Ok);
return;
}
insertPhotosForAlbum(albumIds);
#endif
RsWireGroup group = mOwnGroups[idx];
mAddDialog->setGroup(group);
mAddDialog->show();
}
void WireDialog::addAlbum(const std::string &id)
void WireDialog::addPulse(RsWirePulse &pulse, RsWireGroup &group)
{
#if 0
RsPhotoAlbum album;
rsPhoto->getAlbum(id, album);
RsPhotoThumbnail thumbnail;
rsPhoto->getAlbumThumbnail(id, thumbnail);
std::cerr << " WireDialog::addAlbum() AlbumId: " << album.mAlbumId << std::endl;
PulseItem *item = new PulseItem(this, album, thumbnail);
QLayout *alayout = ui.scrollAreaWidgetContents->layout();
alayout->addWidget(item);
#endif
}
void WireDialog::clearAlbums()
{
#if 0
std::cerr << "WireDialog::clearAlbums()" << std::endl;
std::list<PulseItem *> photoItems;
std::list<PulseItem *>::iterator pit;
QLayout *alayout = ui.scrollAreaWidgetContents->layout();
int count = alayout->count();
for(int i = 0; i < count; ++i)
{
QLayoutItem *litem = alayout->itemAt(i);
if (!litem)
{
std::cerr << "WireDialog::clearAlbums() missing litem";
std::cerr << std::endl;
continue;
}
PulseItem *item = dynamic_cast<PulseItem *>(litem->widget());
if (item)
{
std::cerr << "WireDialog::clearAlbums() item: " << item;
std::cerr << std::endl;
photoItems.push_back(item);
}
else
{
std::cerr << "WireDialog::clearAlbums() Found Child, which is not a PulseItem???";
std::cerr << std::endl;
}
}
for(pit = photoItems.begin(); pit != photoItems.end(); ++pit)
{
PulseItem *item = *pit;
alayout->removeWidget(item);
delete item;
}
mAlbumSelected = NULL;
#endif
}
void WireDialog::clearPhotos()
{
#if 0
std::cerr << "WireDialog::clearPhotos()" << std::endl;
std::list<PulseItem *> photoItems;
std::list<PulseItem *>::iterator pit;
QLayout *alayout = ui.scrollAreaWidgetContents_2->layout();
int count = alayout->count();
for(int i = 0; i < count; ++i)
{
QLayoutItem *litem = alayout->itemAt(i);
if (!litem)
{
std::cerr << "WireDialog::clearPhotos() missing litem";
std::cerr << std::endl;
continue;
}
PulseItem *item = dynamic_cast<PulseItem *>(litem->widget());
if (item)
{
std::cerr << "WireDialog::clearPhotos() item: " << item;
std::cerr << std::endl;
photoItems.push_back(item);
}
else
{
std::cerr << "WireDialog::clearPhotos() Found Child, which is not a PulseItem???";
std::cerr << std::endl;
}
}
for(pit = photoItems.begin(); pit != photoItems.end(); ++pit)
{
PulseItem *item = *pit;
alayout->removeWidget(item);
delete item;
}
mPhotoSelected = NULL;
#endif
}
void WireDialog::insertPhotosForAlbum(const std::list<std::string> &albumIds)
{
#if 0
/* clear it all */
clearPhotos();
//ui.photoLayout->clear();
/* create a list of albums */
std::list<std::string> ids;
std::list<std::string> photoIds;
std::list<std::string> filteredPhotoIds;
std::list<std::string>::const_iterator it;
for(it = albumIds.begin(); it != albumIds.end(); ++it)
{
rsPhoto->getPhotoList(*it, photoIds);
}
/* Filter Albums */ /* Sort Albums */
#define MAX_PHOTOS 50
int count = MAX_PHOTOS;
FilterNSortPhotos(photoIds, filteredPhotoIds, MAX_PHOTOS);
for(it = filteredPhotoIds.begin(); it != filteredPhotoIds.end(); ++it)
{
addPhoto(*it);
}
#endif
}
void WireDialog::addPhoto(const std::string &id)
{
#if 0
RsPhotoPhoto photo;
rsPhoto->getPhoto(id,photo);
RsPhotoThumbnail thumbnail;
rsPhoto->getPhotoThumbnail(id, thumbnail);
std::cerr << "WireDialog::addPhoto() AlbumId: " << photo.mAlbumId;
std::cerr << " PhotoId: " << photo.mId;
std::cerr << "WireDialog::addPulse() GroupId : " << pulse.mMeta.mGroupId;
std::cerr << " MsgId : " << pulse.mMeta.mGroupId;
std::cerr << std::endl;
PulseItem *item = new PulseItem(this, photo, thumbnail);
QLayout *alayout = ui.scrollAreaWidgetContents_2->layout();
alayout->addWidget(item);
#endif
QWidget *item = new PulseItem(this, pulse, group);
addItem(item);
}
void WireDialog::deletePulseItem(PulseItem *item, uint32_t type)
void WireDialog::addGroup(RsWireGroup &group)
{
std::cerr << "WireDialog::addGroup() GroupId : " << group.mMeta.mGroupId;
std::cerr << std::endl;
addGroup(new WireGroupItem(group));
}
void WireDialog::deletePulses()
{
std::cerr << "WireDialog::deletePulses()";
std::cerr << std::endl;
QLayout *alayout = ui.scrollAreaWidgetContents->layout();
QLayoutItem *item;
int i = 0;
while (i < alayout->count())
{
item = alayout->itemAt(i);
QWidget *widget = item->widget();
if (NULL != dynamic_cast<PulseItem *>(widget))
{
std::cerr << "WireDialog::deletePulses() Removing Item at: " << i;
std::cerr << std::endl;
item = alayout->takeAt(i);
delete item->widget();
delete item;
}
else
{
std::cerr << "WireDialog::deletePulses() Leaving Item at: " << i;
std::cerr << std::endl;
i++;
}
}
}
void WireDialog::deleteGroups()
{
std::cerr << "WireDialog::deleteGroups()";
std::cerr << std::endl;
mAllGroups.clear();
mOwnGroups.clear();
ui.groupChooser->clear();
return;
QLayout *alayout = ui.scrollAreaWidgetContents_groups->layout();
QLayoutItem *item;
int i = 0;
while (i < alayout->count())
{
item = alayout->itemAt(i);
QWidget *widget = item->widget();
if (NULL != dynamic_cast<WireGroupItem *>(widget))
{
std::cerr << "WireDialog::deleteGroups() Removing Item at: " << i;
std::cerr << std::endl;
item = alayout->takeAt(i);
delete item->widget();
delete item;
}
else
{
std::cerr << "WireDialog::deleteGroups() Leaving Item at: " << i;
std::cerr << std::endl;
i++;
}
}
}
void WireDialog::updateGroups(std::vector<RsWireGroup>& groups)
{
std::vector<RsWireGroup>::const_iterator it;
for(it = groups.begin(); it != groups.end(); it++) {
// save list of all groups.
mAllGroups[it->mMeta.mGroupId] = *it;
if (it->mMeta.mSubscribeFlags & GXS_SERV::GROUP_SUBSCRIBE_ADMIN)
{
// grab own groups.
// setup Chooser too.
mOwnGroups.push_back(*it);
ui.groupChooser->addItem(QString::fromStdString(it->mMeta.mGroupName));
}
}
}
// LOAD DATA...............................................
void WireDialog::requestGroupData()
{
std::cerr << "WireDialog::requestGroupData()";
std::cerr << std::endl;
RsTokReqOptions opts;
uint32_t token;
opts.mReqType = GXS_REQUEST_TYPE_GROUP_DATA;
mWireQueue->requestGroupInfo(token, RS_TOKREQ_ANSTYPE_DATA, opts, 0);
}
bool WireDialog::loadGroupData(const uint32_t &token)
{
std::cerr << "WireDialog::loadGroupData()";
std::cerr << std::endl;
deleteGroups();
deletePulses();
std::vector<RsWireGroup> groups;
rsWire->getGroupData(token, groups);
std::vector<RsWireGroup>::iterator vit = groups.begin();
for(; vit != groups.end(); ++vit)
{
RsWireGroup& group = *vit;
std::cerr << " WireDialog::addGroup() GroupId: " << group.mMeta.mGroupId << std::endl;
addGroup(group);
std::list<RsGxsGroupId> grpIds;
grpIds.push_back(group.mMeta.mGroupId);
requestPulseData(grpIds);
}
// save list of groups.
updateGroups(groups);
return true;
}
void WireDialog::requestPulseData(const std::list<RsGxsGroupId>& grpIds)
{
std::cerr << "WireDialog::requestPulseData()";
std::cerr << std::endl;
RsTokReqOptions opts;
opts.mReqType = GXS_REQUEST_TYPE_MSG_DATA;
opts.mOptions = RS_TOKREQOPT_MSG_LATEST;
uint32_t token;
mWireQueue->requestMsgInfo(token, RS_TOKREQ_ANSTYPE_DATA, opts, grpIds, 0);
}
bool WireDialog::loadPulseData(const uint32_t &token)
{
std::cerr << "WireDialog::loadPulseData()";
std::cerr << std::endl;
// clearPulses();
std::vector<RsWirePulse> pulses;
rsWire->getPulseData(token, pulses);
std::vector<RsWirePulse>::iterator vit = pulses.begin();
for(; vit != pulses.end(); vit++)
{
RsWirePulse& pulse = *vit;
RsGxsGroupId &gid = pulse.mMeta.mGroupId;
std::map<RsGxsGroupId, RsWireGroup>::iterator mit = mAllGroups.find(gid);
if (mit != mAllGroups.end())
{
RsWireGroup &group = mit->second;
addPulse(pulse, group);
std::cerr << "WireDialog::loadPulseData() GroupId: " << pulse.mMeta.mGroupId;
std::cerr << " PulseId: " << pulse.mMeta.mMsgId;
std::cerr << std::endl;
}
else
{
std::cerr << "WireDialog::loadPulseData() ERROR Missing GroupId: " << pulse.mMeta.mGroupId;
std::cerr << " PulseId: " << pulse.mMeta.mMsgId;
std::cerr << std::endl;
}
}
// updatePulses();
return true;
}
/**************************** Request / Response Filling of Data ************************/
void WireDialog::loadRequest(const TokenQueue *queue, const TokenRequest &req)
{
std::cerr << "WireDialog::loadRequest()";
std::cerr << std::endl;
if (queue == mWireQueue)
{
/* now switch on req */
switch(req.mType)
{
case TOKENREQ_GROUPINFO:
switch(req.mAnsType)
{
// case RS_TOKREQ_ANSTYPE_LIST:
// loadGroupList(req.mToken);
// break;
case RS_TOKREQ_ANSTYPE_DATA:
loadGroupData(req.mToken);
break;
// case RS_TOKREQ_ANSTYPE_ACK:
// acknowledgeGroup(req.mToken);
// break;
default:
std::cerr << "WireDialog::loadRequest() ERROR: GROUP: INVALID ANS TYPE";
std::cerr << std::endl;
break;
}
break;
case TOKENREQ_MSGINFO:
switch(req.mAnsType)
{
#if 0
case RS_TOKREQ_ANSTYPE_LIST:
loadPhotoList(req.mToken);
break;
case RS_TOKREQ_ANSTYPE_ACK:
acknowledgeMessage(req.mToken);
break;
#endif
case RS_TOKREQ_ANSTYPE_DATA:
loadPulseData(req.mToken);
break;
default:
std::cerr << "WireDialog::loadRequest() ERROR: MSG: INVALID ANS TYPE";
std::cerr << std::endl;
break;
}
break;
#if 0
case TOKENREQ_MSGRELATEDINFO:
switch(req.mAnsType)
{
case RS_TOKREQ_ANSTYPE_DATA:
loadPhotoData(req.mToken);
break;
default:
std::cerr << "WireDialog::loadRequest() ERROR: MSG: INVALID ANS TYPE";
std::cerr << std::endl;
break;
}
break;
#endif
default:
std::cerr << "WireDialog::loadRequest() ERROR: INVALID TYPE";
std::cerr << std::endl;
break;
}
}
}
/**************************** Request / Response Filling of Data ************************/

View File

@ -1,7 +1,7 @@
/*******************************************************************************
* gui/TheWire/WireDialog.h *
* *
* Copyright (c) 2012 Robert Fernie <retroshare.project@gmail.com> *
* Copyright (c) 2012-2020 Robert Fernie <retroshare.project@gmail.com> *
* *
* This program is free software: you can redistribute it and/or modify *
* it under the terms of the GNU Affero General Public License as *
@ -24,67 +24,75 @@
#include "retroshare-gui/mainpage.h"
#include "ui_WireDialog.h"
#include <retroshare/rsphoto.h>
#include <retroshare/rswire.h>
#include <map>
#include "gui/TheWire/PulseItem.h"
#include "gui/TheWire/PulseAddDialog.h"
#include "util/TokenQueue.h"
#define IMAGE_WIRE ":/images/kgames.png"
class WireDialog : public MainPage, public PulseHolder
class WireDialog : public MainPage, public TokenResponse, public PulseHolder
{
Q_OBJECT
public:
WireDialog(QWidget *parent = 0);
virtual QIcon iconPixmap() const { return QIcon(IMAGE_WIRE) ; }
virtual QString pageName() const { return tr("The Wire") ; }
virtual QString helpText() const { return ""; }
virtual QIcon iconPixmap() const { return QIcon(IMAGE_WIRE) ; }
virtual QString pageName() const { return tr("The Wire") ; }
virtual QString helpText() const { return ""; }
virtual void deletePulseItem(PulseItem *, uint32_t type);
virtual void notifySelection(PulseItem *item, int ptype);
// PulseHolder interface.
virtual void deletePulseItem(PulseItem *, uint32_t type);
virtual void notifySelection(PulseItem *item, int ptype);
virtual void follow(RsGxsGroupId &groupId);
virtual void rate(RsGxsId &authorId);
virtual void reply(RsWirePulse &pulse, std::string &groupName);
void notifyPulseSelection(PulseItem *item);
private slots:
void createGroup();
void createPulse();
void checkUpdate();
void OpenOrShowPulseAddDialog();
void refreshGroups();
private:
void addItem(QWidget *item);
void addGroup(QWidget *item);
void addPulse(RsWirePulse &pulse, RsWireGroup &group);
void addGroup(RsWireGroup &group);
/* TODO: These functions must be filled in for proper filtering to work
* and tied to the GUI input
*/
void deletePulses();
void deleteGroups();
void updateGroups(std::vector<RsWireGroup> &groups);
bool matchesAlbumFilter(const RsPhotoAlbum &album);
double AlbumScore(const RsPhotoAlbum &album);
bool matchesPhotoFilter(const RsPhotoPhoto &photo);
double PhotoScore(const RsPhotoPhoto &photo);
// Loading Data.
void requestGroupData();
bool loadGroupData(const uint32_t &token);
/* Grunt work of setting up the GUI */
void requestPulseData(const std::list<RsGxsGroupId>& grpIds);
bool loadPulseData(const uint32_t &token);
bool FilterNSortAlbums(const std::list<std::string> &albumIds, std::list<std::string> &filteredAlbumIds, int count);
bool FilterNSortPhotos(const std::list<std::string> &photoIds, std::list<std::string> &filteredPhotoIds, int count);
void insertAlbums();
void insertPhotosForAlbum(const std::list<std::string> &albumIds);
void insertPhotosForSelectedAlbum();
void addAlbum(const std::string &id);
void addPhoto(const std::string &id);
void clearAlbums();
void clearPhotos();
virtual void loadRequest(const TokenQueue *queue, const TokenRequest &req);
PulseAddDialog *mAddDialog;
PulseItem *mPulseSelected;
TokenQueue *mWireQueue;
std::map<RsGxsGroupId, RsWireGroup> mAllGroups;
std::vector<RsWireGroup> mOwnGroups;
/* UI - from Designer */
Ui::WireDialog ui;

View File

@ -10,16 +10,168 @@
<height>557</height>
</rect>
</property>
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="windowTitle">
<string/>
</property>
<layout class="QGridLayout" name="gridLayout_2">
<item row="0" column="0" rowspan="3">
<item row="0" column="0" colspan="2">
<widget class="QFrame" name="frame_2">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="frameShape">
<enum>QFrame::StyledPanel</enum>
</property>
<property name="frameShadow">
<enum>QFrame::Raised</enum>
</property>
<layout class="QHBoxLayout" name="horizontalLayout">
<item>
<widget class="QToolButton" name="toolButton_createAccount">
<property name="text">
<string>Create Account</string>
</property>
</widget>
</item>
<item>
<widget class="QToolButton" name="toolButton_createPulse">
<property name="text">
<string>Post Pulse</string>
</property>
</widget>
</item>
<item>
<widget class="QToolButton" name="toolButton_3">
<property name="text">
<string>...</string>
</property>
</widget>
</item>
<item>
<widget class="QToolButton" name="toolButton_4">
<property name="text">
<string>...</string>
</property>
</widget>
</item>
<item>
<widget class="QToolButton" name="toolButton_5">
<property name="text">
<string>...</string>
</property>
</widget>
</item>
<item>
<spacer name="horizontalSpacer">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>296</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
<item>
<widget class="QToolButton" name="toolButton_refresh">
<property name="text">
<string>Refresh</string>
</property>
</widget>
</item>
<item>
<widget class="QComboBox" name="groupChooser"/>
</item>
<item>
<widget class="QToolButton" name="toolButton_Settings">
<property name="text">
<string>Settings</string>
</property>
</widget>
</item>
</layout>
</widget>
</item>
<item row="6" column="0">
<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>567</width>
<height>412</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>
<item row="1" column="0" rowspan="5">
<layout class="QGridLayout" name="gridLayout">
<item row="0" column="0">
<widget class="QLabel" name="label_3">
<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>TimeRange</string>
<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>
@ -66,40 +218,23 @@
</item>
</widget>
</item>
<item row="0" column="3" colspan="2">
<widget class="QDateTimeEdit" name="dateTimeEdit"/>
</item>
<item row="1" column="0">
<widget class="QLabel" name="label_2">
<item row="0" column="0">
<widget class="QLabel" name="label_3">
<property name="text">
<string>Search/Filter</string>
<string>TimeRange</string>
</property>
</widget>
</item>
<item row="1" column="1" colspan="3">
<widget class="QLineEdit" name="lineEdit"/>
</item>
<item row="1" column="4">
<widget class="QCheckBox" name="checkBox_9">
<property name="text">
<string>Network Wide</string>
</property>
</widget>
</item>
</layout>
</item>
<item row="0" column="1">
<widget class="QPushButton" name="pushButton_Accounts">
<property name="text">
<string>Manage Accounts</string>
</property>
</widget>
</item>
<item row="2" column="1" rowspan="2">
<item row="5" column="1" rowspan="2">
<widget class="QFrame" name="frame">
<property name="maximumSize">
<size>
<width>160</width>
<width>200</width>
<height>16777215</height>
</size>
</property>
@ -113,7 +248,16 @@
<property name="spacing">
<number>0</number>
</property>
<property name="margin">
<property name="leftMargin">
<number>0</number>
</property>
<property name="topMargin">
<number>0</number>
</property>
<property name="rightMargin">
<number>0</number>
</property>
<property name="bottomMargin">
<number>0</number>
</property>
<item>
@ -121,126 +265,16 @@
<property name="widgetResizable">
<bool>true</bool>
</property>
<widget class="QWidget" name="scrollAreaWidgetContents_2">
<widget class="QWidget" name="scrollAreaWidgetContents_groups">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>156</width>
<height>469</height>
<width>129</width>
<height>416</height>
</rect>
</property>
<layout class="QVBoxLayout" name="verticalLayout_4">
<item>
<widget class="QGroupBox" name="groupBox">
<property name="title">
<string>Showing:</string>
</property>
<layout class="QVBoxLayout" name="verticalLayout">
<property name="margin">
<number>0</number>
</property>
<item>
<widget class="QRadioButton" name="radioButton">
<property name="text">
<string>Yourself</string>
</property>
</widget>
</item>
<item>
<widget class="QRadioButton" name="radioButton_2">
<property name="text">
<string>Friends</string>
</property>
</widget>
</item>
<item>
<widget class="QRadioButton" name="radioButton_3">
<property name="text">
<string>Following</string>
</property>
</widget>
</item>
<item>
<widget class="QRadioButton" name="radioButton_4">
<property name="text">
<string>All</string>
</property>
</widget>
</item>
<item>
<widget class="Line" name="line">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
</widget>
</item>
<item>
<widget class="QRadioButton" name="radioButton_5">
<property name="text">
<string>Custom</string>
</property>
</widget>
</item>
</layout>
</widget>
</item>
<item>
<widget class="QCheckBox" name="checkBox">
<property name="text">
<string>Account 1</string>
</property>
</widget>
</item>
<item>
<widget class="QCheckBox" name="checkBox_2">
<property name="text">
<string>Account 2</string>
</property>
</widget>
</item>
<item>
<widget class="QCheckBox" name="checkBox_3">
<property name="text">
<string>Account 3</string>
</property>
</widget>
</item>
<item>
<widget class="QCheckBox" name="checkBox_4">
<property name="text">
<string>CheckBox</string>
</property>
</widget>
</item>
<item>
<widget class="QCheckBox" name="checkBox_5">
<property name="text">
<string>CheckBox</string>
</property>
</widget>
</item>
<item>
<widget class="QCheckBox" name="checkBox_6">
<property name="text">
<string>CheckBox</string>
</property>
</widget>
</item>
<item>
<widget class="QCheckBox" name="checkBox_7">
<property name="text">
<string>CheckBox</string>
</property>
</widget>
</item>
<item>
<widget class="QCheckBox" name="checkBox_8">
<property name="text">
<string>CheckBox</string>
</property>
</widget>
</item>
<item>
<spacer name="verticalSpacer_2">
<property name="orientation">
@ -261,51 +295,36 @@
</layout>
</widget>
</item>
<item row="3" column="0">
<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>540</width>
<height>465</height>
</rect>
<item row="3" column="1">
<widget class="QComboBox" name="comboBox_3">
<item>
<property name="text">
<string>Yourself</string>
</property>
<property name="styleSheet">
<string notr="true">QWidget#scrollAreaWidgetContents{border: none;}</string>
</item>
<item>
<property name="text">
<string>Subscribed</string>
</property>
<layout class="QVBoxLayout" name="verticalLayout_2">
<property name="spacing">
<number>0</number>
</property>
<property name="margin">
<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>
</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="1" column="1">
<item row="2" column="1">
<widget class="QPushButton" name="pushButton_Post">
<property name="text">
<string>Post Pulse to Wire</string>
@ -315,7 +334,7 @@
</layout>
</widget>
<resources>
<include location="../images.qrc"/>
<include location="TheWire_images.qrc"/>
</resources>
<connections/>
</ui>

View File

@ -0,0 +1,180 @@
/*******************************************************************************
* gui/TheWire/WireGroupDialog.cpp *
* *
* Copyright (C) 2020 by Robert Fernie <retroshare.project@gmail.com> *
* *
* This program is free software: you can redistribute it and/or modify *
* it under the terms of the GNU Affero General Public License as *
* published by the Free Software Foundation, either version 3 of the *
* License, or (at your option) any later version. *
* *
* This program is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU Affero General Public License for more details. *
* *
* You should have received a copy of the GNU Affero General Public License *
* along with this program. If not, see <https://www.gnu.org/licenses/>. *
* *
*******************************************************************************/
#include <QBuffer>
#include "WireGroupDialog.h"
#include "gui/gxs/GxsIdDetails.h"
#include <iostream>
const uint32_t WireCreateEnabledFlags = (
GXS_GROUP_FLAGS_NAME |
GXS_GROUP_FLAGS_ICON |
GXS_GROUP_FLAGS_DESCRIPTION |
GXS_GROUP_FLAGS_DISTRIBUTION |
// GXS_GROUP_FLAGS_PUBLISHSIGN |
// GXS_GROUP_FLAGS_SHAREKEYS | // disabled because the UI doesn't handle it yet.
// GXS_GROUP_FLAGS_PERSONALSIGN |
// GXS_GROUP_FLAGS_COMMENTS |
GXS_GROUP_FLAGS_EXTRA |
0);
uint32_t WireCreateDefaultsFlags = ( GXS_GROUP_DEFAULTS_DISTRIB_PUBLIC |
// 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_PERSONAL_GPG |
GXS_GROUP_DEFAULTS_PERSONAL_REQUIRED |
// GXS_GROUP_DEFAULTS_PERSONAL_IFNOPUB |
// GXS_GROUP_DEFAULTS_COMMENTS_YES |
GXS_GROUP_DEFAULTS_COMMENTS_NO |
0);
uint32_t WireEditEnabledFlags = WireCreateEnabledFlags;
uint32_t WireEditDefaultsFlags = WireCreateDefaultsFlags;
WireGroupDialog::WireGroupDialog(TokenQueue *tokenQueue, QWidget *parent)
: GxsGroupDialog(tokenQueue, WireCreateEnabledFlags, WireCreateDefaultsFlags, parent)
{
}
WireGroupDialog::WireGroupDialog(TokenQueue *tokenExternalQueue, RsTokenService *tokenService, Mode mode, RsGxsGroupId groupId, QWidget *parent)
: GxsGroupDialog(tokenExternalQueue, tokenService, mode, groupId, WireEditEnabledFlags, WireEditDefaultsFlags, parent)
{
}
void WireGroupDialog::initUi()
{
switch (mode())
{
case MODE_CREATE:
setUiText(UITYPE_SERVICE_HEADER, tr("Create New Wire"));
setUiText(UITYPE_BUTTONBOX_OK, tr("Create"));
break;
case MODE_SHOW:
setUiText(UITYPE_SERVICE_HEADER, tr("Wire"));
break;
case MODE_EDIT:
setUiText(UITYPE_SERVICE_HEADER, tr("Edit Wire"));
setUiText(UITYPE_BUTTONBOX_OK, tr("Update Wire"));
break;
}
setUiText(UITYPE_ADD_ADMINS_CHECKBOX, tr("Add Wire Admins"));
setUiText(UITYPE_CONTACTS_DOCK, tr("Select Wire Admins"));
}
QPixmap WireGroupDialog::serviceImage()
{
return QPixmap(":/images/wire_create_64.png");
}
void WireGroupDialog::prepareWireGroup(RsWireGroup &group, const RsGroupMetaData &meta)
{
group.mMeta = meta;
group.mDescription = getDescription().toUtf8().constData();
#if 0
QPixmap pixmap = getLogo();
if (!pixmap.isNull()) {
QByteArray ba;
QBuffer buffer(&ba);
buffer.open(QIODevice::WriteOnly);
pixmap.save(&buffer, "PNG"); // writes image into ba in PNG format
group.mThumbnail.copy((uint8_t *) ba.data(), ba.size());
} else {
group.mThumbnail.clear();
}
#endif
}
bool WireGroupDialog::service_CreateGroup(uint32_t &token, const RsGroupMetaData &meta)
{
// Specific Function.
RsWireGroup grp;
prepareWireGroup(grp, meta);
rsWire->createGroup(token, grp);
return true;
}
bool WireGroupDialog::service_EditGroup(uint32_t &token, RsGroupMetaData &editedMeta)
{
RsWireGroup grp;
prepareWireGroup(grp, editedMeta);
std::cerr << "WireGroupDialog::service_EditGroup() submitting changes";
std::cerr << std::endl;
// TODO: no interface here, yet.
// rsWire->updateGroup(token, grp);
return true;
}
bool WireGroupDialog::service_loadGroup(uint32_t token, Mode /*mode*/, RsGroupMetaData& groupMetaData, QString &description)
{
std::cerr << "WireGroupDialog::service_loadGroup(" << token << ")";
std::cerr << std::endl;
std::vector<RsWireGroup> groups;
if (!rsWire->getGroupData(token, groups))
{
std::cerr << "WireGroupDialog::service_loadGroup() Error getting GroupData";
std::cerr << std::endl;
return false;
}
if (groups.size() != 1)
{
std::cerr << "WireGroupDialog::service_loadGroup() Error Group.size() != 1";
std::cerr << std::endl;
return false;
}
std::cerr << "WireGroupDialog::service_loadGroup() Unfinished Loading";
std::cerr << std::endl;
const RsWireGroup &group = groups[0];
groupMetaData = group.mMeta;
description = QString::fromUtf8(group.mDescription.c_str());
#if 0
if (group.mThumbnail.mData) {
QPixmap pixmap;
if (GxsIdDetails::loadPixmapFromData(group.mThumbnail.mData, group.mThumbnail.mSize, pixmap,GxsIdDetails::ORIGINAL)) {
setLogo(pixmap);
}
} else {
setLogo(QPixmap(":/images/album_create_64.png"));
}
#endif
return true;
}

View File

@ -0,0 +1,46 @@
/*******************************************************************************
* gui/TheWire/WireGroupDialog.h *
* *
* Copyright (C) 2020 by Robert Fernie <retroshare.project@gmail.com> *
* *
* This program is free software: you can redistribute it and/or modify *
* it under the terms of the GNU Affero General Public License as *
* published by the Free Software Foundation, either version 3 of the *
* License, or (at your option) any later version. *
* *
* This program is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU Affero General Public License for more details. *
* *
* You should have received a copy of the GNU Affero General Public License *
* along with this program. If not, see <https://www.gnu.org/licenses/>. *
* *
*******************************************************************************/
#ifndef _WIRE_GROUP_DIALOG_H
#define _WIRE_GROUP_DIALOG_H
#include "gui/gxs/GxsGroupDialog.h"
#include <retroshare/rswire.h>
class WireGroupDialog : public GxsGroupDialog
{
Q_OBJECT
public:
WireGroupDialog(TokenQueue *tokenQueue, QWidget *parent);
WireGroupDialog(TokenQueue *tokenExternalQueue, RsTokenService *tokenService, Mode mode, RsGxsGroupId groupId, QWidget *parent);
protected:
virtual void initUi();
virtual QPixmap serviceImage();
virtual bool service_CreateGroup(uint32_t &token, const RsGroupMetaData &meta);
virtual bool service_loadGroup(uint32_t token, Mode mode, RsGroupMetaData& groupMetaData, QString &description);
virtual bool service_EditGroup(uint32_t &token, RsGroupMetaData &editedMeta);
private:
void prepareWireGroup(RsWireGroup &group, const RsGroupMetaData &meta);
};
#endif

View File

@ -0,0 +1,92 @@
/*******************************************************************************
* gui/TheWire/WireGroupItem.cpp *
* *
* Copyright (c) 2020 Robert Fernie <retroshare.project@gmail.com> *
* *
* This program is free software: you can redistribute it and/or modify *
* it under the terms of the GNU Affero General Public License as *
* published by the Free Software Foundation, either version 3 of the *
* License, or (at your option) any later version. *
* *
* This program is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU Affero General Public License for more details. *
* *
* You should have received a copy of the GNU Affero General Public License *
* along with this program. If not, see <https://www.gnu.org/licenses/>. *
* *
*******************************************************************************/
#include <QDateTime>
#include <QMessageBox>
#include <QMouseEvent>
#include <QBuffer>
#include "WireGroupItem.h"
#include <algorithm>
#include <iostream>
/** Constructor */
WireGroupItem::WireGroupItem(RsWireGroup grp)
:QWidget(NULL), mGroup(grp), mType(0)
{
setupUi(this);
setAttribute ( Qt::WA_DeleteOnClose, true );
setup();
}
void WireGroupItem::setup()
{
label_groupName->setText(QString::fromStdString(mGroup.mMeta.mGroupName));
// label_authorId->setText(mGroup.mMeta.mAuthorId);
frame_details->setVisible(false);
connect(toolButton_show, SIGNAL(clicked()), this, SLOT(show()));
}
void WireGroupItem::show()
{
frame_details->setVisible(!frame_details->isVisible());
}
void WireGroupItem::removeItem()
{
}
void WireGroupItem::setSelected(bool on)
{
}
bool WireGroupItem::isSelected()
{
return mSelected;
}
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);
}
const QPixmap *WireGroupItem::getPixmap()
{
return NULL;
}

View File

@ -0,0 +1,58 @@
/*******************************************************************************
* gui/TheWire/WireGroupItem.h *
* *
* Copyright (c) 2020 Robert Fernie <retroshare.project@gmail.com> *
* *
* This program is free software: you can redistribute it and/or modify *
* it under the terms of the GNU Affero General Public License as *
* published by the Free Software Foundation, either version 3 of the *
* License, or (at your option) any later version. *
* *
* This program is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU Affero General Public License for more details. *
* *
* You should have received a copy of the GNU Affero General Public License *
* along with this program. If not, see <https://www.gnu.org/licenses/>. *
* *
*******************************************************************************/
#ifndef MRK_WIRE_GROUP_ITEM_H
#define MRK_WIRE_GROUP_ITEM_H
#include "ui_WireGroupItem.h"
#include <retroshare/rswire.h>
class WireGroupItem;
class WireGroupItem : public QWidget, private Ui::WireGroupItem
{
Q_OBJECT
public:
WireGroupItem(RsWireGroup grp);
void removeItem();
void setSelected(bool on);
bool isSelected();
const QPixmap *getPixmap();
private slots:
void show();
protected:
void mousePressEvent(QMouseEvent *event);
private:
void setup();
RsWireGroup mGroup;
uint32_t mType;
bool mSelected;
};
#endif

View File

@ -0,0 +1,110 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>WireGroupItem</class>
<widget class="QWidget" name="WireGroupItem">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>276</width>
<height>114</height>
</rect>
</property>
<property name="windowTitle">
<string>Form</string>
</property>
<layout class="QHBoxLayout" name="horizontalLayout">
<item>
<widget class="QFrame" name="frame">
<property name="frameShape">
<enum>QFrame::StyledPanel</enum>
</property>
<property name="frameShadow">
<enum>QFrame::Raised</enum>
</property>
<layout class="QVBoxLayout" name="verticalLayout">
<item>
<layout class="QHBoxLayout" name="horizontalLayout_2">
<item>
<widget class="QLabel" name="label_groupName">
<property name="text">
<string>WireGroupName</string>
</property>
</widget>
</item>
<item>
<spacer name="horizontalSpacer">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>118</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
<item>
<widget class="QToolButton" name="toolButton_2">
<property name="text">
<string>Type</string>
</property>
</widget>
</item>
<item>
<widget class="QToolButton" name="toolButton_show">
<property name="text">
<string>\/</string>
</property>
</widget>
</item>
</layout>
</item>
<item>
<widget class="QFrame" name="frame_details">
<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_authorId">
<property name="text">
<string> GxsIdLabel</string>
</property>
</widget>
</item>
<item>
<spacer name="horizontalSpacer_2">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>61</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
<item>
<widget class="QToolButton" name="toolButton">
<property name="text">
<string>Sub/Un</string>
</property>
</widget>
</item>
</layout>
</widget>
</item>
</layout>
</widget>
</item>
</layout>
</widget>
<resources/>
<connections/>
</ui>

View File

@ -28,7 +28,7 @@
#include "WikiDialog.h"
#include "gui/WikiPoos/WikiAddDialog.h"
#include "gui/WikiPoos/WikiEditDialog.h"
#include "gui/settings/rsharesettings.h"
#include "gui/gxs/WikiGroupDialog.h"
#include <retroshare/rswiki.h>
@ -105,6 +105,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);
/* Setup Group Tree */
mYourGroups = ui.groupTreeWidget->addCategoryItem(tr("My Groups"), QIcon(), true);
@ -112,13 +115,37 @@ 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);
// load settings
processSettings(true);
}
WikiDialog::~WikiDialog()
{
// save settings
processSettings(false);
delete(mWikiQueue);
}
void WikiDialog::processSettings(bool load)
{
Settings->beginGroup("WikiDialog");
if (load) {
// load settings
// state of splitter
ui.listSplitter->restoreState(Settings->value("SplitterList").toByteArray());
} else {
// save settings
// state of splitter
Settings->setValue("SplitterList", ui.listSplitter->saveState());
}
Settings->endGroup();
}
void WikiDialog::OpenOrShowAddPageDialog()
{
RsGxsGroupId groupId = getSelectedGroup();

View File

@ -69,39 +69,38 @@ private slots:
// GroupTreeWidget stuff.
void groupListCustomPopupMenu(QPoint point);
void subscribeToGroup();
void unsubscribeToGroup();
void subscribeToGroup();
void unsubscribeToGroup();
void wikiGroupChanged(const QString &groupId);
void todo();
private:
void clearWikiPage();
void clearGroupTree();
void clearWikiPage();
void clearGroupTree();
void updateWikiPage(const RsWikiSnapshot &page);
void updateWikiPage(const RsWikiSnapshot &page);
bool getSelectedPage(RsGxsGroupId &groupId, RsGxsMessageId &pageId, RsGxsMessageId &origPageId);
std::string getSelectedPage();
const RsGxsGroupId &getSelectedGroup();
bool getSelectedPage(RsGxsGroupId &groupId, RsGxsMessageId &pageId, RsGxsMessageId &origPageId);
std::string getSelectedPage();
const RsGxsGroupId &getSelectedGroup();
// Using GroupTreeWidget.
void wikiSubscribe(bool subscribe);
void GroupMetaDataToGroupItemInfo(const RsGroupMetaData &groupInfo, GroupItemInfo &groupItemInfo);
void insertGroupsData(const std::list<RsGroupMetaData> &wikiList);
// Using GroupTreeWidget.
void wikiSubscribe(bool subscribe);
void GroupMetaDataToGroupItemInfo(const RsGroupMetaData &groupInfo, GroupItemInfo &groupItemInfo);
void insertGroupsData(const std::list<RsGroupMetaData> &wikiList);
void processSettings(bool load);
void requestGroupMeta();
void loadGroupMeta(const uint32_t &token);
void requestGroupMeta();
void loadGroupMeta(const uint32_t &token);
void requestPages(const std::list<RsGxsGroupId> &groupIds);
void loadPages(const uint32_t &token);
void requestWikiPage(const RsGxsGrpMsgIdPair &msgId);
void loadWikiPage(const uint32_t &token);
void requestPages(const std::list<RsGxsGroupId> &groupIds);
void loadPages(const uint32_t &token);
void requestWikiPage(const RsGxsGrpMsgIdPair &msgId);
void loadWikiPage(const uint32_t &token);
TokenQueue *mWikiQueue;
@ -110,7 +109,7 @@ void loadWikiPage(const uint32_t &token);
WikiEditDialog *mEditDialog;
std::string mGroupSelected;
RsGxsMessageId mPageSelected;
RsGxsMessageId mPageSelected;
std::string mModSelected;
@ -118,7 +117,7 @@ void loadWikiPage(const uint32_t &token);
QTreeWidgetItem *mSubscribedGroups;
QTreeWidgetItem *mPopularGroups;
QTreeWidgetItem *mOtherGroups;
RsGxsGroupId mGroupId; // From GroupTreeWidget
RsGxsGroupId mGroupId; // From GroupTreeWidget
/* UI - from Designer */
Ui::WikiDialog ui;

View File

@ -27,7 +27,7 @@
<number>0</number>
</property>
<item>
<widget class="QSplitter" name="splitter">
<widget class="QSplitter" name="listSplitter">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>

View File

@ -203,7 +203,7 @@ void GxsChannelPostsWidget::groupNameChanged(const QString &name)
{
if (groupId().isNull()) {
ui->nameLabel->setText(tr("No Channel Selected"));
ui->logoLabel->setPixmap(QPixmap(":/images/channels.png"));
ui->logoLabel->setPixmap(QPixmap(":/icons/png/channels.png"));
} else {
ui->nameLabel->setText(name);
}

View File

@ -103,7 +103,7 @@
<file>icons/png/newsfeed-notify.png</file>
<file>icons/png/newsfeed.png</file>
<file>icons/png/options.png</file>
<file>icons/png/pencil-edit-button.png</file>
<file>icons/png/pencil-edit-button.png</file>
<file>icons/png/people-notify.png</file>
<file>icons/png/people.png</file>
<file>icons/png/person.png</file>
@ -122,7 +122,7 @@
<file>icons/png/thumbs-down.png</file>
<file>icons/png/thumbs-neutral.png</file>
<file>icons/png/thumbs-up.png</file>
<file>icons/png/typing.png</file>
<file>icons/png/typing.png</file>
<file>icons/png/video.png</file>
<file>icons/quit_128.png</file>
<file>icons/search_red_128.png</file>
@ -299,5 +299,24 @@
<file>icons/png/add-file.png</file>
<file>icons/png/add-image.png</file>
<file>icons/png/attachements.png</file>
<file>icons/mail/compose.png</file>
<file>icons/mail/delete.png</file>
<file>icons/mail/tags.png</file>
<file>icons/mail/quote.png</file>
<file>icons/mail/send.png</file>
<file>icons/mail/contacts.png</file>
<file>icons/mail/save.png</file>
<file>icons/mail/filter24.png</file>
<file>icons/mail/foward.png</file>
<file>icons/mail/reply.png</file>
<file>icons/mail/reply-all.png</file>
<file>icons/mail/attach24.png</file>
<file>icons/textedit/align.png</file>
<file>icons/textedit/font-decrease.png</file>
<file>icons/textedit/smile.png</file>
<file>icons/textedit/font-increase.png</file>
<file>icons/textedit/code.png</file>
<file>icons/fullscreen.png</file>
<file>icons/fullscreen-exit.png</file>
</qresource>
</RCC>

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 803 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 616 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.7 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.5 KiB

After

Width:  |  Height:  |  Size: 2.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 539 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.0 KiB

View File

@ -351,38 +351,6 @@
<file>images/mimetypes/source_c.png</file>
<file>images/mimetypes/source_cpp.png</file>
<file>images/mimetypes/source_h.png</file>
<file>images/textedit/textbold.png</file>
<file>images/textedit/textitalic.png</file>
<file>images/textedit/textunder.png</file>
<file>images/textedit/textjustify.png</file>
<file>images/textedit/textcenter.png</file>
<file>images/textedit/textleft.png</file>
<file>images/textedit/textright.png</file>
<file>images/textedit/editcopy.png</file>
<file>images/textedit/editcut.png</file>
<file>images/textedit/editpaste.png</file>
<file>images/textedit/editredo.png</file>
<file>images/textedit/editundo.png</file>
<file>images/textedit/edit-image-face-add.png</file>
<file>images/textedit/exportpdf.png</file>
<file>images/textedit/filenew.png</file>
<file>images/textedit/fileopen.png</file>
<file>images/textedit/fileprint.png</file>
<file>images/textedit/filesave.png</file>
<file>images/textedit/format-text-color.png</file>
<file>images/textedit/format-text-strikethrough.png</file>
<file>images/textedit/format-indent-less.png</file>
<file>images/textedit/format-indent-more.png</file>
<file>images/textedit/insert-link.png</file>
<file>images/textedit/format-list-ordered.png</file>
<file>images/textedit/format-list-unordered.png</file>
<file>images/textedit/zoomin.png</file>
<file>images/textedit/zoomout.png</file>
<file>images/textedit/format_font_size_more.png</file>
<file>images/textedit/format_font_size_less.png</file>
<file>images/textedit/hi22-action-format-text-blockquote.png</file>
<file>images/textedit/hi22-action-format-text-code.png</file>
<file>images/textedit/hi22-action-insert-more-mark.png</file>
<file>images/toaster/backgroundtoaster.png</file>
<file>images/thumb-default-video.png</file>
<file>images/user/add_user24.png</file>

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.3 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.9 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.7 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.7 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.0 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 768 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.6 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.2 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 718 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 701 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 619 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 314 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 825 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 579 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 850 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.5 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.3 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 667 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 313 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 630 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 261 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 314 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 313 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 537 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.2 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.2 KiB

View File

@ -223,16 +223,16 @@ MessageComposer::MessageComposer(QWidget *parent, Qt::WindowFlags flags)
QActionGroup *grp = new QActionGroup(this);
connect(grp, SIGNAL(triggered(QAction *)), this, SLOT(textAlign(QAction *)));
actionAlignLeft = new QAction(QIcon(":/images/textedit/textleft.png"), tr("&Left"), grp);
actionAlignLeft = new QAction(QIcon(""), tr("&Left"), grp);
actionAlignLeft->setShortcut(Qt::CTRL + Qt::Key_L);
actionAlignLeft->setCheckable(true);
actionAlignCenter = new QAction(QIcon(":/images/textedit/textcenter.png"), tr("C&enter"), grp);
actionAlignCenter = new QAction(QIcon(""), tr("C&enter"), grp);
actionAlignCenter->setShortcut(Qt::CTRL + Qt::Key_E);
actionAlignCenter->setCheckable(true);
actionAlignRight = new QAction(QIcon(":/images/textedit/textright.png"), tr("&Right"), grp);
actionAlignRight = new QAction(QIcon(""), tr("&Right"), grp);
actionAlignRight->setShortcut(Qt::CTRL + Qt::Key_R);
actionAlignRight->setCheckable(true);
actionAlignJustify = new QAction(QIcon(":/images/textedit/textjustify.png"), tr("&Justify"), grp);
actionAlignJustify = new QAction(QIcon(""), tr("&Justify"), grp);
actionAlignJustify->setShortcut(Qt::CTRL + Qt::Key_J);
actionAlignJustify->setCheckable(true);
@ -280,8 +280,6 @@ MessageComposer::MessageComposer(QWidget *parent, Qt::WindowFlags flags)
connect(ui.comboSize, SIGNAL(activated(const QString &)),this, SLOT(textSize(const QString &)));
ui.comboSize->setCurrentIndex(ui.comboSize->findText(QString::number(QApplication::font().pointSize())));
ui.textalignmentbtn->setIcon(QIcon(QString(":/images/textedit/textcenter.png")));
QMenu * alignmentmenu = new QMenu();
alignmentmenu->addAction(actionAlignLeft);
alignmentmenu->addAction(actionAlignCenter);
@ -1892,19 +1890,19 @@ void MessageComposer::setupFileActions()
QAction *a;
a = new QAction(QIcon(":/images/textedit/filenew.png"), tr("&New"), this);
a = new QAction(QIcon(""), tr("&New"), this);
a->setShortcut(QKeySequence::New);
connect(a, SIGNAL(triggered()), this, SLOT(fileNew()));
menu->addAction(a);
a = new QAction(QIcon(":/images/textedit/fileopen.png"), tr("&Open..."), this);
a = new QAction(QIcon(""), tr("&Open..."), this);
a->setShortcut(QKeySequence::Open);
connect(a, SIGNAL(triggered()), this, SLOT(fileOpen()));
menu->addAction(a);
menu->addSeparator();
actionSave = a = new QAction(QIcon(":/images/textedit/filesave.png"), tr("&Save"), this);
actionSave = a = new QAction(QIcon(""), tr("&Save"), this);
a->setShortcut(QKeySequence::Save);
connect(a, SIGNAL(triggered()), this, SLOT(saveasDraft()));
a->setEnabled(false);
@ -1919,7 +1917,7 @@ void MessageComposer::setupFileActions()
menu->addAction(a);
menu->addSeparator();
a = new QAction(QIcon(":/images/textedit/fileprint.png"), tr("&Print..."), this);
a = new QAction(QIcon(""), tr("&Print..."), this);
a->setShortcut(QKeySequence::Print);
connect(a, SIGNAL(triggered()), this, SLOT(filePrint()));
menu->addAction(a);
@ -1928,7 +1926,7 @@ void MessageComposer::setupFileActions()
connect(a, SIGNAL(triggered()), this, SLOT(filePrintPreview()));
menu->addAction(a);*/
a = new QAction(QIcon(":/images/textedit/exportpdf.png"), tr("&Export PDF..."), this);
a = new QAction(QIcon(""), tr("&Export PDF..."), this);
a->setShortcut(Qt::CTRL + Qt::Key_D);
connect(a, SIGNAL(triggered()), this, SLOT(filePrintPdf()));
menu->addAction(a);
@ -1947,20 +1945,20 @@ void MessageComposer::setupEditActions()
menuBar()->addMenu(menu);
QAction *a;
a = actionUndo = new QAction(QIcon(":/images/textedit/editundo.png"), tr("&Undo"), this);
a = actionUndo = new QAction(QIcon(""), tr("&Undo"), this);
a->setShortcut(QKeySequence::Undo);
menu->addAction(a);
a = actionRedo = new QAction(QIcon(":/images/textedit/editredo.png"), tr("&Redo"), this);
a = actionRedo = new QAction(QIcon(""), tr("&Redo"), this);
a->setShortcut(QKeySequence::Redo);
menu->addAction(a);
menu->addSeparator();
a = actionCut = new QAction(QIcon(":/images/textedit/editcut.png"), tr("Cu&t"), this);
a = actionCut = new QAction(QIcon(""), tr("Cu&t"), this);
a->setShortcut(QKeySequence::Cut);
menu->addAction(a);
a = actionCopy = new QAction(QIcon(":/images/textedit/editcopy.png"), tr("&Copy"), this);
a = actionCopy = new QAction(QIcon(""), tr("&Copy"), this);
a->setShortcut(QKeySequence::Copy);
menu->addAction(a);
a = actionPaste = new QAction(QIcon(":/images/textedit/editpaste.png"), tr("&Paste"), this);
a = actionPaste = new QAction(QIcon(""), tr("&Paste"), this);
a->setShortcut(QKeySequence::Paste);
menu->addAction(a);
actionPaste->setEnabled(!QApplication::clipboard()->text().isEmpty());
@ -2431,9 +2429,9 @@ void MessageComposer::on_contactsdockWidget_visibilityChanged(bool visible)
void MessageComposer::updatecontactsviewicons()
{
if(!ui.contactsdockWidget->isVisible()){
ui.actionContactsView->setIcon(QIcon(":/images/contactsclosed24.png"));
ui.actionContactsView->setIcon(QIcon(":/icons/mail/contacts.png"));
}else{
ui.actionContactsView->setIcon(QIcon(":/images/contacts24.png"));
ui.actionContactsView->setIcon(QIcon(":/icons/mail/contacts.png"));
}
}

Some files were not shown because too many files have changed in this diff Show More