mirror of
https://github.com/RetroShare/RetroShare.git
synced 2025-02-02 18:44:53 -05:00
commit
ce6fb603c7
@ -48,7 +48,7 @@ public:
|
|||||||
TYPE_UPDATED = 0x07,
|
TYPE_UPDATED = 0x07,
|
||||||
TYPE_MESSAGE_DELETED = 0x08,
|
TYPE_MESSAGE_DELETED = 0x08,
|
||||||
TYPE_GROUP_DELETED = 0x09,
|
TYPE_GROUP_DELETED = 0x09,
|
||||||
};
|
};
|
||||||
|
|
||||||
virtual NotifyType getType() = 0;
|
virtual NotifyType getType() = 0;
|
||||||
|
|
||||||
|
@ -115,6 +115,7 @@ enum class RsPostedEventCode: uint8_t
|
|||||||
UPDATED_MESSAGE = 0x05,
|
UPDATED_MESSAGE = 0x05,
|
||||||
READ_STATUS_CHANGED = 0x06,
|
READ_STATUS_CHANGED = 0x06,
|
||||||
STATISTICS_CHANGED = 0x07,
|
STATISTICS_CHANGED = 0x07,
|
||||||
|
MESSAGE_VOTES_UPDATED = 0x08,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
@ -127,6 +128,7 @@ struct RsGxsPostedEvent: RsEvent
|
|||||||
RsPostedEventCode mPostedEventCode;
|
RsPostedEventCode mPostedEventCode;
|
||||||
RsGxsGroupId mPostedGroupId;
|
RsGxsGroupId mPostedGroupId;
|
||||||
RsGxsMessageId mPostedMsgId;
|
RsGxsMessageId mPostedMsgId;
|
||||||
|
RsGxsMessageId mPostedThreadId;
|
||||||
|
|
||||||
///* @see RsEvent @see RsSerializable
|
///* @see RsEvent @see RsSerializable
|
||||||
void serial_process( RsGenericSerializer::SerializeJob j,RsGenericSerializer::SerializeContext& ctx) override
|
void serial_process( RsGenericSerializer::SerializeJob j,RsGenericSerializer::SerializeContext& ctx) override
|
||||||
@ -172,7 +174,11 @@ public:
|
|||||||
|
|
||||||
virtual bool getBoardsServiceStatistics(GxsServiceStatistic& stat) =0;
|
virtual bool getBoardsServiceStatistics(GxsServiceStatistic& stat) =0;
|
||||||
|
|
||||||
enum RS_DEPRECATED RankType {TopRankType, HotRankType, NewRankType };
|
virtual bool voteForPost(bool up,const RsGxsGroupId& postGrpId,const RsGxsMessageId& postMsgId,const RsGxsId& voterId) =0;
|
||||||
|
|
||||||
|
virtual bool setPostReadStatus(const RsGxsGrpMsgIdPair& msgId, bool read) = 0;
|
||||||
|
|
||||||
|
enum RS_DEPRECATED RankType {TopRankType, HotRankType, NewRankType };
|
||||||
|
|
||||||
RS_DEPRECATED_FOR(getBoardsInfo)
|
RS_DEPRECATED_FOR(getBoardsInfo)
|
||||||
virtual bool getGroupData( const uint32_t& token,
|
virtual bool getGroupData( const uint32_t& token,
|
||||||
@ -201,8 +207,9 @@ public:
|
|||||||
//virtual bool createNewComment(uint32_t &token, RsGxsComment &comment) = 0;
|
//virtual bool createNewComment(uint32_t &token, RsGxsComment &comment) = 0;
|
||||||
//virtual bool createNewVote(uint32_t &token, RsGxsVote &vote) = 0;
|
//virtual bool createNewVote(uint32_t &token, RsGxsVote &vote) = 0;
|
||||||
|
|
||||||
|
RS_DEPRECATED_FOR(setPostReadStatus)
|
||||||
|
virtual void setMessageReadStatus(uint32_t& token, const RsGxsGrpMsgIdPair& msgId, bool read) = 0;
|
||||||
//////////////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////////////
|
||||||
virtual void setMessageReadStatus(uint32_t& token, const RsGxsGrpMsgIdPair& msgId, bool read) = 0;
|
|
||||||
|
|
||||||
virtual bool createGroup(uint32_t &token, RsPostedGroup &group) = 0;
|
virtual bool createGroup(uint32_t &token, RsPostedGroup &group) = 0;
|
||||||
virtual bool createPost(uint32_t &token, RsPostedPost &post) = 0;
|
virtual bool createPost(uint32_t &token, RsPostedPost &post) = 0;
|
||||||
|
@ -38,6 +38,7 @@
|
|||||||
/****
|
/****
|
||||||
* #define POSTBASE_DEBUG 1
|
* #define POSTBASE_DEBUG 1
|
||||||
****/
|
****/
|
||||||
|
#define POSTBASE_DEBUG 1
|
||||||
|
|
||||||
#define POSTBASE_BACKGROUND_PROCESSING 0x0002
|
#define POSTBASE_BACKGROUND_PROCESSING 0x0002
|
||||||
#define PROCESSING_START_PERIOD 30
|
#define PROCESSING_START_PERIOD 30
|
||||||
@ -88,101 +89,123 @@ void p3PostBase::notifyChanges(std::vector<RsGxsNotify *> &changes)
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
for(auto it = changes.begin(); it != changes.end(); ++it)
|
for(auto it = changes.begin(); it != changes.end(); ++it)
|
||||||
{
|
{
|
||||||
RsGxsMsgChange *msgChange = dynamic_cast<RsGxsMsgChange *>(*it);
|
RsGxsMsgChange *msgChange = dynamic_cast<RsGxsMsgChange *>(*it);
|
||||||
|
|
||||||
if (msgChange)
|
if(msgChange)
|
||||||
{
|
{
|
||||||
|
// To start with we are just going to trigger updates on these groups.
|
||||||
|
// FUTURE OPTIMISATION.
|
||||||
|
// It could be taken a step further and directly request these msgs for an update.
|
||||||
|
addGroupForProcessing(msgChange->mGroupId);
|
||||||
|
|
||||||
|
if (rsEvents)
|
||||||
|
{
|
||||||
|
switch(msgChange->getType())
|
||||||
|
{
|
||||||
|
case RsGxsNotify::TYPE_RECEIVED_NEW:
|
||||||
|
case RsGxsNotify::TYPE_PUBLISHED:
|
||||||
|
{
|
||||||
|
auto ev = std::make_shared<RsGxsPostedEvent>();
|
||||||
|
ev->mPostedMsgId = msgChange->mMsgId;
|
||||||
|
ev->mPostedThreadId = msgChange->mNewMsgItem->meta.mThreadId;
|
||||||
|
ev->mPostedGroupId = msgChange->mGroupId;
|
||||||
|
ev->mPostedEventCode = RsPostedEventCode::NEW_MESSAGE;
|
||||||
|
rsEvents->postEvent(ev);
|
||||||
#ifdef POSTBASE_DEBUG
|
#ifdef POSTBASE_DEBUG
|
||||||
std::cerr << "p3PostBase::notifyChanges() Found Message Change Notification";
|
std::cerr << "p3PostBase::notifyChanges() Found Message Change Notification: NEW/PUBLISHED ID=" << msgChange->mMsgId << " in group " << msgChange->mGroupId << ", thread ID = " << msgChange->mNewMsgItem->meta.mThreadId << std::endl;
|
||||||
std::cerr << std::endl;
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case RsGxsNotify::TYPE_PROCESSED:
|
||||||
|
{
|
||||||
|
auto ev = std::make_shared<RsGxsPostedEvent>();
|
||||||
|
ev->mPostedMsgId = msgChange->mMsgId;
|
||||||
|
ev->mPostedGroupId = msgChange->mGroupId;
|
||||||
|
ev->mPostedEventCode = RsPostedEventCode::MESSAGE_VOTES_UPDATED;
|
||||||
|
rsEvents->postEvent(ev);
|
||||||
#ifdef POSTBASE_DEBUG
|
#ifdef POSTBASE_DEBUG
|
||||||
std::cerr << "p3PostBase::notifyChanges() Msgs for Group: " << mit->first;
|
std::cerr << "p3PostBase::notifyChanges() Found Message Change Notification: PROCESSED ID=" << msgChange->mMsgId << " in group " << msgChange->mGroupId << std::endl;
|
||||||
std::cerr << std::endl;
|
|
||||||
#endif
|
#endif
|
||||||
// To start with we are just going to trigger updates on these groups.
|
}
|
||||||
// FUTURE OPTIMISATION.
|
break;
|
||||||
// It could be taken a step further and directly request these msgs for an update.
|
default:
|
||||||
addGroupForProcessing(msgChange->mGroupId);
|
|
||||||
|
|
||||||
if (rsEvents && (msgChange->getType() == RsGxsNotify::TYPE_RECEIVED_NEW || msgChange->getType() == RsGxsNotify::TYPE_PUBLISHED))
|
|
||||||
{
|
|
||||||
auto ev = std::make_shared<RsGxsPostedEvent>();
|
|
||||||
ev->mPostedMsgId = msgChange->mMsgId;
|
|
||||||
ev->mPostedGroupId = msgChange->mGroupId;
|
|
||||||
ev->mPostedEventCode = RsPostedEventCode::NEW_MESSAGE;
|
|
||||||
rsEvents->postEvent(ev);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
RsGxsGroupChange *grpChange = dynamic_cast<RsGxsGroupChange *>(*it);
|
|
||||||
|
|
||||||
/* pass on Group Changes to GUI */
|
|
||||||
if (grpChange && rsEvents)
|
|
||||||
{
|
|
||||||
#ifdef POSTBASE_DEBUG
|
#ifdef POSTBASE_DEBUG
|
||||||
std::cerr << "p3PostBase::notifyChanges() Found Group Change Notification";
|
std::cerr << "p3PostBase::notifyChanges() Found Message Change Notification: type " << msgChange->getType() << " (ignored) " << msgChange->mMsgId << std::endl;
|
||||||
std::cerr << std::endl;
|
#endif
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
RsGxsGroupChange *grpChange = dynamic_cast<RsGxsGroupChange *>(*it);
|
||||||
|
|
||||||
|
/* pass on Group Changes to GUI */
|
||||||
|
if (grpChange && rsEvents)
|
||||||
|
{
|
||||||
|
#ifdef POSTBASE_DEBUG
|
||||||
|
std::cerr << "p3PostBase::notifyChanges() Found Group Change Notification";
|
||||||
|
std::cerr << std::endl;
|
||||||
#endif
|
#endif
|
||||||
const RsGxsGroupId& group_id(grpChange->mGroupId);
|
const RsGxsGroupId& group_id(grpChange->mGroupId);
|
||||||
|
|
||||||
switch(grpChange->getType())
|
switch(grpChange->getType())
|
||||||
{
|
{
|
||||||
case RsGxsNotify::TYPE_PROCESSED: // happens when the group is subscribed
|
case RsGxsNotify::TYPE_PROCESSED: // happens when the group is subscribed
|
||||||
{
|
{
|
||||||
auto ev = std::make_shared<RsGxsPostedEvent>();
|
auto ev = std::make_shared<RsGxsPostedEvent>();
|
||||||
ev->mPostedGroupId = group_id;
|
ev->mPostedGroupId = group_id;
|
||||||
ev->mPostedEventCode = RsPostedEventCode::SUBSCRIBE_STATUS_CHANGED;
|
ev->mPostedEventCode = RsPostedEventCode::SUBSCRIBE_STATUS_CHANGED;
|
||||||
rsEvents->postEvent(ev);
|
rsEvents->postEvent(ev);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case RsGxsNotify::TYPE_STATISTICS_CHANGED:
|
case RsGxsNotify::TYPE_STATISTICS_CHANGED:
|
||||||
{
|
{
|
||||||
auto ev = std::make_shared<RsGxsPostedEvent>();
|
auto ev = std::make_shared<RsGxsPostedEvent>();
|
||||||
ev->mPostedGroupId = group_id;
|
ev->mPostedGroupId = group_id;
|
||||||
ev->mPostedEventCode = RsPostedEventCode::STATISTICS_CHANGED;
|
ev->mPostedEventCode = RsPostedEventCode::STATISTICS_CHANGED;
|
||||||
rsEvents->postEvent(ev);
|
rsEvents->postEvent(ev);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case RsGxsNotify::TYPE_PUBLISHED:
|
case RsGxsNotify::TYPE_PUBLISHED:
|
||||||
case RsGxsNotify::TYPE_RECEIVED_NEW:
|
case RsGxsNotify::TYPE_RECEIVED_NEW:
|
||||||
{
|
{
|
||||||
/* group received */
|
/* group received */
|
||||||
|
|
||||||
if(mKnownPosted.find(group_id) == mKnownPosted.end())
|
if(mKnownPosted.find(group_id) == mKnownPosted.end())
|
||||||
{
|
{
|
||||||
mKnownPosted.insert(std::make_pair(group_id, time(nullptr)));
|
mKnownPosted.insert(std::make_pair(group_id, time(nullptr)));
|
||||||
IndicateConfigChanged();
|
IndicateConfigChanged();
|
||||||
|
|
||||||
auto ev = std::make_shared<RsGxsPostedEvent>();
|
auto ev = std::make_shared<RsGxsPostedEvent>();
|
||||||
ev->mPostedGroupId = group_id;
|
ev->mPostedGroupId = group_id;
|
||||||
ev->mPostedEventCode = RsPostedEventCode::NEW_POSTED_GROUP;
|
ev->mPostedEventCode = RsPostedEventCode::NEW_POSTED_GROUP;
|
||||||
rsEvents->postEvent(ev);
|
rsEvents->postEvent(ev);
|
||||||
|
|
||||||
#ifdef POSTBASE_DEBUG
|
#ifdef POSTBASE_DEBUG
|
||||||
std::cerr << "p3PostBase::notifyChanges() Incoming Group: " << group_id;
|
std::cerr << "p3PostBase::notifyChanges() Incoming Group: " << group_id;
|
||||||
std::cerr << std::endl;
|
std::cerr << std::endl;
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
RsInfo() << __PRETTY_FUNCTION__
|
RsInfo() << __PRETTY_FUNCTION__
|
||||||
<< " Not notifying already known forum "
|
<< " Not notifying already known forum "
|
||||||
<< group_id << std::endl;
|
<< group_id << std::endl;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
RsErr() << " Got a GXS event of type " << grpChange->getType() << " Currently not handled." << std::endl;
|
RsErr() << " Got a GXS event of type " << grpChange->getType() << " Currently not handled." << std::endl;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
delete *it;
|
delete *it;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void p3PostBase::service_tick()
|
void p3PostBase::service_tick()
|
||||||
|
@ -442,6 +442,57 @@ bool p3Posted::createBoard(RsPostedGroup& board)
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool p3Posted::voteForPost(bool up,const RsGxsGroupId& postGrpId,const RsGxsMessageId& postMsgId,const RsGxsId& authorId)
|
||||||
|
{
|
||||||
|
// Do some basic tests
|
||||||
|
|
||||||
|
if(!rsIdentity->isOwnId(authorId)) // This is ruled out before waitToken complains. Not sure it's needed.
|
||||||
|
{
|
||||||
|
std::cerr << __PRETTY_FUNCTION__ << ": vote submitted with an ID that is not yours! This cannot work." << std::endl;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
RsGxsVote vote;
|
||||||
|
|
||||||
|
vote.mMeta.mGroupId = postGrpId;
|
||||||
|
vote.mMeta.mThreadId = postMsgId;
|
||||||
|
vote.mMeta.mParentId = postMsgId;
|
||||||
|
vote.mMeta.mAuthorId = authorId;
|
||||||
|
|
||||||
|
if (up)
|
||||||
|
vote.mVoteType = GXS_VOTE_UP;
|
||||||
|
else
|
||||||
|
vote.mVoteType = GXS_VOTE_DOWN;
|
||||||
|
|
||||||
|
uint32_t token;
|
||||||
|
|
||||||
|
if(!createNewVote(token, vote))
|
||||||
|
{
|
||||||
|
std::cerr << __PRETTY_FUNCTION__ << " Error! Failed submitting vote to (group,msg) " << postGrpId << "," << postMsgId << " from author " << authorId << std::endl;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(waitToken(token) != RsTokenService::COMPLETE)
|
||||||
|
{
|
||||||
|
std::cerr << __PRETTY_FUNCTION__ << " Error! GXS operation failed." << std::endl;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool p3Posted::setPostReadStatus(const RsGxsGrpMsgIdPair& msgId, bool read)
|
||||||
|
{
|
||||||
|
uint32_t token;
|
||||||
|
|
||||||
|
setMessageReadStatus(token,msgId,read);
|
||||||
|
|
||||||
|
if(waitToken(token) != RsTokenService::COMPLETE)
|
||||||
|
{
|
||||||
|
std::cerr << __PRETTY_FUNCTION__ << " Error! GXS operation failed." << std::endl;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
bool p3Posted::editBoard(RsPostedGroup& board)
|
bool p3Posted::editBoard(RsPostedGroup& board)
|
||||||
{
|
{
|
||||||
uint32_t token;
|
uint32_t token;
|
||||||
|
@ -84,7 +84,11 @@ virtual void receiveHelperChanges(std::vector<RsGxsNotify*>& changes)
|
|||||||
|
|
||||||
bool createBoard(RsPostedGroup& board) override;
|
bool createBoard(RsPostedGroup& board) override;
|
||||||
|
|
||||||
virtual bool getGroupData(const uint32_t &token, std::vector<RsPostedGroup> &groups) override;
|
bool voteForPost(bool up,const RsGxsGroupId& postGrpId,const RsGxsMessageId& postMsgId,const RsGxsId& voterId) override;
|
||||||
|
|
||||||
|
bool setPostReadStatus(const RsGxsGrpMsgIdPair& msgId, bool read) override;
|
||||||
|
|
||||||
|
virtual bool getGroupData(const uint32_t &token, std::vector<RsPostedGroup> &groups) override;
|
||||||
virtual bool getPostData(const uint32_t &token, std::vector<RsPostedPost> &posts, std::vector<RsGxsComment> &cmts, std::vector<RsGxsVote> &vots) override;
|
virtual bool getPostData(const uint32_t &token, std::vector<RsPostedPost> &posts, std::vector<RsGxsComment> &cmts, std::vector<RsGxsVote> &vots) override;
|
||||||
virtual bool getPostData(const uint32_t &token, std::vector<RsPostedPost> &posts, std::vector<RsGxsComment> &cmts) override;
|
virtual bool getPostData(const uint32_t &token, std::vector<RsPostedPost> &posts, std::vector<RsGxsComment> &cmts) override;
|
||||||
virtual bool getPostData(const uint32_t &token, std::vector<RsPostedPost> &posts) override;
|
virtual bool getPostData(const uint32_t &token, std::vector<RsPostedPost> &posts) override;
|
||||||
@ -126,17 +130,17 @@ virtual void setMessageReadStatus(uint32_t& token, const RsGxsGrpMsgIdPair& msgI
|
|||||||
return mCommentService->createGxsComment(token, msg) && waitToken(token) == RsTokenService::COMPLETE ;
|
return mCommentService->createGxsComment(token, msg) && waitToken(token) == RsTokenService::COMPLETE ;
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual bool createNewVote(uint32_t &token, RsGxsVote &msg)
|
virtual bool createNewVote(uint32_t &token, RsGxsVote &msg) override
|
||||||
{
|
{
|
||||||
return mCommentService->createGxsVote(token, msg);
|
return mCommentService->createGxsVote(token, msg);
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual bool acknowledgeComment(
|
virtual bool acknowledgeComment(
|
||||||
uint32_t token, std::pair<RsGxsGroupId, RsGxsMessageId>& msgId )
|
uint32_t token, std::pair<RsGxsGroupId, RsGxsMessageId>& msgId ) override
|
||||||
{ return acknowledgeMsg(token, msgId); }
|
{ return acknowledgeMsg(token, msgId); }
|
||||||
|
|
||||||
virtual bool acknowledgeVote(
|
virtual bool acknowledgeVote(
|
||||||
uint32_t token, std::pair<RsGxsGroupId, RsGxsMessageId>& msgId )
|
uint32_t token, std::pair<RsGxsGroupId, RsGxsMessageId>& msgId ) override
|
||||||
{
|
{
|
||||||
if (mCommentService->acknowledgeVote(token, msgId)) return true;
|
if (mCommentService->acknowledgeVote(token, msgId)) return true;
|
||||||
return acknowledgeMsg(token, msgId);
|
return acknowledgeMsg(token, msgId);
|
||||||
|
@ -268,7 +268,7 @@
|
|||||||
</widget>
|
</widget>
|
||||||
<widget class="QTabWidget" name="rightTabWidget">
|
<widget class="QTabWidget" name="rightTabWidget">
|
||||||
<property name="currentIndex">
|
<property name="currentIndex">
|
||||||
<number>1</number>
|
<number>0</number>
|
||||||
</property>
|
</property>
|
||||||
<widget class="QWidget" name="personTab">
|
<widget class="QWidget" name="personTab">
|
||||||
<attribute name="icon">
|
<attribute name="icon">
|
||||||
@ -289,8 +289,8 @@
|
|||||||
<rect>
|
<rect>
|
||||||
<x>0</x>
|
<x>0</x>
|
||||||
<y>0</y>
|
<y>0</y>
|
||||||
<width>1372</width>
|
<width>634</width>
|
||||||
<height>719</height>
|
<height>523</height>
|
||||||
</rect>
|
</rect>
|
||||||
</property>
|
</property>
|
||||||
<layout class="QVBoxLayout" name="scrollAreaWidgetContentsVLayout">
|
<layout class="QVBoxLayout" name="scrollAreaWidgetContentsVLayout">
|
||||||
@ -1031,7 +1031,7 @@ border-image: url(:/images/closepressed.png)
|
|||||||
</layout>
|
</layout>
|
||||||
<action name="editIdentity">
|
<action name="editIdentity">
|
||||||
<property name="icon">
|
<property name="icon">
|
||||||
<iconset resource="../images.qrc">
|
<iconset>
|
||||||
<normaloff>:/images/edit_16.png</normaloff>:/images/edit_16.png</iconset>
|
<normaloff>:/images/edit_16.png</normaloff>:/images/edit_16.png</iconset>
|
||||||
</property>
|
</property>
|
||||||
<property name="text">
|
<property name="text">
|
||||||
|
511
retroshare-gui/src/gui/Posted/BoardPostDisplayWidget.cpp
Normal file
511
retroshare-gui/src/gui/Posted/BoardPostDisplayWidget.cpp
Normal file
@ -0,0 +1,511 @@
|
|||||||
|
/*******************************************************************************
|
||||||
|
* retroshare-gui/src/gui/Posted/BoardPostDisplayWidget.cpp *
|
||||||
|
* *
|
||||||
|
* Copyright (C) 2019 Retroshare Team <retroshare.project@gmail.com> *
|
||||||
|
* *
|
||||||
|
* This program is free software: you can redistribute it and/or modify *
|
||||||
|
* it under the terms of the GNU Affero General Public License as *
|
||||||
|
* published by the Free Software Foundation, either version 3 of the *
|
||||||
|
* License, or (at your option) any later version. *
|
||||||
|
* *
|
||||||
|
* This program is distributed in the hope that it will be useful, *
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
|
||||||
|
* GNU Affero General Public License for more details. *
|
||||||
|
* *
|
||||||
|
* You should have received a copy of the GNU Affero General Public License *
|
||||||
|
* along with this program. If not, see <https://www.gnu.org/licenses/>. *
|
||||||
|
* *
|
||||||
|
*******************************************************************************/
|
||||||
|
|
||||||
|
#include <QDateTime>
|
||||||
|
#include <QMenu>
|
||||||
|
#include <QStyle>
|
||||||
|
#include <QTextDocument>
|
||||||
|
#include <QToolButton>
|
||||||
|
|
||||||
|
#include "rshare.h"
|
||||||
|
#include "BoardPostDisplayWidget.h"
|
||||||
|
#include "PhotoView.h"
|
||||||
|
#include "gui/gxs/GxsIdDetails.h"
|
||||||
|
#include "util/misc.h"
|
||||||
|
#include "gui/common/FilesDefs.h"
|
||||||
|
#include "util/qtthreadsutils.h"
|
||||||
|
#include "util/HandleRichText.h"
|
||||||
|
#include "gui/Identity/IdDialog.h"
|
||||||
|
#include "gui/MainWindow.h"
|
||||||
|
|
||||||
|
#include "ui_BoardPostDisplayWidget_compact.h"
|
||||||
|
#include "ui_BoardPostDisplayWidget_card.h"
|
||||||
|
|
||||||
|
#include <retroshare/rsposted.h>
|
||||||
|
#include <iostream>
|
||||||
|
|
||||||
|
#define LINK_IMAGE ":/images/thumb-link.png"
|
||||||
|
|
||||||
|
// #ifdef DEBUG_BOARDPOSTDISPLAYWIDGET 1
|
||||||
|
|
||||||
|
/** Constructor */
|
||||||
|
|
||||||
|
const char *BoardPostDisplayWidget_compact::DEFAULT_BOARD_IMAGE = ":/icons/png/newsfeed2.png";
|
||||||
|
|
||||||
|
//===================================================================================================================================
|
||||||
|
//== Base class BoardPostDisplayWidgetBase ==
|
||||||
|
//===================================================================================================================================
|
||||||
|
|
||||||
|
BoardPostDisplayWidgetBase::BoardPostDisplayWidgetBase(const RsPostedPost& post,uint8_t display_flags,QWidget *parent)
|
||||||
|
: QWidget(parent), mPost(post),mDisplayFlags(display_flags)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void BoardPostDisplayWidgetBase::setCommentsSize(int comNb)
|
||||||
|
{
|
||||||
|
QString sComButText ;
|
||||||
|
|
||||||
|
if (comNb == 1)
|
||||||
|
sComButText = tr("1 comment");
|
||||||
|
else if(comNb > 1)
|
||||||
|
sComButText = tr("%1 comments").arg(comNb);
|
||||||
|
else
|
||||||
|
sComButText = tr("No comments yet. Click to add one.");
|
||||||
|
|
||||||
|
commentButton()->setToolTip(sComButText);
|
||||||
|
|
||||||
|
if(comNb > 0)
|
||||||
|
commentButton()->setIcon(FilesDefs::getIconFromQtResourcePath(":/images/comments_blue.png"));
|
||||||
|
else
|
||||||
|
commentButton()->setIcon(FilesDefs::getIconFromQtResourcePath(":/images/comments.png"));
|
||||||
|
|
||||||
|
// QString sComButText = tr("Comment");
|
||||||
|
// if (comNb == 1)
|
||||||
|
// sComButText = sComButText.append("(1)");
|
||||||
|
// else if(comNb > 1)
|
||||||
|
// sComButText = tr("Comments ").append("(%1)").arg(comNb);
|
||||||
|
//
|
||||||
|
commentButton()->setText(tr("Comments"));
|
||||||
|
}
|
||||||
|
|
||||||
|
void BoardPostDisplayWidgetBase::makeDownVote()
|
||||||
|
{
|
||||||
|
RsGxsGrpMsgIdPair msgId;
|
||||||
|
msgId.first = mPost.mMeta.mGroupId;
|
||||||
|
msgId.second = mPost.mMeta.mMsgId;
|
||||||
|
|
||||||
|
voteUpButton()->setEnabled(false);
|
||||||
|
voteDownButton()->setEnabled(false);
|
||||||
|
|
||||||
|
emit vote(msgId, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
void BoardPostDisplayWidgetBase::makeUpVote()
|
||||||
|
{
|
||||||
|
RsGxsGrpMsgIdPair msgId;
|
||||||
|
msgId.first = mPost.mMeta.mGroupId;
|
||||||
|
msgId.second = mPost.mMeta.mMsgId;
|
||||||
|
|
||||||
|
voteUpButton()->setEnabled(false);
|
||||||
|
voteDownButton()->setEnabled(false);
|
||||||
|
|
||||||
|
emit vote(msgId, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
void BoardPostDisplayWidgetBase::setReadStatus(bool isNew, bool isUnread)
|
||||||
|
{
|
||||||
|
if (isUnread)
|
||||||
|
readButton()->setIcon(FilesDefs::getIconFromQtResourcePath(":/images/message-state-unread.png"));
|
||||||
|
else
|
||||||
|
readButton()->setIcon(FilesDefs::getIconFromQtResourcePath(":/images/message-state-read.png"));
|
||||||
|
|
||||||
|
newLabel()->setVisible(isNew);
|
||||||
|
|
||||||
|
mainFrame()->setProperty("new", isNew);
|
||||||
|
mainFrame()->style()->unpolish(mainFrame());
|
||||||
|
mainFrame()->style()->polish(mainFrame());
|
||||||
|
}
|
||||||
|
|
||||||
|
void BoardPostDisplayWidget_compact::doExpand(bool e)
|
||||||
|
{
|
||||||
|
#ifdef DEBUG_BOARDPOSTDISPLAYWIDGET
|
||||||
|
std::cerr << "Expanding" << std::endl;
|
||||||
|
#endif
|
||||||
|
if(e)
|
||||||
|
ui->frame_notes->show();
|
||||||
|
else
|
||||||
|
ui->frame_notes->hide();
|
||||||
|
|
||||||
|
emit expand(mPost.mMeta.mMsgId,e);
|
||||||
|
}
|
||||||
|
|
||||||
|
void BoardPostDisplayWidgetBase::loadComments(bool e)
|
||||||
|
{
|
||||||
|
emit commentsRequested(mPost.mMeta.mMsgId,e);
|
||||||
|
}
|
||||||
|
|
||||||
|
void BoardPostDisplayWidgetBase::readToggled()
|
||||||
|
{
|
||||||
|
bool s = IS_MSG_UNREAD(mPost.mMeta.mMsgStatus);
|
||||||
|
|
||||||
|
emit changeReadStatusRequested(mPost.mMeta.mMsgId,s);
|
||||||
|
}
|
||||||
|
|
||||||
|
void BoardPostDisplayWidgetBase::setup()
|
||||||
|
{
|
||||||
|
// show/hide things based on the view type
|
||||||
|
|
||||||
|
if(!(mDisplayFlags & SHOW_COMMENTS))
|
||||||
|
commentButton()->setChecked(false);
|
||||||
|
else
|
||||||
|
commentButton()->setChecked(true);
|
||||||
|
|
||||||
|
/* clear ui */
|
||||||
|
titleLabel()->setText(tr("Loading"));
|
||||||
|
dateLabel()->clear();
|
||||||
|
fromLabel()->clear();
|
||||||
|
siteLabel()->clear();
|
||||||
|
|
||||||
|
QObject::connect(commentButton(), SIGNAL(toggled(bool)), this, SLOT(loadComments(bool)));
|
||||||
|
QObject::connect(voteUpButton(), SIGNAL(clicked()), this, SLOT(makeUpVote()));
|
||||||
|
QObject::connect(voteDownButton(), SIGNAL(clicked()), this, SLOT(makeDownVote()));
|
||||||
|
QObject::connect(readButton(), SIGNAL(clicked()), this, SLOT(readToggled()));
|
||||||
|
|
||||||
|
QAction *CopyLinkAction = new QAction(QIcon(""),tr("Copy RetroShare Link"), this);
|
||||||
|
connect(CopyLinkAction, SIGNAL(triggered()), this, SLOT(handleCopyLinkClicked()));
|
||||||
|
|
||||||
|
int S = QFontMetricsF(font()).height() ;
|
||||||
|
|
||||||
|
readButton()->setChecked(false);
|
||||||
|
|
||||||
|
QMenu *menu = new QMenu();
|
||||||
|
menu->addAction(CopyLinkAction);
|
||||||
|
menu->addSeparator();
|
||||||
|
shareButton()->setMenu(menu);
|
||||||
|
|
||||||
|
connect(shareButton(),SIGNAL(pressed()),this,SLOT(handleShareButtonClicked()));
|
||||||
|
|
||||||
|
RsReputationLevel overall_reputation = rsReputations->overallReputationLevel(mPost.mMeta.mAuthorId);
|
||||||
|
bool redacted = (overall_reputation == RsReputationLevel::LOCALLY_NEGATIVE);
|
||||||
|
|
||||||
|
if(redacted)
|
||||||
|
{
|
||||||
|
commentButton()->setDisabled(true);
|
||||||
|
voteUpButton()->setDisabled(true);
|
||||||
|
voteDownButton()->setDisabled(true);
|
||||||
|
fromLabel()->setId(mPost.mMeta.mAuthorId);
|
||||||
|
titleLabel()->setText(tr( "<p><font color=\"#ff0000\"><b>The author of this message (with ID %1) is banned.</b>").arg(QString::fromStdString(mPost.mMeta.mAuthorId.toStdString()))) ;
|
||||||
|
QDateTime qtime;
|
||||||
|
qtime.setTime_t(mPost.mMeta.mPublishTs);
|
||||||
|
QString timestamp = qtime.toString("hh:mm dd-MMM-yyyy");
|
||||||
|
dateLabel()->setText(timestamp);
|
||||||
|
pictureLabel()->setDisabled(true);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
QPixmap sqpixmap2 = FilesDefs::getPixmapFromQtResourcePath(":/images/thumb-default.png");
|
||||||
|
|
||||||
|
QDateTime qtime;
|
||||||
|
qtime.setTime_t(mPost.mMeta.mPublishTs);
|
||||||
|
QString timestamp = qtime.toString("hh:mm dd-MMM-yyyy");
|
||||||
|
QString timestamp2 = misc::timeRelativeToNow(mPost.mMeta.mPublishTs) + " " + tr("ago");
|
||||||
|
dateLabel()->setText(timestamp2);
|
||||||
|
dateLabel()->setToolTip(timestamp);
|
||||||
|
|
||||||
|
fromLabel()->setId(mPost.mMeta.mAuthorId);
|
||||||
|
|
||||||
|
// Use QUrl to check/parse our URL
|
||||||
|
// The only combination that seems to work: load as EncodedUrl, extract toEncoded().
|
||||||
|
QByteArray urlarray(mPost.mLink.c_str());
|
||||||
|
QUrl url = QUrl::fromEncoded(urlarray.trimmed());
|
||||||
|
QString urlstr = "Invalid Link";
|
||||||
|
QString sitestr = "Invalid Link";
|
||||||
|
|
||||||
|
bool urlOkay = url.isValid();
|
||||||
|
if (urlOkay)
|
||||||
|
{
|
||||||
|
QString scheme = url.scheme();
|
||||||
|
if ((scheme != "https")
|
||||||
|
&& (scheme != "http")
|
||||||
|
&& (scheme != "ftp")
|
||||||
|
&& (scheme != "retroshare"))
|
||||||
|
{
|
||||||
|
urlOkay = false;
|
||||||
|
sitestr = "Invalid Link Scheme";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (urlOkay)
|
||||||
|
{
|
||||||
|
urlstr = QString("<a href=\"");
|
||||||
|
urlstr += QString(url.toEncoded());
|
||||||
|
urlstr += QString("\" ><span style=\" text-decoration: underline; color:#2255AA;\"> ");
|
||||||
|
urlstr += QString::fromUtf8(mPost.mMeta.mMsgName.c_str());
|
||||||
|
urlstr += QString(" </span></a>");
|
||||||
|
|
||||||
|
QString siteurl = url.toEncoded();
|
||||||
|
sitestr = QString("<a href=\"%1\" ><span style=\" text-decoration: underline; color:#0079d3;\"> %2 </span></a>").arg(siteurl).arg(siteurl);
|
||||||
|
|
||||||
|
titleLabel()->setText(urlstr);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
titleLabel()->setText( QString::fromUtf8(mPost.mMeta.mMsgName.c_str()) );
|
||||||
|
|
||||||
|
if (urlarray.isEmpty())
|
||||||
|
siteLabel()->hide();
|
||||||
|
|
||||||
|
siteLabel()->setText(sitestr);
|
||||||
|
}
|
||||||
|
|
||||||
|
//QString score = "Hot" + QString::number(post.mHotScore);
|
||||||
|
//score += " Top" + QString::number(post.mTopScore);
|
||||||
|
//score += " New" + QString::number(post.mNewScore);
|
||||||
|
|
||||||
|
QString score = QString::number(mPost.mTopScore);
|
||||||
|
|
||||||
|
scoreLabel()->setText(score);
|
||||||
|
|
||||||
|
// FIX THIS UP LATER.
|
||||||
|
notes()->setText(RsHtml().formatText(NULL, QString::fromUtf8(mPost.mNotes.c_str()), RSHTML_FORMATTEXT_EMBED_SMILEYS | RSHTML_FORMATTEXT_EMBED_LINKS));
|
||||||
|
pictureLabel()->setText(RsHtml().formatText(NULL, QString::fromUtf8(mPost.mNotes.c_str()), RSHTML_FORMATTEXT_EMBED_SMILEYS | RSHTML_FORMATTEXT_EMBED_LINKS));
|
||||||
|
|
||||||
|
// feed.
|
||||||
|
//frame_comment->show();
|
||||||
|
commentButton()->show();
|
||||||
|
|
||||||
|
setCommentsSize(mPost.mComments);
|
||||||
|
|
||||||
|
setReadStatus(IS_MSG_NEW(mPost.mMeta.mMsgStatus), IS_MSG_UNREAD(mPost.mMeta.mMsgStatus) || IS_MSG_NEW(mPost.mMeta.mMsgStatus));
|
||||||
|
|
||||||
|
// disable voting buttons - if they have already voted.
|
||||||
|
if (mPost.mMeta.mMsgStatus & GXS_SERV::GXS_MSG_STATUS_VOTE_MASK)
|
||||||
|
{
|
||||||
|
voteUpButton()->setEnabled(false);
|
||||||
|
voteDownButton()->setEnabled(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
connect(pictureLabel(), SIGNAL(clicked()), this, SLOT(viewPicture()));
|
||||||
|
|
||||||
|
#ifdef TODO
|
||||||
|
emit sizeChanged(this);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
void BoardPostDisplayWidgetBase::handleShareButtonClicked()
|
||||||
|
{
|
||||||
|
emit shareButtonClicked();
|
||||||
|
}
|
||||||
|
|
||||||
|
void BoardPostDisplayWidgetBase::handleCopyLinkClicked()
|
||||||
|
{
|
||||||
|
emit copylinkClicked();
|
||||||
|
}
|
||||||
|
//===================================================================================================================================
|
||||||
|
//== class BoardPostDisplayWidget ==
|
||||||
|
//===================================================================================================================================
|
||||||
|
|
||||||
|
BoardPostDisplayWidget_compact::BoardPostDisplayWidget_compact(const RsPostedPost& post, uint8_t display_flags,QWidget *parent=nullptr)
|
||||||
|
: BoardPostDisplayWidgetBase(post,display_flags,parent), ui(new Ui::BoardPostDisplayWidget_compact())
|
||||||
|
{
|
||||||
|
ui->setupUi(this);
|
||||||
|
setup();
|
||||||
|
|
||||||
|
ui->verticalLayout->addStretch();
|
||||||
|
ui->verticalLayout->setAlignment(Qt::AlignTop);
|
||||||
|
ui->topLayout->setAlignment(Qt::AlignTop);
|
||||||
|
ui->arrowsLayout->addStretch();
|
||||||
|
ui->arrowsLayout->setAlignment(Qt::AlignTop);
|
||||||
|
ui->verticalLayout_2->addStretch();
|
||||||
|
|
||||||
|
adjustSize();
|
||||||
|
}
|
||||||
|
|
||||||
|
BoardPostDisplayWidget_compact::~BoardPostDisplayWidget_compact()
|
||||||
|
{
|
||||||
|
delete ui;
|
||||||
|
}
|
||||||
|
|
||||||
|
void BoardPostDisplayWidget_compact::setup()
|
||||||
|
{
|
||||||
|
BoardPostDisplayWidgetBase::setup();
|
||||||
|
|
||||||
|
// show/hide things based on the view type
|
||||||
|
|
||||||
|
setAttribute(Qt::WA_DeleteOnClose, true);
|
||||||
|
ui->pictureLabel->setEnableZoom(false);
|
||||||
|
|
||||||
|
RsReputationLevel overall_reputation = rsReputations->overallReputationLevel(mPost.mMeta.mAuthorId);
|
||||||
|
bool redacted = (overall_reputation == RsReputationLevel::LOCALLY_NEGATIVE);
|
||||||
|
|
||||||
|
int desired_height = QFontMetricsF(font()).height() * 5;
|
||||||
|
ui->pictureLabel->setFixedSize(16/9.0*desired_height,desired_height);
|
||||||
|
|
||||||
|
if(redacted)
|
||||||
|
{
|
||||||
|
ui->pictureLabel->setPicture( FilesDefs::getPixmapFromQtResourcePath(":/images/thumb-blocked.png") );
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if(mPost.mImage.mData != NULL)
|
||||||
|
{
|
||||||
|
QPixmap pixmap;
|
||||||
|
GxsIdDetails::loadPixmapFromData(mPost.mImage.mData, mPost.mImage.mSize, pixmap,GxsIdDetails::ORIGINAL);
|
||||||
|
// Wiping data - as its been passed to thumbnail.
|
||||||
|
|
||||||
|
#ifdef DEBUG_BOARDPOSTDISPLAYWIDGET
|
||||||
|
std::cerr << "Got pixmap of size " << pixmap.width() << " x " << pixmap.height() << std::endl;
|
||||||
|
std::cerr << "Saving to pix.png" << std::endl;
|
||||||
|
pixmap.save("pix.png","PNG");
|
||||||
|
#endif
|
||||||
|
|
||||||
|
ui->pictureLabel->setPicture(pixmap);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
ui->pictureLabel->setPicture( FilesDefs::getPixmapFromQtResourcePath(":/images/thumb-default.png") );
|
||||||
|
}
|
||||||
|
|
||||||
|
ui->notes->setText(RsHtml().formatText(NULL, QString::fromUtf8(mPost.mNotes.c_str()), RSHTML_FORMATTEXT_EMBED_SMILEYS | RSHTML_FORMATTEXT_EMBED_LINKS));
|
||||||
|
|
||||||
|
QObject::connect(ui->expandButton, SIGNAL(toggled(bool)), this, SLOT(doExpand(bool)));
|
||||||
|
|
||||||
|
QTextDocument doc;
|
||||||
|
doc.setHtml(notes()->text());
|
||||||
|
|
||||||
|
if(mDisplayFlags & SHOW_NOTES)
|
||||||
|
{
|
||||||
|
ui->frame_notes->show();
|
||||||
|
ui->expandButton->setChecked(true);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
ui->frame_notes->hide();
|
||||||
|
ui->expandButton->setChecked(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
if(doc.toPlainText().trimmed().isEmpty())
|
||||||
|
{
|
||||||
|
ui->frame_notes->hide();
|
||||||
|
ui->expandButton->hide();
|
||||||
|
}
|
||||||
|
updateGeometry();
|
||||||
|
|
||||||
|
#ifdef TODO
|
||||||
|
emit sizeChanged(this);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
void BoardPostDisplayWidget_compact::viewPicture()
|
||||||
|
{
|
||||||
|
if(mPost.mImage.mData == NULL)
|
||||||
|
return;
|
||||||
|
|
||||||
|
QString timestamp = misc::timeRelativeToNow(mPost.mMeta.mPublishTs);
|
||||||
|
QPixmap pixmap;
|
||||||
|
GxsIdDetails::loadPixmapFromData(mPost.mImage.mData, mPost.mImage.mSize, pixmap,GxsIdDetails::ORIGINAL);
|
||||||
|
RsGxsId authorID = mPost.mMeta.mAuthorId;
|
||||||
|
|
||||||
|
PhotoView *PView = new PhotoView();
|
||||||
|
|
||||||
|
PView->setPixmap(pixmap);
|
||||||
|
PView->setTitle(QString::fromUtf8(mPost.mMeta.mMsgName.c_str()));
|
||||||
|
PView->setName(authorID);
|
||||||
|
PView->setTime(timestamp);
|
||||||
|
PView->setGroupId(mPost.mMeta.mGroupId);
|
||||||
|
PView->setMessageId(mPost.mMeta.mMsgId);
|
||||||
|
|
||||||
|
PView->show();
|
||||||
|
|
||||||
|
emit thumbnailOpenned();
|
||||||
|
}
|
||||||
|
|
||||||
|
QToolButton *BoardPostDisplayWidget_compact::voteUpButton() { return ui->voteUpButton; }
|
||||||
|
QToolButton *BoardPostDisplayWidget_compact::commentButton() { return ui->commentButton; }
|
||||||
|
QToolButton *BoardPostDisplayWidget_compact::voteDownButton() { return ui->voteDownButton; }
|
||||||
|
QLabel *BoardPostDisplayWidget_compact::newLabel() { return ui->newLabel; }
|
||||||
|
QToolButton *BoardPostDisplayWidget_compact::readButton() { return ui->readButton; }
|
||||||
|
QLabel *BoardPostDisplayWidget_compact::siteLabel() { return ui->siteLabel; }
|
||||||
|
GxsIdLabel *BoardPostDisplayWidget_compact::fromLabel() { return ui->fromLabel; }
|
||||||
|
QLabel *BoardPostDisplayWidget_compact::dateLabel() { return ui->dateLabel; }
|
||||||
|
QLabel *BoardPostDisplayWidget_compact::titleLabel() { return ui->titleLabel; }
|
||||||
|
QLabel *BoardPostDisplayWidget_compact::scoreLabel() { return ui->scoreLabel; }
|
||||||
|
QLabel *BoardPostDisplayWidget_compact::notes() { return ui->notes; }
|
||||||
|
QPushButton *BoardPostDisplayWidget_compact::shareButton() { return ui->shareButton; }
|
||||||
|
QLabel *BoardPostDisplayWidget_compact::pictureLabel() { return ui->pictureLabel; }
|
||||||
|
QFrame *BoardPostDisplayWidget_compact::mainFrame() { return ui->mainFrame; }
|
||||||
|
|
||||||
|
//===================================================================================================================================
|
||||||
|
//== class BoardPostDisplayWidget_card ==
|
||||||
|
//===================================================================================================================================
|
||||||
|
|
||||||
|
BoardPostDisplayWidget_card::BoardPostDisplayWidget_card(const RsPostedPost& post, uint8_t display_flags, QWidget *parent)
|
||||||
|
: BoardPostDisplayWidgetBase(post,display_flags,parent), ui(new Ui::BoardPostDisplayWidget_card())
|
||||||
|
{
|
||||||
|
ui->setupUi(this);
|
||||||
|
setup();
|
||||||
|
|
||||||
|
ui->verticalLayout->addStretch();
|
||||||
|
ui->verticalLayout->setAlignment(Qt::AlignTop);
|
||||||
|
ui->topLayout->setAlignment(Qt::AlignTop);
|
||||||
|
ui->arrowsLayout->addStretch();
|
||||||
|
ui->arrowsLayout->setAlignment(Qt::AlignTop);
|
||||||
|
ui->verticalLayout_2->addStretch();
|
||||||
|
|
||||||
|
adjustSize();
|
||||||
|
}
|
||||||
|
|
||||||
|
BoardPostDisplayWidget_card::~BoardPostDisplayWidget_card()
|
||||||
|
{
|
||||||
|
delete ui;
|
||||||
|
}
|
||||||
|
|
||||||
|
void BoardPostDisplayWidget_card::setup()
|
||||||
|
{
|
||||||
|
BoardPostDisplayWidgetBase::setup();
|
||||||
|
|
||||||
|
RsReputationLevel overall_reputation = rsReputations->overallReputationLevel(mPost.mMeta.mAuthorId);
|
||||||
|
bool redacted = (overall_reputation == RsReputationLevel::LOCALLY_NEGATIVE);
|
||||||
|
|
||||||
|
if(redacted)
|
||||||
|
{
|
||||||
|
ui->pictureLabel->setPixmap( FilesDefs::getPixmapFromQtResourcePath(":/images/thumb-blocked.png") );
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if(mPost.mImage.mData != NULL)
|
||||||
|
{
|
||||||
|
QPixmap pixmap;
|
||||||
|
GxsIdDetails::loadPixmapFromData(mPost.mImage.mData, mPost.mImage.mSize, pixmap,GxsIdDetails::ORIGINAL);
|
||||||
|
// Wiping data - as its been passed to thumbnail.
|
||||||
|
|
||||||
|
QPixmap scaledpixmap;
|
||||||
|
if(pixmap.width() > 800){
|
||||||
|
QPixmap scaledpixmap = pixmap.scaledToWidth(800, Qt::SmoothTransformation);
|
||||||
|
ui->pictureLabel->setPixmap(scaledpixmap);
|
||||||
|
}else{
|
||||||
|
ui->pictureLabel->setPixmap(pixmap);
|
||||||
|
}
|
||||||
|
|
||||||
|
ui->pictureLabel->show();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
ui->pictureLabel->hide();
|
||||||
|
}
|
||||||
|
|
||||||
|
QTextDocument doc;
|
||||||
|
doc.setHtml(notes()->text());
|
||||||
|
|
||||||
|
if(doc.toPlainText().trimmed().isEmpty())
|
||||||
|
notes()->hide();
|
||||||
|
}
|
||||||
|
|
||||||
|
QToolButton *BoardPostDisplayWidget_card::voteUpButton() { return ui->voteUpButton; }
|
||||||
|
QToolButton *BoardPostDisplayWidget_card::commentButton() { return ui->commentButton; }
|
||||||
|
QToolButton *BoardPostDisplayWidget_card::voteDownButton() { return ui->voteDownButton; }
|
||||||
|
QLabel *BoardPostDisplayWidget_card::newLabel() { return ui->newLabel; }
|
||||||
|
QToolButton *BoardPostDisplayWidget_card::readButton() { return ui->readButton; }
|
||||||
|
QLabel *BoardPostDisplayWidget_card::siteLabel() { return ui->siteLabel; }
|
||||||
|
GxsIdLabel *BoardPostDisplayWidget_card::fromLabel() { return ui->fromLabel; }
|
||||||
|
QLabel *BoardPostDisplayWidget_card::dateLabel() { return ui->dateLabel; }
|
||||||
|
QLabel *BoardPostDisplayWidget_card::titleLabel() { return ui->titleLabel; }
|
||||||
|
QLabel *BoardPostDisplayWidget_card::scoreLabel() { return ui->scoreLabel; }
|
||||||
|
QLabel *BoardPostDisplayWidget_card::notes() { return ui->notes; }
|
||||||
|
QPushButton *BoardPostDisplayWidget_card::shareButton() { return ui->shareButton; }
|
||||||
|
QLabel *BoardPostDisplayWidget_card::pictureLabel() { return ui->pictureLabel; }
|
||||||
|
QFrame *BoardPostDisplayWidget_card::mainFrame() { return ui->mainFrame; }
|
||||||
|
|
183
retroshare-gui/src/gui/Posted/BoardPostDisplayWidget.h
Normal file
183
retroshare-gui/src/gui/Posted/BoardPostDisplayWidget.h
Normal file
@ -0,0 +1,183 @@
|
|||||||
|
/*******************************************************************************
|
||||||
|
* retroshare-gui/src/gui/Posted/BoardPostDisplayWidget.h *
|
||||||
|
* *
|
||||||
|
* Copyright (C) 2019 by Retroshare Team <retroshare.project@gmail.com> *
|
||||||
|
* *
|
||||||
|
* This program is free software: you can redistribute it and/or modify *
|
||||||
|
* it under the terms of the GNU Affero General Public License as *
|
||||||
|
* published by the Free Software Foundation, either version 3 of the *
|
||||||
|
* License, or (at your option) any later version. *
|
||||||
|
* *
|
||||||
|
* This program is distributed in the hope that it will be useful, *
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
|
||||||
|
* GNU Affero General Public License for more details. *
|
||||||
|
* *
|
||||||
|
* You should have received a copy of the GNU Affero General Public License *
|
||||||
|
* along with this program. If not, see <https://www.gnu.org/licenses/>. *
|
||||||
|
* *
|
||||||
|
*******************************************************************************/
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <QMetaType>
|
||||||
|
#include <QWidget>
|
||||||
|
|
||||||
|
#include <retroshare/rsposted.h>
|
||||||
|
|
||||||
|
namespace Ui {
|
||||||
|
class BoardPostDisplayWidget_card;
|
||||||
|
class BoardPostDisplayWidget_compact;
|
||||||
|
}
|
||||||
|
|
||||||
|
class QPushButton;
|
||||||
|
class QFrame;
|
||||||
|
class QLabel;
|
||||||
|
class QToolButton;
|
||||||
|
class QTextEdit;
|
||||||
|
class ClickableLabel;
|
||||||
|
class GxsIdLabel;
|
||||||
|
|
||||||
|
struct RsPostedPost;
|
||||||
|
|
||||||
|
class BoardPostDisplayWidgetBase: public QWidget
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
|
||||||
|
public:
|
||||||
|
enum DisplayFlags: uint8_t {
|
||||||
|
SHOW_NONE = 0x00,
|
||||||
|
SHOW_COMMENTS = 0x01,
|
||||||
|
SHOW_NOTES = 0x02,
|
||||||
|
};
|
||||||
|
|
||||||
|
enum DisplayMode: uint8_t {
|
||||||
|
DISPLAY_MODE_UNKNOWN = 0x00,
|
||||||
|
DISPLAY_MODE_COMPACT = 0x01,
|
||||||
|
DISPLAY_MODE_CARD = 0x02,
|
||||||
|
};
|
||||||
|
|
||||||
|
BoardPostDisplayWidgetBase(const RsPostedPost& post,uint8_t display_flags,QWidget *parent);
|
||||||
|
virtual ~BoardPostDisplayWidgetBase() {}
|
||||||
|
|
||||||
|
static const char *DEFAULT_BOARD_IMAGE;
|
||||||
|
|
||||||
|
protected slots:
|
||||||
|
/* GxsGroupFeedItem */
|
||||||
|
|
||||||
|
virtual void setup(); // to be overloaded by the different views
|
||||||
|
|
||||||
|
virtual QToolButton *voteUpButton() =0;
|
||||||
|
virtual QToolButton *commentButton() =0;
|
||||||
|
virtual QToolButton *voteDownButton() =0;
|
||||||
|
virtual QLabel *newLabel() =0;
|
||||||
|
virtual QLabel *titleLabel()=0;
|
||||||
|
virtual QLabel *siteLabel()=0;
|
||||||
|
virtual GxsIdLabel *fromLabel()=0;
|
||||||
|
virtual QLabel *dateLabel()=0;
|
||||||
|
virtual QLabel *scoreLabel() =0;
|
||||||
|
virtual QLabel *notes() =0;
|
||||||
|
virtual QLabel *pictureLabel()=0;
|
||||||
|
virtual QToolButton *readButton() =0;
|
||||||
|
virtual QPushButton *shareButton() =0;
|
||||||
|
virtual QFrame *mainFrame() =0;
|
||||||
|
|
||||||
|
void loadComments(bool e);
|
||||||
|
void readToggled();
|
||||||
|
void setReadStatus(bool isNew, bool isUnread) ;
|
||||||
|
void makeUpVote() ;
|
||||||
|
void makeDownVote() ;
|
||||||
|
void setCommentsSize(int comNb) ;
|
||||||
|
void handleShareButtonClicked() ;
|
||||||
|
void handleCopyLinkClicked() ;
|
||||||
|
|
||||||
|
|
||||||
|
signals:
|
||||||
|
void changeReadStatusRequested(const RsGxsMessageId&,bool);
|
||||||
|
void vote(const RsGxsGrpMsgIdPair& msgId, bool up_or_down);
|
||||||
|
void expand(RsGxsMessageId,bool);
|
||||||
|
void commentsRequested(const RsGxsMessageId&,bool);
|
||||||
|
void thumbnailOpenned();
|
||||||
|
void shareButtonClicked();
|
||||||
|
void copylinkClicked();
|
||||||
|
|
||||||
|
protected:
|
||||||
|
RsPostedPost mPost;
|
||||||
|
uint8_t mDisplayFlags;
|
||||||
|
};
|
||||||
|
|
||||||
|
class BoardPostDisplayWidget_compact : public BoardPostDisplayWidgetBase
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
|
||||||
|
public:
|
||||||
|
BoardPostDisplayWidget_compact(const RsPostedPost& post, uint8_t display_flags, QWidget *parent);
|
||||||
|
virtual ~BoardPostDisplayWidget_compact();
|
||||||
|
|
||||||
|
static const char *DEFAULT_BOARD_IMAGE;
|
||||||
|
|
||||||
|
QToolButton *voteUpButton() override;
|
||||||
|
QToolButton *commentButton() override;
|
||||||
|
QToolButton *voteDownButton() override;
|
||||||
|
QLabel *newLabel() override;
|
||||||
|
QLabel *siteLabel() override;
|
||||||
|
GxsIdLabel *fromLabel() override;
|
||||||
|
QLabel *dateLabel() override;
|
||||||
|
QLabel *titleLabel() override;
|
||||||
|
QLabel *scoreLabel() override;
|
||||||
|
QLabel *notes() override;
|
||||||
|
QLabel *pictureLabel() override;
|
||||||
|
QToolButton *readButton() override;
|
||||||
|
QPushButton *shareButton() override;
|
||||||
|
QFrame *mainFrame() override;
|
||||||
|
|
||||||
|
public slots:
|
||||||
|
void viewPicture() ;
|
||||||
|
|
||||||
|
protected slots:
|
||||||
|
/* GxsGroupFeedItem */
|
||||||
|
void doExpand(bool) ;
|
||||||
|
|
||||||
|
protected:
|
||||||
|
void setup() override; // to be overloaded by the different views
|
||||||
|
|
||||||
|
private:
|
||||||
|
/** Qt Designer generated object */
|
||||||
|
Ui::BoardPostDisplayWidget_compact *ui;
|
||||||
|
};
|
||||||
|
|
||||||
|
class BoardPostDisplayWidget_card : public BoardPostDisplayWidgetBase
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
|
||||||
|
public:
|
||||||
|
BoardPostDisplayWidget_card(const RsPostedPost& post,uint8_t display_flags,QWidget *parent=nullptr);
|
||||||
|
virtual ~BoardPostDisplayWidget_card();
|
||||||
|
|
||||||
|
static const char *DEFAULT_BOARD_IMAGE;
|
||||||
|
|
||||||
|
QToolButton *voteUpButton() override;
|
||||||
|
QToolButton *commentButton() override;
|
||||||
|
QToolButton *voteDownButton() override;
|
||||||
|
QLabel *newLabel() override;
|
||||||
|
QLabel *siteLabel() override;
|
||||||
|
GxsIdLabel *fromLabel() override;
|
||||||
|
QLabel *dateLabel() override;
|
||||||
|
QLabel *titleLabel() override;
|
||||||
|
QLabel *scoreLabel() override;
|
||||||
|
QLabel *notes() override;
|
||||||
|
QToolButton *readButton() override;
|
||||||
|
QPushButton *shareButton() override;
|
||||||
|
QLabel *pictureLabel() override;
|
||||||
|
QFrame *mainFrame() override;
|
||||||
|
|
||||||
|
protected slots:
|
||||||
|
/* GxsGroupFeedItem */
|
||||||
|
|
||||||
|
protected:
|
||||||
|
void setup() override; // to be overloaded by the different views
|
||||||
|
|
||||||
|
private:
|
||||||
|
/** Qt Designer generated object */
|
||||||
|
Ui::BoardPostDisplayWidget_card *ui;
|
||||||
|
};
|
463
retroshare-gui/src/gui/Posted/BoardPostDisplayWidget_card.ui
Normal file
463
retroshare-gui/src/gui/Posted/BoardPostDisplayWidget_card.ui
Normal file
@ -0,0 +1,463 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<ui version="4.0">
|
||||||
|
<class>BoardPostDisplayWidget_card</class>
|
||||||
|
<widget class="QWidget" name="BoardPostDisplayWidget_card">
|
||||||
|
<property name="geometry">
|
||||||
|
<rect>
|
||||||
|
<x>0</x>
|
||||||
|
<y>0</y>
|
||||||
|
<width>558</width>
|
||||||
|
<height>202</height>
|
||||||
|
</rect>
|
||||||
|
</property>
|
||||||
|
<property name="sizePolicy">
|
||||||
|
<sizepolicy hsizetype="Preferred" vsizetype="Maximum">
|
||||||
|
<horstretch>0</horstretch>
|
||||||
|
<verstretch>0</verstretch>
|
||||||
|
</sizepolicy>
|
||||||
|
</property>
|
||||||
|
<property name="windowTitle">
|
||||||
|
<string notr="true"/>
|
||||||
|
</property>
|
||||||
|
<property name="styleSheet">
|
||||||
|
<string notr="true"/>
|
||||||
|
</property>
|
||||||
|
<layout class="QHBoxLayout" name="horizontalLayout_3">
|
||||||
|
<property name="spacing">
|
||||||
|
<number>0</number>
|
||||||
|
</property>
|
||||||
|
<property name="sizeConstraint">
|
||||||
|
<enum>QLayout::SetMaximumSize</enum>
|
||||||
|
</property>
|
||||||
|
<property name="leftMargin">
|
||||||
|
<number>2</number>
|
||||||
|
</property>
|
||||||
|
<property name="topMargin">
|
||||||
|
<number>2</number>
|
||||||
|
</property>
|
||||||
|
<property name="rightMargin">
|
||||||
|
<number>2</number>
|
||||||
|
</property>
|
||||||
|
<property name="bottomMargin">
|
||||||
|
<number>2</number>
|
||||||
|
</property>
|
||||||
|
<item>
|
||||||
|
<widget class="QFrame" name="mainFrame">
|
||||||
|
<property name="sizePolicy">
|
||||||
|
<sizepolicy hsizetype="Preferred" vsizetype="Maximum">
|
||||||
|
<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="QVBoxLayout" name="verticalLayout_2">
|
||||||
|
<property name="spacing">
|
||||||
|
<number>2</number>
|
||||||
|
</property>
|
||||||
|
<property name="sizeConstraint">
|
||||||
|
<enum>QLayout::SetMaximumSize</enum>
|
||||||
|
</property>
|
||||||
|
<property name="leftMargin">
|
||||||
|
<number>1</number>
|
||||||
|
</property>
|
||||||
|
<property name="topMargin">
|
||||||
|
<number>2</number>
|
||||||
|
</property>
|
||||||
|
<property name="rightMargin">
|
||||||
|
<number>1</number>
|
||||||
|
</property>
|
||||||
|
<property name="bottomMargin">
|
||||||
|
<number>2</number>
|
||||||
|
</property>
|
||||||
|
<item>
|
||||||
|
<layout class="QHBoxLayout" name="topLayout">
|
||||||
|
<property name="leftMargin">
|
||||||
|
<number>2</number>
|
||||||
|
</property>
|
||||||
|
<property name="topMargin">
|
||||||
|
<number>2</number>
|
||||||
|
</property>
|
||||||
|
<property name="rightMargin">
|
||||||
|
<number>2</number>
|
||||||
|
</property>
|
||||||
|
<property name="bottomMargin">
|
||||||
|
<number>2</number>
|
||||||
|
</property>
|
||||||
|
<item>
|
||||||
|
<widget class="QFrame" name="voteFrame">
|
||||||
|
<layout class="QVBoxLayout" name="arrowsLayout">
|
||||||
|
<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>
|
||||||
|
<widget class="QToolButton" name="voteUpButton">
|
||||||
|
<property name="sizePolicy">
|
||||||
|
<sizepolicy hsizetype="Preferred" vsizetype="Preferred">
|
||||||
|
<horstretch>0</horstretch>
|
||||||
|
<verstretch>0</verstretch>
|
||||||
|
</sizepolicy>
|
||||||
|
</property>
|
||||||
|
<property name="toolTip">
|
||||||
|
<string>Vote up</string>
|
||||||
|
</property>
|
||||||
|
<property name="text">
|
||||||
|
<string/>
|
||||||
|
</property>
|
||||||
|
<property name="icon">
|
||||||
|
<iconset resource="Posted_images.qrc">
|
||||||
|
<normaloff>:/images/up-arrow.png</normaloff>:/images/up-arrow.png</iconset>
|
||||||
|
</property>
|
||||||
|
<property name="autoRaise">
|
||||||
|
<bool>true</bool>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="StyledLabel" name="scoreLabel">
|
||||||
|
<property name="font">
|
||||||
|
<font>
|
||||||
|
<pointsize>9</pointsize>
|
||||||
|
</font>
|
||||||
|
</property>
|
||||||
|
<property name="text">
|
||||||
|
<string>0</string>
|
||||||
|
</property>
|
||||||
|
<property name="alignment">
|
||||||
|
<set>Qt::AlignCenter</set>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QToolButton" name="voteDownButton">
|
||||||
|
<property name="sizePolicy">
|
||||||
|
<sizepolicy hsizetype="Preferred" vsizetype="Preferred">
|
||||||
|
<horstretch>0</horstretch>
|
||||||
|
<verstretch>0</verstretch>
|
||||||
|
</sizepolicy>
|
||||||
|
</property>
|
||||||
|
<property name="minimumSize">
|
||||||
|
<size>
|
||||||
|
<width>0</width>
|
||||||
|
<height>0</height>
|
||||||
|
</size>
|
||||||
|
</property>
|
||||||
|
<property name="toolTip">
|
||||||
|
<string>Vote down</string>
|
||||||
|
</property>
|
||||||
|
<property name="styleSheet">
|
||||||
|
<string notr="true"/>
|
||||||
|
</property>
|
||||||
|
<property name="text">
|
||||||
|
<string>\/</string>
|
||||||
|
</property>
|
||||||
|
<property name="icon">
|
||||||
|
<iconset resource="Posted_images.qrc">
|
||||||
|
<normaloff>:/images/down-arrow.png</normaloff>:/images/down-arrow.png</iconset>
|
||||||
|
</property>
|
||||||
|
<property name="autoRaise">
|
||||||
|
<bool>true</bool>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<layout class="QVBoxLayout" name="verticalLayout">
|
||||||
|
<item>
|
||||||
|
<layout class="QHBoxLayout" name="horizontalLayout_2">
|
||||||
|
<property name="spacing">
|
||||||
|
<number>5</number>
|
||||||
|
</property>
|
||||||
|
<property name="leftMargin">
|
||||||
|
<number>0</number>
|
||||||
|
</property>
|
||||||
|
<property name="rightMargin">
|
||||||
|
<number>6</number>
|
||||||
|
</property>
|
||||||
|
<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>
|
||||||
|
<weight>50</weight>
|
||||||
|
<bold>false</bold>
|
||||||
|
</font>
|
||||||
|
</property>
|
||||||
|
<property name="text">
|
||||||
|
<string>Posted by</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="GxsIdLabel" name="fromLabel">
|
||||||
|
<property name="sizePolicy">
|
||||||
|
<sizepolicy hsizetype="Minimum" vsizetype="Preferred">
|
||||||
|
<horstretch>0</horstretch>
|
||||||
|
<verstretch>0</verstretch>
|
||||||
|
</sizepolicy>
|
||||||
|
</property>
|
||||||
|
<property name="text">
|
||||||
|
<string notr="true">Signed by</string>
|
||||||
|
</property>
|
||||||
|
<property name="openExternalLinks">
|
||||||
|
<bool>true</bool>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QLabel" name="dateLabel">
|
||||||
|
<property name="sizePolicy">
|
||||||
|
<sizepolicy hsizetype="Minimum" vsizetype="Preferred">
|
||||||
|
<horstretch>0</horstretch>
|
||||||
|
<verstretch>0</verstretch>
|
||||||
|
</sizepolicy>
|
||||||
|
</property>
|
||||||
|
<property name="text">
|
||||||
|
<string notr="true">You eyes only</string>
|
||||||
|
</property>
|
||||||
|
<property name="openExternalLinks">
|
||||||
|
<bool>true</bool>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QToolButton" name="readButton">
|
||||||
|
<property name="maximumSize">
|
||||||
|
<size>
|
||||||
|
<width>24</width>
|
||||||
|
<height>16777215</height>
|
||||||
|
</size>
|
||||||
|
</property>
|
||||||
|
<property name="focusPolicy">
|
||||||
|
<enum>Qt::NoFocus</enum>
|
||||||
|
</property>
|
||||||
|
<property name="toolTip">
|
||||||
|
<string>Toggle Message Read Status</string>
|
||||||
|
</property>
|
||||||
|
<property name="icon">
|
||||||
|
<iconset resource="../images.qrc">
|
||||||
|
<normaloff>:/images/message-state-unread.png</normaloff>:/images/message-state-unread.png</iconset>
|
||||||
|
</property>
|
||||||
|
<property name="checkable">
|
||||||
|
<bool>false</bool>
|
||||||
|
</property>
|
||||||
|
<property name="checked">
|
||||||
|
<bool>false</bool>
|
||||||
|
</property>
|
||||||
|
<property name="autoRaise">
|
||||||
|
<bool>true</bool>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QLabel" name="newLabel">
|
||||||
|
<property name="text">
|
||||||
|
<string>New</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<spacer name="horizontalSpacer_4">
|
||||||
|
<property name="orientation">
|
||||||
|
<enum>Qt::Horizontal</enum>
|
||||||
|
</property>
|
||||||
|
<property name="sizeType">
|
||||||
|
<enum>QSizePolicy::Expanding</enum>
|
||||||
|
</property>
|
||||||
|
<property name="sizeHint" stdset="0">
|
||||||
|
<size>
|
||||||
|
<width>70</width>
|
||||||
|
<height>20</height>
|
||||||
|
</size>
|
||||||
|
</property>
|
||||||
|
</spacer>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="StyledLabel" name="titleLabel">
|
||||||
|
<property name="sizePolicy">
|
||||||
|
<sizepolicy hsizetype="Preferred" vsizetype="Preferred">
|
||||||
|
<horstretch>0</horstretch>
|
||||||
|
<verstretch>0</verstretch>
|
||||||
|
</sizepolicy>
|
||||||
|
</property>
|
||||||
|
<property name="font">
|
||||||
|
<font>
|
||||||
|
<family>Arial</family>
|
||||||
|
<pointsize>10</pointsize>
|
||||||
|
<weight>75</weight>
|
||||||
|
<bold>true</bold>
|
||||||
|
</font>
|
||||||
|
</property>
|
||||||
|
<property name="text">
|
||||||
|
<string notr="true">This is a very very very very loooooooooooooooonnnnnnnnnnnnnnnnng title don't you think? Yes it is and should wrap around I hope</string>
|
||||||
|
</property>
|
||||||
|
<property name="alignment">
|
||||||
|
<set>Qt::AlignLeading|Qt::AlignLeft|Qt::AlignTop</set>
|
||||||
|
</property>
|
||||||
|
<property name="wordWrap">
|
||||||
|
<bool>true</bool>
|
||||||
|
</property>
|
||||||
|
<property name="openExternalLinks">
|
||||||
|
<bool>true</bool>
|
||||||
|
</property>
|
||||||
|
<property name="textInteractionFlags">
|
||||||
|
<set>Qt::LinksAccessibleByMouse|Qt::TextSelectableByMouse</set>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QLabel" name="siteLabel">
|
||||||
|
<property name="sizePolicy">
|
||||||
|
<sizepolicy hsizetype="Expanding" vsizetype="Preferred">
|
||||||
|
<horstretch>0</horstretch>
|
||||||
|
<verstretch>0</verstretch>
|
||||||
|
</sizepolicy>
|
||||||
|
</property>
|
||||||
|
<property name="text">
|
||||||
|
<string notr="true">site</string>
|
||||||
|
</property>
|
||||||
|
<property name="openExternalLinks">
|
||||||
|
<bool>true</bool>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<layout class="QHBoxLayout" name="pictureLabelLayout">
|
||||||
|
<item>
|
||||||
|
<widget class="QLabel" name="pictureLabel">
|
||||||
|
<property name="text">
|
||||||
|
<string>PictureLabel</string>
|
||||||
|
</property>
|
||||||
|
<property name="scaledContents">
|
||||||
|
<bool>true</bool>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<spacer name="horizontalSpacer">
|
||||||
|
<property name="orientation">
|
||||||
|
<enum>Qt::Horizontal</enum>
|
||||||
|
</property>
|
||||||
|
<property name="sizeHint" stdset="0">
|
||||||
|
<size>
|
||||||
|
<width>268</width>
|
||||||
|
<height>17</height>
|
||||||
|
</size>
|
||||||
|
</property>
|
||||||
|
</spacer>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QLabel" name="notes">
|
||||||
|
<property name="text">
|
||||||
|
<string>TextLabel</string>
|
||||||
|
</property>
|
||||||
|
<property name="wordWrap">
|
||||||
|
<bool>true</bool>
|
||||||
|
</property>
|
||||||
|
<property name="openExternalLinks">
|
||||||
|
<bool>true</bool>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<layout class="QHBoxLayout" name="horizontalLayout">
|
||||||
|
<item>
|
||||||
|
<widget class="QToolButton" name="commentButton">
|
||||||
|
<property name="text">
|
||||||
|
<string>Comments</string>
|
||||||
|
</property>
|
||||||
|
<property name="icon">
|
||||||
|
<iconset resource="Posted_images.qrc">
|
||||||
|
<normaloff>:/images/comments.png</normaloff>:/images/comments.png</iconset>
|
||||||
|
</property>
|
||||||
|
<property name="checkable">
|
||||||
|
<bool>true</bool>
|
||||||
|
</property>
|
||||||
|
<property name="toolButtonStyle">
|
||||||
|
<enum>Qt::ToolButtonTextBesideIcon</enum>
|
||||||
|
</property>
|
||||||
|
<property name="autoRaise">
|
||||||
|
<bool>true</bool>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QPushButton" name="shareButton">
|
||||||
|
<property name="text">
|
||||||
|
<string>Share</string>
|
||||||
|
</property>
|
||||||
|
<property name="icon">
|
||||||
|
<iconset resource="Posted_images.qrc">
|
||||||
|
<normaloff>:/images/share.png</normaloff>:/images/share.png</iconset>
|
||||||
|
</property>
|
||||||
|
<property name="flat">
|
||||||
|
<bool>true</bool>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<spacer name="horizontalSpacer_2">
|
||||||
|
<property name="orientation">
|
||||||
|
<enum>Qt::Horizontal</enum>
|
||||||
|
</property>
|
||||||
|
<property name="sizeHint" stdset="0">
|
||||||
|
<size>
|
||||||
|
<width>40</width>
|
||||||
|
<height>20</height>
|
||||||
|
</size>
|
||||||
|
</property>
|
||||||
|
</spacer>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</widget>
|
||||||
|
<customwidgets>
|
||||||
|
<customwidget>
|
||||||
|
<class>GxsIdLabel</class>
|
||||||
|
<extends>QLabel</extends>
|
||||||
|
<header>gui/gxs/GxsIdLabel.h</header>
|
||||||
|
</customwidget>
|
||||||
|
<customwidget>
|
||||||
|
<class>StyledLabel</class>
|
||||||
|
<extends>QLabel</extends>
|
||||||
|
<header>gui/common/StyledLabel.h</header>
|
||||||
|
</customwidget>
|
||||||
|
</customwidgets>
|
||||||
|
<resources>
|
||||||
|
<include location="Posted_images.qrc"/>
|
||||||
|
<include location="../images.qrc"/>
|
||||||
|
</resources>
|
||||||
|
<connections/>
|
||||||
|
</ui>
|
511
retroshare-gui/src/gui/Posted/BoardPostDisplayWidget_compact.ui
Normal file
511
retroshare-gui/src/gui/Posted/BoardPostDisplayWidget_compact.ui
Normal file
@ -0,0 +1,511 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<ui version="4.0">
|
||||||
|
<class>BoardPostDisplayWidget_compact</class>
|
||||||
|
<widget class="QWidget" name="BoardPostDisplayWidget_compact">
|
||||||
|
<property name="geometry">
|
||||||
|
<rect>
|
||||||
|
<x>0</x>
|
||||||
|
<y>0</y>
|
||||||
|
<width>540</width>
|
||||||
|
<height>172</height>
|
||||||
|
</rect>
|
||||||
|
</property>
|
||||||
|
<property name="sizePolicy">
|
||||||
|
<sizepolicy hsizetype="Preferred" vsizetype="Maximum">
|
||||||
|
<horstretch>0</horstretch>
|
||||||
|
<verstretch>0</verstretch>
|
||||||
|
</sizepolicy>
|
||||||
|
</property>
|
||||||
|
<property name="windowTitle">
|
||||||
|
<string notr="true"/>
|
||||||
|
</property>
|
||||||
|
<property name="styleSheet">
|
||||||
|
<string notr="true"/>
|
||||||
|
</property>
|
||||||
|
<layout class="QHBoxLayout" name="horizontalLayout_3">
|
||||||
|
<property name="spacing">
|
||||||
|
<number>0</number>
|
||||||
|
</property>
|
||||||
|
<property name="sizeConstraint">
|
||||||
|
<enum>QLayout::SetMaximumSize</enum>
|
||||||
|
</property>
|
||||||
|
<property name="leftMargin">
|
||||||
|
<number>2</number>
|
||||||
|
</property>
|
||||||
|
<property name="topMargin">
|
||||||
|
<number>2</number>
|
||||||
|
</property>
|
||||||
|
<property name="rightMargin">
|
||||||
|
<number>2</number>
|
||||||
|
</property>
|
||||||
|
<property name="bottomMargin">
|
||||||
|
<number>2</number>
|
||||||
|
</property>
|
||||||
|
<item>
|
||||||
|
<widget class="QFrame" name="mainFrame">
|
||||||
|
<property name="sizePolicy">
|
||||||
|
<sizepolicy hsizetype="Preferred" vsizetype="Maximum">
|
||||||
|
<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="QVBoxLayout" name="verticalLayout_2">
|
||||||
|
<property name="spacing">
|
||||||
|
<number>2</number>
|
||||||
|
</property>
|
||||||
|
<property name="sizeConstraint">
|
||||||
|
<enum>QLayout::SetMaximumSize</enum>
|
||||||
|
</property>
|
||||||
|
<property name="leftMargin">
|
||||||
|
<number>1</number>
|
||||||
|
</property>
|
||||||
|
<property name="topMargin">
|
||||||
|
<number>2</number>
|
||||||
|
</property>
|
||||||
|
<property name="rightMargin">
|
||||||
|
<number>1</number>
|
||||||
|
</property>
|
||||||
|
<property name="bottomMargin">
|
||||||
|
<number>2</number>
|
||||||
|
</property>
|
||||||
|
<item>
|
||||||
|
<layout class="QHBoxLayout" name="topLayout">
|
||||||
|
<property name="leftMargin">
|
||||||
|
<number>2</number>
|
||||||
|
</property>
|
||||||
|
<property name="topMargin">
|
||||||
|
<number>2</number>
|
||||||
|
</property>
|
||||||
|
<property name="rightMargin">
|
||||||
|
<number>2</number>
|
||||||
|
</property>
|
||||||
|
<property name="bottomMargin">
|
||||||
|
<number>2</number>
|
||||||
|
</property>
|
||||||
|
<item>
|
||||||
|
<layout class="QVBoxLayout" name="arrowsLayout">
|
||||||
|
<item>
|
||||||
|
<widget class="QToolButton" name="voteUpButton">
|
||||||
|
<property name="sizePolicy">
|
||||||
|
<sizepolicy hsizetype="Preferred" vsizetype="Preferred">
|
||||||
|
<horstretch>0</horstretch>
|
||||||
|
<verstretch>0</verstretch>
|
||||||
|
</sizepolicy>
|
||||||
|
</property>
|
||||||
|
<property name="toolTip">
|
||||||
|
<string>Vote up</string>
|
||||||
|
</property>
|
||||||
|
<property name="text">
|
||||||
|
<string/>
|
||||||
|
</property>
|
||||||
|
<property name="icon">
|
||||||
|
<iconset resource="Posted_images.qrc">
|
||||||
|
<normaloff>:/images/up-arrow.png</normaloff>:/images/up-arrow.png</iconset>
|
||||||
|
</property>
|
||||||
|
<property name="autoRaise">
|
||||||
|
<bool>true</bool>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="StyledLabel" name="scoreLabel">
|
||||||
|
<property name="font">
|
||||||
|
<font>
|
||||||
|
<pointsize>9</pointsize>
|
||||||
|
</font>
|
||||||
|
</property>
|
||||||
|
<property name="text">
|
||||||
|
<string>0</string>
|
||||||
|
</property>
|
||||||
|
<property name="alignment">
|
||||||
|
<set>Qt::AlignCenter</set>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QToolButton" name="voteDownButton">
|
||||||
|
<property name="sizePolicy">
|
||||||
|
<sizepolicy hsizetype="Preferred" vsizetype="Preferred">
|
||||||
|
<horstretch>0</horstretch>
|
||||||
|
<verstretch>0</verstretch>
|
||||||
|
</sizepolicy>
|
||||||
|
</property>
|
||||||
|
<property name="minimumSize">
|
||||||
|
<size>
|
||||||
|
<width>0</width>
|
||||||
|
<height>0</height>
|
||||||
|
</size>
|
||||||
|
</property>
|
||||||
|
<property name="toolTip">
|
||||||
|
<string>Vote down</string>
|
||||||
|
</property>
|
||||||
|
<property name="styleSheet">
|
||||||
|
<string notr="true"/>
|
||||||
|
</property>
|
||||||
|
<property name="text">
|
||||||
|
<string>\/</string>
|
||||||
|
</property>
|
||||||
|
<property name="icon">
|
||||||
|
<iconset resource="Posted_images.qrc">
|
||||||
|
<normaloff>:/images/down-arrow.png</normaloff>:/images/down-arrow.png</iconset>
|
||||||
|
</property>
|
||||||
|
<property name="autoRaise">
|
||||||
|
<bool>true</bool>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="ZoomableLabel" name="pictureLabel">
|
||||||
|
<property name="sizePolicy">
|
||||||
|
<sizepolicy hsizetype="Preferred" vsizetype="Preferred">
|
||||||
|
<horstretch>0</horstretch>
|
||||||
|
<verstretch>0</verstretch>
|
||||||
|
</sizepolicy>
|
||||||
|
</property>
|
||||||
|
<property name="toolTip">
|
||||||
|
<string>Click to view picture</string>
|
||||||
|
</property>
|
||||||
|
<property name="text">
|
||||||
|
<string>PictureLabel_compact</string>
|
||||||
|
</property>
|
||||||
|
<property name="alignment">
|
||||||
|
<set>Qt::AlignLeading|Qt::AlignLeft|Qt::AlignTop</set>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<layout class="QVBoxLayout" name="verticalLayout">
|
||||||
|
<property name="leftMargin">
|
||||||
|
<number>3</number>
|
||||||
|
</property>
|
||||||
|
<item>
|
||||||
|
<widget class="StyledLabel" name="titleLabel">
|
||||||
|
<property name="sizePolicy">
|
||||||
|
<sizepolicy hsizetype="Preferred" vsizetype="Preferred">
|
||||||
|
<horstretch>0</horstretch>
|
||||||
|
<verstretch>0</verstretch>
|
||||||
|
</sizepolicy>
|
||||||
|
</property>
|
||||||
|
<property name="font">
|
||||||
|
<font>
|
||||||
|
<family>Arial</family>
|
||||||
|
<pointsize>10</pointsize>
|
||||||
|
<weight>75</weight>
|
||||||
|
<bold>true</bold>
|
||||||
|
</font>
|
||||||
|
</property>
|
||||||
|
<property name="text">
|
||||||
|
<string notr="true">This is a very very very very loooooooooooooooonnnnnnnnnnnnnnnnng title don't you think? Yes it is and should wrap around I hope</string>
|
||||||
|
</property>
|
||||||
|
<property name="alignment">
|
||||||
|
<set>Qt::AlignLeading|Qt::AlignLeft|Qt::AlignTop</set>
|
||||||
|
</property>
|
||||||
|
<property name="wordWrap">
|
||||||
|
<bool>true</bool>
|
||||||
|
</property>
|
||||||
|
<property name="openExternalLinks">
|
||||||
|
<bool>true</bool>
|
||||||
|
</property>
|
||||||
|
<property name="textInteractionFlags">
|
||||||
|
<set>Qt::LinksAccessibleByMouse|Qt::TextSelectableByMouse</set>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<layout class="QHBoxLayout" name="horizontalLayout_2">
|
||||||
|
<property name="spacing">
|
||||||
|
<number>6</number>
|
||||||
|
</property>
|
||||||
|
<property name="leftMargin">
|
||||||
|
<number>2</number>
|
||||||
|
</property>
|
||||||
|
<property name="topMargin">
|
||||||
|
<number>2</number>
|
||||||
|
</property>
|
||||||
|
<property name="rightMargin">
|
||||||
|
<number>6</number>
|
||||||
|
</property>
|
||||||
|
<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>
|
||||||
|
<weight>50</weight>
|
||||||
|
<bold>false</bold>
|
||||||
|
</font>
|
||||||
|
</property>
|
||||||
|
<property name="text">
|
||||||
|
<string>Posted by</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="GxsIdLabel" name="fromLabel">
|
||||||
|
<property name="sizePolicy">
|
||||||
|
<sizepolicy hsizetype="Minimum" vsizetype="Preferred">
|
||||||
|
<horstretch>0</horstretch>
|
||||||
|
<verstretch>0</verstretch>
|
||||||
|
</sizepolicy>
|
||||||
|
</property>
|
||||||
|
<property name="text">
|
||||||
|
<string notr="true">Signed by</string>
|
||||||
|
</property>
|
||||||
|
<property name="openExternalLinks">
|
||||||
|
<bool>true</bool>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QLabel" name="dateLabel">
|
||||||
|
<property name="sizePolicy">
|
||||||
|
<sizepolicy hsizetype="Minimum" vsizetype="Preferred">
|
||||||
|
<horstretch>0</horstretch>
|
||||||
|
<verstretch>0</verstretch>
|
||||||
|
</sizepolicy>
|
||||||
|
</property>
|
||||||
|
<property name="text">
|
||||||
|
<string notr="true">You eyes only</string>
|
||||||
|
</property>
|
||||||
|
<property name="openExternalLinks">
|
||||||
|
<bool>true</bool>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<spacer name="horizontalSpacer_4">
|
||||||
|
<property name="orientation">
|
||||||
|
<enum>Qt::Horizontal</enum>
|
||||||
|
</property>
|
||||||
|
<property name="sizeType">
|
||||||
|
<enum>QSizePolicy::Expanding</enum>
|
||||||
|
</property>
|
||||||
|
<property name="sizeHint" stdset="0">
|
||||||
|
<size>
|
||||||
|
<width>70</width>
|
||||||
|
<height>20</height>
|
||||||
|
</size>
|
||||||
|
</property>
|
||||||
|
</spacer>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QLabel" name="siteLabel">
|
||||||
|
<property name="sizePolicy">
|
||||||
|
<sizepolicy hsizetype="Expanding" vsizetype="Preferred">
|
||||||
|
<horstretch>0</horstretch>
|
||||||
|
<verstretch>0</verstretch>
|
||||||
|
</sizepolicy>
|
||||||
|
</property>
|
||||||
|
<property name="text">
|
||||||
|
<string notr="true">site</string>
|
||||||
|
</property>
|
||||||
|
<property name="openExternalLinks">
|
||||||
|
<bool>true</bool>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<layout class="QHBoxLayout" name="horizontalLayout">
|
||||||
|
<item>
|
||||||
|
<widget class="QToolButton" name="commentButton">
|
||||||
|
<property name="text">
|
||||||
|
<string>Comments</string>
|
||||||
|
</property>
|
||||||
|
<property name="icon">
|
||||||
|
<iconset resource="Posted_images.qrc">
|
||||||
|
<normaloff>:/images/comments.png</normaloff>:/images/comments.png</iconset>
|
||||||
|
</property>
|
||||||
|
<property name="checkable">
|
||||||
|
<bool>true</bool>
|
||||||
|
</property>
|
||||||
|
<property name="toolButtonStyle">
|
||||||
|
<enum>Qt::ToolButtonTextBesideIcon</enum>
|
||||||
|
</property>
|
||||||
|
<property name="autoRaise">
|
||||||
|
<bool>true</bool>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QToolButton" name="expandButton">
|
||||||
|
<property name="toolTip">
|
||||||
|
<string>Expand</string>
|
||||||
|
</property>
|
||||||
|
<property name="text">
|
||||||
|
<string/>
|
||||||
|
</property>
|
||||||
|
<property name="icon">
|
||||||
|
<iconset resource="Posted_images.qrc">
|
||||||
|
<normaloff>:/images/expand.png</normaloff>:/images/expand.png</iconset>
|
||||||
|
</property>
|
||||||
|
<property name="checkable">
|
||||||
|
<bool>true</bool>
|
||||||
|
</property>
|
||||||
|
<property name="autoRaise">
|
||||||
|
<bool>true</bool>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QPushButton" name="shareButton">
|
||||||
|
<property name="text">
|
||||||
|
<string>Share</string>
|
||||||
|
</property>
|
||||||
|
<property name="icon">
|
||||||
|
<iconset resource="Posted_images.qrc">
|
||||||
|
<normaloff>:/images/share.png</normaloff>:/images/share.png</iconset>
|
||||||
|
</property>
|
||||||
|
<property name="flat">
|
||||||
|
<bool>true</bool>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QToolButton" name="readButton">
|
||||||
|
<property name="maximumSize">
|
||||||
|
<size>
|
||||||
|
<width>24</width>
|
||||||
|
<height>16777215</height>
|
||||||
|
</size>
|
||||||
|
</property>
|
||||||
|
<property name="focusPolicy">
|
||||||
|
<enum>Qt::NoFocus</enum>
|
||||||
|
</property>
|
||||||
|
<property name="toolTip">
|
||||||
|
<string>Toggle Message Read Status</string>
|
||||||
|
</property>
|
||||||
|
<property name="icon">
|
||||||
|
<iconset resource="../images.qrc">
|
||||||
|
<normaloff>:/images/message-state-unread.png</normaloff>:/images/message-state-unread.png</iconset>
|
||||||
|
</property>
|
||||||
|
<property name="checkable">
|
||||||
|
<bool>false</bool>
|
||||||
|
</property>
|
||||||
|
<property name="checked">
|
||||||
|
<bool>false</bool>
|
||||||
|
</property>
|
||||||
|
<property name="autoRaise">
|
||||||
|
<bool>true</bool>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QLabel" name="newLabel">
|
||||||
|
<property name="text">
|
||||||
|
<string>New</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<spacer name="horizontalSpacer_2">
|
||||||
|
<property name="orientation">
|
||||||
|
<enum>Qt::Horizontal</enum>
|
||||||
|
</property>
|
||||||
|
<property name="sizeHint" stdset="0">
|
||||||
|
<size>
|
||||||
|
<width>40</width>
|
||||||
|
<height>20</height>
|
||||||
|
</size>
|
||||||
|
</property>
|
||||||
|
</spacer>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QFrame" name="frame_notes">
|
||||||
|
<property name="frameShape">
|
||||||
|
<enum>QFrame::StyledPanel</enum>
|
||||||
|
</property>
|
||||||
|
<property name="frameShadow">
|
||||||
|
<enum>QFrame::Raised</enum>
|
||||||
|
</property>
|
||||||
|
<layout class="QHBoxLayout" name="horizontalLayout_4">
|
||||||
|
<property name="spacing">
|
||||||
|
<number>2</number>
|
||||||
|
</property>
|
||||||
|
<property name="sizeConstraint">
|
||||||
|
<enum>QLayout::SetMaximumSize</enum>
|
||||||
|
</property>
|
||||||
|
<property name="leftMargin">
|
||||||
|
<number>1</number>
|
||||||
|
</property>
|
||||||
|
<property name="topMargin">
|
||||||
|
<number>2</number>
|
||||||
|
</property>
|
||||||
|
<property name="rightMargin">
|
||||||
|
<number>1</number>
|
||||||
|
</property>
|
||||||
|
<property name="bottomMargin">
|
||||||
|
<number>2</number>
|
||||||
|
</property>
|
||||||
|
<item>
|
||||||
|
<widget class="QLabel" name="notes">
|
||||||
|
<property name="sizePolicy">
|
||||||
|
<sizepolicy hsizetype="MinimumExpanding" vsizetype="Preferred">
|
||||||
|
<horstretch>0</horstretch>
|
||||||
|
<verstretch>0</verstretch>
|
||||||
|
</sizepolicy>
|
||||||
|
</property>
|
||||||
|
<property name="text">
|
||||||
|
<string>TextLabel</string>
|
||||||
|
</property>
|
||||||
|
<property name="scaledContents">
|
||||||
|
<bool>true</bool>
|
||||||
|
</property>
|
||||||
|
<property name="wordWrap">
|
||||||
|
<bool>true</bool>
|
||||||
|
</property>
|
||||||
|
<property name="textInteractionFlags">
|
||||||
|
<set>Qt::LinksAccessibleByMouse|Qt::TextSelectableByMouse</set>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</widget>
|
||||||
|
<customwidgets>
|
||||||
|
<customwidget>
|
||||||
|
<class>GxsIdLabel</class>
|
||||||
|
<extends>QLabel</extends>
|
||||||
|
<header>gui/gxs/GxsIdLabel.h</header>
|
||||||
|
</customwidget>
|
||||||
|
<customwidget>
|
||||||
|
<class>StyledLabel</class>
|
||||||
|
<extends>QLabel</extends>
|
||||||
|
<header>gui/common/StyledLabel.h</header>
|
||||||
|
</customwidget>
|
||||||
|
<customwidget>
|
||||||
|
<class>ZoomableLabel</class>
|
||||||
|
<extends>QLabel</extends>
|
||||||
|
<header>gui/gxschannels/GxsChannelPostThumbnail.h</header>
|
||||||
|
</customwidget>
|
||||||
|
</customwidgets>
|
||||||
|
<resources>
|
||||||
|
<include location="Posted_images.qrc"/>
|
||||||
|
<include location="../images.qrc"/>
|
||||||
|
</resources>
|
||||||
|
<connections/>
|
||||||
|
</ui>
|
@ -31,7 +31,7 @@ class PostedCardView;
|
|||||||
}
|
}
|
||||||
|
|
||||||
class FeedHolder;
|
class FeedHolder;
|
||||||
class RsPostedPost;
|
struct RsPostedPost;
|
||||||
|
|
||||||
class PostedCardView : public BasePostedItem
|
class PostedCardView : public BasePostedItem
|
||||||
{
|
{
|
||||||
@ -47,7 +47,7 @@ protected:
|
|||||||
|
|
||||||
void setup() override;
|
void setup() override;
|
||||||
void fill() override;
|
void fill() override;
|
||||||
void doExpand(bool open) override {}
|
void doExpand(bool) override {}
|
||||||
void setComment(const RsGxsComment&) override;
|
void setComment(const RsGxsComment&) override;
|
||||||
void setReadStatus(bool isNew, bool isUnread) override;
|
void setReadStatus(bool isNew, bool isUnread) override;
|
||||||
void toggle() override {}
|
void toggle() override {}
|
||||||
|
@ -45,7 +45,7 @@
|
|||||||
#define VIEW_IMAGE 2
|
#define VIEW_IMAGE 2
|
||||||
#define VIEW_LINK 3
|
#define VIEW_LINK 3
|
||||||
|
|
||||||
PostedCreatePostDialog::PostedCreatePostDialog(RsPosted *posted, const RsGxsGroupId& grpId, QWidget *parent):
|
PostedCreatePostDialog::PostedCreatePostDialog(RsPosted *posted, const RsGxsGroupId& grpId, const RsGxsId& default_author, QWidget *parent):
|
||||||
QDialog(parent, Qt::WindowSystemMenuHint | Qt::WindowTitleHint | Qt::WindowMinimizeButtonHint | Qt::WindowMaximizeButtonHint | Qt::WindowCloseButtonHint),
|
QDialog(parent, Qt::WindowSystemMenuHint | Qt::WindowTitleHint | Qt::WindowMinimizeButtonHint | Qt::WindowMaximizeButtonHint | Qt::WindowCloseButtonHint),
|
||||||
mPosted(posted), mGrpId(grpId),
|
mPosted(posted), mGrpId(grpId),
|
||||||
ui(new Ui::PostedCreatePostDialog)
|
ui(new Ui::PostedCreatePostDialog)
|
||||||
@ -70,8 +70,8 @@ PostedCreatePostDialog::PostedCreatePostDialog(RsPosted *posted, const RsGxsGrou
|
|||||||
ui->sizeWarningLabel->setText(QString("Post size is limited to %1 KB, pictures will be downscaled.").arg(MAXMESSAGESIZE / 1024));
|
ui->sizeWarningLabel->setText(QString("Post size is limited to %1 KB, pictures will be downscaled.").arg(MAXMESSAGESIZE / 1024));
|
||||||
|
|
||||||
/* fill in the available OwnIds for signing */
|
/* fill in the available OwnIds for signing */
|
||||||
ui->idChooser->loadIds(IDCHOOSER_ID_REQUIRED, RsGxsId());
|
ui->idChooser->loadIds(IDCHOOSER_ID_REQUIRED, default_author);
|
||||||
|
|
||||||
QSignalMapper *signalMapper = new QSignalMapper(this);
|
QSignalMapper *signalMapper = new QSignalMapper(this);
|
||||||
connect(ui->postButton, SIGNAL(clicked()), signalMapper, SLOT(map()));
|
connect(ui->postButton, SIGNAL(clicked()), signalMapper, SLOT(map()));
|
||||||
connect(ui->imageButton, SIGNAL(clicked()), signalMapper, SLOT(map()));
|
connect(ui->imageButton, SIGNAL(clicked()), signalMapper, SLOT(map()));
|
||||||
@ -86,6 +86,15 @@ PostedCreatePostDialog::PostedCreatePostDialog(RsPosted *posted, const RsGxsGrou
|
|||||||
|
|
||||||
/* load settings */
|
/* load settings */
|
||||||
processSettings(true);
|
processSettings(true);
|
||||||
|
|
||||||
|
// Override the default ID, if supplied, since it is changed by processSettings
|
||||||
|
|
||||||
|
if(!default_author.isNull())
|
||||||
|
{
|
||||||
|
ui->idChooser->setChosenId(default_author);
|
||||||
|
|
||||||
|
// should we save the ID in the settings here? I'm not sure we want this.
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
PostedCreatePostDialog::~PostedCreatePostDialog()
|
PostedCreatePostDialog::~PostedCreatePostDialog()
|
||||||
|
@ -39,7 +39,7 @@ public:
|
|||||||
* @param tokenQ parent callee token
|
* @param tokenQ parent callee token
|
||||||
* @param posted
|
* @param posted
|
||||||
*/
|
*/
|
||||||
explicit PostedCreatePostDialog(RsPosted* posted, const RsGxsGroupId& grpId, QWidget *parent = 0);
|
explicit PostedCreatePostDialog(RsPosted* posted, const RsGxsGroupId& grpId, const RsGxsId& default_author=RsGxsId(),QWidget *parent = 0);
|
||||||
~PostedCreatePostDialog();
|
~PostedCreatePostDialog();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
@ -21,7 +21,7 @@
|
|||||||
#include "PostedDialog.h"
|
#include "PostedDialog.h"
|
||||||
#include "PostedItem.h"
|
#include "PostedItem.h"
|
||||||
#include "PostedGroupDialog.h"
|
#include "PostedGroupDialog.h"
|
||||||
#include "PostedListWidget.h"
|
#include "PostedListWidgetWithModel.h"
|
||||||
#include "PostedUserNotify.h"
|
#include "PostedUserNotify.h"
|
||||||
#include "gui/gxs/GxsGroupShareKey.h"
|
#include "gui/gxs/GxsGroupShareKey.h"
|
||||||
#include "gui/settings/rsharesettings.h"
|
#include "gui/settings/rsharesettings.h"
|
||||||
@ -195,7 +195,7 @@ int PostedDialog::shareKeyType()
|
|||||||
|
|
||||||
GxsMessageFrameWidget *PostedDialog::createMessageFrameWidget(const RsGxsGroupId &groupId)
|
GxsMessageFrameWidget *PostedDialog::createMessageFrameWidget(const RsGxsGroupId &groupId)
|
||||||
{
|
{
|
||||||
return new PostedListWidget(groupId);
|
return new PostedListWidgetWithModel(groupId);
|
||||||
}
|
}
|
||||||
|
|
||||||
RsGxsCommentService *PostedDialog::getCommentService()
|
RsGxsCommentService *PostedDialog::getCommentService()
|
||||||
|
1170
retroshare-gui/src/gui/Posted/PostedListWidgetWithModel.cpp
Normal file
1170
retroshare-gui/src/gui/Posted/PostedListWidgetWithModel.cpp
Normal file
File diff suppressed because it is too large
Load Diff
175
retroshare-gui/src/gui/Posted/PostedListWidgetWithModel.h
Normal file
175
retroshare-gui/src/gui/Posted/PostedListWidgetWithModel.h
Normal file
@ -0,0 +1,175 @@
|
|||||||
|
/*******************************************************************************
|
||||||
|
* retroshare-gui/src/gui/gxschannels/BoardPostsWidget.h *
|
||||||
|
* *
|
||||||
|
* Copyright 2013 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 _GXS_CHANNELPOSTSWIDGET_H
|
||||||
|
#define _GXS_CHANNELPOSTSWIDGET_H
|
||||||
|
|
||||||
|
#include <map>
|
||||||
|
|
||||||
|
#include <QStyledItemDelegate>
|
||||||
|
|
||||||
|
#include "retroshare/rsposted.h"
|
||||||
|
|
||||||
|
#include "gui/gxs/GxsMessageFramePostWidget.h"
|
||||||
|
#include "gui/feeds/FeedHolder.h"
|
||||||
|
#include "gui/Posted/BoardPostDisplayWidget.h"
|
||||||
|
|
||||||
|
namespace Ui {
|
||||||
|
class PostedListWidgetWithModel;
|
||||||
|
}
|
||||||
|
|
||||||
|
class QTreeWidgetItem;
|
||||||
|
class QSortFilterProxyModel;
|
||||||
|
class RsPostedPostsModel;
|
||||||
|
class PostedListWidgetWithModel;
|
||||||
|
|
||||||
|
class PostedPostDelegate: public QAbstractItemDelegate
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
|
||||||
|
public:
|
||||||
|
PostedPostDelegate(PostedListWidgetWithModel *p,QObject *parent=0) : QAbstractItemDelegate(parent),mCellWidthPix(100),mPostListWidget(p),mDisplayMode(BoardPostDisplayWidget_compact::DISPLAY_MODE_COMPACT){}
|
||||||
|
virtual ~PostedPostDelegate(){}
|
||||||
|
|
||||||
|
void paint(QPainter * painter, const QStyleOptionViewItem & option, const QModelIndex & index) const override;
|
||||||
|
QSize sizeHint(const QStyleOptionViewItem& option, const QModelIndex& index) const override;
|
||||||
|
void updateEditorGeometry(QWidget *editor, const QStyleOptionViewItem &option, const QModelIndex &) const override;
|
||||||
|
QWidget *createEditor(QWidget *parent, const QStyleOptionViewItem &option, const QModelIndex &index) const override;
|
||||||
|
|
||||||
|
void setCellWidth(int pix) { mCellWidthPix = pix; }
|
||||||
|
void setDisplayMode(BoardPostDisplayWidget_compact::DisplayMode dm) { mDisplayMode = dm; }
|
||||||
|
BoardPostDisplayWidget_compact::DisplayMode getDisplayMode() const { return mDisplayMode; }
|
||||||
|
|
||||||
|
public slots:
|
||||||
|
void expandItem(RsGxsMessageId msgId,bool expanded);
|
||||||
|
//void commentItem(RsGxsMessageId msgId,bool comment);
|
||||||
|
|
||||||
|
private:
|
||||||
|
// The class keeps a list of expanded items. Because items are constantly re-created, it is not possible
|
||||||
|
// to let the items themselves hold that information.
|
||||||
|
|
||||||
|
uint8_t displayFlags(const RsGxsMessageId& id) const;
|
||||||
|
|
||||||
|
int mCellWidthPix;
|
||||||
|
PostedListWidgetWithModel *mPostListWidget; // used for sending vote signals and so on.
|
||||||
|
BoardPostDisplayWidget_compact::DisplayMode mDisplayMode;
|
||||||
|
std::set<RsGxsMessageId> mExpandedItems;
|
||||||
|
std::set<RsGxsMessageId> mShowCommentItems;
|
||||||
|
};
|
||||||
|
|
||||||
|
class PostedListWidgetWithModel: public GxsMessageFrameWidget
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
|
||||||
|
public:
|
||||||
|
/* Filters */
|
||||||
|
enum Filter {
|
||||||
|
SORT_TITLE = 1,
|
||||||
|
SORT_MSG = 2,
|
||||||
|
SORT_FILE_NAME = 3
|
||||||
|
};
|
||||||
|
|
||||||
|
public:
|
||||||
|
/** Default Constructor */
|
||||||
|
PostedListWidgetWithModel(const RsGxsGroupId &postedId, QWidget *parent = 0);
|
||||||
|
/** Default Destructor */
|
||||||
|
~PostedListWidgetWithModel();
|
||||||
|
|
||||||
|
/* GxsMessageFrameWidget */
|
||||||
|
virtual QIcon groupIcon() override;
|
||||||
|
virtual void groupIdChanged() override { updateDisplay(true); }
|
||||||
|
virtual QString groupName(bool) override ;
|
||||||
|
virtual bool navigate(const RsGxsMessageId&) override;
|
||||||
|
|
||||||
|
void updateDisplay(bool complete) ;
|
||||||
|
void forceRedraw(); // does not re-load the data, but makes sure the underlying model triggers a full redraw, recomputes sizes, etc.
|
||||||
|
|
||||||
|
#ifdef TODO
|
||||||
|
/* FeedHolder */
|
||||||
|
virtual QScrollArea *getScrollArea();
|
||||||
|
virtual void deleteFeedItem(FeedItem *feedItem, uint32_t type);
|
||||||
|
virtual void openChat(const RsPeerId& peerId);
|
||||||
|
#endif
|
||||||
|
public slots:
|
||||||
|
virtual void openComments(const RsGxsMessageId &msgId);
|
||||||
|
virtual void changeReadStatus(const RsGxsMessageId& msgId,bool b);
|
||||||
|
|
||||||
|
protected:
|
||||||
|
/* GxsMessageFramePostWidget */
|
||||||
|
virtual void groupNameChanged(const QString &name);
|
||||||
|
|
||||||
|
#ifdef TODO
|
||||||
|
virtual bool insertGroupData(const RsGxsGenericGroupData *data) override;
|
||||||
|
#endif
|
||||||
|
virtual void blank() override;
|
||||||
|
|
||||||
|
#ifdef TODO
|
||||||
|
virtual bool getGroupData(RsGxsGenericGroupData *& data) override;
|
||||||
|
virtual void getMsgData(const std::set<RsGxsMessageId>& msgIds,std::vector<RsGxsGenericMsgData*>& posts) override;
|
||||||
|
virtual void getAllMsgData(std::vector<RsGxsGenericMsgData*>& posts) override;
|
||||||
|
virtual void insertPosts(const std::vector<RsGxsGenericMsgData*>& posts) override;
|
||||||
|
virtual void insertAllPosts(const std::vector<RsGxsGenericMsgData*>& posts, GxsMessageFramePostThread *thread) override;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* GxsMessageFrameWidget */
|
||||||
|
virtual void setAllMessagesReadDo(bool read, uint32_t &token) override;
|
||||||
|
|
||||||
|
private slots:
|
||||||
|
void showAuthorInPeople();
|
||||||
|
void tabCloseRequested(int index);
|
||||||
|
void updateSorting(int);
|
||||||
|
void switchDisplayMode();
|
||||||
|
void updateGroupData();
|
||||||
|
void createMsg();
|
||||||
|
void subscribeGroup(bool subscribe);
|
||||||
|
void settingsChanged();
|
||||||
|
void postPostLoad();
|
||||||
|
void postContextMenu(const QPoint&);
|
||||||
|
void copyMessageLink();
|
||||||
|
void next10Posts();
|
||||||
|
void prev10Posts();
|
||||||
|
void filterItems(QString s);
|
||||||
|
|
||||||
|
public slots:
|
||||||
|
void handlePostsTreeSizeChange(QSize size);
|
||||||
|
void voteMsg(RsGxsGrpMsgIdPair msg,bool up_or_down);
|
||||||
|
void markCurrentPostAsRead();
|
||||||
|
|
||||||
|
private:
|
||||||
|
void processSettings(bool load);
|
||||||
|
int viewMode();
|
||||||
|
|
||||||
|
void insertBoardDetails(const RsPostedGroup &group);
|
||||||
|
void handleEvent_main_thread(std::shared_ptr<const RsEvent> event);
|
||||||
|
|
||||||
|
private:
|
||||||
|
RsPostedGroup mGroup;
|
||||||
|
RsEventsHandlerId_t mEventHandlerId ;
|
||||||
|
|
||||||
|
RsPostedPostsModel *mPostedPostsModel;
|
||||||
|
PostedPostDelegate *mPostedPostsDelegate;
|
||||||
|
|
||||||
|
RsGxsMessageId mSelectedPost;
|
||||||
|
|
||||||
|
/* UI - from Designer */
|
||||||
|
Ui::PostedListWidgetWithModel *ui;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
560
retroshare-gui/src/gui/Posted/PostedListWidgetWithModel.ui
Normal file
560
retroshare-gui/src/gui/Posted/PostedListWidgetWithModel.ui
Normal file
@ -0,0 +1,560 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<ui version="4.0">
|
||||||
|
<class>PostedListWidgetWithModel</class>
|
||||||
|
<widget class="QWidget" name="PostedListWidgetWithModel">
|
||||||
|
<property name="geometry">
|
||||||
|
<rect>
|
||||||
|
<x>0</x>
|
||||||
|
<y>0</y>
|
||||||
|
<width>731</width>
|
||||||
|
<height>593</height>
|
||||||
|
</rect>
|
||||||
|
</property>
|
||||||
|
<property name="windowTitle">
|
||||||
|
<string>Form</string>
|
||||||
|
</property>
|
||||||
|
<layout class="QHBoxLayout" name="horizontalLayout">
|
||||||
|
<item>
|
||||||
|
<widget class="RSTabWidget" name="tabWidget">
|
||||||
|
<property name="currentIndex">
|
||||||
|
<number>1</number>
|
||||||
|
</property>
|
||||||
|
<property name="tabsClosable">
|
||||||
|
<bool>true</bool>
|
||||||
|
</property>
|
||||||
|
<widget class="QWidget" name="tab">
|
||||||
|
<attribute name="title">
|
||||||
|
<string>Details</string>
|
||||||
|
</attribute>
|
||||||
|
<layout class="QVBoxLayout" name="verticalLayout_3">
|
||||||
|
<item>
|
||||||
|
<widget class="QGroupBox" name="infoGroupBox">
|
||||||
|
<property name="autoFillBackground">
|
||||||
|
<bool>false</bool>
|
||||||
|
</property>
|
||||||
|
<property name="styleSheet">
|
||||||
|
<string notr="true"/>
|
||||||
|
</property>
|
||||||
|
<property name="title">
|
||||||
|
<string>Board Details</string>
|
||||||
|
</property>
|
||||||
|
<property name="flat">
|
||||||
|
<bool>false</bool>
|
||||||
|
</property>
|
||||||
|
<property name="checkable">
|
||||||
|
<bool>false</bool>
|
||||||
|
</property>
|
||||||
|
<layout class="QVBoxLayout" name="verticalLayout">
|
||||||
|
<property name="topMargin">
|
||||||
|
<number>6</number>
|
||||||
|
</property>
|
||||||
|
<item>
|
||||||
|
<layout class="QFormLayout" name="formLayout">
|
||||||
|
<property name="topMargin">
|
||||||
|
<number>0</number>
|
||||||
|
</property>
|
||||||
|
<item row="3" column="0">
|
||||||
|
<widget class="QLabel" name="label_4">
|
||||||
|
<property name="font">
|
||||||
|
<font>
|
||||||
|
<weight>75</weight>
|
||||||
|
<bold>true</bold>
|
||||||
|
</font>
|
||||||
|
</property>
|
||||||
|
<property name="text">
|
||||||
|
<string>Popularity</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="3" column="1">
|
||||||
|
<widget class="QLabel" name="poplabel">
|
||||||
|
<property name="font">
|
||||||
|
<font>
|
||||||
|
<weight>75</weight>
|
||||||
|
<bold>true</bold>
|
||||||
|
</font>
|
||||||
|
</property>
|
||||||
|
<property name="text">
|
||||||
|
<string>0</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="4" column="0">
|
||||||
|
<widget class="QLabel" name="infoPostsLabel">
|
||||||
|
<property name="sizePolicy">
|
||||||
|
<sizepolicy hsizetype="Maximum" vsizetype="Preferred">
|
||||||
|
<horstretch>0</horstretch>
|
||||||
|
<verstretch>0</verstretch>
|
||||||
|
</sizepolicy>
|
||||||
|
</property>
|
||||||
|
<property name="font">
|
||||||
|
<font>
|
||||||
|
<weight>75</weight>
|
||||||
|
<bold>true</bold>
|
||||||
|
</font>
|
||||||
|
</property>
|
||||||
|
<property name="text">
|
||||||
|
<string>Posts</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="4" column="1">
|
||||||
|
<widget class="QLabel" name="infoPosts">
|
||||||
|
<property name="font">
|
||||||
|
<font>
|
||||||
|
<weight>75</weight>
|
||||||
|
<bold>true</bold>
|
||||||
|
</font>
|
||||||
|
</property>
|
||||||
|
<property name="text">
|
||||||
|
<string notr="true">0</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="7" column="0">
|
||||||
|
<widget class="QLabel" name="createdlabel">
|
||||||
|
<property name="font">
|
||||||
|
<font>
|
||||||
|
<weight>75</weight>
|
||||||
|
<bold>true</bold>
|
||||||
|
</font>
|
||||||
|
</property>
|
||||||
|
<property name="text">
|
||||||
|
<string>Created</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="7" column="1">
|
||||||
|
<widget class="QLabel" name="createdinfolabel">
|
||||||
|
<property name="text">
|
||||||
|
<string>unknown</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="9" column="0">
|
||||||
|
<widget class="QLabel" name="label">
|
||||||
|
<property name="font">
|
||||||
|
<font>
|
||||||
|
<weight>75</weight>
|
||||||
|
<bold>true</bold>
|
||||||
|
</font>
|
||||||
|
</property>
|
||||||
|
<property name="text">
|
||||||
|
<string>Administrator:</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="9" column="1">
|
||||||
|
<widget class="GxsIdLabel" name="infoAdministrator">
|
||||||
|
<property name="text">
|
||||||
|
<string>unknown</string>
|
||||||
|
</property>
|
||||||
|
<property name="openExternalLinks">
|
||||||
|
<bool>true</bool>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="10" column="0">
|
||||||
|
<widget class="QLabel" name="label_3">
|
||||||
|
<property name="font">
|
||||||
|
<font>
|
||||||
|
<weight>75</weight>
|
||||||
|
<bold>true</bold>
|
||||||
|
</font>
|
||||||
|
</property>
|
||||||
|
<property name="text">
|
||||||
|
<string>Distribution:</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="10" column="1">
|
||||||
|
<widget class="QLabel" name="infoDistribution">
|
||||||
|
<property name="text">
|
||||||
|
<string>unknown</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="6" column="0">
|
||||||
|
<widget class="QLabel" name="infoLastPostLabel">
|
||||||
|
<property name="sizePolicy">
|
||||||
|
<sizepolicy hsizetype="Maximum" vsizetype="Preferred">
|
||||||
|
<horstretch>0</horstretch>
|
||||||
|
<verstretch>0</verstretch>
|
||||||
|
</sizepolicy>
|
||||||
|
</property>
|
||||||
|
<property name="font">
|
||||||
|
<font>
|
||||||
|
<weight>75</weight>
|
||||||
|
<bold>true</bold>
|
||||||
|
</font>
|
||||||
|
</property>
|
||||||
|
<property name="text">
|
||||||
|
<string>Last Post:</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="6" column="1">
|
||||||
|
<widget class="QLabel" name="infoLastPost">
|
||||||
|
<property name="text">
|
||||||
|
<string notr="true">unknown</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="1" column="0">
|
||||||
|
<widget class="QLabel" name="logoLabel">
|
||||||
|
<property name="minimumSize">
|
||||||
|
<size>
|
||||||
|
<width>64</width>
|
||||||
|
<height>64</height>
|
||||||
|
</size>
|
||||||
|
</property>
|
||||||
|
<property name="maximumSize">
|
||||||
|
<size>
|
||||||
|
<width>64</width>
|
||||||
|
<height>64</height>
|
||||||
|
</size>
|
||||||
|
</property>
|
||||||
|
<property name="pixmap">
|
||||||
|
<pixmap resource="../icons.qrc">:/icons/png/postedlinks.png</pixmap>
|
||||||
|
</property>
|
||||||
|
<property name="scaledContents">
|
||||||
|
<bool>true</bool>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="1" column="1">
|
||||||
|
<widget class="QLabel" name="namelabel">
|
||||||
|
<property name="font">
|
||||||
|
<font>
|
||||||
|
<pointsize>14</pointsize>
|
||||||
|
</font>
|
||||||
|
</property>
|
||||||
|
<property name="text">
|
||||||
|
<string>TextLabel</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="SubscribeToolButton" name="subscribeToolButton">
|
||||||
|
<property name="sizePolicy">
|
||||||
|
<sizepolicy hsizetype="Preferred" vsizetype="Preferred">
|
||||||
|
<horstretch>0</horstretch>
|
||||||
|
<verstretch>0</verstretch>
|
||||||
|
</sizepolicy>
|
||||||
|
</property>
|
||||||
|
<property name="font">
|
||||||
|
<font>
|
||||||
|
<weight>50</weight>
|
||||||
|
<italic>false</italic>
|
||||||
|
<bold>false</bold>
|
||||||
|
</font>
|
||||||
|
</property>
|
||||||
|
<property name="styleSheet">
|
||||||
|
<string notr="true"/>
|
||||||
|
</property>
|
||||||
|
<property name="text">
|
||||||
|
<string notr="true">Subscribe</string>
|
||||||
|
</property>
|
||||||
|
<property name="autoRaise">
|
||||||
|
<bool>false</bool>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QTextBrowser" name="infoDescription">
|
||||||
|
<property name="styleSheet">
|
||||||
|
<string notr="true"/>
|
||||||
|
</property>
|
||||||
|
<property name="html">
|
||||||
|
<string notr="true"><!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd">
|
||||||
|
<html><head><meta name="qrichtext" content="1" /><style type="text/css">
|
||||||
|
p, li { white-space: pre-wrap; }
|
||||||
|
</style></head><body style=" font-family:'Ubuntu'; font-size:11pt; font-weight:400; font-style:normal;">
|
||||||
|
<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'MS Shell Dlg 2'; font-size:8pt;">Description</span></p></body></html></string>
|
||||||
|
</property>
|
||||||
|
<property name="textInteractionFlags">
|
||||||
|
<set>Qt::LinksAccessibleByMouse|Qt::TextSelectableByMouse</set>
|
||||||
|
</property>
|
||||||
|
<property name="openExternalLinks">
|
||||||
|
<bool>true</bool>
|
||||||
|
</property>
|
||||||
|
<property name="openLinks">
|
||||||
|
<bool>true</bool>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</widget>
|
||||||
|
<widget class="QWidget" name="tab_2">
|
||||||
|
<attribute name="title">
|
||||||
|
<string>Posts</string>
|
||||||
|
</attribute>
|
||||||
|
<layout class="QVBoxLayout" name="verticalLayout_2">
|
||||||
|
<item>
|
||||||
|
<widget class="QFrame" name="headerFrame">
|
||||||
|
<property name="frameShape">
|
||||||
|
<enum>QFrame::Box</enum>
|
||||||
|
</property>
|
||||||
|
<property name="frameShadow">
|
||||||
|
<enum>QFrame::Sunken</enum>
|
||||||
|
</property>
|
||||||
|
<layout class="QHBoxLayout" name="horizontalLayout_3">
|
||||||
|
<property name="leftMargin">
|
||||||
|
<number>6</number>
|
||||||
|
</property>
|
||||||
|
<property name="topMargin">
|
||||||
|
<number>2</number>
|
||||||
|
</property>
|
||||||
|
<property name="rightMargin">
|
||||||
|
<number>6</number>
|
||||||
|
</property>
|
||||||
|
<property name="bottomMargin">
|
||||||
|
<number>2</number>
|
||||||
|
</property>
|
||||||
|
<item>
|
||||||
|
<widget class="QToolButton" name="submitPostButton">
|
||||||
|
<property name="sizePolicy">
|
||||||
|
<sizepolicy hsizetype="Fixed" vsizetype="Fixed">
|
||||||
|
<horstretch>0</horstretch>
|
||||||
|
<verstretch>0</verstretch>
|
||||||
|
</sizepolicy>
|
||||||
|
</property>
|
||||||
|
<property name="text">
|
||||||
|
<string>Create Post</string>
|
||||||
|
</property>
|
||||||
|
<property name="icon">
|
||||||
|
<iconset resource="Posted_images.qrc">
|
||||||
|
<normaloff>:/images/write.png</normaloff>:/images/write.png</iconset>
|
||||||
|
</property>
|
||||||
|
<property name="iconSize">
|
||||||
|
<size>
|
||||||
|
<width>24</width>
|
||||||
|
<height>24</height>
|
||||||
|
</size>
|
||||||
|
</property>
|
||||||
|
<property name="toolButtonStyle">
|
||||||
|
<enum>Qt::ToolButtonTextBesideIcon</enum>
|
||||||
|
</property>
|
||||||
|
<property name="autoRaise">
|
||||||
|
<bool>true</bool>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QComboBox" name="sortStrategy_CB">
|
||||||
|
<property name="toolTip">
|
||||||
|
<string><html><head/><body><p><span style=" font-family:'-apple-system,BlinkMacSystemFont,Segoe UI,Helvetica,Arial,sans-serif,Apple Color Emoji,Segoe UI Emoji,Segoe UI Symbol'; font-size:14px; color:#24292e; background-color:#ffffff;">Select sorting</span></p></body></html></string>
|
||||||
|
</property>
|
||||||
|
<property name="styleSheet">
|
||||||
|
<string notr="true"/>
|
||||||
|
</property>
|
||||||
|
<property name="currentIndex">
|
||||||
|
<number>0</number>
|
||||||
|
</property>
|
||||||
|
<property name="iconSize">
|
||||||
|
<size>
|
||||||
|
<width>24</width>
|
||||||
|
<height>24</height>
|
||||||
|
</size>
|
||||||
|
</property>
|
||||||
|
<item>
|
||||||
|
<property name="text">
|
||||||
|
<string>New</string>
|
||||||
|
</property>
|
||||||
|
<property name="icon">
|
||||||
|
<iconset resource="../icons.qrc">
|
||||||
|
<normaloff>:/icons/png/new.png</normaloff>:/icons/png/new.png</iconset>
|
||||||
|
</property>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<property name="text">
|
||||||
|
<string>Top</string>
|
||||||
|
</property>
|
||||||
|
<property name="icon">
|
||||||
|
<iconset resource="../icons.qrc">
|
||||||
|
<normaloff>:/icons/png/top.png</normaloff>:/icons/png/top.png</iconset>
|
||||||
|
</property>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<property name="text">
|
||||||
|
<string>Hot</string>
|
||||||
|
</property>
|
||||||
|
<property name="icon">
|
||||||
|
<iconset resource="../icons.qrc">
|
||||||
|
<normaloff>:/icons/png/flame.png</normaloff>:/icons/png/flame.png</iconset>
|
||||||
|
</property>
|
||||||
|
</item>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="LineEditClear" name="filter_LE">
|
||||||
|
<property name="placeholderText">
|
||||||
|
<string>Search</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<spacer name="horizontalSpacer_2">
|
||||||
|
<property name="orientation">
|
||||||
|
<enum>Qt::Horizontal</enum>
|
||||||
|
</property>
|
||||||
|
<property name="sizeHint" stdset="0">
|
||||||
|
<size>
|
||||||
|
<width>40</width>
|
||||||
|
<height>20</height>
|
||||||
|
</size>
|
||||||
|
</property>
|
||||||
|
</spacer>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<layout class="QHBoxLayout" name="horizontalLayout_2">
|
||||||
|
<property name="spacing">
|
||||||
|
<number>0</number>
|
||||||
|
</property>
|
||||||
|
<item>
|
||||||
|
<widget class="QPushButton" name="viewModeButton">
|
||||||
|
<property name="font">
|
||||||
|
<font>
|
||||||
|
<kerning>true</kerning>
|
||||||
|
</font>
|
||||||
|
</property>
|
||||||
|
<property name="toolTip">
|
||||||
|
<string>Classic view</string>
|
||||||
|
</property>
|
||||||
|
<property name="icon">
|
||||||
|
<iconset resource="Posted_images.qrc">
|
||||||
|
<normaloff>:/images/classic.png</normaloff>:/images/classic.png</iconset>
|
||||||
|
</property>
|
||||||
|
<property name="iconSize">
|
||||||
|
<size>
|
||||||
|
<width>24</width>
|
||||||
|
<height>24</height>
|
||||||
|
</size>
|
||||||
|
</property>
|
||||||
|
<property name="checkable">
|
||||||
|
<bool>true</bool>
|
||||||
|
</property>
|
||||||
|
<property name="flat">
|
||||||
|
<bool>true</bool>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QPushButton" name="prevButton">
|
||||||
|
<property name="toolTip">
|
||||||
|
<string>Previous</string>
|
||||||
|
</property>
|
||||||
|
<property name="text">
|
||||||
|
<string/>
|
||||||
|
</property>
|
||||||
|
<property name="icon">
|
||||||
|
<iconset resource="../icons.qrc">
|
||||||
|
<normaloff>:/icons/png/arrow-left.png</normaloff>:/icons/png/arrow-left.png</iconset>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QLabel" name="showLabel">
|
||||||
|
<property name="text">
|
||||||
|
<string>1-10</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QPushButton" name="nextButton">
|
||||||
|
<property name="toolTip">
|
||||||
|
<string>Next</string>
|
||||||
|
</property>
|
||||||
|
<property name="text">
|
||||||
|
<string/>
|
||||||
|
</property>
|
||||||
|
<property name="icon">
|
||||||
|
<iconset resource="../icons.qrc">
|
||||||
|
<normaloff>:/icons/png/arrow-right.png</normaloff>:/icons/png/arrow-right.png</iconset>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="GxsIdChooser" name="idChooser">
|
||||||
|
<property name="toolTip">
|
||||||
|
<string><html><head/><body><p>Default identity used when voting</p></body></html></string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="RSTreeView" name="postsTree">
|
||||||
|
<property name="contextMenuPolicy">
|
||||||
|
<enum>Qt::CustomContextMenu</enum>
|
||||||
|
</property>
|
||||||
|
<property name="editTriggers">
|
||||||
|
<set>QAbstractItemView::CurrentChanged|QAbstractItemView::SelectedClicked</set>
|
||||||
|
</property>
|
||||||
|
<property name="verticalScrollMode">
|
||||||
|
<enum>QAbstractItemView::ScrollPerPixel</enum>
|
||||||
|
</property>
|
||||||
|
<property name="indentation">
|
||||||
|
<number>0</number>
|
||||||
|
</property>
|
||||||
|
<property name="rootIsDecorated">
|
||||||
|
<bool>false</bool>
|
||||||
|
</property>
|
||||||
|
<attribute name="headerVisible">
|
||||||
|
<bool>false</bool>
|
||||||
|
</attribute>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</widget>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</widget>
|
||||||
|
<customwidgets>
|
||||||
|
<customwidget>
|
||||||
|
<class>GxsIdLabel</class>
|
||||||
|
<extends>QLabel</extends>
|
||||||
|
<header>gui/gxs/GxsIdLabel.h</header>
|
||||||
|
</customwidget>
|
||||||
|
<customwidget>
|
||||||
|
<class>SubscribeToolButton</class>
|
||||||
|
<extends>QToolButton</extends>
|
||||||
|
<header>gui/common/SubscribeToolButton.h</header>
|
||||||
|
</customwidget>
|
||||||
|
<customwidget>
|
||||||
|
<class>RSTreeView</class>
|
||||||
|
<extends>QTreeView</extends>
|
||||||
|
<header>gui/common/RSTreeView.h</header>
|
||||||
|
</customwidget>
|
||||||
|
<customwidget>
|
||||||
|
<class>LineEditClear</class>
|
||||||
|
<extends>QLineEdit</extends>
|
||||||
|
<header>gui/common/LineEditClear.h</header>
|
||||||
|
</customwidget>
|
||||||
|
<customwidget>
|
||||||
|
<class>GxsIdChooser</class>
|
||||||
|
<extends>QComboBox</extends>
|
||||||
|
<header>gui/gxs/GxsIdChooser.h</header>
|
||||||
|
</customwidget>
|
||||||
|
<customwidget>
|
||||||
|
<class>RSTabWidget</class>
|
||||||
|
<extends>QTabWidget</extends>
|
||||||
|
<header>gui/common/RSTabWidget.h</header>
|
||||||
|
<container>1</container>
|
||||||
|
</customwidget>
|
||||||
|
</customwidgets>
|
||||||
|
<resources>
|
||||||
|
<include location="Posted_images.qrc"/>
|
||||||
|
<include location="../icons.qrc"/>
|
||||||
|
</resources>
|
||||||
|
<connections/>
|
||||||
|
</ui>
|
794
retroshare-gui/src/gui/Posted/PostedPostsModel.cpp
Normal file
794
retroshare-gui/src/gui/Posted/PostedPostsModel.cpp
Normal file
@ -0,0 +1,794 @@
|
|||||||
|
/*******************************************************************************
|
||||||
|
* retroshare-gui/src/gui/gxschannels/GxsChannelPostsModel.cpp *
|
||||||
|
* *
|
||||||
|
* Copyright 2020 by Cyril Soler <csoler@users.sourceforge.net> *
|
||||||
|
* *
|
||||||
|
* 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 <QApplication>
|
||||||
|
#include <QFontMetrics>
|
||||||
|
#include <QModelIndex>
|
||||||
|
#include <QIcon>
|
||||||
|
|
||||||
|
#include "retroshare/rsgxsflags.h"
|
||||||
|
#include "retroshare/rsexpr.h"
|
||||||
|
|
||||||
|
#include "gui/common/FilesDefs.h"
|
||||||
|
#include "util/qtthreadsutils.h"
|
||||||
|
#include "util/HandleRichText.h"
|
||||||
|
#include "util/DateTime.h"
|
||||||
|
|
||||||
|
#include "PostedPostsModel.h"
|
||||||
|
|
||||||
|
//#define DEBUG_CHANNEL_MODEL
|
||||||
|
|
||||||
|
Q_DECLARE_METATYPE(RsMsgMetaData)
|
||||||
|
Q_DECLARE_METATYPE(RsPostedPost)
|
||||||
|
|
||||||
|
const uint32_t RsPostedPostsModel::DEFAULT_DISPLAYED_NB_POSTS = 10;
|
||||||
|
|
||||||
|
std::ostream& operator<<(std::ostream& o, const QModelIndex& i);// defined elsewhere
|
||||||
|
|
||||||
|
RsPostedPostsModel::RsPostedPostsModel(QObject *parent)
|
||||||
|
: QAbstractItemModel(parent), mTreeMode(TREE_MODE_PLAIN)
|
||||||
|
{
|
||||||
|
initEmptyHierarchy();
|
||||||
|
|
||||||
|
mEventHandlerId = 0;
|
||||||
|
mSortingStrategy = SORT_NEW_SCORE;
|
||||||
|
|
||||||
|
// Needs to be asynced because this function is called by another thread!
|
||||||
|
|
||||||
|
rsEvents->registerEventsHandler( [this](std::shared_ptr<const RsEvent> event)
|
||||||
|
{
|
||||||
|
RsQThreadUtils::postToObject([=](){ handleEvent_main_thread(event); }, this );
|
||||||
|
}, mEventHandlerId, RsEventType::GXS_POSTED);
|
||||||
|
}
|
||||||
|
|
||||||
|
RsPostedPostsModel::~RsPostedPostsModel()
|
||||||
|
{
|
||||||
|
rsEvents->unregisterEventsHandler(mEventHandlerId);
|
||||||
|
}
|
||||||
|
|
||||||
|
void RsPostedPostsModel::handleEvent_main_thread(std::shared_ptr<const RsEvent> event)
|
||||||
|
{
|
||||||
|
const RsGxsPostedEvent *e = dynamic_cast<const RsGxsPostedEvent*>(event.get());
|
||||||
|
|
||||||
|
if(!e)
|
||||||
|
return;
|
||||||
|
|
||||||
|
switch(e->mPostedEventCode)
|
||||||
|
{
|
||||||
|
case RsPostedEventCode::UPDATED_MESSAGE:
|
||||||
|
case RsPostedEventCode::READ_STATUS_CHANGED:
|
||||||
|
case RsPostedEventCode::MESSAGE_VOTES_UPDATED:
|
||||||
|
case RsPostedEventCode::NEW_MESSAGE:
|
||||||
|
{
|
||||||
|
// Normally we should just emit dataChanged() on the index of the data that has changed:
|
||||||
|
//
|
||||||
|
// We need to update the data!
|
||||||
|
|
||||||
|
if(e->mPostedGroupId == mPostedGroup.mMeta.mGroupId)
|
||||||
|
RsThread::async([this, e]()
|
||||||
|
{
|
||||||
|
// 1 - get message data from p3GxsChannels
|
||||||
|
|
||||||
|
std::vector<RsPostedPost> posts;
|
||||||
|
std::vector<RsGxsComment> comments;
|
||||||
|
std::vector<RsGxsVote> votes;
|
||||||
|
|
||||||
|
if(!rsPosted->getBoardContent(mPostedGroup.mMeta.mGroupId,std::set<RsGxsMessageId>{ e->mPostedMsgId }, posts,comments,votes))
|
||||||
|
{
|
||||||
|
std::cerr << __PRETTY_FUNCTION__ << " failed to retrieve channel message data for channel/msg " << e->mPostedGroupId << "/" << e->mPostedMsgId << std::endl;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 2 - update the model in the UI thread.
|
||||||
|
|
||||||
|
RsQThreadUtils::postToObject( [posts,comments,votes,this]()
|
||||||
|
{
|
||||||
|
for(uint32_t i=0;i<posts.size();++i)
|
||||||
|
{
|
||||||
|
// linear search. Not good at all, but normally this is for a single post.
|
||||||
|
|
||||||
|
for(uint32_t j=0;j<mPosts.size();++j)
|
||||||
|
if(mPosts[j].mMeta.mMsgId == posts[i].mMeta.mMsgId)
|
||||||
|
{
|
||||||
|
mPosts[j] = posts[i];
|
||||||
|
|
||||||
|
//emit dataChanged(createIndex(0,0,(void*)NULL), createIndex(mFilteredPosts.size(),0,(void*)NULL));
|
||||||
|
|
||||||
|
preMods();
|
||||||
|
postMods();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},this);
|
||||||
|
});
|
||||||
|
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void RsPostedPostsModel::initEmptyHierarchy()
|
||||||
|
{
|
||||||
|
preMods();
|
||||||
|
|
||||||
|
mPosts.clear();
|
||||||
|
mFilteredPosts.clear();
|
||||||
|
mDisplayedNbPosts = DEFAULT_DISPLAYED_NB_POSTS;
|
||||||
|
mDisplayedStartIndex = 0;
|
||||||
|
|
||||||
|
postMods();
|
||||||
|
}
|
||||||
|
|
||||||
|
void RsPostedPostsModel::preMods()
|
||||||
|
{
|
||||||
|
beginResetModel();
|
||||||
|
}
|
||||||
|
void RsPostedPostsModel::postMods()
|
||||||
|
{
|
||||||
|
endResetModel();
|
||||||
|
|
||||||
|
emit dataChanged(createIndex(0,0,(void*)NULL), createIndex(mDisplayedNbPosts,0,(void*)NULL));
|
||||||
|
}
|
||||||
|
void RsPostedPostsModel::update()
|
||||||
|
{
|
||||||
|
emit dataChanged(createIndex(0,0,(void*)NULL), createIndex(mDisplayedNbPosts,0,(void*)NULL));
|
||||||
|
}
|
||||||
|
void RsPostedPostsModel::triggerRedraw()
|
||||||
|
{
|
||||||
|
preMods();
|
||||||
|
postMods();
|
||||||
|
}
|
||||||
|
|
||||||
|
void RsPostedPostsModel::setFilter(const QStringList& strings, uint32_t& count)
|
||||||
|
{
|
||||||
|
preMods();
|
||||||
|
|
||||||
|
beginRemoveRows(QModelIndex(),0,rowCount()-1);
|
||||||
|
endRemoveRows();
|
||||||
|
|
||||||
|
if(strings.empty())
|
||||||
|
{
|
||||||
|
mFilteredPosts.clear();
|
||||||
|
for(int i=0;i<mPosts.size();++i)
|
||||||
|
mFilteredPosts.push_back(i);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
mFilteredPosts.clear();
|
||||||
|
//mFilteredPosts.push_back(0);
|
||||||
|
|
||||||
|
for(int i=0;i<mPosts.size();++i)
|
||||||
|
{
|
||||||
|
bool passes_strings = true;
|
||||||
|
|
||||||
|
for(auto& s:strings)
|
||||||
|
passes_strings = passes_strings && QString::fromStdString(mPosts[i].mMeta.mMsgName).contains(s,Qt::CaseInsensitive);
|
||||||
|
|
||||||
|
if(passes_strings)
|
||||||
|
mFilteredPosts.push_back(i);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
count = mFilteredPosts.size();
|
||||||
|
|
||||||
|
mDisplayedStartIndex = 0;
|
||||||
|
mDisplayedNbPosts = std::min(count,DEFAULT_DISPLAYED_NB_POSTS) ;
|
||||||
|
|
||||||
|
std::cerr << "After filtering: " << count << " posts remain." << std::endl;
|
||||||
|
|
||||||
|
beginInsertRows(QModelIndex(),0,rowCount()-1);
|
||||||
|
endInsertRows();
|
||||||
|
|
||||||
|
postMods();
|
||||||
|
}
|
||||||
|
|
||||||
|
int RsPostedPostsModel::rowCount(const QModelIndex& parent) const
|
||||||
|
{
|
||||||
|
if(parent.column() > 0)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
if(mFilteredPosts.empty()) // security. Should never happen.
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
if(!parent.isValid())
|
||||||
|
return mDisplayedNbPosts;
|
||||||
|
|
||||||
|
RsErr() << __PRETTY_FUNCTION__ << " rowCount cannot figure out the porper number of rows." << std::endl;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int RsPostedPostsModel::columnCount(const QModelIndex &/*parent*/) const
|
||||||
|
{
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool RsPostedPostsModel::getPostData(const QModelIndex& i,RsPostedPost& fmpe) const
|
||||||
|
{
|
||||||
|
if(!i.isValid())
|
||||||
|
return true;
|
||||||
|
|
||||||
|
quintptr ref = i.internalId();
|
||||||
|
uint32_t entry = 0;
|
||||||
|
|
||||||
|
if(!convertRefPointerToTabEntry(ref,entry))
|
||||||
|
return false ;
|
||||||
|
|
||||||
|
fmpe = mPosts[mFilteredPosts[entry]];
|
||||||
|
|
||||||
|
return true;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
bool RsPostedPostsModel::hasChildren(const QModelIndex &parent) const
|
||||||
|
{
|
||||||
|
if(!parent.isValid())
|
||||||
|
return true;
|
||||||
|
|
||||||
|
return false; // by default, no post has children
|
||||||
|
}
|
||||||
|
|
||||||
|
bool RsPostedPostsModel::convertTabEntryToRefPointer(uint32_t entry,quintptr& ref)
|
||||||
|
{
|
||||||
|
// the pointer is formed the following way:
|
||||||
|
//
|
||||||
|
// [ 32 bits ]
|
||||||
|
//
|
||||||
|
// This means that the whole software has the following build-in limitation:
|
||||||
|
// * 4 B simultaenous posts. Should be enough !
|
||||||
|
|
||||||
|
ref = (intptr_t)(entry+1);
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool RsPostedPostsModel::convertRefPointerToTabEntry(quintptr ref, uint32_t& entry)
|
||||||
|
{
|
||||||
|
intptr_t val = (intptr_t)ref;
|
||||||
|
|
||||||
|
if(val > (1<<30)) // make sure the pointer is an int that fits in 32bits and not too big which would look suspicious
|
||||||
|
{
|
||||||
|
RsErr() << "(EE) trying to make a ChannelPostsModelIndex out of a number that is larger than 2^32-1 !" << std::endl;
|
||||||
|
return false ;
|
||||||
|
}
|
||||||
|
if(val==0)
|
||||||
|
{
|
||||||
|
RsErr() << "(EE) trying to make a ChannelPostsModelIndex out of index 0." << std::endl;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
entry = val - 1;
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
QModelIndex RsPostedPostsModel::index(int row, int column, const QModelIndex & parent) const
|
||||||
|
{
|
||||||
|
if(row < 0 || column < 0)
|
||||||
|
return QModelIndex();
|
||||||
|
|
||||||
|
quintptr ref = getChildRef(parent.internalId(),row);
|
||||||
|
|
||||||
|
#ifdef DEBUG_CHANNEL_MODEL
|
||||||
|
std::cerr << "index-3(" << row << "," << column << " parent=" << parent << ") : " << createIndex(row,column,ref) << std::endl;
|
||||||
|
#endif
|
||||||
|
return createIndex(row,column,ref) ;
|
||||||
|
}
|
||||||
|
|
||||||
|
QModelIndex RsPostedPostsModel::parent(const QModelIndex& index) const
|
||||||
|
{
|
||||||
|
if(!index.isValid())
|
||||||
|
return QModelIndex();
|
||||||
|
|
||||||
|
return QModelIndex(); // there's no hierarchy here. So nothing to do!
|
||||||
|
}
|
||||||
|
|
||||||
|
quintptr RsPostedPostsModel::getChildRef(quintptr ref,int index) const
|
||||||
|
{
|
||||||
|
if (index < 0)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
if(ref == quintptr(0))
|
||||||
|
{
|
||||||
|
quintptr new_ref;
|
||||||
|
convertTabEntryToRefPointer(index+mDisplayedStartIndex,new_ref);
|
||||||
|
return new_ref;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
return 0 ;
|
||||||
|
}
|
||||||
|
|
||||||
|
quintptr RsPostedPostsModel::getParentRow(quintptr ref,int& row) const
|
||||||
|
{
|
||||||
|
PostedPostsModelIndex ref_entry;
|
||||||
|
|
||||||
|
if(!convertRefPointerToTabEntry(ref,ref_entry) || ref_entry >= mFilteredPosts.size())
|
||||||
|
return 0 ;
|
||||||
|
|
||||||
|
if(ref_entry == 0)
|
||||||
|
{
|
||||||
|
RsErr() << "getParentRow() shouldn't be asked for the parent of NULL" << std::endl;
|
||||||
|
row = 0;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
row = ref_entry-1;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int RsPostedPostsModel::getChildrenCount(quintptr ref) const
|
||||||
|
{
|
||||||
|
uint32_t entry = 0 ;
|
||||||
|
|
||||||
|
if(ref == quintptr(0))
|
||||||
|
return rowCount()-1;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
QVariant RsPostedPostsModel::data(const QModelIndex& index, int role) const
|
||||||
|
{
|
||||||
|
#ifdef DEBUG_CHANNEL_MODEL
|
||||||
|
std::cerr << "calling data(" << index << ") role=" << role << std::endl;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
if(!index.isValid())
|
||||||
|
return QVariant();
|
||||||
|
|
||||||
|
switch(role)
|
||||||
|
{
|
||||||
|
case Qt::SizeHintRole: return sizeHintRole(index.column()) ;
|
||||||
|
case Qt::StatusTipRole:return QVariant();
|
||||||
|
default: break;
|
||||||
|
}
|
||||||
|
|
||||||
|
quintptr ref = (index.isValid())?index.internalId():0 ;
|
||||||
|
uint32_t entry = 0;
|
||||||
|
|
||||||
|
#ifdef DEBUG_CHANNEL_MODEL
|
||||||
|
std::cerr << "data(" << index << ")" ;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
if(!ref)
|
||||||
|
{
|
||||||
|
#ifdef DEBUG_CHANNEL_MODEL
|
||||||
|
std::cerr << " [empty]" << std::endl;
|
||||||
|
#endif
|
||||||
|
return QVariant() ;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(!convertRefPointerToTabEntry(ref,entry) || entry >= mFilteredPosts.size())
|
||||||
|
{
|
||||||
|
#ifdef DEBUG_CHANNEL_MODEL
|
||||||
|
std::cerr << "Bad pointer: " << (void*)ref << std::endl;
|
||||||
|
#endif
|
||||||
|
return QVariant() ;
|
||||||
|
}
|
||||||
|
|
||||||
|
const RsPostedPost& fmpe(mPosts[mFilteredPosts[entry]]);
|
||||||
|
|
||||||
|
switch(role)
|
||||||
|
{
|
||||||
|
case Qt::DisplayRole: return displayRole (fmpe,index.column()) ;
|
||||||
|
case Qt::UserRole: return userRole (fmpe,index.column()) ;
|
||||||
|
default:
|
||||||
|
return QVariant();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
QVariant RsPostedPostsModel::sizeHintRole(int col) const
|
||||||
|
{
|
||||||
|
float factor = QFontMetricsF(QApplication::font()).height()/14.0f ;
|
||||||
|
|
||||||
|
return QVariant( QSize(factor * 170, factor*14 ));
|
||||||
|
}
|
||||||
|
|
||||||
|
QVariant RsPostedPostsModel::displayRole(const RsPostedPost& fmpe,int col) const
|
||||||
|
{
|
||||||
|
switch(col)
|
||||||
|
{
|
||||||
|
default:
|
||||||
|
return QString::fromUtf8(fmpe.mMeta.mMsgName.c_str());
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
return QVariant("[ERROR]");
|
||||||
|
}
|
||||||
|
|
||||||
|
QVariant RsPostedPostsModel::userRole(const RsPostedPost& fmpe,int col) const
|
||||||
|
{
|
||||||
|
switch(col)
|
||||||
|
{
|
||||||
|
default:
|
||||||
|
return QVariant::fromValue(fmpe);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const RsGxsGroupId& RsPostedPostsModel::currentGroupId() const
|
||||||
|
{
|
||||||
|
return mPostedGroup.mMeta.mGroupId;
|
||||||
|
}
|
||||||
|
|
||||||
|
void RsPostedPostsModel::updateBoard(const RsGxsGroupId& board_group_id)
|
||||||
|
{
|
||||||
|
if(board_group_id.isNull())
|
||||||
|
return;
|
||||||
|
|
||||||
|
update_posts(board_group_id);
|
||||||
|
}
|
||||||
|
|
||||||
|
void RsPostedPostsModel::clear()
|
||||||
|
{
|
||||||
|
preMods();
|
||||||
|
|
||||||
|
initEmptyHierarchy();
|
||||||
|
|
||||||
|
postMods();
|
||||||
|
emit boardPostsLoaded();
|
||||||
|
}
|
||||||
|
|
||||||
|
class PostSorter
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
|
||||||
|
PostSorter(RsPostedPostsModel::SortingStrategy s) : mSortingStrategy(s) {}
|
||||||
|
|
||||||
|
bool operator()(const RsPostedPost& p1,const RsPostedPost& p2) const
|
||||||
|
{
|
||||||
|
switch(mSortingStrategy)
|
||||||
|
{
|
||||||
|
default:
|
||||||
|
case RsPostedPostsModel::SORT_NEW_SCORE : return p1.mNewScore > p2.mNewScore;
|
||||||
|
case RsPostedPostsModel::SORT_TOP_SCORE : return p1.mTopScore > p2.mTopScore;
|
||||||
|
case RsPostedPostsModel::SORT_HOT_SCORE : return p1.mHotScore > p2.mHotScore;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
RsPostedPostsModel::SortingStrategy mSortingStrategy;
|
||||||
|
};
|
||||||
|
|
||||||
|
Qt::ItemFlags RsPostedPostsModel::flags(const QModelIndex& index) const
|
||||||
|
{
|
||||||
|
if (!index.isValid())
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
return QAbstractItemModel::flags(index) | Qt::ItemIsEditable;
|
||||||
|
}
|
||||||
|
|
||||||
|
void RsPostedPostsModel::setSortingStrategy(RsPostedPostsModel::SortingStrategy s)
|
||||||
|
{
|
||||||
|
preMods();
|
||||||
|
|
||||||
|
mSortingStrategy = s;
|
||||||
|
std::sort(mPosts.begin(),mPosts.end(), PostSorter(s));
|
||||||
|
|
||||||
|
postMods();
|
||||||
|
}
|
||||||
|
|
||||||
|
void RsPostedPostsModel::setPostsInterval(int start,int nb_posts)
|
||||||
|
{
|
||||||
|
if(start >= mFilteredPosts.size())
|
||||||
|
return;
|
||||||
|
|
||||||
|
preMods();
|
||||||
|
|
||||||
|
uint32_t old_nb_rows = rowCount() ;
|
||||||
|
|
||||||
|
mDisplayedNbPosts = (uint32_t)std::min(nb_posts,(int)mFilteredPosts.size() - (start+1));
|
||||||
|
mDisplayedStartIndex = start;
|
||||||
|
|
||||||
|
beginRemoveRows(QModelIndex(),mDisplayedNbPosts,old_nb_rows);
|
||||||
|
endRemoveRows();
|
||||||
|
|
||||||
|
beginInsertRows(QModelIndex(),old_nb_rows,mDisplayedNbPosts);
|
||||||
|
endInsertRows();
|
||||||
|
|
||||||
|
postMods();
|
||||||
|
}
|
||||||
|
|
||||||
|
void RsPostedPostsModel::deepUpdate()
|
||||||
|
{
|
||||||
|
auto posts(mPosts);
|
||||||
|
setPosts(mPostedGroup,posts);
|
||||||
|
}
|
||||||
|
|
||||||
|
void RsPostedPostsModel::setPosts(const RsPostedGroup& group, std::vector<RsPostedPost>& posts)
|
||||||
|
{
|
||||||
|
preMods();
|
||||||
|
|
||||||
|
beginRemoveRows(QModelIndex(),0,rowCount()-1);
|
||||||
|
endRemoveRows();
|
||||||
|
|
||||||
|
mPosts.clear();
|
||||||
|
mPostedGroup = group;
|
||||||
|
|
||||||
|
createPostsArray(posts);
|
||||||
|
|
||||||
|
std::sort(mPosts.begin(),mPosts.end(), PostSorter(mSortingStrategy));
|
||||||
|
|
||||||
|
uint32_t tmpval;
|
||||||
|
setFilter(QStringList(),tmpval);
|
||||||
|
|
||||||
|
mDisplayedNbPosts = std::min((uint32_t)mFilteredPosts.size(),DEFAULT_DISPLAYED_NB_POSTS);
|
||||||
|
mDisplayedStartIndex = 0;
|
||||||
|
|
||||||
|
beginInsertRows(QModelIndex(),0,rowCount()-1);
|
||||||
|
endInsertRows();
|
||||||
|
|
||||||
|
postMods();
|
||||||
|
|
||||||
|
emit boardPostsLoaded();
|
||||||
|
}
|
||||||
|
|
||||||
|
void RsPostedPostsModel::update_posts(const RsGxsGroupId& group_id)
|
||||||
|
{
|
||||||
|
if(group_id.isNull())
|
||||||
|
return;
|
||||||
|
|
||||||
|
RsThread::async([this, group_id]()
|
||||||
|
{
|
||||||
|
// 1 - get message data from p3GxsChannels
|
||||||
|
|
||||||
|
std::list<RsGxsGroupId> groupIds;
|
||||||
|
std::vector<RsMsgMetaData> msg_metas;
|
||||||
|
std::vector<RsPostedGroup> groups;
|
||||||
|
|
||||||
|
groupIds.push_back(group_id);
|
||||||
|
|
||||||
|
if(!rsPosted->getBoardsInfo(groupIds,groups) || groups.size() != 1)
|
||||||
|
{
|
||||||
|
std::cerr << __PRETTY_FUNCTION__ << " failed to retrieve channel group info for channel " << group_id << std::endl;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
RsPostedGroup group = groups[0];
|
||||||
|
|
||||||
|
// We use the heap because the arrays need to be stored accross async
|
||||||
|
|
||||||
|
std::vector<RsPostedPost> *posts = new std::vector<RsPostedPost>();
|
||||||
|
std::vector<RsGxsComment> *comments = new std::vector<RsGxsComment>();
|
||||||
|
std::vector<RsGxsVote> *votes = new std::vector<RsGxsVote>();
|
||||||
|
|
||||||
|
if(!rsPosted->getBoardAllContent(group_id, *posts,*comments,*votes))
|
||||||
|
{
|
||||||
|
std::cerr << __PRETTY_FUNCTION__ << " failed to retrieve channel messages for channel " << group_id << std::endl;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 2 - update the model in the UI thread.
|
||||||
|
|
||||||
|
RsQThreadUtils::postToObject( [group,posts,comments,votes,this]()
|
||||||
|
{
|
||||||
|
/* Here it goes any code you want to be executed on the Qt Gui
|
||||||
|
* thread, for example to update the data model with new information
|
||||||
|
* after a blocking call to RetroShare API complete, note that
|
||||||
|
* Qt::QueuedConnection is important!
|
||||||
|
*/
|
||||||
|
|
||||||
|
setPosts(group,*posts) ;
|
||||||
|
|
||||||
|
delete posts;
|
||||||
|
delete comments;
|
||||||
|
delete votes;
|
||||||
|
|
||||||
|
}, this );
|
||||||
|
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool decreasing_time_comp(const std::pair<time_t,RsGxsMessageId>& e1,const std::pair<time_t,RsGxsMessageId>& e2) { return e2.first < e1.first ; }
|
||||||
|
|
||||||
|
void RsPostedPostsModel::createPostsArray(std::vector<RsPostedPost>& posts)
|
||||||
|
{
|
||||||
|
#ifdef TODO
|
||||||
|
// Collect new versions of posts if any. For now Boards do not have versions, but if that ever happens, we'll be handlign it already. This code
|
||||||
|
// is a blind copy of the channel code.
|
||||||
|
|
||||||
|
#ifdef DEBUG_CHANNEL_MODEL
|
||||||
|
std::cerr << "Inserting channel posts" << std::endl;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
std::vector<uint32_t> new_versions ;
|
||||||
|
for (uint32_t i=0;i<posts.size();++i)
|
||||||
|
{
|
||||||
|
if(posts[i].mMeta.mOrigMsgId == posts[i].mMeta.mMsgId)
|
||||||
|
posts[i].mMeta.mOrigMsgId.clear();
|
||||||
|
|
||||||
|
#ifdef DEBUG_CHANNEL_MODEL
|
||||||
|
std::cerr << " " << i << ": name=\"" << posts[i].mMeta.mMsgName << "\" msg_id=" << posts[i].mMeta.mMsgId << ": orig msg id = " << posts[i].mMeta.mOrigMsgId << std::endl;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
if(!posts[i].mMeta.mOrigMsgId.isNull())
|
||||||
|
new_versions.push_back(i) ;
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef DEBUG_CHANNEL_MODEL
|
||||||
|
std::cerr << "New versions: " << new_versions.size() << std::endl;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
if(!new_versions.empty())
|
||||||
|
{
|
||||||
|
#ifdef DEBUG_CHANNEL_MODEL
|
||||||
|
std::cerr << " New versions present. Replacing them..." << std::endl;
|
||||||
|
std::cerr << " Creating search map." << std::endl;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// make a quick search map
|
||||||
|
std::map<RsGxsMessageId,uint32_t> search_map ;
|
||||||
|
for (uint32_t i=0;i<posts.size();++i)
|
||||||
|
search_map[posts[i].mMeta.mMsgId] = i ;
|
||||||
|
|
||||||
|
for(uint32_t i=0;i<new_versions.size();++i)
|
||||||
|
{
|
||||||
|
#ifdef DEBUG_CHANNEL_MODEL
|
||||||
|
std::cerr << " Taking care of new version at index " << new_versions[i] << std::endl;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
uint32_t current_index = new_versions[i] ;
|
||||||
|
uint32_t source_index = new_versions[i] ;
|
||||||
|
#ifdef DEBUG_CHANNEL_MODEL
|
||||||
|
RsGxsMessageId source_msg_id = posts[source_index].mMeta.mMsgId ;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// What we do is everytime we find a replacement post, we climb up the replacement graph until we find the original post
|
||||||
|
// (or the most recent version of it). When we reach this post, we replace it with the data of the source post.
|
||||||
|
// In the mean time, all other posts have their MsgId cleared, so that the posts are removed from the list.
|
||||||
|
|
||||||
|
//std::vector<uint32_t> versions ;
|
||||||
|
std::map<RsGxsMessageId,uint32_t>::const_iterator vit ;
|
||||||
|
|
||||||
|
while(search_map.end() != (vit=search_map.find(posts[current_index].mMeta.mOrigMsgId)))
|
||||||
|
{
|
||||||
|
#ifdef DEBUG_CHANNEL_MODEL
|
||||||
|
std::cerr << " post at index " << current_index << " replaces a post at position " << vit->second ;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// Now replace the post only if the new versionis more recent. It may happen indeed that the same post has been corrected multiple
|
||||||
|
// times. In this case, we only need to replace the post with the newest version
|
||||||
|
|
||||||
|
//uint32_t prev_index = current_index ;
|
||||||
|
current_index = vit->second ;
|
||||||
|
|
||||||
|
if(posts[current_index].mMeta.mMsgId.isNull()) // This handles the branching situation where this post has been already erased. No need to go down further.
|
||||||
|
{
|
||||||
|
#ifdef DEBUG_CHANNEL_MODEL
|
||||||
|
std::cerr << " already erased. Stopping." << std::endl;
|
||||||
|
#endif
|
||||||
|
break ;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(posts[current_index].mMeta.mPublishTs < posts[source_index].mMeta.mPublishTs)
|
||||||
|
{
|
||||||
|
#ifdef DEBUG_CHANNEL_MODEL
|
||||||
|
std::cerr << " and is more recent => following" << std::endl;
|
||||||
|
#endif
|
||||||
|
for(std::set<RsGxsMessageId>::const_iterator itt(posts[current_index].mOlderVersions.begin());itt!=posts[current_index].mOlderVersions.end();++itt)
|
||||||
|
posts[source_index].mOlderVersions.insert(*itt);
|
||||||
|
|
||||||
|
posts[source_index].mOlderVersions.insert(posts[current_index].mMeta.mMsgId);
|
||||||
|
posts[current_index].mMeta.mMsgId.clear(); // clear the msg Id so the post will be ignored
|
||||||
|
}
|
||||||
|
#ifdef DEBUG_CHANNEL_MODEL
|
||||||
|
else
|
||||||
|
std::cerr << " but is older -> Stopping" << std::endl;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef DEBUG_CHANNEL_MODEL
|
||||||
|
std::cerr << "Now adding " << posts.size() << " posts into array structure..." << std::endl;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
mPosts.clear();
|
||||||
|
|
||||||
|
for (std::vector<RsPostedPost>::const_reverse_iterator it = posts.rbegin(); it != posts.rend(); ++it)
|
||||||
|
{
|
||||||
|
if(!(*it).mMeta.mMsgId.isNull())
|
||||||
|
{
|
||||||
|
#ifdef DEBUG_CHANNEL_MODEL
|
||||||
|
std::cerr << " adding post \"" << (*it).mMeta.mMsgName << "\"" << std::endl;
|
||||||
|
#endif
|
||||||
|
mPosts.push_back(*it);
|
||||||
|
}
|
||||||
|
#ifdef DEBUG_CHANNEL_MODEL
|
||||||
|
else
|
||||||
|
std::cerr << " skipped older version post \"" << (*it).mMeta.mMsgName << "\"" << std::endl;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void RsPostedPostsModel::setAllMsgReadStatus(bool read)
|
||||||
|
{
|
||||||
|
// make a temporary listof pairs
|
||||||
|
|
||||||
|
std::list<RsGxsGrpMsgIdPair> pairs;
|
||||||
|
|
||||||
|
for(uint32_t i=0;i<mPosts.size();++i)
|
||||||
|
pairs.push_back(RsGxsGrpMsgIdPair(mPosts[i].mMeta.mGroupId,mPosts[i].mMeta.mMsgId));
|
||||||
|
|
||||||
|
RsThread::async([read,pairs]()
|
||||||
|
{
|
||||||
|
// Call blocking API
|
||||||
|
|
||||||
|
for(auto& p:pairs)
|
||||||
|
rsPosted->setPostReadStatus(p,read);
|
||||||
|
} );
|
||||||
|
}
|
||||||
|
void RsPostedPostsModel::setMsgReadStatus(const QModelIndex& i,bool read_status)
|
||||||
|
{
|
||||||
|
if(!i.isValid())
|
||||||
|
return ;
|
||||||
|
|
||||||
|
// no need to call preMods()/postMods() here because we'renot changing the model
|
||||||
|
|
||||||
|
quintptr ref = i.internalId();
|
||||||
|
uint32_t entry = 0;
|
||||||
|
|
||||||
|
if(!convertRefPointerToTabEntry(ref,entry) || entry >= mFilteredPosts.size())
|
||||||
|
return ;
|
||||||
|
|
||||||
|
RsGxsGroupId grpId = mPosts[entry].mMeta.mGroupId;
|
||||||
|
RsGxsMessageId msgId = mPosts[entry].mMeta.mMsgId;
|
||||||
|
|
||||||
|
bool current_read_status = !(IS_MSG_UNREAD(mPosts[entry].mMeta.mMsgStatus) || IS_MSG_NEW(mPosts[entry].mMeta.mMsgStatus));
|
||||||
|
|
||||||
|
if(current_read_status != read_status)
|
||||||
|
RsThread::async([msgId,grpId,read_status]()
|
||||||
|
{
|
||||||
|
// Call blocking API
|
||||||
|
|
||||||
|
rsPosted->setPostReadStatus(RsGxsGrpMsgIdPair(grpId,msgId),read_status);
|
||||||
|
} );
|
||||||
|
}
|
||||||
|
|
||||||
|
QModelIndex RsPostedPostsModel::getIndexOfMessage(const RsGxsMessageId& mid) const
|
||||||
|
{
|
||||||
|
// Brutal search. This is not so nice, so dont call that in a loop! If too costly, we'll use a map.
|
||||||
|
|
||||||
|
RsGxsMessageId postId = mid;
|
||||||
|
|
||||||
|
for(uint32_t i=mDisplayedStartIndex;i<mDisplayedStartIndex+mDisplayedNbPosts;++i)
|
||||||
|
{
|
||||||
|
// First look into msg versions, in case the msg is a version of an existing message
|
||||||
|
|
||||||
|
#ifdef TODO
|
||||||
|
for(auto& msg_id:mPosts[mFilteredPosts[i]].mOlderVersions)
|
||||||
|
if(msg_id == postId)
|
||||||
|
{
|
||||||
|
quintptr ref ;
|
||||||
|
convertTabEntryToRefPointer(i,ref); // we dont use i+1 here because i is not a row, but an index in the mPosts tab
|
||||||
|
|
||||||
|
return createIndex(i,0, ref);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
if(mPosts[mFilteredPosts[i]].mMeta.mMsgId == postId)
|
||||||
|
{
|
||||||
|
quintptr ref ;
|
||||||
|
convertTabEntryToRefPointer(i,ref); // we dont use i+1 here because i is not a row, but an index in the mPosts tab
|
||||||
|
|
||||||
|
return createIndex(i,0, ref);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return QModelIndex();
|
||||||
|
}
|
||||||
|
|
252
retroshare-gui/src/gui/Posted/PostedPostsModel.h
Normal file
252
retroshare-gui/src/gui/Posted/PostedPostsModel.h
Normal file
@ -0,0 +1,252 @@
|
|||||||
|
/*******************************************************************************
|
||||||
|
* retroshare-gui/src/gui/gxschannels/GxsChannelPostsModel.h *
|
||||||
|
* *
|
||||||
|
* Copyright 2020 by Cyril Soler <csoler@users.sourceforge.net> *
|
||||||
|
* *
|
||||||
|
* 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 "retroshare/rsposted.h"
|
||||||
|
#include "retroshare/rsgxsifacetypes.h"
|
||||||
|
#include "retroshare/rsevents.h"
|
||||||
|
|
||||||
|
#include <QModelIndex>
|
||||||
|
#include <QColor>
|
||||||
|
|
||||||
|
// This class holds the actual hierarchy of posts, represented by identifiers
|
||||||
|
// It is responsible for auto-updating when necessary and holds a mutex to allow the Model to
|
||||||
|
// safely access the data.
|
||||||
|
|
||||||
|
// The model contains a post in place 0 that is the parent of all posts.
|
||||||
|
|
||||||
|
// The model contains 3 layers:
|
||||||
|
//
|
||||||
|
// Layer 1: list of all posts
|
||||||
|
//
|
||||||
|
// * this list is sorted according to the current sorting strategy
|
||||||
|
// * Variables: mPosts
|
||||||
|
//
|
||||||
|
// Layer 2: list of post filtered by search
|
||||||
|
//
|
||||||
|
// * depending on which chunk of posts are actually displayed, this list contains
|
||||||
|
// the subset of the general list of posts
|
||||||
|
// * Variables: mFilteredPosts
|
||||||
|
//
|
||||||
|
// Layer 3: start and end of posts actually displayed in the previous list
|
||||||
|
//
|
||||||
|
// * Variables: mDisplayedStartIndex, mDisplayedNbPosts
|
||||||
|
//
|
||||||
|
// The array below indicates which variables are updated depending on the type of data/view change:
|
||||||
|
//
|
||||||
|
// | Global list (mPosts) | Filtered List | Displayed list (mDisplayedStartIndex, mDisplayedNbPosts)
|
||||||
|
// -----------+-----------------------+------------------+----------------------------------------------------------
|
||||||
|
// New group | X | X | X (updated because FilteredList may change)
|
||||||
|
// Sort order | X | |
|
||||||
|
// Filter Str | | X | X (updated because FilteredList may change)
|
||||||
|
// Chunk chng | | X | X
|
||||||
|
//
|
||||||
|
// In the model, indexes internal refs are pointer casts of the index in the mFilteredPosts tab. Another possible choice
|
||||||
|
// was to use indexes in the tab of displayed indices, but this leads to a more complex impleemntation.
|
||||||
|
|
||||||
|
typedef uint32_t PostedPostsModelIndex;
|
||||||
|
|
||||||
|
// struct ChannelPostsModelPostEntry
|
||||||
|
// {
|
||||||
|
// ChannelPostsModelPostEntry() : mPublishTs(0),mPostFlags(0),mMsgStatus(0),prow(0) {}
|
||||||
|
//
|
||||||
|
// enum { // flags for display of posts. To be used in mPostFlags
|
||||||
|
// FLAG_POST_IS_PINNED = 0x0001,
|
||||||
|
// FLAG_POST_IS_MISSING = 0x0002,
|
||||||
|
// FLAG_POST_IS_REDACTED = 0x0004,
|
||||||
|
// FLAG_POST_HAS_UNREAD_CHILDREN = 0x0008,
|
||||||
|
// FLAG_POST_HAS_READ_CHILDREN = 0x0010,
|
||||||
|
// FLAG_POST_PASSES_FILTER = 0x0020,
|
||||||
|
// FLAG_POST_CHILDREN_PASSES_FILTER = 0x0040,
|
||||||
|
// };
|
||||||
|
//
|
||||||
|
// std::string mTitle ;
|
||||||
|
// RsGxsMessageId mMsgId;
|
||||||
|
// uint32_t mPublishTs;
|
||||||
|
// uint32_t mPostFlags;
|
||||||
|
// int mMsgStatus;
|
||||||
|
//
|
||||||
|
// int prow ;// parent row, which basically means position in the array of posts
|
||||||
|
// };
|
||||||
|
|
||||||
|
// This class is the item model used by Qt to display the information
|
||||||
|
|
||||||
|
class RsPostedPostsModel : public QAbstractItemModel
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
|
||||||
|
public:
|
||||||
|
explicit RsPostedPostsModel(QObject *parent = NULL);
|
||||||
|
virtual ~RsPostedPostsModel() override;
|
||||||
|
|
||||||
|
static const uint32_t COLUMN_THREAD_NB_COLUMNS = 0x01;
|
||||||
|
static const uint32_t DEFAULT_DISPLAYED_NB_POSTS ;
|
||||||
|
|
||||||
|
enum SortingStrategy {
|
||||||
|
SORT_UNKNOWN = 0x00,
|
||||||
|
SORT_NEW_SCORE = 0x01,
|
||||||
|
SORT_TOP_SCORE = 0x02,
|
||||||
|
SORT_HOT_SCORE = 0x03
|
||||||
|
};
|
||||||
|
|
||||||
|
enum Columns {
|
||||||
|
COLUMN_POSTS =0x00,
|
||||||
|
COLUMN_THREAD_MSGID =0x01,
|
||||||
|
COLUMN_THREAD_DATA =0x02,
|
||||||
|
};
|
||||||
|
|
||||||
|
enum Roles{ SortRole = Qt::UserRole+1,
|
||||||
|
StatusRole = Qt::UserRole+2,
|
||||||
|
FilterRole = Qt::UserRole+3,
|
||||||
|
};
|
||||||
|
|
||||||
|
enum TreeMode{ TREE_MODE_UNKWN = 0x00,
|
||||||
|
TREE_MODE_PLAIN = 0x01,
|
||||||
|
TREE_MODE_FILES = 0x02,
|
||||||
|
};
|
||||||
|
|
||||||
|
#ifdef TODO
|
||||||
|
enum SortMode{ SORT_MODE_PUBLISH_TS = 0x00,
|
||||||
|
SORT_MODE_CHILDREN_PUBLISH_TS = 0x01,
|
||||||
|
};
|
||||||
|
#endif
|
||||||
|
|
||||||
|
QModelIndex root() const{ return createIndex(0,0,(void*)NULL) ;}
|
||||||
|
QModelIndex getIndexOfMessage(const RsGxsMessageId& mid) const;
|
||||||
|
|
||||||
|
// This method will asynchroneously update the data
|
||||||
|
|
||||||
|
void updateBoard(const RsGxsGroupId& posted_group_id);
|
||||||
|
const RsGxsGroupId& currentGroupId() const;
|
||||||
|
|
||||||
|
// Triggers a data change for all items. This can be used to redraw the view without re-loading the data.
|
||||||
|
void update();
|
||||||
|
|
||||||
|
// Triggers a preMod, begin/end remove rows and data update. Could be useful if update is not enough to reset cell sizes.
|
||||||
|
void deepUpdate();
|
||||||
|
|
||||||
|
// same without data update, which is far less costly
|
||||||
|
void triggerRedraw();
|
||||||
|
|
||||||
|
#ifdef TODO
|
||||||
|
void setSortMode(SortMode mode) ;
|
||||||
|
|
||||||
|
void setTextColorRead (QColor color) { mTextColorRead = color;}
|
||||||
|
void setTextColorUnread (QColor color) { mTextColorUnread = color;}
|
||||||
|
void setTextColorUnreadChildren(QColor color) { mTextColorUnreadChildren = color;}
|
||||||
|
void setTextColorNotSubscribed (QColor color) { mTextColorNotSubscribed = color;}
|
||||||
|
void setTextColorMissing (QColor color) { mTextColorMissing = color;}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
void setAllMsgReadStatus(bool read);
|
||||||
|
void setMsgReadStatus(const QModelIndex &i, bool read_status);
|
||||||
|
void setFilter(const QStringList &strings, uint32_t &count) ;
|
||||||
|
void setSortingStrategy(SortingStrategy s);
|
||||||
|
void setPostsInterval(int start,int nb_posts);
|
||||||
|
|
||||||
|
#ifdef TODO
|
||||||
|
void setAuthorOpinion(const QModelIndex& indx,RsOpinion op);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// Helper functions
|
||||||
|
|
||||||
|
bool getPostData(const QModelIndex& i,RsPostedPost& fmpe) const ;
|
||||||
|
uint32_t totalPostsCount() const { return mPosts.size() ; }
|
||||||
|
uint32_t filteredPostsCount() const { return mFilteredPosts.size() ; }
|
||||||
|
uint32_t displayedStartPostIndex() const { return mDisplayedStartIndex ; }
|
||||||
|
void clear() ;
|
||||||
|
|
||||||
|
// AbstractItemModel functions.
|
||||||
|
|
||||||
|
int rowCount(const QModelIndex& parent = QModelIndex()) const override;
|
||||||
|
int columnCount(const QModelIndex &parent = QModelIndex()) const override;
|
||||||
|
bool hasChildren(const QModelIndex &parent = QModelIndex()) const override;
|
||||||
|
|
||||||
|
QModelIndex index(int row, int column, const QModelIndex & parent = QModelIndex()) const override;
|
||||||
|
QModelIndex parent(const QModelIndex& child) const override;
|
||||||
|
Qt::ItemFlags flags(const QModelIndex& index) const override;
|
||||||
|
|
||||||
|
QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override;
|
||||||
|
|
||||||
|
// Custom item roles
|
||||||
|
|
||||||
|
QVariant sizeHintRole (int col) const;
|
||||||
|
QVariant displayRole (const RsPostedPost& fmpe, int col) const;
|
||||||
|
QVariant toolTipRole (const RsPostedPost& fmpe, int col) const;
|
||||||
|
QVariant userRole (const RsPostedPost& fmpe, int col) const;
|
||||||
|
#ifdef TODO
|
||||||
|
QVariant decorationRole(const RsPostedPost& fmpe, int col) const;
|
||||||
|
QVariant pinnedRole (const RsPostedPost& fmpe, int col) const;
|
||||||
|
QVariant missingRole (const RsPostedPost& fmpe, int col) const;
|
||||||
|
QVariant statusRole (const RsPostedPost& fmpe, int col) const;
|
||||||
|
QVariant authorRole (const RsPostedPost& fmpe, int col) const;
|
||||||
|
QVariant sortRole (const RsPostedPost& fmpe, int col) const;
|
||||||
|
QVariant fontRole (const RsPostedPost& fmpe, int col) const;
|
||||||
|
QVariant filterRole (const RsPostedPost& fmpe, int col) const;
|
||||||
|
QVariant textColorRole (const RsPostedPost& fmpe, int col) const;
|
||||||
|
QVariant backgroundRole(const RsPostedPost& fmpe, int col) const;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief debug_dump
|
||||||
|
* Dumps the hierarchy of posts in the terminal, to allow checking whether the internal representation is correct.
|
||||||
|
*/
|
||||||
|
void debug_dump();
|
||||||
|
|
||||||
|
signals:
|
||||||
|
void boardPostsLoaded(); // emitted after the posts have been loaded.
|
||||||
|
|
||||||
|
private:
|
||||||
|
RsPostedGroup mPostedGroup;
|
||||||
|
|
||||||
|
TreeMode mTreeMode;
|
||||||
|
|
||||||
|
void preMods() ;
|
||||||
|
void postMods() ;
|
||||||
|
|
||||||
|
quintptr getParentRow(quintptr ref,int& row) const;
|
||||||
|
quintptr getChildRef(quintptr ref, int index) const;
|
||||||
|
int getChildrenCount(quintptr ref) const;
|
||||||
|
|
||||||
|
static bool convertTabEntryToRefPointer(uint32_t entry, quintptr &ref);
|
||||||
|
static bool convertRefPointerToTabEntry(quintptr ref,uint32_t& entry);
|
||||||
|
static void computeReputationLevel(uint32_t forum_sign_flags, RsPostedPost& entry);
|
||||||
|
|
||||||
|
void update_posts(const RsGxsGroupId& group_id);
|
||||||
|
|
||||||
|
#ifdef TODO
|
||||||
|
void setForumMessageSummary(const std::vector<RsGxsForumMsg>& messages);
|
||||||
|
void recursUpdateReadStatusAndTimes(ChannelPostsModelIndex i,bool& has_unread_below,bool& has_read_below);
|
||||||
|
uint32_t recursUpdateFilterStatus(ChannelPostsModelIndex i,int column,const QStringList& strings);
|
||||||
|
void recursSetMsgReadStatus(ChannelPostsModelIndex i,bool read_status,bool with_children);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
void createPostsArray(std::vector<RsPostedPost> &posts);
|
||||||
|
void setPosts(const RsPostedGroup& group, std::vector<RsPostedPost> &posts);
|
||||||
|
void initEmptyHierarchy();
|
||||||
|
void handleEvent_main_thread(std::shared_ptr<const RsEvent> event);
|
||||||
|
|
||||||
|
std::vector<RsPostedPost> mPosts ;
|
||||||
|
std::vector<int> mFilteredPosts;
|
||||||
|
uint32_t mDisplayedStartIndex;
|
||||||
|
uint32_t mDisplayedNbPosts;
|
||||||
|
SortingStrategy mSortingStrategy;
|
||||||
|
|
||||||
|
RsEventsHandlerId_t mEventHandlerId ;
|
||||||
|
};
|
@ -5,6 +5,8 @@
|
|||||||
<file>images/down-arrow.png</file>
|
<file>images/down-arrow.png</file>
|
||||||
<file>images/up-arrow.png</file>
|
<file>images/up-arrow.png</file>
|
||||||
<file>images/comments.png</file>
|
<file>images/comments.png</file>
|
||||||
|
<file>images/comments_blue.png</file>
|
||||||
|
<file>images/thumb-blocked.png</file>
|
||||||
<file>images/thumb-default.png</file>
|
<file>images/thumb-default.png</file>
|
||||||
<file>images/thumb-link.png</file>
|
<file>images/thumb-link.png</file>
|
||||||
<file>images/share.png</file>
|
<file>images/share.png</file>
|
||||||
|
BIN
retroshare-gui/src/gui/Posted/images/comments_blue.png
Normal file
BIN
retroshare-gui/src/gui/Posted/images/comments_blue.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 4.3 KiB |
BIN
retroshare-gui/src/gui/Posted/images/thumb-blocked.png
Normal file
BIN
retroshare-gui/src/gui/Posted/images/thumb-blocked.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 10 KiB |
@ -22,6 +22,7 @@
|
|||||||
#include <QtGui>
|
#include <QtGui>
|
||||||
|
|
||||||
#include "PulseReply.h"
|
#include "PulseReply.h"
|
||||||
|
#include "gui/common/FilesDefs.h"
|
||||||
|
|
||||||
#include "PulseAddDialog.h"
|
#include "PulseAddDialog.h"
|
||||||
|
|
||||||
|
@ -24,6 +24,7 @@
|
|||||||
#include <QBuffer>
|
#include <QBuffer>
|
||||||
|
|
||||||
#include "PulseTopLevel.h"
|
#include "PulseTopLevel.h"
|
||||||
|
#include "gui/common/FilesDefs.h"
|
||||||
|
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
|
@ -26,6 +26,7 @@
|
|||||||
#include "PulseViewGroup.h"
|
#include "PulseViewGroup.h"
|
||||||
|
|
||||||
#include "gui/gxs/GxsIdDetails.h"
|
#include "gui/gxs/GxsIdDetails.h"
|
||||||
|
#include "gui/common/FilesDefs.h"
|
||||||
#include "util/DateTime.h"
|
#include "util/DateTime.h"
|
||||||
|
|
||||||
/** Constructor */
|
/** Constructor */
|
||||||
|
@ -26,6 +26,7 @@
|
|||||||
#include "PulseViewItem.h"
|
#include "PulseViewItem.h"
|
||||||
|
|
||||||
#include "gui/gxs/GxsIdDetails.h"
|
#include "gui/gxs/GxsIdDetails.h"
|
||||||
|
#include "gui/common/FilesDefs.h"
|
||||||
#include "util/DateTime.h"
|
#include "util/DateTime.h"
|
||||||
|
|
||||||
/** Constructor */
|
/** Constructor */
|
||||||
|
@ -22,6 +22,7 @@
|
|||||||
#include "WireGroupExtra.h"
|
#include "WireGroupExtra.h"
|
||||||
|
|
||||||
#include "WireGroupDialog.h"
|
#include "WireGroupDialog.h"
|
||||||
|
#include "gui/common/FilesDefs.h"
|
||||||
#include "gui/gxs/GxsIdDetails.h"
|
#include "gui/gxs/GxsIdDetails.h"
|
||||||
|
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
|
@ -25,6 +25,7 @@
|
|||||||
|
|
||||||
#include "WireGroupItem.h"
|
#include "WireGroupItem.h"
|
||||||
#include "gui/gxs/GxsIdDetails.h"
|
#include "gui/gxs/GxsIdDetails.h"
|
||||||
|
#include "gui/common/FilesDefs.h"
|
||||||
|
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
|
@ -60,7 +60,7 @@ void GxsCommentContainer::commentLoad(const RsGxsGroupId &grpId, const std::set<
|
|||||||
comments += "...";
|
comments += "...";
|
||||||
}
|
}
|
||||||
|
|
||||||
GxsCommentDialog *commentDialog = new GxsCommentDialog(this, getTokenService(), getCommentService());
|
GxsCommentDialog *commentDialog = new GxsCommentDialog(this, RsGxsId(),getTokenService(), getCommentService());
|
||||||
|
|
||||||
QWidget *commentHeader = createHeaderWidget(grpId, msgId);
|
QWidget *commentHeader = createHeaderWidget(grpId, msgId);
|
||||||
commentDialog->setCommentHeader(commentHeader);
|
commentDialog->setCommentHeader(commentHeader);
|
||||||
|
@ -30,24 +30,24 @@
|
|||||||
#include <QDateTime>
|
#include <QDateTime>
|
||||||
|
|
||||||
/** Constructor */
|
/** Constructor */
|
||||||
GxsCommentDialog::GxsCommentDialog(QWidget *parent, RsTokenService *token_service, RsGxsCommentService *comment_service)
|
GxsCommentDialog::GxsCommentDialog(QWidget *parent, const RsGxsId &default_author, RsTokenService *token_service, RsGxsCommentService *comment_service)
|
||||||
: QWidget(parent), ui(new Ui::GxsCommentDialog)
|
: QWidget(parent), ui(new Ui::GxsCommentDialog)
|
||||||
{
|
{
|
||||||
/* Invoke the Qt Designer generated QObject setup routine */
|
/* Invoke the Qt Designer generated QObject setup routine */
|
||||||
ui->setupUi(this);
|
ui->setupUi(this);
|
||||||
|
|
||||||
setTokenService(token_service,comment_service);
|
setTokenService(token_service,comment_service);
|
||||||
init();
|
init(default_author);
|
||||||
}
|
}
|
||||||
|
|
||||||
void GxsCommentDialog::init()
|
void GxsCommentDialog::init(const RsGxsId& default_author)
|
||||||
{
|
{
|
||||||
/* Set header resize modes and initial section sizes */
|
/* Set header resize modes and initial section sizes */
|
||||||
QHeaderView * ttheader = ui->treeWidget->header () ;
|
QHeaderView * ttheader = ui->treeWidget->header () ;
|
||||||
ttheader->resizeSection (0, 440);
|
ttheader->resizeSection (0, 440);
|
||||||
|
|
||||||
/* fill in the available OwnIds for signing */
|
/* fill in the available OwnIds for signing */
|
||||||
ui->idChooser->loadIds(IDCHOOSER_ID_REQUIRED, RsGxsId());
|
ui->idChooser->loadIds(IDCHOOSER_ID_REQUIRED, default_author);
|
||||||
|
|
||||||
connect(ui->refreshButton, SIGNAL(clicked()), this, SLOT(refresh()));
|
connect(ui->refreshButton, SIGNAL(clicked()), this, SLOT(refresh()));
|
||||||
connect(ui->idChooser, SIGNAL(currentIndexChanged( int )), this, SLOT(voterSelectionChanged( int )));
|
connect(ui->idChooser, SIGNAL(currentIndexChanged( int )), this, SLOT(voterSelectionChanged( int )));
|
||||||
@ -70,13 +70,13 @@ void GxsCommentDialog::setTokenService(RsTokenService *token_service, RsGxsComme
|
|||||||
ui->treeWidget->setup(token_service, comment_service);
|
ui->treeWidget->setup(token_service, comment_service);
|
||||||
}
|
}
|
||||||
|
|
||||||
GxsCommentDialog::GxsCommentDialog(QWidget *parent)
|
GxsCommentDialog::GxsCommentDialog(QWidget *parent,const RsGxsId &default_author)
|
||||||
: QWidget(parent), ui(new Ui::GxsCommentDialog)
|
: QWidget(parent), ui(new Ui::GxsCommentDialog)
|
||||||
{
|
{
|
||||||
/* Invoke the Qt Designer generated QObject setup routine */
|
/* Invoke the Qt Designer generated QObject setup routine */
|
||||||
ui->setupUi(this);
|
ui->setupUi(this);
|
||||||
|
|
||||||
init();
|
init(default_author);
|
||||||
}
|
}
|
||||||
|
|
||||||
GxsCommentDialog::~GxsCommentDialog()
|
GxsCommentDialog::~GxsCommentDialog()
|
||||||
@ -84,7 +84,7 @@ GxsCommentDialog::~GxsCommentDialog()
|
|||||||
delete(ui);
|
delete(ui);
|
||||||
}
|
}
|
||||||
|
|
||||||
void GxsCommentDialog::commentLoad(const RsGxsGroupId &grpId, const std::set<RsGxsMessageId>& msg_versions,const RsGxsMessageId& most_recent_msgId)
|
void GxsCommentDialog::commentLoad(const RsGxsGroupId &grpId, const std::set<RsGxsMessageId>& msg_versions,const RsGxsMessageId& most_recent_msgId,bool use_cache)
|
||||||
{
|
{
|
||||||
std::cerr << "GxsCommentDialog::commentLoad(" << grpId << ", most recent msg version: " << most_recent_msgId << ")";
|
std::cerr << "GxsCommentDialog::commentLoad(" << grpId << ", most recent msg version: " << most_recent_msgId << ")";
|
||||||
std::cerr << std::endl;
|
std::cerr << std::endl;
|
||||||
@ -93,7 +93,8 @@ void GxsCommentDialog::commentLoad(const RsGxsGroupId &grpId, const std::set<RsG
|
|||||||
mMostRecentMsgId = most_recent_msgId;
|
mMostRecentMsgId = most_recent_msgId;
|
||||||
mMsgVersions = msg_versions;
|
mMsgVersions = msg_versions;
|
||||||
|
|
||||||
ui->treeWidget->requestComments(mGrpId,msg_versions,most_recent_msgId);
|
ui->treeWidget->setUseCache(use_cache);
|
||||||
|
ui->treeWidget->requestComments(mGrpId,msg_versions,most_recent_msgId);
|
||||||
}
|
}
|
||||||
|
|
||||||
void GxsCommentDialog::notifyCommentsLoaded(int n)
|
void GxsCommentDialog::notifyCommentsLoaded(int n)
|
||||||
@ -151,10 +152,10 @@ void GxsCommentDialog::setCommentHeader(QWidget *header)
|
|||||||
//header->setParent(ui->postFrame);
|
//header->setParent(ui->postFrame);
|
||||||
//ui->postFrame->setVisible(true);
|
//ui->postFrame->setVisible(true);
|
||||||
|
|
||||||
QLayout *alayout = ui->postFrame->layout();
|
#if 0
|
||||||
|
QLayout *alayout = ui->postFrame->layout();
|
||||||
alayout->addWidget(header);
|
alayout->addWidget(header);
|
||||||
|
|
||||||
#if 0
|
|
||||||
ui->postFrame->setVisible(true);
|
ui->postFrame->setVisible(true);
|
||||||
|
|
||||||
QDateTime qtime;
|
QDateTime qtime;
|
||||||
|
@ -32,19 +32,21 @@ class GxsCommentDialog: public QWidget
|
|||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
|
||||||
public:
|
public:
|
||||||
GxsCommentDialog(QWidget *parent);
|
GxsCommentDialog(QWidget *parent=nullptr,const RsGxsId& default_author=RsGxsId());
|
||||||
GxsCommentDialog(QWidget *parent, RsTokenService *token_service, RsGxsCommentService *comment_service);
|
GxsCommentDialog(QWidget *parent,const RsGxsId& default_author, RsTokenService *token_service, RsGxsCommentService *comment_service);
|
||||||
virtual ~GxsCommentDialog();
|
virtual ~GxsCommentDialog();
|
||||||
|
|
||||||
void setTokenService(RsTokenService *token_service, RsGxsCommentService *comment_service);
|
void setTokenService(RsTokenService *token_service, RsGxsCommentService *comment_service);
|
||||||
void setCommentHeader(QWidget *header);
|
void setCommentHeader(QWidget *header);
|
||||||
void commentLoad(const RsGxsGroupId &grpId, const std::set<RsGxsMessageId> &msg_versions, const RsGxsMessageId &most_recent_msgId);
|
void commentLoad(const RsGxsGroupId &grpId, const std::set<RsGxsMessageId> &msg_versions, const RsGxsMessageId &most_recent_msgId, bool use_cache=false);
|
||||||
|
|
||||||
RsGxsGroupId groupId() { return mGrpId; }
|
RsGxsGroupId groupId() { return mGrpId; }
|
||||||
RsGxsMessageId messageId() { return mMostRecentMsgId; }
|
RsGxsMessageId messageId() { return mMostRecentMsgId; }
|
||||||
|
|
||||||
|
public slots:
|
||||||
|
void refresh();
|
||||||
|
|
||||||
private slots:
|
private slots:
|
||||||
void refresh();
|
|
||||||
void idChooserReady();
|
void idChooserReady();
|
||||||
void voterSelectionChanged( int index );
|
void voterSelectionChanged( int index );
|
||||||
void sortComments(int);
|
void sortComments(int);
|
||||||
@ -54,7 +56,7 @@ signals:
|
|||||||
void commentsLoaded(int);
|
void commentsLoaded(int);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void init();
|
void init(const RsGxsId &default_author);
|
||||||
|
|
||||||
RsGxsGroupId mGrpId;
|
RsGxsGroupId mGrpId;
|
||||||
RsGxsMessageId mMostRecentMsgId;
|
RsGxsMessageId mMostRecentMsgId;
|
||||||
|
@ -7,38 +7,68 @@
|
|||||||
<x>0</x>
|
<x>0</x>
|
||||||
<y>0</y>
|
<y>0</y>
|
||||||
<width>632</width>
|
<width>632</width>
|
||||||
<height>547</height>
|
<height>248</height>
|
||||||
</rect>
|
</rect>
|
||||||
</property>
|
</property>
|
||||||
|
<property name="sizePolicy">
|
||||||
|
<sizepolicy hsizetype="Preferred" vsizetype="Preferred">
|
||||||
|
<horstretch>0</horstretch>
|
||||||
|
<verstretch>0</verstretch>
|
||||||
|
</sizepolicy>
|
||||||
|
</property>
|
||||||
<property name="windowTitle">
|
<property name="windowTitle">
|
||||||
<string>Form</string>
|
<string>Form</string>
|
||||||
</property>
|
</property>
|
||||||
<layout class="QGridLayout" name="GxsCommentDialogGLayout">
|
<layout class="QGridLayout" name="GxsCommentDialogGLayout">
|
||||||
<item row="0" column="0">
|
<item row="1" column="0">
|
||||||
<widget class="QFrame" name="postFrame">
|
<widget class="GxsCommentTreeWidget" name="treeWidget">
|
||||||
<property name="sizePolicy">
|
<property name="sizePolicy">
|
||||||
<sizepolicy hsizetype="Expanding" vsizetype="Preferred">
|
<sizepolicy hsizetype="Expanding" vsizetype="Expanding">
|
||||||
<horstretch>0</horstretch>
|
<horstretch>0</horstretch>
|
||||||
<verstretch>0</verstretch>
|
<verstretch>0</verstretch>
|
||||||
</sizepolicy>
|
</sizepolicy>
|
||||||
</property>
|
</property>
|
||||||
<layout class="QVBoxLayout" name="postFrameVLayout">
|
<property name="sortingEnabled">
|
||||||
<property name="leftMargin">
|
<bool>true</bool>
|
||||||
<number>1</number>
|
</property>
|
||||||
|
<column>
|
||||||
|
<property name="text">
|
||||||
|
<string>Comment</string>
|
||||||
</property>
|
</property>
|
||||||
<property name="topMargin">
|
</column>
|
||||||
<number>1</number>
|
<column>
|
||||||
|
<property name="text">
|
||||||
|
<string>Author</string>
|
||||||
</property>
|
</property>
|
||||||
<property name="rightMargin">
|
</column>
|
||||||
<number>1</number>
|
<column>
|
||||||
|
<property name="text">
|
||||||
|
<string>Date</string>
|
||||||
</property>
|
</property>
|
||||||
<property name="bottomMargin">
|
</column>
|
||||||
<number>1</number>
|
<column>
|
||||||
|
<property name="text">
|
||||||
|
<string>Score</string>
|
||||||
</property>
|
</property>
|
||||||
</layout>
|
</column>
|
||||||
|
<column>
|
||||||
|
<property name="text">
|
||||||
|
<string>UpVotes</string>
|
||||||
|
</property>
|
||||||
|
</column>
|
||||||
|
<column>
|
||||||
|
<property name="text">
|
||||||
|
<string>DownVotes</string>
|
||||||
|
</property>
|
||||||
|
</column>
|
||||||
|
<column>
|
||||||
|
<property name="text">
|
||||||
|
<string>OwnVote</string>
|
||||||
|
</property>
|
||||||
|
</column>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
<item row="1" column="0">
|
<item row="0" column="0">
|
||||||
<layout class="QHBoxLayout" name="toolBarHLayout">
|
<layout class="QHBoxLayout" name="toolBarHLayout">
|
||||||
<item>
|
<item>
|
||||||
<widget class="QToolButton" name="commentButton">
|
<widget class="QToolButton" name="commentButton">
|
||||||
@ -141,48 +171,6 @@
|
|||||||
</item>
|
</item>
|
||||||
</layout>
|
</layout>
|
||||||
</item>
|
</item>
|
||||||
<item row="2" column="0">
|
|
||||||
<widget class="GxsCommentTreeWidget" name="treeWidget">
|
|
||||||
<property name="sortingEnabled">
|
|
||||||
<bool>true</bool>
|
|
||||||
</property>
|
|
||||||
<column>
|
|
||||||
<property name="text">
|
|
||||||
<string>Comment</string>
|
|
||||||
</property>
|
|
||||||
</column>
|
|
||||||
<column>
|
|
||||||
<property name="text">
|
|
||||||
<string>Author</string>
|
|
||||||
</property>
|
|
||||||
</column>
|
|
||||||
<column>
|
|
||||||
<property name="text">
|
|
||||||
<string>Date</string>
|
|
||||||
</property>
|
|
||||||
</column>
|
|
||||||
<column>
|
|
||||||
<property name="text">
|
|
||||||
<string>Score</string>
|
|
||||||
</property>
|
|
||||||
</column>
|
|
||||||
<column>
|
|
||||||
<property name="text">
|
|
||||||
<string>UpVotes</string>
|
|
||||||
</property>
|
|
||||||
</column>
|
|
||||||
<column>
|
|
||||||
<property name="text">
|
|
||||||
<string>DownVotes</string>
|
|
||||||
</property>
|
|
||||||
</column>
|
|
||||||
<column>
|
|
||||||
<property name="text">
|
|
||||||
<string>OwnVote</string>
|
|
||||||
</property>
|
|
||||||
</column>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
</layout>
|
</layout>
|
||||||
</widget>
|
</widget>
|
||||||
<customwidgets>
|
<customwidgets>
|
||||||
|
@ -64,6 +64,9 @@
|
|||||||
#define IMAGE_VOTEUP ":/images/vote_up.png"
|
#define IMAGE_VOTEUP ":/images/vote_up.png"
|
||||||
#define IMAGE_VOTEDOWN ":/images/vote_down.png"
|
#define IMAGE_VOTEDOWN ":/images/vote_down.png"
|
||||||
|
|
||||||
|
std::map<RsGxsMessageId, std::vector<RsGxsComment> > GxsCommentTreeWidget::mCommentsCache;
|
||||||
|
QMutex GxsCommentTreeWidget::mCacheMutex;
|
||||||
|
|
||||||
// This class allows to draw the item using an appropriate size
|
// This class allows to draw the item using an appropriate size
|
||||||
|
|
||||||
class MultiLinesCommentDelegate: public QStyledItemDelegate
|
class MultiLinesCommentDelegate: public QStyledItemDelegate
|
||||||
@ -148,6 +151,8 @@ GxsCommentTreeWidget::GxsCommentTreeWidget(QWidget *parent)
|
|||||||
commentsRole = new RSTreeWidgetItemCompareRole;
|
commentsRole = new RSTreeWidgetItemCompareRole;
|
||||||
commentsRole->setRole(PCITEM_COLUMN_DATE, ROLE_SORT);
|
commentsRole->setRole(PCITEM_COLUMN_DATE, ROLE_SORT);
|
||||||
|
|
||||||
|
mUseCache = false;
|
||||||
|
|
||||||
// QFont font = QFont("ARIAL", 10);
|
// QFont font = QFont("ARIAL", 10);
|
||||||
// font.setBold(true);
|
// font.setBold(true);
|
||||||
|
|
||||||
@ -318,7 +323,7 @@ void GxsCommentTreeWidget::banUser()
|
|||||||
|
|
||||||
void GxsCommentTreeWidget::makeComment()
|
void GxsCommentTreeWidget::makeComment()
|
||||||
{
|
{
|
||||||
GxsCreateCommentDialog pcc(mCommentService, std::make_pair(mGroupId,mLatestMsgId), mLatestMsgId, this);
|
GxsCreateCommentDialog pcc(mCommentService, std::make_pair(mGroupId,mLatestMsgId), mLatestMsgId, mVoterId,this);
|
||||||
pcc.exec();
|
pcc.exec();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -327,7 +332,7 @@ void GxsCommentTreeWidget::replyToComment()
|
|||||||
RsGxsGrpMsgIdPair msgId;
|
RsGxsGrpMsgIdPair msgId;
|
||||||
msgId.first = mGroupId;
|
msgId.first = mGroupId;
|
||||||
msgId.second = mCurrentCommentMsgId;
|
msgId.second = mCurrentCommentMsgId;
|
||||||
GxsCreateCommentDialog pcc(mCommentService, msgId, mLatestMsgId, this);
|
GxsCreateCommentDialog pcc(mCommentService, msgId, mLatestMsgId, mVoterId,this);
|
||||||
|
|
||||||
pcc.loadComment(mCurrentCommentText, mCurrentCommentAuthor, mCurrentCommentAuthorId);
|
pcc.loadComment(mCurrentCommentText, mCurrentCommentAuthor, mCurrentCommentAuthorId);
|
||||||
pcc.exec();
|
pcc.exec();
|
||||||
@ -362,6 +367,19 @@ void GxsCommentTreeWidget::requestComments(const RsGxsGroupId& group, const std:
|
|||||||
mMsgVersions = message_versions ;
|
mMsgVersions = message_versions ;
|
||||||
mLatestMsgId = most_recent_message;
|
mLatestMsgId = most_recent_message;
|
||||||
|
|
||||||
|
if(mUseCache)
|
||||||
|
{
|
||||||
|
QMutexLocker lock(&mCacheMutex);
|
||||||
|
|
||||||
|
auto it = mCommentsCache.find(most_recent_message);
|
||||||
|
|
||||||
|
if(it != mCommentsCache.end())
|
||||||
|
{
|
||||||
|
std::cerr << "Got " << it->second.size() << " comments from cache." << std::endl;
|
||||||
|
insertComments(it->second);
|
||||||
|
completeItems();
|
||||||
|
}
|
||||||
|
}
|
||||||
service_requestComments(group,message_versions);
|
service_requestComments(group,message_versions);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -581,11 +599,28 @@ void GxsCommentTreeWidget::service_loadThread(const uint32_t &token)
|
|||||||
std::vector<RsGxsComment> comments;
|
std::vector<RsGxsComment> comments;
|
||||||
mCommentService->getRelatedComments(token, comments);
|
mCommentService->getRelatedComments(token, comments);
|
||||||
|
|
||||||
std::vector<RsGxsComment>::iterator vit;
|
// This is inconsistent since we cannot know here that all comments are for the same thread. However they are only
|
||||||
|
// requested in requestComments() where a single MsgId is used.
|
||||||
|
|
||||||
for(vit = comments.begin(); vit != comments.end(); ++vit)
|
if(mUseCache)
|
||||||
|
{
|
||||||
|
QMutexLocker lock(&mCacheMutex);
|
||||||
|
|
||||||
|
if(!comments.empty())
|
||||||
|
{
|
||||||
|
std::cerr << "Updating cache with " << comments.size() << " for thread " << comments[0].mMeta.mThreadId << std::endl;
|
||||||
|
mCommentsCache[comments[0].mMeta.mThreadId] = comments;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
insertComments(comments);
|
||||||
|
}
|
||||||
|
|
||||||
|
void GxsCommentTreeWidget::insertComments(const std::vector<RsGxsComment>& comments)
|
||||||
|
{
|
||||||
|
for(auto vit = comments.begin(); vit != comments.end(); ++vit)
|
||||||
{
|
{
|
||||||
RsGxsComment &comment = *vit;
|
const RsGxsComment &comment = *vit;
|
||||||
/* convert to a QTreeWidgetItem */
|
/* convert to a QTreeWidgetItem */
|
||||||
std::cerr << "GxsCommentTreeWidget::service_loadThread() Got Comment: " << comment.mMeta.mMsgId;
|
std::cerr << "GxsCommentTreeWidget::service_loadThread() Got Comment: " << comment.mMeta.mMsgId;
|
||||||
std::cerr << std::endl;
|
std::cerr << std::endl;
|
||||||
@ -636,8 +671,6 @@ void GxsCommentTreeWidget::service_loadThread(const uint32_t &token)
|
|||||||
|
|
||||||
addItem(comment.mMeta.mMsgId, comment.mMeta.mParentId, item);
|
addItem(comment.mMeta.mMsgId, comment.mMeta.mParentId, item);
|
||||||
}
|
}
|
||||||
|
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
QTreeWidgetItem *GxsCommentTreeWidget::service_createMissingItem(const RsGxsMessageId& parent)
|
QTreeWidgetItem *GxsCommentTreeWidget::service_createMissingItem(const RsGxsMessageId& parent)
|
||||||
|
@ -22,6 +22,7 @@
|
|||||||
#define _GXS_COMMENT_TREE_WIDGET_H
|
#define _GXS_COMMENT_TREE_WIDGET_H
|
||||||
|
|
||||||
#include <QTreeWidget>
|
#include <QTreeWidget>
|
||||||
|
#include <QMutex>
|
||||||
|
|
||||||
#include "util/TokenQueue.h"
|
#include "util/TokenQueue.h"
|
||||||
#include <retroshare/rsgxscommon.h>
|
#include <retroshare/rsgxscommon.h>
|
||||||
@ -45,6 +46,7 @@ public:
|
|||||||
void loadRequest(const TokenQueue *queue, const TokenRequest &req);
|
void loadRequest(const TokenQueue *queue, const TokenRequest &req);
|
||||||
void setVoteId(const RsGxsId &voterId);
|
void setVoteId(const RsGxsId &voterId);
|
||||||
|
|
||||||
|
void setUseCache(bool b) { mUseCache = b ;}
|
||||||
protected:
|
protected:
|
||||||
|
|
||||||
/* to be overloaded */
|
/* to be overloaded */
|
||||||
@ -60,8 +62,8 @@ protected:
|
|||||||
|
|
||||||
void loadThread(const uint32_t &token);
|
void loadThread(const uint32_t &token);
|
||||||
|
|
||||||
|
void insertComments(const std::vector<RsGxsComment>& comments);
|
||||||
void addItem(RsGxsMessageId itemId, RsGxsMessageId parentId, QTreeWidgetItem *item);
|
void addItem(RsGxsMessageId itemId, RsGxsMessageId parentId, QTreeWidgetItem *item);
|
||||||
|
|
||||||
public slots:
|
public slots:
|
||||||
void customPopUpMenu(const QPoint& point);
|
void customPopUpMenu(const QPoint& point);
|
||||||
void setCurrentCommentMsgId(QTreeWidgetItem* current, QTreeWidgetItem* previous);
|
void setCurrentCommentMsgId(QTreeWidgetItem* current, QTreeWidgetItem* previous);
|
||||||
@ -108,6 +110,9 @@ protected:
|
|||||||
RsTokenService *mRsTokenService;
|
RsTokenService *mRsTokenService;
|
||||||
RsGxsCommentService *mCommentService;
|
RsGxsCommentService *mCommentService;
|
||||||
|
|
||||||
|
bool mUseCache;
|
||||||
|
static std::map<RsGxsMessageId, std::vector<RsGxsComment> > mCommentsCache;
|
||||||
|
static QMutex mCacheMutex;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
@ -26,7 +26,7 @@
|
|||||||
#include <QMessageBox>
|
#include <QMessageBox>
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
|
|
||||||
GxsCreateCommentDialog::GxsCreateCommentDialog(RsGxsCommentService *service, const RsGxsGrpMsgIdPair &parentId, const RsGxsMessageId& threadId, QWidget *parent) :
|
GxsCreateCommentDialog::GxsCreateCommentDialog(RsGxsCommentService *service, const RsGxsGrpMsgIdPair &parentId, const RsGxsMessageId& threadId, const RsGxsId& default_author,QWidget *parent) :
|
||||||
QDialog(parent),
|
QDialog(parent),
|
||||||
ui(new Ui::GxsCreateCommentDialog), mCommentService(service), mParentId(parentId), mThreadId(threadId)
|
ui(new Ui::GxsCreateCommentDialog), mCommentService(service), mParentId(parentId), mThreadId(threadId)
|
||||||
{
|
{
|
||||||
@ -35,7 +35,7 @@ GxsCreateCommentDialog::GxsCreateCommentDialog(RsGxsCommentService *service, co
|
|||||||
connect(ui->buttonBox, SIGNAL(rejected()), this, SLOT(close()));
|
connect(ui->buttonBox, SIGNAL(rejected()), this, SLOT(close()));
|
||||||
|
|
||||||
/* fill in the available OwnIds for signing */
|
/* fill in the available OwnIds for signing */
|
||||||
ui->idChooser->loadIds(IDCHOOSER_ID_REQUIRED, RsGxsId());
|
ui->idChooser->loadIds(IDCHOOSER_ID_REQUIRED, default_author);
|
||||||
}
|
}
|
||||||
|
|
||||||
void GxsCreateCommentDialog::loadComment(const QString &msgText, const QString &msgAuthor, const RsGxsId &msgAuthorId)
|
void GxsCreateCommentDialog::loadComment(const QString &msgText, const QString &msgAuthor, const RsGxsId &msgAuthorId)
|
||||||
|
@ -36,7 +36,7 @@ class GxsCreateCommentDialog : public QDialog
|
|||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
|
||||||
public:
|
public:
|
||||||
explicit GxsCreateCommentDialog(RsGxsCommentService *service, const RsGxsGrpMsgIdPair& parentId, const RsGxsMessageId& threadId, QWidget *parent = 0);
|
explicit GxsCreateCommentDialog(RsGxsCommentService *service, const RsGxsGrpMsgIdPair& parentId, const RsGxsMessageId& threadId, const RsGxsId& default_author=RsGxsId(),QWidget *parent = 0);
|
||||||
~GxsCreateCommentDialog();
|
~GxsCreateCommentDialog();
|
||||||
|
|
||||||
void loadComment(const QString &msgText, const QString &msgAuthor, const RsGxsId &msgAuthorId);
|
void loadComment(const QString &msgText, const QString &msgAuthor, const RsGxsId &msgAuthorId);
|
||||||
|
@ -731,7 +731,7 @@ void GxsGroupFrameDialog::loadComment(const RsGxsGroupId &grpId, const QVector<R
|
|||||||
comments += "...";
|
comments += "...";
|
||||||
}
|
}
|
||||||
|
|
||||||
commentDialog = new GxsCommentDialog(this, mInterface->getTokenService(), commentService);
|
commentDialog = new GxsCommentDialog(this,RsGxsId(), mInterface->getTokenService(), commentService);
|
||||||
|
|
||||||
QWidget *commentHeader = createCommentHeaderWidget(grpId, most_recent_msgId);
|
QWidget *commentHeader = createCommentHeaderWidget(grpId, most_recent_msgId);
|
||||||
if (commentHeader) {
|
if (commentHeader) {
|
||||||
|
@ -313,7 +313,7 @@ void GxsIdChooser::setDefaultItem()
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (def >= 0) {
|
if (def >= 0) {
|
||||||
setCurrentIndex(def);
|
whileBlocking(this)->setCurrentIndex(def);
|
||||||
#ifdef IDCHOOSER_DEBUG
|
#ifdef IDCHOOSER_DEBUG
|
||||||
std::cerr << "GxsIdChooser-002" << (void*)this << " setting current index to " << def << std::endl;
|
std::cerr << "GxsIdChooser-002" << (void*)this << " setting current index to " << def << std::endl;
|
||||||
#endif
|
#endif
|
||||||
|
@ -65,10 +65,8 @@ CreateGxsChannelMsg::CreateGxsChannelMsg(const RsGxsGroupId &cId, RsGxsMessageId
|
|||||||
|
|
||||||
setAttribute ( Qt::WA_DeleteOnClose, true );
|
setAttribute ( Qt::WA_DeleteOnClose, true );
|
||||||
|
|
||||||
buttonBox->button(QDialogButtonBox::Ok)->setText(tr("Post"));
|
connect(postButton, SIGNAL(clicked()), this, SLOT(sendMsg()));
|
||||||
|
connect(cancelButton, SIGNAL(clicked()), this, SLOT(cancelMsg()));
|
||||||
connect(buttonBox, SIGNAL(accepted()), this, SLOT(sendMsg()));
|
|
||||||
connect(buttonBox, SIGNAL(rejected()), this, SLOT(cancelMsg()));
|
|
||||||
|
|
||||||
connect(addFileButton, SIGNAL(clicked() ), this , SLOT(addExtraFile()));
|
connect(addFileButton, SIGNAL(clicked() ), this , SLOT(addExtraFile()));
|
||||||
connect(addfilepushButton, SIGNAL(clicked() ), this , SLOT(addExtraFile()));
|
connect(addfilepushButton, SIGNAL(clicked() ), this , SLOT(addExtraFile()));
|
||||||
@ -599,8 +597,8 @@ void CreateGxsChannelMsg::checkAttachmentReady()
|
|||||||
* recognized by librs but not correctly by gui (can't
|
* recognized by librs but not correctly by gui (can't
|
||||||
* formally remove it)
|
* formally remove it)
|
||||||
*/
|
*/
|
||||||
buttonBox->button(QDialogButtonBox::Ok)->setEnabled(false);
|
postButton->setEnabled(false);
|
||||||
buttonBox->button(QDialogButtonBox::Cancel)->setEnabled(false);
|
cancelButton->setEnabled(false);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -608,8 +606,8 @@ void CreateGxsChannelMsg::checkAttachmentReady()
|
|||||||
|
|
||||||
if (fit == mAttachments.end())
|
if (fit == mAttachments.end())
|
||||||
{
|
{
|
||||||
buttonBox->button(QDialogButtonBox::Ok)->setEnabled(true);
|
postButton->setEnabled(true);
|
||||||
buttonBox->button(QDialogButtonBox::Cancel)->setEnabled(true);
|
cancelButton->setEnabled(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* repeat... */
|
/* repeat... */
|
||||||
|
@ -329,7 +329,7 @@ p, li { white-space: pre-wrap; }
|
|||||||
<rect>
|
<rect>
|
||||||
<x>0</x>
|
<x>0</x>
|
||||||
<y>0</y>
|
<y>0</y>
|
||||||
<width>842</width>
|
<width>81</width>
|
||||||
<height>24</height>
|
<height>24</height>
|
||||||
</rect>
|
</rect>
|
||||||
</property>
|
</property>
|
||||||
@ -431,6 +431,9 @@ p, li { white-space: pre-wrap; }
|
|||||||
</item>
|
</item>
|
||||||
<item row="2" column="0" colspan="3">
|
<item row="2" column="0" colspan="3">
|
||||||
<layout class="QHBoxLayout" name="buttonHLayout">
|
<layout class="QHBoxLayout" name="buttonHLayout">
|
||||||
|
<property name="spacing">
|
||||||
|
<number>9</number>
|
||||||
|
</property>
|
||||||
<item>
|
<item>
|
||||||
<widget class="QCheckBox" name="generateCheckBox">
|
<widget class="QCheckBox" name="generateCheckBox">
|
||||||
<property name="text">
|
<property name="text">
|
||||||
@ -449,15 +452,29 @@ p, li { white-space: pre-wrap; }
|
|||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
<item>
|
<item>
|
||||||
<widget class="QDialogButtonBox" name="buttonBox">
|
<spacer name="horizontalSpacer_3">
|
||||||
<property name="styleSheet">
|
|
||||||
<string notr="true"/>
|
|
||||||
</property>
|
|
||||||
<property name="orientation">
|
<property name="orientation">
|
||||||
<enum>Qt::Horizontal</enum>
|
<enum>Qt::Horizontal</enum>
|
||||||
</property>
|
</property>
|
||||||
<property name="standardButtons">
|
<property name="sizeHint" stdset="0">
|
||||||
<set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set>
|
<size>
|
||||||
|
<width>40</width>
|
||||||
|
<height>20</height>
|
||||||
|
</size>
|
||||||
|
</property>
|
||||||
|
</spacer>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QPushButton" name="postButton">
|
||||||
|
<property name="text">
|
||||||
|
<string>Post</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QPushButton" name="cancelButton">
|
||||||
|
<property name="text">
|
||||||
|
<string>Cancel</string>
|
||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
|
@ -1,78 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8"?>
|
|
||||||
<ui version="4.0">
|
|
||||||
<class>GxsChannelFilesWidget</class>
|
|
||||||
<widget class="QWidget" name="GxsChannelFilesWidget">
|
|
||||||
<property name="geometry">
|
|
||||||
<rect>
|
|
||||||
<x>0</x>
|
|
||||||
<y>0</y>
|
|
||||||
<width>400</width>
|
|
||||||
<height>300</height>
|
|
||||||
</rect>
|
|
||||||
</property>
|
|
||||||
<property name="windowTitle">
|
|
||||||
<string>Form</string>
|
|
||||||
</property>
|
|
||||||
<layout class="QVBoxLayout" name="verticalLayout">
|
|
||||||
<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>
|
|
||||||
<widget class="QTreeWidget" name="treeWidget">
|
|
||||||
<property name="rootIsDecorated">
|
|
||||||
<bool>false</bool>
|
|
||||||
</property>
|
|
||||||
<property name="itemsExpandable">
|
|
||||||
<bool>false</bool>
|
|
||||||
</property>
|
|
||||||
<property name="sortingEnabled">
|
|
||||||
<bool>true</bool>
|
|
||||||
</property>
|
|
||||||
<attribute name="headerShowSortIndicator" stdset="0">
|
|
||||||
<bool>true</bool>
|
|
||||||
</attribute>
|
|
||||||
<column>
|
|
||||||
<property name="text">
|
|
||||||
<string notr="true">1</string>
|
|
||||||
</property>
|
|
||||||
</column>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item>
|
|
||||||
<widget class="QFrame" name="feedItemFrame">
|
|
||||||
<property name="frameShape">
|
|
||||||
<enum>QFrame::StyledPanel</enum>
|
|
||||||
</property>
|
|
||||||
<property name="frameShadow">
|
|
||||||
<enum>QFrame::Raised</enum>
|
|
||||||
</property>
|
|
||||||
<layout class="QVBoxLayout" name="verticalLayout_2">
|
|
||||||
<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>
|
|
||||||
</layout>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
</layout>
|
|
||||||
</widget>
|
|
||||||
<resources/>
|
|
||||||
<connections/>
|
|
||||||
</ui>
|
|
@ -18,12 +18,16 @@
|
|||||||
* *
|
* *
|
||||||
*******************************************************************************/
|
*******************************************************************************/
|
||||||
|
|
||||||
|
#include <math.h>
|
||||||
|
|
||||||
#include <QWheelEvent>
|
#include <QWheelEvent>
|
||||||
#include <QDateTime>
|
#include <QDateTime>
|
||||||
|
|
||||||
#include "gui/common/FilesDefs.h"
|
#include "gui/common/FilesDefs.h"
|
||||||
#include "gui/gxschannels/GxsChannelPostThumbnail.h"
|
#include "gui/gxschannels/GxsChannelPostThumbnail.h"
|
||||||
|
|
||||||
|
// #define DEBUG_GXSCHANNELPOSTTHUMBNAIL 1
|
||||||
|
|
||||||
const float ChannelPostThumbnailView::DEFAULT_SIZE_IN_FONT_HEIGHT = 5.0;
|
const float ChannelPostThumbnailView::DEFAULT_SIZE_IN_FONT_HEIGHT = 5.0;
|
||||||
const float ChannelPostThumbnailView::FONT_SCALE_FACTOR = 1.5;
|
const float ChannelPostThumbnailView::FONT_SCALE_FACTOR = 1.5;
|
||||||
|
|
||||||
@ -50,7 +54,9 @@ void ChannelPostThumbnailView::setText(const QString& s)
|
|||||||
{
|
{
|
||||||
if(mPostTitle == NULL)
|
if(mPostTitle == NULL)
|
||||||
{
|
{
|
||||||
|
#ifdef DEBUG_GXSCHANNELPOSTTHUMBNAIL
|
||||||
std::cerr << "(EE) calling setText on a ChannelPostThumbnailView without SHOW_TEXT flag!"<< std::endl;
|
std::cerr << "(EE) calling setText on a ChannelPostThumbnailView without SHOW_TEXT flag!"<< std::endl;
|
||||||
|
#endif
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -246,6 +252,8 @@ void ZoomableLabel::mousePressEvent(QMouseEvent *me)
|
|||||||
mMoving = true;
|
mMoving = true;
|
||||||
mLastX = me->x();
|
mLastX = me->x();
|
||||||
mLastY = me->y();
|
mLastY = me->y();
|
||||||
|
|
||||||
|
emit clicked();
|
||||||
}
|
}
|
||||||
void ZoomableLabel::mouseReleaseEvent(QMouseEvent *)
|
void ZoomableLabel::mouseReleaseEvent(QMouseEvent *)
|
||||||
{
|
{
|
||||||
@ -292,7 +300,11 @@ QPixmap ZoomableLabel::extractCroppedScaledPicture() const
|
|||||||
|
|
||||||
void ZoomableLabel::setPicture(const QPixmap& pix)
|
void ZoomableLabel::setPicture(const QPixmap& pix)
|
||||||
{
|
{
|
||||||
|
#ifdef DEBUG_GXSCHANNELPOSTTHUMBNAIL
|
||||||
|
std::cerr << "Setting new picture of size " << pix.width() << " x " << pix.height() << std::endl;
|
||||||
|
#endif
|
||||||
mFullImage = pix;
|
mFullImage = pix;
|
||||||
|
setScaledContents(true);
|
||||||
|
|
||||||
reset();
|
reset();
|
||||||
updateView();
|
updateView();
|
||||||
@ -312,7 +324,15 @@ void ZoomableLabel::updateView()
|
|||||||
// - the original center is preferred
|
// - the original center is preferred
|
||||||
// - if the crop overlaps the image border, the center is moved.
|
// - if the crop overlaps the image border, the center is moved.
|
||||||
|
|
||||||
QRect rect(mCenterX - 0.5 * width()*mZoomFactor, mCenterY - 0.5 * height()*mZoomFactor, width()*mZoomFactor, height()*mZoomFactor);
|
QRect rect(mCenterX - 0.5 * width()*mZoomFactor, mCenterY - 0.5 * height()*mZoomFactor, floor(width()*mZoomFactor), floor(height()*mZoomFactor));
|
||||||
|
|
||||||
|
#ifdef DEBUG_GXSCHANNELPOSTTHUMBNAIL
|
||||||
|
std::cerr << "Updating view: mCenterX=" << mCenterX << ", mCenterY=" << mCenterY << ", mZoomFactor=" << mZoomFactor << std::endl;
|
||||||
|
std::cerr << " Image size: " << mFullImage.width() << " x " << mFullImage.height() << ", window size: " << width() << " x " << height() << std::endl;
|
||||||
|
std::cerr << " cropped image: " << rect.left() << "," << rect.top() << "+" << rect.width() << "+" << rect.height() << std::endl;
|
||||||
|
std::cerr << " saving crop to pix2.png" << std::endl;
|
||||||
|
mFullImage.copy(rect).save("pix2.png","PNG");
|
||||||
|
#endif
|
||||||
QLabel::setPixmap(mFullImage.copy(rect));
|
QLabel::setPixmap(mFullImage.copy(rect));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -37,8 +37,10 @@
|
|||||||
|
|
||||||
class ZoomableLabel: public QLabel
|
class ZoomableLabel: public QLabel
|
||||||
{
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
|
||||||
public:
|
public:
|
||||||
ZoomableLabel(QWidget *parent): QLabel(parent),mZoomFactor(1.0),mCenterX(0.0),mCenterY(0.0),mZoomEnabled(true) {}
|
ZoomableLabel(QWidget *parent): QLabel(parent),mUseStyleSheet(true),mZoomFactor(1.0),mCenterX(0.0),mCenterY(0.0),mZoomEnabled(true) {}
|
||||||
|
|
||||||
void setPicture(const QPixmap& pix);
|
void setPicture(const QPixmap& pix);
|
||||||
void setEnableZoom(bool b) { mZoomEnabled = b; }
|
void setEnableZoom(bool b) { mZoomEnabled = b; }
|
||||||
@ -48,6 +50,9 @@ public:
|
|||||||
|
|
||||||
const QPixmap& originalImage() const { return mFullImage ; }
|
const QPixmap& originalImage() const { return mFullImage ; }
|
||||||
|
|
||||||
|
signals:
|
||||||
|
void clicked();
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
void mousePressEvent(QMouseEvent *ev) override;
|
void mousePressEvent(QMouseEvent *ev) override;
|
||||||
void mouseReleaseEvent(QMouseEvent *ev) override;
|
void mouseReleaseEvent(QMouseEvent *ev) override;
|
||||||
@ -55,11 +60,16 @@ protected:
|
|||||||
void resizeEvent(QResizeEvent *ev) override;
|
void resizeEvent(QResizeEvent *ev) override;
|
||||||
void wheelEvent(QWheelEvent *me) override;
|
void wheelEvent(QWheelEvent *me) override;
|
||||||
|
|
||||||
|
void enterEvent(QEvent * /* ev */ ) override { if(mUseStyleSheet) setStyleSheet("QLabel { border: 2px solid #039bd5; }");}
|
||||||
|
void leaveEvent(QEvent * /* ev */ ) override { if(mUseStyleSheet) setStyleSheet("QLabel { border: 2px solid #CCCCCC; border-radius: 3px; }");}
|
||||||
|
|
||||||
|
bool mUseStyleSheet;
|
||||||
|
|
||||||
QPixmap mFullImage;
|
QPixmap mFullImage;
|
||||||
|
|
||||||
|
float mZoomFactor;
|
||||||
float mCenterX;
|
float mCenterX;
|
||||||
float mCenterY;
|
float mCenterY;
|
||||||
float mZoomFactor;
|
|
||||||
int mLastX,mLastY;
|
int mLastX,mLastY;
|
||||||
bool mMoving;
|
bool mMoving;
|
||||||
bool mZoomEnabled;
|
bool mZoomEnabled;
|
||||||
|
@ -1069,6 +1069,8 @@ void GxsChannelPostsWidgetWithModel::insertChannelDetails(const RsGxsChannelGrou
|
|||||||
RetroShareLink link = RetroShareLink::createMessage(group.mMeta.mAuthorId, "");
|
RetroShareLink link = RetroShareLink::createMessage(group.mMeta.mAuthorId, "");
|
||||||
ui->infoAdministrator->setText(link.toHtml());
|
ui->infoAdministrator->setText(link.toHtml());
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
ui->infoAdministrator->setText("[No contact author]");
|
||||||
|
|
||||||
ui->infoCreated->setText(DateTime::formatLongDateTime(group.mMeta.mPublishTs));
|
ui->infoCreated->setText(DateTime::formatLongDateTime(group.mMeta.mPublishTs));
|
||||||
|
|
||||||
@ -1165,6 +1167,9 @@ bool GxsChannelPostsWidgetWithModel::navigate(const RsGxsMessageId& msgId)
|
|||||||
ui->postsTree->scrollTo(index);//May change if model reloaded
|
ui->postsTree->scrollTo(index);//May change if model reloaded
|
||||||
ui->postsTree->setFocus();
|
ui->postsTree->setFocus();
|
||||||
|
|
||||||
|
ui->channel_TW->setCurrentIndex(CHANNEL_TABS_POSTS);
|
||||||
|
ui->details_TW->setCurrentIndex(CHANNEL_TABS_DETAILS);
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -431,7 +431,7 @@ p, li { white-space: pre-wrap; }
|
|||||||
</font>
|
</font>
|
||||||
</property>
|
</property>
|
||||||
<property name="currentIndex">
|
<property name="currentIndex">
|
||||||
<number>1</number>
|
<number>0</number>
|
||||||
</property>
|
</property>
|
||||||
<widget class="QWidget" name="tab">
|
<widget class="QWidget" name="tab">
|
||||||
<attribute name="title">
|
<attribute name="title">
|
||||||
|
@ -115,7 +115,23 @@ GxsCreateCommentDialog QFrame#frame {
|
|||||||
background: white;
|
background: white;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
CreateGxsChannelMsg QPushButton#postButton {
|
||||||
|
font: bold;
|
||||||
|
font-size: 15px;
|
||||||
|
color: white;
|
||||||
|
background: #0099cc;
|
||||||
|
border-radius: 4px;
|
||||||
|
max-height: 27px;
|
||||||
|
min-width: 4em;
|
||||||
|
padding: 2px;
|
||||||
|
}
|
||||||
|
|
||||||
|
CreateGxsChannelMsg QPushButton#postButton:hover {
|
||||||
|
background: #03b1f3;
|
||||||
|
border-radius: 4px;
|
||||||
|
min-width: 4em;
|
||||||
|
padding: 2px;
|
||||||
|
}
|
||||||
|
|
||||||
/* Forums */
|
/* Forums */
|
||||||
|
|
||||||
@ -699,16 +715,16 @@ GenCertDialog QFrame#profileframe{
|
|||||||
border-width: 0px;
|
border-width: 0px;
|
||||||
}
|
}
|
||||||
|
|
||||||
PostedListWidget QComboBox#comboBox {
|
PostedListWidgetWithModel QComboBox#sortStrategy_CB {
|
||||||
font: bold;
|
font: bold;
|
||||||
color: #0099cc;
|
color: #0099cc;
|
||||||
}
|
}
|
||||||
|
|
||||||
PostedListWidget QToolButton#submitPostButton {
|
PostedListWidgetWithModel QToolButton#submitPostButton {
|
||||||
font: bold;
|
font: bold;
|
||||||
}
|
}
|
||||||
|
|
||||||
PostedListWidget QToolButton#subscribeToolButton {
|
PostedListWidgetWithModel QToolButton#subscribeToolButton {
|
||||||
font: bold;
|
font: bold;
|
||||||
font-size: 15px;
|
font-size: 15px;
|
||||||
color: white;
|
color: white;
|
||||||
@ -717,12 +733,12 @@ PostedListWidget QToolButton#subscribeToolButton {
|
|||||||
max-height: 27px;
|
max-height: 27px;
|
||||||
}
|
}
|
||||||
|
|
||||||
PostedListWidget QToolButton#subscribeToolButton:hover {
|
PostedListWidgetWithModel QToolButton#subscribeToolButton:hover {
|
||||||
background: #03b1f3;
|
background: #03b1f3;
|
||||||
border-radius: 4px;
|
border-radius: 4px;
|
||||||
}
|
}
|
||||||
|
|
||||||
PostedListWidget QFrame#headerFrame {
|
PostedListWidgetWithModel QFrame#headerFrame {
|
||||||
background-color: qlineargradient(x1:0, y1:0, x2:0, y2:1, stop:0 #FEFEFE, stop:1 #E8E8E8);
|
background-color: qlineargradient(x1:0, y1:0, x2:0, y2:1, stop:0 #FEFEFE, stop:1 #E8E8E8);
|
||||||
border: 1px solid #CCCCCC;
|
border: 1px solid #CCCCCC;
|
||||||
}
|
}
|
||||||
@ -807,50 +823,45 @@ GxsGroupDialog QLabel#groupLogo{
|
|||||||
border-radius: 3px;
|
border-radius: 3px;
|
||||||
}
|
}
|
||||||
|
|
||||||
PostedItem QFrame#frame_notes {
|
|
||||||
background: white;
|
|
||||||
}
|
|
||||||
|
|
||||||
PostedItem QFrame#mainFrame {
|
BoardPostDisplayWidget_compact QFrame#mainFrame {
|
||||||
background-color: white;
|
background-color: white;
|
||||||
}
|
}
|
||||||
|
|
||||||
PostedItem QLabel#notes {
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
PostedItem QFrame#voteFrame {
|
PostedItem QFrame#voteFrame {
|
||||||
background: #f8f9fa;
|
background: #f8f9fa;
|
||||||
}
|
}
|
||||||
|
|
||||||
PostedItem QFrame#mainFrame [new=false]{
|
BoardPostDisplayWidget_compact > QFrame#mainFrame [new=false]{
|
||||||
background: white;
|
background: white;
|
||||||
}
|
}
|
||||||
|
|
||||||
PostedItem > QFrame#mainFrame[new=true] {
|
BoardPostDisplayWidget_compact > QFrame#mainFrame[new=true] {
|
||||||
background-color: qlineargradient(x1:0, y1:0, x2:0, y2:1, stop:0 #F0F8FD, stop:0.8 #E6F2FD, stop: 0.81 #E6F2FD, stop: 1 #D2E7FD);
|
background-color: qlineargradient(x1:0, y1:0, x2:0, y2:1, stop:0 #F0F8FD, stop:0.8 #E6F2FD, stop: 0.81 #E6F2FD, stop: 1 #D2E7FD);
|
||||||
}
|
}
|
||||||
|
|
||||||
PostedItem QFrame#frame_picture{
|
BoardPostDisplayWidget_compact QLabel#pictureLabel{
|
||||||
background: white;
|
|
||||||
}
|
|
||||||
|
|
||||||
PostedItem QLabel#thumbnailLabel{
|
|
||||||
border: 2px solid #CCCCCC;
|
border: 2px solid #CCCCCC;
|
||||||
border-radius: 3px;
|
border-radius: 3px;
|
||||||
}
|
}
|
||||||
|
|
||||||
PostedItem QLabel#fromBoldLabel, QLabel#fromLabel, QLabel#dateLabel, QLabel#siteBoldLabel {
|
BoardPostDisplayWidget_compact QLabel#fromBoldLabel ,
|
||||||
|
BoardPostDisplayWidget_card QLabel#fromBoldLabel {
|
||||||
|
font: bold;
|
||||||
|
}
|
||||||
|
|
||||||
|
BoardPostDisplayWidget_compact QLabel#fromBoldLabel, QLabel#fromLabel, QLabel#dateLabel, QLabel#siteBoldLabel ,
|
||||||
|
BoardPostDisplayWidget_card QLabel#fromBoldLabel, QLabel#fromLabel, QLabel#dateLabel, QLabel#siteBoldLabel{
|
||||||
color: #787c7e;
|
color: #787c7e;
|
||||||
}
|
}
|
||||||
|
|
||||||
PostedItem QLabel#newLabel {
|
BoardPostDisplayWidget_compact QLabel#newLabel {
|
||||||
border: 1px solid #167BE7;
|
border: 1px solid #167BE7;
|
||||||
background-color: qlineargradient(x1: 0, y1: 0, x2: 0, y2: 1, stop: 0 #2291E0, stop: 1 #3EB3FF);
|
background-color: qlineargradient(x1: 0, y1: 0, x2: 0, y2: 1, stop: 0 #2291E0, stop: 1 #3EB3FF);
|
||||||
border-radius: 3px;
|
border-radius: 3px;
|
||||||
}
|
}
|
||||||
|
|
||||||
PostedCardView QLabel#newLabel {
|
BoardPostDisplayWidget_card QLabel#newLabel {
|
||||||
border: 1px solid #167BE7;
|
border: 1px solid #167BE7;
|
||||||
background-color: qlineargradient(x1: 0, y1: 0, x2: 0, y2: 1, stop: 0 #2291E0, stop: 1 #3EB3FF);
|
background-color: qlineargradient(x1: 0, y1: 0, x2: 0, y2: 1, stop: 0 #2291E0, stop: 1 #3EB3FF);
|
||||||
border-radius: 3px;
|
border-radius: 3px;
|
||||||
@ -860,17 +871,30 @@ PostedCardView QFrame#voteFrame {
|
|||||||
background: #f8f9fa;
|
background: #f8f9fa;
|
||||||
}
|
}
|
||||||
|
|
||||||
PostedCardView QFrame#mainFrame {
|
BoardPostDisplayWidget_card QFrame#mainFrame{
|
||||||
background: white;
|
background: white;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
BoardPostDisplayWidget_card > QFrame#mainFrame [new=false]{
|
||||||
|
background: white;
|
||||||
|
}
|
||||||
|
|
||||||
|
BoardPostDisplayWidget_card > QFrame#mainFrame[new=true] {
|
||||||
|
background-color: qlineargradient(x1:0, y1:0, x2:0, y2:1, stop:0 #F0F8FD, stop:0.8 #E6F2FD, stop: 0.81 #E6F2FD, stop: 1 #D2E7FD);
|
||||||
|
}
|
||||||
|
|
||||||
|
BoardPostDisplayWidget_compact QLabel#titleLabel,
|
||||||
|
BoardPostDisplayWidget_card QLabel#titleLabel{
|
||||||
|
font-size: 14px;
|
||||||
|
font: bold;
|
||||||
|
}
|
||||||
|
|
||||||
GxsCommentDialog QComboBox#sortBox {
|
GxsCommentDialog QComboBox#sortBox {
|
||||||
font: bold;
|
font: bold;
|
||||||
color: #0099cc;
|
color: #0099cc;
|
||||||
}
|
}
|
||||||
|
|
||||||
PostedListWidget QTextBrowser#infoDescription {
|
PostedListWidgetWithModel QTextBrowser#infoDescription {
|
||||||
background: transparent;
|
background: transparent;
|
||||||
border: none;
|
border: none;
|
||||||
}
|
}
|
||||||
|
@ -20,7 +20,8 @@
|
|||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <retroshare-gui/configpage.h>
|
#include "retroshare-gui/configpage.h"
|
||||||
|
#include "gui/common/FilesDefs.h"
|
||||||
#include "ui_WebuiPage.h"
|
#include "ui_WebuiPage.h"
|
||||||
|
|
||||||
namespace resource_api{
|
namespace resource_api{
|
||||||
|
@ -1983,7 +1983,7 @@ QTreeView [new=true]{
|
|||||||
|
|
||||||
/* changes for the subscribe Button */
|
/* changes for the subscribe Button */
|
||||||
|
|
||||||
PostedListWidget QToolButton#subscribeToolButton {
|
PostedListWidgetWithModel QToolButton#subscribeToolButton {
|
||||||
font: bold;
|
font: bold;
|
||||||
font-size: 15px;
|
font-size: 15px;
|
||||||
color: white;
|
color: white;
|
||||||
@ -1992,7 +1992,7 @@ PostedListWidget QToolButton#subscribeToolButton {
|
|||||||
max-height: 27px;
|
max-height: 27px;
|
||||||
}
|
}
|
||||||
|
|
||||||
PostedListWidget QToolButton#subscribeToolButton:hover {
|
PostedListWidgetWithModel QToolButton#subscribeToolButton:hover {
|
||||||
background: #03b1f3;
|
background: #03b1f3;
|
||||||
border-radius: 4px;
|
border-radius: 4px;
|
||||||
}
|
}
|
||||||
@ -2011,7 +2011,7 @@ GxsForumThreadWidget QToolButton#subscribeToolButton:hover {
|
|||||||
border-radius: 4px;
|
border-radius: 4px;
|
||||||
}
|
}
|
||||||
|
|
||||||
GxsChannelPostsWidget QToolButton#subscribeToolButton {
|
GxsChannelPostsWidgetWithModel QToolButton#subscribeToolButton {
|
||||||
font: bold;
|
font: bold;
|
||||||
font-size: 14px;
|
font-size: 14px;
|
||||||
color: white;
|
color: white;
|
||||||
@ -2020,18 +2020,18 @@ GxsChannelPostsWidget QToolButton#subscribeToolButton {
|
|||||||
max-height: 27px;
|
max-height: 27px;
|
||||||
}
|
}
|
||||||
|
|
||||||
GxsChannelPostsWidget QToolButton#subscribeToolButton:hover {
|
GxsChannelPostsWidgetWithModel QToolButton#subscribeToolButton:hover {
|
||||||
background: #03b1f3;
|
background: #03b1f3;
|
||||||
border-radius: 4px;
|
border-radius: 4px;
|
||||||
}
|
}
|
||||||
|
|
||||||
GxsChannelPostsWidget QToolButton#subscribeToolButton:pressed {
|
GxsChannelPostsWidgetWithModel QToolButton#subscribeToolButton:pressed {
|
||||||
background: #03b1f3;
|
background: #03b1f3;
|
||||||
border-radius: 4px;
|
border-radius: 4px;
|
||||||
border: 1px solid gray;
|
border: 1px solid gray;
|
||||||
}
|
}
|
||||||
|
|
||||||
GxsChannelPostsWidget QToolButton#subscribeToolButton:disabled {
|
GxsChannelPostsWidgetWithModel QToolButton#subscribeToolButton:disabled {
|
||||||
background: gray;
|
background: gray;
|
||||||
border-radius: 4px;
|
border-radius: 4px;
|
||||||
border: 1px solid gray;
|
border: 1px solid gray;
|
||||||
@ -2039,19 +2039,37 @@ GxsChannelPostsWidget QToolButton#subscribeToolButton:disabled {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* only for MenuButtonPopup */
|
/* only for MenuButtonPopup */
|
||||||
GxsChannelPostsWidget QToolButton#subscribeToolButton[popupMode="1"] {
|
GxsChannelPostsWidgetWithModel QToolButton#subscribeToolButton[popupMode="1"] {
|
||||||
padding-right: 0px;
|
padding-right: 0px;
|
||||||
}
|
}
|
||||||
|
|
||||||
GxsChannelPostsWidget QToolButton#subscribeToolButton::menu-arrow {
|
GxsChannelPostsWidgetWithModel QToolButton#subscribeToolButton::menu-arrow {
|
||||||
image: none;
|
image: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
GxsChannelPostsWidget QToolButton#subscribeToolButton::menu-button {
|
GxsChannelPostsWidgetWithModel QToolButton#subscribeToolButton::menu-button {
|
||||||
image: none;
|
image: none;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
CreateGxsChannelMsg QPushButton#postButton {
|
||||||
|
font: bold;
|
||||||
|
font-size: 15px;
|
||||||
|
color: white;
|
||||||
|
background: #0099cc;
|
||||||
|
border-radius: 4px;
|
||||||
|
max-height: 27px;
|
||||||
|
min-width: 4em;
|
||||||
|
padding: 2px;
|
||||||
|
}
|
||||||
|
|
||||||
|
CreateGxsChannelMsg QPushButton#postButton:hover {
|
||||||
|
background: #03b1f3;
|
||||||
|
border-radius: 4px;
|
||||||
|
min-width: 4em;
|
||||||
|
padding: 2px;
|
||||||
|
}
|
||||||
|
|
||||||
QTabBar#smTab::tab{
|
QTabBar#smTab::tab{
|
||||||
height: 32px;
|
height: 32px;
|
||||||
width: 32px;
|
width: 32px;
|
||||||
@ -2074,73 +2092,86 @@ PostedCreatePostDialog QPushButton#submitButton:hover {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
PostedItem QFrame#mainFrame {
|
BoardPostDisplayWidget_compact QFrame#mainFrame {
|
||||||
border-radius: 4px;
|
border-radius: 4px;
|
||||||
border: 1px solid #32414B;
|
border: 1px solid #32414B;
|
||||||
background-color: #19232D;
|
background-color: #19232D;
|
||||||
|
}
|
||||||
|
|
||||||
|
BoardPostDisplayWidget_compact QFrame#mainFrame [new=false]{
|
||||||
|
background: #19232D;
|
||||||
|
}
|
||||||
|
|
||||||
|
BoardPostDisplayWidget_compact QFrame#mainFrame[new=true] {
|
||||||
|
background-color: #1464a0;
|
||||||
}
|
}
|
||||||
|
|
||||||
GxsChannelPostItem QFrame#mainFrame {
|
GxsChannelPostItem QFrame#mainFrame {
|
||||||
border-radius: 4px;
|
border-radius: 4px;
|
||||||
border: 1px solid #32414B;
|
border: 1px solid #32414B;
|
||||||
background-color: #19232D;
|
background-color: #19232D;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
PostedItem QPushButton#shareButton
|
BoardPostDisplayWidget_compact QPushButton#shareButton {
|
||||||
{
|
|
||||||
background-color: transparent;
|
background-color: transparent;
|
||||||
min-width: 80px;
|
min-width: 80px;
|
||||||
max-height: 22px;
|
max-height: 22px;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
PostedItem QLabel#scoreLabel
|
BoardPostDisplayWidget_compact QFrame#voteFrame {
|
||||||
{
|
|
||||||
background-color: transparent;
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
PostedItem QFrame#voteFrame {
|
|
||||||
background: #141415;
|
background: #141415;
|
||||||
}
|
}
|
||||||
|
|
||||||
PostedItem QToolButton#voteDownButton, QToolButton#voteUpButton
|
BoardPostDisplayWidget_compact QToolButton#voteDownButton, QToolButton#voteUpButton,
|
||||||
|
BoardPostDisplayWidget_card QToolButton#voteDownButton, QToolButton#voteUpButton
|
||||||
{
|
{
|
||||||
border: none;
|
border: none;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
PostedItem QLabel#thumbnailLabel{
|
BoardPostDisplayWidget_compact QLabel#pictureLabel{
|
||||||
border: 2px solid #CCCCCC;
|
border: 2px solid #CCCCCC;
|
||||||
border-radius: 3px;
|
border-radius: 3px;
|
||||||
}
|
}
|
||||||
|
|
||||||
PostedCardView QPushButton#shareButton
|
BoardPostDisplayWidget_compact QLabel#scoreLabel, QLabel#titleLabel, QLabel#fromBoldLabel , QLabel#fromLabel, QLabel#dateLabel,
|
||||||
{
|
BoardPostDisplayWidget_card QLabel#scoreLabel, QLabel#titleLabel{
|
||||||
background-color: transparent;
|
background-color: transparent;
|
||||||
min-width: 80px;
|
|
||||||
max-height: 22px;
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
PostedCardView QFrame#voteFrame {
|
BoardPostDisplayWidget_compact QLabel#newLabel,
|
||||||
|
BoardPostDisplayWidget_card QLabel#newLabel {
|
||||||
|
border: 1px solid #00B712;
|
||||||
|
background-color: qlineargradient(x1: 0, y1: 0, x2: 0, y2: 1, stop: 0 #5AFF15, stop: 1 #00B712);
|
||||||
|
border-radius: 3px;
|
||||||
|
color: black;
|
||||||
|
}
|
||||||
|
|
||||||
|
BoardPostDisplayWidget_card QPushButton#shareButton{
|
||||||
|
background-color: transparent;
|
||||||
|
min-width: 80px;
|
||||||
|
max-height: 22px;
|
||||||
|
}
|
||||||
|
|
||||||
|
BoardPostDisplayWidget_card QFrame#voteFrame {
|
||||||
background: #141415;
|
background: #141415;
|
||||||
}
|
}
|
||||||
|
|
||||||
PostedCardView QFrame#mainFrame {
|
BoardPostDisplayWidget_card QFrame#mainFrame {
|
||||||
|
background-color: #19232D;
|
||||||
background-color: #19232D;
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
PostedCardView QFrame#mainFrame [new=false]{
|
BoardPostDisplayWidget_card QFrame#mainFrame [new=false]{
|
||||||
background: #19232D;
|
background: #19232D;
|
||||||
}
|
}
|
||||||
|
|
||||||
PostedCardView > QFrame#mainFrame[new=true] {
|
BoardPostDisplayWidget_card QFrame#mainFrame[new=true] {
|
||||||
background-color: #005000;
|
background-color: #1464a0;
|
||||||
|
}
|
||||||
|
|
||||||
|
BoardPostDisplayWidget_compact QLabel#titleLabel,
|
||||||
|
BoardPostDisplayWidget_card QLabel#titleLabel{
|
||||||
|
font-size: 14px;
|
||||||
|
font: bold;
|
||||||
}
|
}
|
||||||
|
|
||||||
WireGroupItem QFrame#wire_frame{
|
WireGroupItem QFrame#wire_frame{
|
||||||
@ -2162,3 +2193,5 @@ PulseTopLevel QFrame#frame, PulseViewGroup QFrame#frame, PulseReply QFrame#frame
|
|||||||
border: 2px solid #38444d;
|
border: 2px solid #38444d;
|
||||||
border-radius: 6px;
|
border-radius: 6px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -1148,7 +1148,7 @@ OpModeStatus[opMode="Minimal"] {
|
|||||||
|
|
||||||
/* changes for the subscribe Button */
|
/* changes for the subscribe Button */
|
||||||
|
|
||||||
PostedListWidget QToolButton#subscribeToolButton {
|
PostedListWidgetWithModel QToolButton#subscribeToolButton {
|
||||||
font: bold;
|
font: bold;
|
||||||
font-size: 15px;
|
font-size: 15px;
|
||||||
color: white;
|
color: white;
|
||||||
@ -1157,7 +1157,7 @@ PostedListWidget QToolButton#subscribeToolButton {
|
|||||||
max-height: 27px;
|
max-height: 27px;
|
||||||
}
|
}
|
||||||
|
|
||||||
PostedListWidget QToolButton#subscribeToolButton:hover {
|
PostedListWidgetWithModel QToolButton#subscribeToolButton:hover {
|
||||||
background: #03b1f3;
|
background: #03b1f3;
|
||||||
border-radius: 4px;
|
border-radius: 4px;
|
||||||
}
|
}
|
||||||
@ -1176,7 +1176,7 @@ GxsForumThreadWidget QToolButton#subscribeToolButton:hover {
|
|||||||
border-radius: 4px;
|
border-radius: 4px;
|
||||||
}
|
}
|
||||||
|
|
||||||
GxsChannelPostsWidget QToolButton#subscribeToolButton {
|
GxsChannelPostsWidgetWithModel QToolButton#subscribeToolButton {
|
||||||
font: bold;
|
font: bold;
|
||||||
font-size: 14px;
|
font-size: 14px;
|
||||||
color: white;
|
color: white;
|
||||||
@ -1185,18 +1185,18 @@ GxsChannelPostsWidget QToolButton#subscribeToolButton {
|
|||||||
max-height: 27px;
|
max-height: 27px;
|
||||||
}
|
}
|
||||||
|
|
||||||
GxsChannelPostsWidget QToolButton#subscribeToolButton:hover {
|
GxsChannelPostsWidgetWithModel QToolButton#subscribeToolButton:hover {
|
||||||
background: #03b1f3;
|
background: #03b1f3;
|
||||||
border-radius: 4px;
|
border-radius: 4px;
|
||||||
}
|
}
|
||||||
|
|
||||||
GxsChannelPostsWidget QToolButton#subscribeToolButton:pressed {
|
GxsChannelPostsWidgetWithModel QToolButton#subscribeToolButton:pressed {
|
||||||
background: #03b1f3;
|
background: #03b1f3;
|
||||||
border-radius: 4px;
|
border-radius: 4px;
|
||||||
border: 1px solid gray;
|
border: 1px solid gray;
|
||||||
}
|
}
|
||||||
|
|
||||||
GxsChannelPostsWidget QToolButton#subscribeToolButton:disabled {
|
GxsChannelPostsWidgetWithModel QToolButton#subscribeToolButton:disabled {
|
||||||
background: gray;
|
background: gray;
|
||||||
border-radius: 4px;
|
border-radius: 4px;
|
||||||
border: 1px solid gray;
|
border: 1px solid gray;
|
||||||
@ -1204,19 +1204,37 @@ GxsChannelPostsWidget QToolButton#subscribeToolButton:disabled {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* only for MenuButtonPopup */
|
/* only for MenuButtonPopup */
|
||||||
GxsChannelPostsWidget QToolButton#subscribeToolButton[popupMode="1"] {
|
GxsChannelPostsWidgetWithModel QToolButton#subscribeToolButton[popupMode="1"] {
|
||||||
padding-right: 0px;
|
padding-right: 0px;
|
||||||
}
|
}
|
||||||
|
|
||||||
GxsChannelPostsWidget QToolButton#subscribeToolButton::menu-arrow {
|
GxsChannelPostsWidgetWithModel QToolButton#subscribeToolButton::menu-arrow {
|
||||||
image: none;
|
image: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
GxsChannelPostsWidget QToolButton#subscribeToolButton::menu-button {
|
GxsChannelPostsWidgetWithModel QToolButton#subscribeToolButton::menu-button {
|
||||||
image: none;
|
image: none;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
CreateGxsChannelMsg QPushButton#postButton {
|
||||||
|
font: bold;
|
||||||
|
font-size: 15px;
|
||||||
|
color: white;
|
||||||
|
background: #0099cc;
|
||||||
|
border-radius: 4px;
|
||||||
|
max-height: 27px;
|
||||||
|
min-width: 4em;
|
||||||
|
padding: 2px;
|
||||||
|
}
|
||||||
|
|
||||||
|
CreateGxsChannelMsg QPushButton#postButton:hover {
|
||||||
|
background: #03b1f3;
|
||||||
|
border-radius: 4px;
|
||||||
|
min-width: 4em;
|
||||||
|
padding: 2px;
|
||||||
|
}
|
||||||
|
|
||||||
QTabBar#smTab::tab{
|
QTabBar#smTab::tab{
|
||||||
height: 32px;
|
height: 32px;
|
||||||
width: 32px;
|
width: 32px;
|
||||||
@ -1247,26 +1265,26 @@ GxsForumThreadWidget QLabel#forumName
|
|||||||
font: bold;
|
font: bold;
|
||||||
}
|
}
|
||||||
|
|
||||||
PostedItem QPushButton#shareButton
|
BoardPostDisplayWidget_compact QPushButton#shareButton
|
||||||
{
|
{
|
||||||
background-color: transparent;
|
background-color: transparent;
|
||||||
border: none;
|
border: none;
|
||||||
min-width: 75px;
|
min-width: 75px;
|
||||||
max-height: 22px;
|
max-height: 22px;
|
||||||
}
|
}
|
||||||
|
|
||||||
PostedCardView QPushButton#shareButton
|
BoardPostDisplayWidget_card QPushButton#shareButton
|
||||||
{
|
{
|
||||||
background-color: transparent;
|
background-color: transparent;
|
||||||
border: none;
|
border: none;
|
||||||
min-width: 75px;
|
min-width: 75px;
|
||||||
}
|
}
|
||||||
|
|
||||||
PostedItem QFrame#voteFrame {
|
BoardPostDisplayWidget_compact QFrame#voteFrame {
|
||||||
background: #141415;
|
background: #141415;
|
||||||
}
|
}
|
||||||
|
|
||||||
PostedCardView QFrame#voteFrame {
|
BoardPostDisplayWidget_card QFrame#voteFrame {
|
||||||
background: #141415;
|
background: #141415;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1275,30 +1293,63 @@ QPushButton#shareButton:hover, QPushButton#shareButton::menu-button:hover {
|
|||||||
border: 1px solid gray;
|
border: 1px solid gray;
|
||||||
}
|
}
|
||||||
|
|
||||||
PostedItem QToolButton#voteDownButton, QToolButton#voteUpButton, QToolButton#expandButton, QToolButton#readButton,
|
BoardPostDisplayWidget_compact QToolButton#voteDownButton, QToolButton#voteUpButton, QToolButton#expandButton, QToolButton#readButton,
|
||||||
QToolButton#commentButton, QToolButton#notesButton
|
QToolButton#commentButton, QToolButton#notesButton
|
||||||
{
|
{
|
||||||
border: none;
|
border: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
PostedItem QLabel#thumbnailLabel{
|
BoardPostDisplayWidget_compact QLabel#pictureLabel{
|
||||||
border: 2px solid #CCCCCC;
|
border: 2px solid #CCCCCC;
|
||||||
border-radius: 3px;
|
border-radius: 3px;
|
||||||
}
|
}
|
||||||
|
|
||||||
PostedCardView QToolButton#voteDownButton, QToolButton#voteUpButton
|
BoardPostDisplayWidget_compact > QFrame#frame [new=false]{
|
||||||
|
background: #302F2F;
|
||||||
|
}
|
||||||
|
|
||||||
|
BoardPostDisplayWidget_compact > QFrame#frame[new=true] {
|
||||||
|
background-color: #005000;
|
||||||
|
}
|
||||||
|
|
||||||
|
BoardPostDisplayWidget_card QToolButton#voteDownButton, QToolButton#voteUpButton
|
||||||
{
|
{
|
||||||
border: none;
|
border: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
PostedCardView QFrame#mainFrame [new=false]{
|
BoardPostDisplayWidget_card QFrame#frame{
|
||||||
background: #302F2F;
|
background: #302F2F;
|
||||||
}
|
}
|
||||||
|
|
||||||
PostedCardView > QFrame#mainFrame[new=true] {
|
BoardPostDisplayWidget_card > QFrame#frame [new=false]{
|
||||||
|
background: #302F2F;
|
||||||
|
}
|
||||||
|
|
||||||
|
BoardPostDisplayWidget_card > QFrame#frame[new=true] {
|
||||||
background-color: #005000;
|
background-color: #005000;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
BoardPostDisplayWidget_compact QLabel#newLabel {
|
||||||
|
border: 1px solid #00B712;
|
||||||
|
background-color: qlineargradient(x1: 0, y1: 0, x2: 0, y2: 1, stop: 0 #5AFF15, stop: 1 #00B712);
|
||||||
|
border-radius: 3px;
|
||||||
|
color: black;
|
||||||
|
}
|
||||||
|
|
||||||
|
BoardPostDisplayWidget_card QLabel#newLabel {
|
||||||
|
border: 1px solid #00B712;
|
||||||
|
background-color: qlineargradient(x1: 0, y1: 0, x2: 0, y2: 1, stop: 0 #5AFF15, stop: 1 #00B712);
|
||||||
|
border-radius: 3px;
|
||||||
|
color: black;
|
||||||
|
}
|
||||||
|
|
||||||
|
BoardPostDisplayWidget_compact QLabel#titleLabel,
|
||||||
|
BoardPostDisplayWidget_card QLabel#titleLabel{
|
||||||
|
font-size: 14px;
|
||||||
|
font: bold;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
WireGroupItem QFrame#wire_frame
|
WireGroupItem QFrame#wire_frame
|
||||||
{
|
{
|
||||||
border: 1px solid #38444d;
|
border: 1px solid #38444d;
|
||||||
|
@ -1376,8 +1376,8 @@ gxschannels {
|
|||||||
gui/gxschannels/GxsChannelPostsWidgetWithModel.cpp \
|
gui/gxschannels/GxsChannelPostsWidgetWithModel.cpp \
|
||||||
gui/gxschannels/GxsChannelPostsModel.cpp \
|
gui/gxschannels/GxsChannelPostsModel.cpp \
|
||||||
gui/gxschannels/GxsChannelPostFilesModel.cpp \
|
gui/gxschannels/GxsChannelPostFilesModel.cpp \
|
||||||
|
gui/gxschannels/GxsChannelFilesStatusWidget.cpp \
|
||||||
gui/gxschannels/GxsChannelPostThumbnail.cpp \
|
gui/gxschannels/GxsChannelPostThumbnail.cpp \
|
||||||
gui/gxschannels/GxsChannelFilesStatusWidget.cpp \
|
|
||||||
gui/gxschannels/GxsChannelGroupDialog.cpp \
|
gui/gxschannels/GxsChannelGroupDialog.cpp \
|
||||||
gui/gxschannels/CreateGxsChannelMsg.cpp \
|
gui/gxschannels/CreateGxsChannelMsg.cpp \
|
||||||
gui/feeds/GxsChannelGroupItem.cpp \
|
gui/feeds/GxsChannelGroupItem.cpp \
|
||||||
@ -1389,7 +1389,9 @@ gxschannels {
|
|||||||
posted {
|
posted {
|
||||||
|
|
||||||
HEADERS += gui/Posted/PostedDialog.h \
|
HEADERS += gui/Posted/PostedDialog.h \
|
||||||
gui/Posted/PostedListWidget.h \
|
gui/Posted/PostedListWidgetWithModel.h \
|
||||||
|
gui/Posted/PostedPostsModel.h \
|
||||||
|
gui/Posted/BoardPostDisplayWidget.h \
|
||||||
gui/Posted/PostedItem.h \
|
gui/Posted/PostedItem.h \
|
||||||
gui/Posted/PostedCardView.h \
|
gui/Posted/PostedCardView.h \
|
||||||
gui/Posted/PostedGroupDialog.h \
|
gui/Posted/PostedGroupDialog.h \
|
||||||
@ -1401,18 +1403,22 @@ posted {
|
|||||||
#gui/Posted/PostedCreateCommentDialog.h \
|
#gui/Posted/PostedCreateCommentDialog.h \
|
||||||
#gui/Posted/PostedComments.h \
|
#gui/Posted/PostedComments.h \
|
||||||
|
|
||||||
FORMS += gui/Posted/PostedListWidget.ui \
|
FORMS += gui/Posted/PostedListWidgetWithModel.ui \
|
||||||
gui/feeds/PostedGroupItem.ui \
|
gui/feeds/PostedGroupItem.ui \
|
||||||
|
gui/Posted/BoardPostDisplayWidget_compact.ui \
|
||||||
|
gui/Posted/BoardPostDisplayWidget_card.ui \
|
||||||
gui/Posted/PostedItem.ui \
|
gui/Posted/PostedItem.ui \
|
||||||
gui/Posted/PostedCardView.ui \
|
gui/Posted/PostedCardView.ui \
|
||||||
gui/Posted/PostedCreatePostDialog.ui \
|
gui/Posted/PostedCreatePostDialog.ui \
|
||||||
gui/Posted/PhotoView.ui
|
gui/Posted/PhotoView.ui \
|
||||||
#gui/Posted/PostedDialog.ui \
|
#gui/Posted/PostedDialog.ui \
|
||||||
#gui/Posted/PostedComments.ui \
|
#gui/Posted/PostedComments.ui \
|
||||||
#gui/Posted/PostedCreateCommentDialog.ui
|
#gui/Posted/PostedCreateCommentDialog.ui
|
||||||
|
|
||||||
SOURCES += gui/Posted/PostedDialog.cpp \
|
SOURCES += gui/Posted/PostedDialog.cpp \
|
||||||
gui/Posted/PostedListWidget.cpp \
|
gui/Posted/PostedListWidgetWithModel.cpp \
|
||||||
|
gui/Posted/BoardPostDisplayWidget.cpp \
|
||||||
|
gui/Posted/PostedPostsModel.cpp \
|
||||||
gui/feeds/PostedGroupItem.cpp \
|
gui/feeds/PostedGroupItem.cpp \
|
||||||
gui/Posted/PostedItem.cpp \
|
gui/Posted/PostedItem.cpp \
|
||||||
gui/Posted/PostedCardView.cpp \
|
gui/Posted/PostedCardView.cpp \
|
||||||
|
@ -32,4 +32,4 @@ ClickableLabel::~ClickableLabel() {
|
|||||||
|
|
||||||
void ClickableLabel::mousePressEvent(QMouseEvent* event) {
|
void ClickableLabel::mousePressEvent(QMouseEvent* event) {
|
||||||
emit clicked();
|
emit clicked();
|
||||||
}
|
}
|
||||||
|
@ -32,16 +32,17 @@ public:
|
|||||||
explicit ClickableLabel(QWidget* parent = Q_NULLPTR, Qt::WindowFlags f = Qt::WindowFlags());
|
explicit ClickableLabel(QWidget* parent = Q_NULLPTR, Qt::WindowFlags f = Qt::WindowFlags());
|
||||||
~ClickableLabel();
|
~ClickableLabel();
|
||||||
|
|
||||||
|
void setUseStyleSheet(bool b){ mUseStyleSheet=b ; update();}
|
||||||
signals:
|
signals:
|
||||||
void clicked();
|
void clicked();
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
void mousePressEvent(QMouseEvent* event);
|
void mousePressEvent(QMouseEvent* event) override;
|
||||||
|
|
||||||
void enterEvent(QEvent * /* ev */ ) override { setStyleSheet("QLabel { border: 2px solid #039bd5; }");}
|
void enterEvent(QEvent * /* ev */ ) override { if(mUseStyleSheet) setStyleSheet("QLabel { border: 2px solid #039bd5; }");}
|
||||||
|
void leaveEvent(QEvent * /* ev */ ) override { if(mUseStyleSheet) setStyleSheet("QLabel { border: 2px solid #CCCCCC; border-radius: 3px; }");}
|
||||||
void leaveEvent(QEvent * /* ev */ ) override { setStyleSheet("QLabel { border: 2px solid #CCCCCC; border-radius: 3px; }");}
|
|
||||||
|
|
||||||
|
bool mUseStyleSheet;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // CLICKABLELABEL_H
|
#endif // CLICKABLELABEL_H
|
||||||
|
Loading…
x
Reference in New Issue
Block a user