rework on notify for wire posts

This commit is contained in:
defnax 2025-03-12 20:35:16 +01:00
parent 8fcc52b304
commit 212197f980
42 changed files with 3276 additions and 134 deletions

View File

@ -176,6 +176,7 @@ list(
src/gui/common/FlowLayout.cpp
src/gui/common/PictureFlow.cpp
src/gui/common/ToasterNotify.cpp
src/gui/common/NotifyWidget.cpp
src/gui/style/RSStyle.cpp
src/gui/style/StyleDialog.cpp
@ -382,6 +383,7 @@ list(
src/gui/common/RsCollectionDialog.ui
src/gui/common/HeaderFrame.ui
src/gui/common/RSFeedWidget.ui
src/gui/common/NotifyWidget.ui
src/gui/style/StyleDialog.ui
@ -641,6 +643,7 @@ list(
src/gui/common/FlowLayout.h
src/gui/common/PictureFlow.h
src/gui/common/ToasterNotify.h
src/gui/common/NotifyWidget.h
src/gui/style/RSStyle.h
src/gui/style/StyleDialog.h
@ -999,7 +1002,10 @@ if(RS_GXSTHEWIRE)
src/gui/TheWire/PulseViewGroup.h
src/gui/TheWire/PulseReply.h
src/gui/TheWire/PulseReplySeperator.h
src/gui/TheWire/PulseMessage.h
src/gui/TheWire/PulseMessage.h
src/gui/TheWire/WireUserNotify.h
src/gui/feeds/WireNotifyGroupItem.h
src/gui/feeds/WireNotifyPostItem.h
)
list(
@ -1012,7 +1018,9 @@ if(RS_GXSTHEWIRE)
src/gui/TheWire/PulseViewGroup.ui
src/gui/TheWire/PulseReply.ui
src/gui/TheWire/PulseReplySeperator.ui
src/gui/TheWire/PulseMessage.ui
src/gui/TheWire/PulseMessage.ui
src/gui/feeds/WireNotifyGroupItem.ui
src/gui/feeds/WireNotifyPostItem.ui
)
list(
@ -1028,6 +1036,9 @@ if(RS_GXSTHEWIRE)
src/gui/TheWire/PulseReply.cpp
src/gui/TheWire/PulseReplySeperator.cpp
src/gui/TheWire/PulseMessage.cpp
src/gui/TheWire/WireUserNotify.cpp
src/gui/feeds/WireNotifyGroupItem.cpp
src/gui/feeds/WireNotifyPostItem.cpp
)
list(
@ -1112,6 +1123,7 @@ if(RS_GXSGUI)
src/gui/gxs/GxsFeedWidget.h
src/util/TokenQueue.h
src/util/RsGxsUpdateBroadcast.h
src/gui/gxs/GxsStatisticsProvider.h
)
list(
@ -1147,6 +1159,7 @@ if(RS_GXSGUI)
src/gui/gxs/GxsFeedWidget.cpp
src/util/TokenQueue.cpp
src/util/RsGxsUpdateBroadcast.cpp
src/gui/gxs/GxsStatisticsProvider.cpp
)
endif(RS_GXSGUI)

View File

@ -1073,6 +1073,11 @@ void SetForegroundWindowInternal(HWND hWnd)
case Posted:
_instance->ui->stackPages->setCurrentPage( _instance->postedDialog );
return true ;
#ifdef RS_USE_WIRE
case Wire:
_instance->ui->stackPages->setCurrentPage( _instance->wireDialog );
return true ;
#endif
default:
std::cerr << "Show page called on value that is not handled yet. Please code it! (value = " << page << ")" << std::endl;
}
@ -1157,6 +1162,8 @@ void SetForegroundWindowInternal(HWND hWnd)
return _instance->postedDialog;
case Home:
return _instance->homePage;
case Wire:
return _instance->wireDialog;
}
return NULL;

View File

@ -67,6 +67,7 @@ class BandwidthGraph;
class MainPage;
class NewsFeed;
class UserNotify;
class WireDialog;
#ifdef MESSENGER_WINDOW
class MessengerWindow;
@ -103,7 +104,8 @@ public:
Posted = 11, /** Posted links */
People = 12, /** People page. */
Options = 13, /** People page. */
Home = 14 /** Home page. */
Home = 14, /** Home page. */
Wire = 15 /** Wire page. */
};
@ -163,7 +165,8 @@ public:
GxsChannelDialog *gxschannelDialog ;
GxsForumsDialog *gxsforumDialog ;
PostedDialog *postedDialog;
WireDialog *wireDialog;
// ForumsDialog *forumsDialog;
// ChannelFeed *channelFeed;
Idle *idle;

View File

@ -31,6 +31,7 @@
#include <retroshare/rspeers.h>
#include <retroshare/rsplugin.h>
#include <retroshare/rsposted.h>
#include <retroshare/rswire.h>
#include "util/misc.h"
#include "util/qtthreadsutils.h"
@ -48,6 +49,8 @@
#include "feeds/PostedGroupItem.h"
#include "feeds/SecurityItem.h"
#include "feeds/SecurityIpItem.h"
#include "feeds/WireNotifyGroupItem.h"
#include "feeds/WireNotifyPostItem.h"
#include "settings/rsettingswin.h"
#include "settings/rsharesettings.h"
@ -81,7 +84,8 @@ NewsFeed::NewsFeed(QWidget *parent) : MainPage(parent), ui(new Ui::NewsFeed),
RsEventType::GXS_CHANNELS ,
RsEventType::GXS_FORUMS ,
RsEventType::GXS_POSTED ,
RsEventType::MAIL_STATUS
RsEventType::MAIL_STATUS ,
RsEventType::WIRE
})
{
/* Invoke the Qt Designer generated object setup routine */
@ -127,6 +131,9 @@ NewsFeed::NewsFeed(QWidget *parent) : MainPage(parent), ui(new Ui::NewsFeed),
" <li>Channel and Board comments</li>"
" <li>New Mail messages</li>"
" <li>Private messages from your friends</li>"
#ifdef RS_USE_WIRE
" <li>New Wire pulses and mentions</li>"
#endif
" </ul> </p>"
).arg(QString::number(2*H));
@ -214,6 +221,10 @@ void NewsFeed::handleEvent_main_thread(std::shared_ptr<const RsEvent> event)
if(event->mType == RsEventType::MAIL_STATUS && (flags & RS_FEED_TYPE_MSG))
handleMailEvent(event);
if(event->mType == RsEventType::WIRE && (flags & RS_FEED_TYPE_WIRE))
handleWireEvent(event);
}
void NewsFeed::handleMailEvent(std::shared_ptr<const RsEvent> event)
@ -510,6 +521,40 @@ void NewsFeed::handleSecurityEvent(std::shared_ptr<const RsEvent> event)
NotifyQt::getInstance()->addToaster(RS_POPUP_CONNECT_ATTEMPT, e.mPgpId.toStdString().c_str(), det.location, e.mSslId.toStdString().c_str());
}
void NewsFeed::handleWireEvent(std::shared_ptr<const RsEvent> event)
{
const RsWireEvent *pe =
dynamic_cast<const RsWireEvent*>(event.get());
if(!pe) return;
switch(pe->mWireEventCode)
{
case RsWireEventCode::FOLLOW_STATUS_CHANGED:
addFeedItem( new WireNotifyGroupItem(this, NEWSFEED_WIRELIST, pe->mWireGroupId, false, true));
break;
case RsWireEventCode::NEW_POST:
addFeedItem( new WireNotifyPostItem(this, NEWSFEED_WIRELIST, pe->mWireGroupId, pe->mWireMsgId, false, true));
break;
case RsWireEventCode::NEW_REPLY:
addFeedItem( new WireNotifyPostItem(this, NEWSFEED_WIRELIST, pe->mWireGroupId, pe->mWireMsgId, false, true));
break;
case RsWireEventCode::NEW_LIKE:
addFeedItem( new WireNotifyPostItem(this, NEWSFEED_WIRELIST, pe->mWireGroupId, pe->mWireMsgId, false, true));
break;
case RsWireEventCode::NEW_REPUBLISH:
addFeedItem( new WireNotifyPostItem(this, NEWSFEED_WIRELIST, pe->mWireGroupId, pe->mWireMsgId, false, true));
break;
// case RsWireEventCode::WIRE_UPDATED:
// addFeedItem( new WireNotifyGroupItem(this, NEWSFEED_WIRELIST, pe->mWireGroupId, false, true));
// break;
// case RsWireEventCode::POST_UPDATED:
// addFeedItem( new WireNotifyGroupItem(this, NEWSFEED_WIRELIST, pe->mWireGroupId, false, true));
// break;
default: break;
}
sendNewsFeedChanged();
}
void NewsFeed::testFeeds(uint /*notifyFlags*/)
{
#ifdef TO_REMOVE

View File

@ -48,6 +48,7 @@ const uint32_t NEWSFEED_POSTEDNEWLIST = 0x000b;
const uint32_t NEWSFEED_POSTEDMSGLIST = 0x000c;
const uint32_t NEWSFEED_CIRCLELIST = 0x000d;
const uint32_t NEWSFEED_CHANNELPUBKEYLIST= 0x000e;
const uint32_t NEWSFEED_WIRELIST = 0X000f;
namespace Ui {
class NewsFeed;
@ -106,6 +107,7 @@ private:
void handleMailEvent(std::shared_ptr<const RsEvent> event);
void handlePostedEvent(std::shared_ptr<const RsEvent> event);
void handleChannelEvent(std::shared_ptr<const RsEvent> event);
void handleWireEvent(std::shared_ptr<const RsEvent> event);
void addFeedItem(FeedItem *item);
void addFeedItemIfUnique(FeedItem *item, bool replace);

View File

@ -33,6 +33,7 @@
#include "FileTransfer/SearchDialog.h"
#include "gxschannels/GxsChannelDialog.h"
#include "gxsforums/GxsForumsDialog.h"
#include "TheWire/WireDialog.h"
#include "msgs/MessageComposer.h"
#include "Posted/PostedDialog.h"
#include "util/misc.h"
@ -76,7 +77,8 @@
#define HOST_IDENTITY "identity"
#define HOST_FILE_TREE "collection"
#define HOST_CHAT_ROOM "chat_room"
#define HOST_REGEXP "file|person|forum|channel|search|message|certificate|extra|private_chat|public_msg|posted|identity|collection|chat_room"
#define HOST_REGEXP "file|person|forum|channel|wire|search|message|certificate|extra|private_chat|public_msg|posted|identity|collection|chat_room"
#define HOST_WIRE "wire"
#define FILE_NAME "name"
#define FILE_SIZE "size"
@ -94,6 +96,10 @@
#define CHANNEL_ID "id"
#define CHANNEL_MSGID "msgid"
#define WIRE_NAME "name"
#define WIRE_ID "id"
#define WIRE_MSGID "msgid"
#define SEARCH_KEYWORDS "keywords"
#define MESSAGE_ID "id"
@ -291,6 +297,19 @@ void RetroShareLink::fromUrl(const QUrl& url)
return;
}
if (url.host() == HOST_WIRE) {
_type = TYPE_WIRE;
_name = decodedQueryItemValue(urlQuery, WIRE_NAME);
_hash = urlQuery.queryItemValue(WIRE_ID);
_msgId = urlQuery.queryItemValue(WIRE_MSGID);
#ifdef DEBUG_RSLINK
std::cerr << "Got a wire link!!" << std::endl;
#endif
check();
return;
}
if (url.host() == HOST_SEARCH) {
_type = TYPE_SEARCH;
_name = decodedQueryItemValue(urlQuery, SEARCH_KEYWORDS);
@ -470,7 +489,7 @@ RetroShareLink RetroShareLink::createPerson(const RsPgpId& id)
return link;
}
//For Forum, Channel & Posted
//For Forum, Channel, Posted and Wire
RetroShareLink RetroShareLink::createGxsGroupLink(const RetroShareLink::enumType &linkType, const RsGxsGroupId &groupId, const QString &groupName)
{
RetroShareLink link;
@ -795,6 +814,17 @@ void RetroShareLink::check()
_valid = false;
break;
case TYPE_WIRE:
if(_size != 0)
_valid = false;
if(_name.isEmpty())
_valid = false;
if(_hash.isEmpty())
_valid = false;
break;
case TYPE_SEARCH:
if(_size != 0)
_valid = false;
@ -888,7 +918,9 @@ QString RetroShareLink::title() const
return QString("Forum id: %1").arg(hash());
case TYPE_CHANNEL:
return QString("Channel id: %1").arg(hash());
case TYPE_SEARCH:
case TYPE_WIRE:
return QString("Wire id: %1").arg(hash());
case TYPE_SEARCH:
return QString("Search files");
case TYPE_MESSAGE:
@ -1075,6 +1107,17 @@ QString RetroShareLink::toString() const
break;
case TYPE_WIRE:
url.setScheme(RSLINK_SCHEME);
url.setHost(HOST_WIRE);
urlQuery.addQueryItem(WIRE_NAME, encodeItem(_name));
urlQuery.addQueryItem(WIRE_ID, _hash);
if (!_msgId.isEmpty()) {
urlQuery.addQueryItem(WIRE_MSGID, _msgId);
}
break;
}
#if QT_VERSION >= QT_VERSION_CHECK(5,0,0)
@ -1309,6 +1352,7 @@ static void processList(const QStringList &list, const QString &textSingular, co
case TYPE_FILE:
case TYPE_FORUM:
case TYPE_CHANNEL:
case TYPE_WIRE:
case TYPE_SEARCH:
case TYPE_MESSAGE:
case TYPE_CERTIFICATE:
@ -1357,6 +1401,12 @@ static void processList(const QStringList &list, const QString &textSingular, co
QStringList channelUnknown;
QStringList channelMsgUnknown;
// wire
QStringList wireFound;
QStringList wireMsgFound;
QStringList wireUnknown;
QStringList wireMsgUnknown;
// search
QStringList searchStarted;
@ -1383,9 +1433,9 @@ static void processList(const QStringList &list, const QString &textSingular, co
QList<QStringList*> processedList;
QList<QStringList*> errorList;
processedList << &fileAdded << &personAdded << &forumFound << &channelFound << &searchStarted << &messageStarted << &postedFound << &chatroomFound;
errorList << &fileExist << &personExist << &personFailed << &personNotFound << &forumUnknown << &forumMsgUnknown << &channelUnknown << &channelMsgUnknown << &messageReceipientNotAccepted << &messageReceipientUnknown << &postedUnknown << &postedMsgUnknown << &chatroomUnknown;
// not needed: forumFound, channelFound, messageStarted
processedList << &fileAdded << &personAdded << &forumFound << &channelFound << &wireFound << &searchStarted << &messageStarted << &postedFound << &chatroomFound;
errorList << &fileExist << &personExist << &personFailed << &personNotFound << &forumUnknown << &forumMsgUnknown << &channelUnknown << &channelMsgUnknown << &wireUnknown << &wireMsgUnknown << &messageReceipientNotAccepted << &messageReceipientUnknown << &postedUnknown << &postedMsgUnknown << &chatroomUnknown;
// not needed: forumFound, channelFound, wireFound, messageStarted
// we want to merge all single file links into one collection
// if a collection tree link is found it is processed independen for the other file links
@ -1477,6 +1527,34 @@ static void processList(const QStringList &list, const QString &textSingular, co
}
break;
case TYPE_WIRE:
{
#ifdef DEBUG_RSLINK
std::cerr << " RetroShareLink::process WireRequest : name : " << link.name().toStdString() << ". id : " << link.hash().toStdString() << ". msgId : " << link.msgId().toStdString() << std::endl;
#endif
MainWindow::showWindow(MainWindow::Wire);
WireDialog *wireDialog = dynamic_cast<WireDialog*>(MainWindow::getPage(MainWindow::Wire));
if (!wireDialog) {
return false;
}
if (wireDialog->navigate(RsGxsGroupId(link.id().toStdString()), RsGxsMessageId(link.msgId().toStdString()))) {
if (link.msgId().isEmpty()) {
wireFound.append(link.name());
} else {
wireMsgFound.append(link.name());
}
} else {
if (link.msgId().isEmpty()) {
wireUnknown.append(link.name());
} else {
wireMsgUnknown.append(link.name());
}
}
}
break;
case TYPE_SEARCH:
{
#ifdef DEBUG_RSLINK
@ -1855,6 +1933,16 @@ static void processList(const QStringList &list, const QString &textSingular, co
}
}
// wire
if (flag & RSLINK_PROCESS_NOTIFY_ERROR) {
if (!wireUnknown.isEmpty()) {
processList(wireUnknown, QObject::tr("Wire not found"), QObject::tr("Wires not found"), result);
}
if (!wireMsgUnknown.isEmpty()) {
processList(wireMsgUnknown, QObject::tr("Wire message not found"), QObject::tr("Wire messages not found"), result);
}
}
// message
if (flag & RSLINK_PROCESS_NOTIFY_ERROR) {
if (!messageReceipientNotAccepted.isEmpty()) {
@ -2038,3 +2126,4 @@ void RSLinkClipboard::parseText(QString text, QList<RetroShareLink> &links,Retro
pos += rx.matchedLength();
}
}

View File

@ -74,7 +74,8 @@ class RetroShareLink
TYPE_POSTED = 0x0b,
TYPE_IDENTITY = 0x0c,
TYPE_FILE_TREE = 0x0d,
TYPE_CHAT_ROOM = 0x0e
TYPE_CHAT_ROOM = 0x0e,
TYPE_WIRE = 0x0f
};
public:

View File

@ -150,6 +150,44 @@ void PulseReply::setReferenceString(QString ref)
void PulseReply::mousePressEvent(QMouseEvent *event)
{
// Check if the event is a left mouse button press
// if (event->button() == Qt::LeftButton && (IS_MSG_UNREAD(mPulse->mMeta.mMsgStatus) || IS_MSG_NEW(mPulse->mMeta.mMsgStatus)))
if (event->button() == Qt::LeftButton && (IS_MSG_UNPROCESSED(mPulse->mMeta.mMsgStatus)))
{
uint32_t token;
// Perform some action when the left mouse button is pressed
RsGxsGrpMsgIdPair msgPair = std::make_pair(mPulse->mMeta.mGroupId, mPulse->mMeta.mMsgId);
rsWire->setMessageReadStatus(token, msgPair, true);
std::cout << "Left mouse button pressed on PulseReply!" <<std::endl;
// You can add your own custom code here
}
else{
bool one = event->button() == Qt::LeftButton;
std::cout << "the first condition:"<< one <<std::endl;
one = IS_MSG_UNREAD(mPulse->mMeta.mMsgStatus);
std::cout << "the second condition:"<< one <<std::endl;
one = IS_MSG_NEW(mPulse->mMeta.mMsgStatus);
std::cout << "the third condition:"<< one <<std::endl;
one = IS_MSG_UNPROCESSED(mPulse->mMeta.mMsgStatus);
std::cout << "the fourth condition:"<< one <<std::endl;
}
// Call the base class implementation to ensure proper event handling
QWidget::mousePressEvent(event);
}
//void WireDialog::setAllMessagesReadDo(bool read, uint32_t &token)
//{
// if (groupId().isNull() || !IS_GROUP_SUBSCRIBED(subscribeFlags())) {
// return;
// }
// foreach (RsWirePulseItem *item, mPostItems) {
// RsGxsGrpMsgIdPair msgPair = std::make_pair(item->groupId(), item->messageId());
// rsWire->setMessageReadStatus(token, msgPair, read);
// }
//}

View File

@ -463,3 +463,16 @@ QString ToNumberUnits(uint32_t count)
return ans;
}
void PulseDataItem::mousePressEvent(QMouseEvent *event)
{
// Check if the event is a left mouse button press
if (event->button() == Qt::LeftButton)
{
// Perform some action when the left mouse button is pressed
std::cout << "Left mouse button pressed on PulseViewItem!" <<std::endl;
// You can add your own custom code here
}
// Call the base class implementation to ensure proper event handling
QWidget::mousePressEvent(event);
}

View File

@ -137,8 +137,11 @@ protected:
//
void setReference(uint32_t flags, RsGxsGroupId groupId, std::string groupName);
void mousePressEvent(QMouseEvent *event);
// DATA.
RsWirePulseSPtr mPulse;
};

View File

@ -25,11 +25,16 @@
#include "gui/settings/rsharesettings.h"
#include "gui/gxs/GxsIdDetails.h"
#include "gui/common/FilesDefs.h"
#include "gui/common/NotifyWidget.h"
#include "gui/gxs/GxsStatisticsProvider.h"
#include "gui/gxs/GxsGroupShareKey.h"
#include "PulseViewGroup.h"
#include "PulseReplySeperator.h"
#include "WireUserNotify.h"
#include "util/qtthreadsutils.h"
#include "util/misc.h"
#include <retroshare/rspeers.h>
#include <retroshare/rswire.h>
@ -55,11 +60,11 @@
#define WIRE_TOKEN_TYPE_SUBSCRIBE_CHANGE 1
#define TOKEN_TYPE_GROUP_SUMMARY 1
/** Constructor */
WireDialog::WireDialog(QWidget *parent)
: MainPage(parent), mGroupSet(GROUP_SET_ALL)
: GxsStatisticsProvider(rsWire, settingsGroupName(),parent, true), mGroupSet(GROUP_SET_ALL)
, mAddDialog(nullptr), mGroupSelected(nullptr), mWireQueue(nullptr)
, mHistoryIndex(-1), mEventHandlerId(0)
{
@ -82,6 +87,9 @@ WireDialog::WireDialog(QWidget *parent)
/* setup TokenQueue */
mWireQueue = new TokenQueue(rsWire->getTokenService(), this);
mCountChildMsgs = false;
mShouldUpdateGroupStatistics = false;
mDistSyncAllowed = true;
requestGroupData();
@ -110,27 +118,50 @@ void WireDialog::handleEvent_main_thread(std::shared_ptr<const RsEvent> event)
#endif
// The following switch statements refresh the wire feed whenever there is a new event
std::cout<<"***************the wire event code is ************************* "<<std::endl;
switch(e->mWireEventCode)
{
case RsWireEventCode::READ_STATUS_CHANGED:
updateGroupStatisticsReal(e->mWireGroupId); // update the list immediately
std::cout<<"1"<<std::endl;
return;
case RsWireEventCode::STATISTICS_CHANGED:
std::cout<<"2"<<std::endl;
case RsWireEventCode::NEW_POST:
std::cout<<"3"<<std::endl;
case RsWireEventCode::NEW_REPLY:
std::cout<<"4"<<std::endl;
case RsWireEventCode::NEW_LIKE:
std::cout<<"5"<<std::endl;
case RsWireEventCode::NEW_REPUBLISH:
std::cout<<"6"<<std::endl;
case RsWireEventCode::POST_UPDATED:
case RsWireEventCode::NEW_WIRE:
std::cout<<"7"<<std::endl;
case RsWireEventCode::FOLLOW_STATUS_CHANGED:
std::cout<<"8"<<std::endl;
case RsWireEventCode::NEW_WIRE:
std::cout<<"9"<<std::endl;
updateGroupStatisticsReal(e->mWireGroupId);
break;
default:
refreshGroups();
#ifdef GXSWIRE_DEBUG
RsDbg() << " Unknown event occured: "<< e->mWireEventCode << std::endl;
#endif
break;
}
refreshGroups();
}
}
@ -140,12 +171,149 @@ WireDialog::~WireDialog()
processSettings(false);
clearTwitterView();
std::cerr << "WireDialog::~WireDialog()" << std::endl;
delete(mWireQueue);
rsEvents->unregisterEventsHandler(mEventHandlerId);
}
UserNotify *WireDialog::createUserNotify(QObject *parent)
{
return new WireUserNotify(rsWire, this, parent);
}
//QString WireDialog::getHelpString() const
//{
// int H = misc::getFontSizeFactor("HelpButton").height();
// QString hlp_str = tr(
// "<h1><img width=\"%1\" src=\":/icons/help_64.png\">&nbsp;&nbsp;Boards</h1>"
// "<p>The wire service is a day to day social network service.</p>"
// "<p>The Wire service allows you to share your pulses, republish someone else's pulses, like "
// "a pulse.</p>"
// "<p>A pulse is like a channel or board post. It can be a image or a text or both. You can "
// "only see the pulses of the people you follow.</p>"
// "<p>Wire posts are kept for %2 days, and sync-ed over the last %3 days, unless you change this.</p>"
// ).arg( QString::number(2*H)
// , QString::number(rsWire->getDefaultStoragePeriod()/86400)
// , QString::number(rsWire->getDefaultSyncPeriod()/86400));
// return hlp_str ;
//}
//QString WireDialog::text(TextType type)
//{
// switch (type) {
// case TEXT_NAME:
// return tr("Wire");
// case TEXT_NEW:
// return tr("Create Wire");
//// Dont know what this does
//// case TEXT_TODO:
//// return "<b>Open points:</b><ul>"
//// "<li>Subreddits/tag to posts support"
//// "<li>Picture Support"
//// "<li>Navigate channel link"
//// "</ul>";
// case TEXT_YOUR_GROUP:
// return tr("My Wire");
// case TEXT_SUBSCRIBED_GROUP:
// return tr("Followed Wires");
// case TEXT_POPULAR_GROUP:
// return tr("Popular Wires");
// case TEXT_OTHER_GROUP:
// return tr("Other Wires");
// }
// return "";
//}
//QString WireDialog::icon(IconType type)
//{
// switch (type) {
// case ICON_NAME:
// return ":/icons/png/postedlinks.png";
// case ICON_NEW:
// return ":/icons/png/add.png";
// case ICON_YOUR_GROUP:
// return "";
// case ICON_SUBSCRIBED_GROUP:
// return "";
// case ICON_POPULAR_GROUP:
// return "";
// case ICON_OTHER_GROUP:
// return "";
// case ICON_SEARCH:
// return ":/images/find.png";
// case ICON_DEFAULT:
// return ":/icons/png/posted.png";
// }
// return "";
//}
//bool WireDialog::getGroupData(std::list<RsGxsGenericGroupData*>& groupInfo)
//{
// std::vector<RsWireGroup> groups;
// // request all group infos at once
// if(! rsWire->getGroups(std::list<RsGxsGroupId>(),groups))
// return false;
// /* Save groups to fill icons and description */
// for (auto& group: groups)
// groupInfo.push_back(new RsWireGroup(group));
// return true;
//}
bool WireDialog::getGroupStatistics(const RsGxsGroupId& groupId,GxsGroupStatistic& stat)
{
// What follows is a hack to replace the GXS group statistics by the actual count of unread messages in wire,
// which should take into account old post versions, discard replies and likes, etc.
RsWireStatistics s;
bool res = rsWire->getWireStatistics(groupId,s);
if(!res)
return false;
stat.mGrpId = groupId;
stat.mNumMsgs = s.mNumberOfPulses;
stat.mTotalSizeOfMsgs = 0; // hopefuly unused. Required the loading of the full channel data, so not very convenient.
stat.mNumThreadMsgsNew = s.mNumberOfNewPulses;
stat.mNumThreadMsgsUnread = s.mNumberOfUnreadPulses;
stat.mNumChildMsgsNew = 0;
stat.mNumChildMsgsUnread = 0;
return true;
}
//GxsGroupDialog *WireDialog::createNewGroupDialog()
//{
// return new WireGroupDialog(this);
//}
//GxsGroupDialog *WireDialog::createGroupDialog(GxsGroupDialog::Mode mode, RsGxsGroupId groupId)
//{
// return new WireGroupDialog(mode, groupId, this);
//}
//int WireDialog::shareKeyType()
//{
// return GroupShareKey::NO_KEY_SHARE;
//}
//GxsMessageFrameWidget *WireDialog::createMessageFrameWidget(const RsGxsGroupId &groupId)
//{
// // to do
//// return new WireListWidgetWithModel(groupId);
//}
void WireDialog::processSettings(bool load)
{
Settings->beginGroup("WireDialog");
@ -475,13 +643,13 @@ bool WireDialog::loadGroupData(const uint32_t &token)
std::cerr << "WireDialog::loadGroupData()";
std::cerr << std::endl;
std::vector<RsWireGroup> groups;
rsWire->getGroupData(token, groups);
std::vector<RsWireGroup> groups;
rsWire->getGroupData(token, groups);
// save list of groups.
updateGroups(groups);
showGroups();
return true;
// save list of groups.
updateGroups(groups);
showGroups();
return true;
}
rstime_t WireDialog::getFilterTimestamp()
@ -689,7 +857,6 @@ void WireDialog::PVHrate(const RsGxsId &authorId)
void WireDialog::postTestTwitterView()
{
clearTwitterView();
std::cerr << "WireDialog::postTestTwitterView()" << std::endl;
addTwitterView(new PulseTopLevel(NULL,RsWirePulseSPtr()));
addTwitterView(new PulseReply(NULL,RsWirePulseSPtr()));
@ -846,7 +1013,6 @@ void WireDialog::requestPulseFocus(const RsGxsGroupId groupId, const RsGxsMessag
void WireDialog::showPulseFocus(const RsGxsGroupId groupId, const RsGxsMessageId msgId)
{
clearTwitterView();
std::cerr << "WireDialog::showPulseFocus()" << std::endl;
// background thread for loading.
RsThread::async([this, groupId, msgId]()
@ -876,8 +1042,6 @@ void WireDialog::showPulseFocus(const RsGxsGroupId groupId, const RsGxsMessageId
void WireDialog::postPulseFocus(RsWirePulseSPtr pPulse)
{
clearTwitterView();
std::cerr << "WireDialog::postPulseFocus()" << std::endl;
if (!pPulse)
{
std::cerr << "WireDialog::postPulseFocus() Invalid pulse";
@ -950,7 +1114,7 @@ void WireDialog::requestGroupFocus(const RsGxsGroupId groupId)
void WireDialog::showGroupFocus(const RsGxsGroupId groupId)
{
clearTwitterView();
std::cerr << "WireDialog::showGroupFocus()" << std::endl;
// background thread for loading.
RsThread::async([this, groupId]()
{
@ -980,6 +1144,8 @@ void WireDialog::showGroupFocus(const RsGxsGroupId groupId)
void WireDialog::postGroupFocus(RsWireGroupSPtr group, std::list<RsWirePulseSPtr> pulses)
{
clearTwitterView();
std::cerr << "WireDialog::postGroupFocus()";
std::cerr << std::endl;
@ -1027,7 +1193,6 @@ void WireDialog::requestGroupsPulses(const std::list<RsGxsGroupId>& groupIds)
void WireDialog::showGroupsPulses(const std::list<RsGxsGroupId>& groupIds)
{
clearTwitterView();
std::cerr << "WireDialog::showGroupPulses()" << std::endl;
// background thread for loading.
RsThread::async([this, groupIds]()
@ -1054,6 +1219,7 @@ void WireDialog::showGroupsPulses(const std::list<RsGxsGroupId>& groupIds)
void WireDialog::postGroupsPulses(std::list<RsWirePulseSPtr> pulses)
{
clearTwitterView();
std::cerr << "WireDialog::postGroupsPulses()";
std::cerr << std::endl;
@ -1077,3 +1243,187 @@ void WireDialog::postGroupsPulses(std::list<RsWirePulseSPtr> pulses)
}
}
void WireDialog::getServiceStatistics(GxsServiceStatistic& stats) const
{
std::cout<<"inside the getServiceStatics *********"<<std::endl;
if(!mCachedGroupStats.empty())
{
stats = GxsServiceStatistic(); // clears everything
for(auto& it: mCachedGroupStats)
{
const GxsGroupStatistic& s(it.second);
stats.mNumMsgs += s.mNumMsgs;
stats.mNumGrps += 1;
stats.mSizeOfMsgs += s.mTotalSizeOfMsgs;
stats.mNumThreadMsgsNew += s.mNumThreadMsgsNew;
stats.mNumThreadMsgsUnread += s.mNumThreadMsgsUnread;
stats.mNumChildMsgsNew += s.mNumChildMsgsNew ;
stats.mNumChildMsgsUnread += s.mNumChildMsgsUnread ;
std::cout<<stats.mNumMsgs <<std::endl;
std::cout<<stats.mNumGrps <<std::endl;
std::cout<<stats.mSizeOfMsgs <<std::endl;
std::cout<<stats.mNumThreadMsgsNew <<std::endl;
std::cout<<stats.mNumThreadMsgsUnread <<std::endl;
std::cout<<stats.mNumChildMsgsNew <<std::endl;
std::cout<<stats.mNumChildMsgsUnread <<std::endl;
}
// Also save the service statistics in conf file, so that we can display it right away at start.
Settings->beginGroup(mSettingsName);
Settings->setValue("NumMsgs", stats.mNumMsgs );
Settings->setValue("NumGrps", stats.mNumGrps );
Settings->setValue("SizeOfMessages", stats.mSizeOfMsgs );
Settings->setValue("NumThreadMsgsNew", stats.mNumThreadMsgsNew );
Settings->setValue("NumThreadMsgsUnread",stats.mNumThreadMsgsUnread);
Settings->setValue("NumChildMsgsNew", stats.mNumChildMsgsNew );
Settings->setValue("NumChildMsgsUnread", stats.mNumChildMsgsUnread );
Settings->endGroup();
}
else // Get statistics from settings if no cache is already present: allows to display at start.
{
Settings->beginGroup(mSettingsName);
stats.mNumMsgs = Settings->value("NumMsgs",QVariant(0)).toInt();
stats.mNumGrps = Settings->value("NumGrps",QVariant(0)).toInt();
stats.mSizeOfMsgs = Settings->value("SizeOfMessages",QVariant(0)).toInt();
stats.mNumThreadMsgsNew = Settings->value("NumThreadMsgsNew",QVariant(0)).toInt();
stats.mNumThreadMsgsUnread = Settings->value("NumThreadMsgsUnread",QVariant(0)).toInt();
stats.mNumChildMsgsNew = Settings->value("NumChildMsgsNew",QVariant(0)).toInt();
stats.mNumChildMsgsUnread = Settings->value("NumChildMsgsUnread",QVariant(0)).toInt();
Settings->endGroup();
}
}
void WireDialog::updateGroupStatistics(const RsGxsGroupId &groupId)
{
mGroupStatisticsToUpdate.insert(groupId);
mShouldUpdateGroupStatistics = true;
}
void WireDialog::updateGroupStatisticsReal(const RsGxsGroupId &groupId)
{
RsThread::async([this,groupId]()
{
GxsGroupStatistic stats;
if(! getGroupStatistics(groupId, stats))
{
std::cerr << __PRETTY_FUNCTION__ << " failed to collect group statistics for group " << groupId << std::endl;
return;
}
RsQThreadUtils::postToObject( [this,stats, groupId]()
{
/* Here it goes any code you want to be executed on the Qt Gui
* thread, for example to update the data model with new information
* after a blocking call to RetroShare API complete, note that
* Qt::QueuedConnection is important!
*/
// QTreeWidgetItem *item = ui.scrollAreaWidgetContents->getItemFromId(QString::fromStdString(stats.mGrpId.toStdString()));
// if (item)
// ui.scrollAreaWidgetContents->setUnreadCount(item, mCountChildMsgs ? (stats.mNumThreadMsgsUnread + stats.mNumChildMsgsUnread) : stats.mNumThreadMsgsUnread);
mCachedGroupStats[groupId] = stats;
getUserNotify()->updateIcon();
}, this );
});
}
bool WireDialog::navigate(const RsGxsGroupId &groupId, const RsGxsMessageId& msgId)
{
if (groupId.isNull()) {
return false;
}
// if (mStateHelper->isLoading(TOKEN_TYPE_GROUP_SUMMARY)) {
// mNavigatePendingGroupId = groupId;
// mNavigatePendingMsgId = msgId;
// /* No information if group is available */
// return true;
// }
// QString groupIdString = QString::fromStdString(groupId.toStdString());
// if (ui.groupTreeWidget->activateId(groupIdString, msgId.isNull()) == NULL) {
// return false;
// }
// changedCurrentGroup(groupIdString);
/* search exisiting tab */
// GxsMessageFrameWidget *msgWidget = messageWidget(mGroupId);
// if (!msgWidget) {
// return false;
// }
// if (msgId.isNull()) {
// return true;
// }
// return msgWidget->navigate(msgId);
return true;
}
GxsMessageFrameWidget *WireDialog::messageWidget(const RsGxsGroupId &groupId)
{
// int tabCount = ui.tabWidget->count();
// for (int index = 0; index < tabCount; ++index)
// {
// GxsMessageFrameWidget *childWidget = dynamic_cast<GxsMessageFrameWidget*>(ui.tabWidget->widget(index));
// if (childWidget && childWidget->groupId() == groupId)
// return childWidget;
// }
return NULL;
}
//void GxsGroupFrameDialog::changedCurrentGroup(const QString& groupId)
//{
// if (mInFill) {
// return;
// }
// if (groupId.isEmpty())
// {
// auto w = currentWidget();
// if(w)
// w->setGroupId(RsGxsGroupId());
// return;
// }
// mGroupId = RsGxsGroupId(groupId.toStdString());
// if (mGroupId.isNull())
// return;
// /* search exisiting tab */
// GxsMessageFrameWidget *msgWidget = messageWidget(mGroupId);
// // check that we have at least one tab
// if(msgWidget)
// ui.messageTabWidget->setCurrentWidget(msgWidget);
// else
// {
// if(useTabs() || ui.messageTabWidget->count()==0)
// {
// msgWidget = createMessageWidget(RsGxsGroupId(groupId.toStdString()));
// ui.messageTabWidget->setCurrentWidget(msgWidget);
// }
// else
// currentWidget()->setGroupId(mGroupId);
// }
//}

View File

@ -34,7 +34,7 @@
#include "gui/TheWire/PulseViewItem.h"
#include "gui/TheWire/PulseTopLevel.h"
#include "gui/TheWire/PulseReply.h"
#include "gui/gxs/GxsStatisticsProvider.h"
#include "util/TokenQueue.h"
@ -68,7 +68,7 @@ public:
};
//---------------------------------------------------------
class WireDialog : public MainPage, public TokenResponse, public WireGroupHolder, public PulseViewHolder
class WireDialog : public GxsStatisticsProvider, public TokenResponse, public WireGroupHolder, public PulseViewHolder
{
Q_OBJECT
@ -118,6 +118,17 @@ public:
void showGroupsPulses(const std::list<RsGxsGroupId>& groupIds);
void postGroupsPulses(std::list<RsWirePulseSPtr> pulses);
void getServiceStatistics(GxsServiceStatistic& stats) const ;
virtual bool navigate(const RsGxsGroupId &groupId, const RsGxsMessageId& msgId) override;
protected:
bool getGroupStatistics(const RsGxsGroupId& groupId,GxsGroupStatistic& stat) override;
UserNotify *createUserNotify(QObject *parent) override;
virtual void updateGroupStatistics(const RsGxsGroupId &groupId) override;
virtual void updateGroupStatisticsReal(const RsGxsGroupId &groupId) override;
private slots:
void createGroup();
@ -150,11 +161,14 @@ private:
// Loading Data.
void requestGroupData();
bool loadGroupData(const uint32_t &token);
bool loadGroupData(const uint32_t &token);
void acknowledgeGroup(const uint32_t &token, const uint32_t &userType);
virtual void loadRequest(const TokenQueue *queue, const TokenRequest &req) override;
virtual QString settingsGroupName() override{ return "PostedDialog"; }
virtual GxsMessageFrameWidget *messageWidget(const RsGxsGroupId &groupId) override;
int mGroupSet;
PulseAddDialog *mAddDialog;

View File

@ -224,7 +224,7 @@
</item>
</layout>
</widget>
<widget class="QTabWidget" name="tabWidget">
<widget class="RSTabWidget" name="tabWidget">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Preferred">
<horstretch>3</horstretch>
@ -432,6 +432,12 @@
<extends>QComboBox</extends>
<header>gui/common/RSComboBox.h</header>
</customwidget>
<customwidget>
<class>RSTabWidget</class>
<extends>QTabWidget</extends>
<header>gui/common/RSTabWidget.h</header>
<container>1</container>
</customwidget>
</customwidgets>
<resources>
<include location="../icons.qrc"/>

View File

@ -0,0 +1,62 @@
/*******************************************************************************
* retroshare-gui/src/gui/TheWire/WireUserNotify.cpp *
* *
* Copyright (C) 2014 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/>. *
* *
*******************************************************************************/
#include "retroshare/rswire.h"
#include "WireUserNotify.h"
#include "gui/MainWindow.h"
#include "gui/common/FilesDefs.h"
WireUserNotify::WireUserNotify(RsGxsIfaceHelper *ifaceImpl, const GxsStatisticsProvider *g, QObject *parent) :
GxsUserNotify(ifaceImpl, g, parent)
{
}
bool WireUserNotify::hasSetting(QString *name, QString *group)
{
if (name) *name = tr("Wire Post");
if (group) *group = "Wire";
return true;
}
QIcon WireUserNotify::getIcon()
{
return FilesDefs::getIconFromQtResourcePath(":/icons/png/wire-circle.png");
}
QIcon WireUserNotify::getMainIcon(bool hasNew)
{
return hasNew ? FilesDefs::getIconFromQtResourcePath(":/icons/png/wire-notify.png") : FilesDefs::getIconFromQtResourcePath(":/icons/png/wire-circle.png");
}
//QString PostedUserNotify::getTrayMessage(bool plural)
//{
// return plural ? tr("You have %1 new board posts") : tr("You have %1 new board post");
//}
//QString PostedUserNotify::getNotifyMessage(bool plural)
//{
// return plural ? tr("%1 new board post") : tr("%1 new board post");
//}
void WireUserNotify::iconClicked()
{
MainWindow::showWindow(MainWindow::Wire);
}

View File

@ -0,0 +1,42 @@
/*******************************************************************************
* retroshare-gui/src/gui/TheWire/WireUserNotify.h *
* *
* Copyright (C) 2014 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/>. *
* *
*******************************************************************************/
#ifndef WIREUSERNOTIFY_H
#define WIREUSERNOTIFY_H
#include "gui/gxs/GxsUserNotify.h"
class WireUserNotify : public GxsUserNotify
{
Q_OBJECT
public:
explicit WireUserNotify(RsGxsIfaceHelper *ifaceImpl, const GxsStatisticsProvider *g, QObject *parent = 0);
virtual bool hasSetting(QString *name, QString *group) override;
private:
virtual QIcon getIcon() override;
virtual QIcon getMainIcon(bool hasNew) override;
virtual void iconClicked() override;
};
#endif // WIREUSERNOTIFY_H

View File

@ -0,0 +1,65 @@
#include "NotifyWidget.h"
#include "ui_NotifyWidget.h"
#include "RSTreeWidgetItem.h"
#define ROLE_ID Qt::UserRole
#define ROLE_NAME Qt::UserRole + 1
#define ROLE_DESCRIPTION Qt::UserRole + 2
#define ROLE_SUBSCRIBE_FLAGS Qt::UserRole + 3
#define ROLE_COLOR Qt::UserRole + 4
#define ROLE_REQUEST_ID Qt::UserRole + 5
#define ROLE_SORT Qt::UserRole + 6
NotifyWidget::NotifyWidget(QWidget *parent) :
QWidget(parent),
ui(new Ui::NotifyWidget)
{
ui->setupUi(this);
}
NotifyWidget::~NotifyWidget()
{
delete ui;
}
void NotifyWidget::setUnreadCount(QTreeWidgetItem *item, int unreadCount)
{
if (item == NULL) {
return;
}
QFont itFont = item->font(GTW_COLUMN_NAME);
if (unreadCount) {
item->setText(GTW_COLUMN_UNREAD, QString::number(unreadCount));
itFont.setBold(true);
} else {
item->setText(GTW_COLUMN_UNREAD, "");
itFont.setBold(false);
}
item->setData(GTW_COLUMN_UNREAD, ROLE_SORT, unreadCount);
item->setFont(GTW_COLUMN_NAME, itFont);
}
QTreeWidgetItem *NotifyWidget::getItemFromId(const QString &id)
{
if (id.isEmpty()) {
return NULL;
}
/* Search exisiting item */
QTreeWidgetItemIterator itemIterator(ui->treeWidget);
QTreeWidgetItem *item;
while ((item = *itemIterator) != NULL) {
++itemIterator;
if (item->parent() == NULL) {
continue;
}
if (item->data(GTW_COLUMN_DATA, ROLE_ID).toString() == id) {
return item;
}
}
return NULL ;
}

View File

@ -0,0 +1,83 @@
/*******************************************************************************
* gui/common/NotifyWidget.h *
* *
* Copyright (C) 2010, 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/>. *
* *
*******************************************************************************/
#ifndef NOTIFYWIDGET_H
#define NOTIFYWIDGET_H
#include <QTreeWidgetItem>
#include <QWidget>
#include <QDateTime>
#include <set>
#define GTW_COLUMN_NAME 0
#define GTW_COLUMN_UNREAD 1
#define GTW_COLUMN_POSTS 2
#define GTW_COLUMN_POPULARITY 3
#define GTW_COLUMN_LAST_POST 4
#define GTW_COLUMN_SEARCH_SCORE 5
#define GTW_COLUMN_DESCRIPTION 6
#define GTW_COLUMN_COUNT 7
#define GTW_COLUMN_DATA GTW_COLUMN_NAME
namespace Ui {
class NotifyWidget;
}
//class GroupItemInfo
//{
//public:
// GroupItemInfo()
// : popularity(0), publishKey(false), adminKey(false)
// , subscribeFlags(0), max_visible_posts(0)
// {}
//public:
// QString id;
// QString name;
// QString description;
// int popularity;
// QDateTime lastpost;
// QIcon icon;
// bool publishKey;
// bool adminKey;
// quint32 subscribeFlags;
// quint32 max_visible_posts ;
// std::set<std::string> context_strings;
//};
class NotifyWidget : public QWidget
{
Q_OBJECT
public:
NotifyWidget(QWidget *parent = nullptr);
~NotifyWidget();
// Set the unread count of an item
void setUnreadCount(QTreeWidgetItem *item, int unreadCount);
QTreeWidgetItem *getItemFromId(const QString &id);
private:
Ui::NotifyWidget *ui;
};
#endif // NOTIFYWIDGET_H

View File

@ -0,0 +1,66 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>NotifyWidget</class>
<widget class="QWidget" name="NotifyWidget">
<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="QGridLayout" name="gridLayout">
<item row="0" column="0">
<widget class="RSTreeWidget" name="treeWidget">
<property name="enabled">
<bool>true</bool>
</property>
<property name="sizePolicy">
<sizepolicy hsizetype="Expanding" vsizetype="Expanding">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="font">
<font>
<pointsize>11</pointsize>
</font>
</property>
<property name="contextMenuPolicy">
<enum>Qt::CustomContextMenu</enum>
</property>
<property name="editTriggers">
<set>QAbstractItemView::NoEditTriggers</set>
</property>
<property name="iconSize">
<size>
<width>19</width>
<height>19</height>
</size>
</property>
<property name="allColumnsShowFocus">
<bool>true</bool>
</property>
<column>
<property name="text">
<string notr="true">1</string>
</property>
</column>
</widget>
</item>
</layout>
</widget>
<customwidgets>
<customwidget>
<class>RSTreeWidget</class>
<extends>QTreeWidget</extends>
<header>gui/common/RSTreeWidget.h</header>
</customwidget>
</customwidgets>
<resources/>
<connections/>
</ui>

View File

@ -0,0 +1,238 @@
/*******************************************************************************
* gui/feeds/WireNotifyGroupItem.cpp *
* *
* Copyright (c) 2014, 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 "WireNotifyGroupItem.h"
#include "ui_WireNotifyGroupItem.h"
#include "FeedHolder.h"
#include "util/qtthreadsutils.h"
#include "gui/RetroShareLink.h"
#include "gui/gxs/GxsIdDetails.h"
#include "gui/common/FilesDefs.h"
#include "util/DateTime.h"
/****
* #define DEBUG_ITEM 1
****/
WireNotifyGroupItem::WireNotifyGroupItem(FeedHolder *feedHolder, uint32_t feedId, const RsGxsGroupId &groupId, bool isHome, bool autoUpdate) :
GxsGroupFeedItem(feedHolder, feedId, groupId, isHome, rsWire, autoUpdate)
{
setup();
requestGroup();
}
WireNotifyGroupItem::WireNotifyGroupItem(FeedHolder *feedHolder, uint32_t feedId, const RsWireGroup &group, bool isHome, bool autoUpdate) :
GxsGroupFeedItem(feedHolder, feedId, group.mMeta.mGroupId, isHome, rsWire, autoUpdate)
{
setup();
setGroup(group);
}
WireNotifyGroupItem::~WireNotifyGroupItem()
{
delete(ui);
}
void WireNotifyGroupItem::setup()
{
/* Invoke the Qt Designer generated object setup routine */
ui = new(Ui::WireNotifyGroupItem);
ui->setupUi(this);
setAttribute(Qt::WA_DeleteOnClose, true);
/* clear ui */
ui->nameLabel->setText(tr("Loading..."));
ui->titleLabel->clear();
ui->descLabel->clear();
/* general ones */
connect(ui->expandButton, SIGNAL(clicked()), this, SLOT(toggle()));
connect(ui->clearButton, SIGNAL(clicked()), this, SLOT(removeItem()));
/* specific */
connect(ui->subscribeButton, SIGNAL(clicked()), this, SLOT(subscribeWire()));
connect(ui->copyLinkButton, SIGNAL(clicked()), this, SLOT(copyGroupLink()));
//ui->copyLinkButton->hide(); // No link type at this moment
ui->expandFrame->hide();
}
bool WireNotifyGroupItem::setGroup(const RsWireGroup &group)
{
if (groupId() != group.mMeta.mGroupId) {
std::cerr << "WireNotifyGroupItem::setContent() - Wrong id, cannot set post";
std::cerr << std::endl;
return false;
}
mGroup = group;
fill();
return true;
}
void WireNotifyGroupItem::loadGroup()
{
RsThread::async([this]()
{
// 1 - get group data
#ifdef DEBUG_FORUMS
std::cerr << "Retrieving post data for post " << mThreadId << std::endl;
#endif
std::vector<RsWireGroup> groups;
const std::list<RsGxsGroupId> groupIds = { groupId() };
if(!rsWire->getGroups(groupIds,groups))
{
RsErr() << "WireNotifyGroupItem::loadGroup() ERROR getting data" << std::endl;
return;
}
if (groups.size() != 1)
{
std::cerr << "WireNotifyGroupItem::loadGroup() Wrong number of Items";
std::cerr << std::endl;
return;
}
RsWireGroup group(groups[0]);
RsQThreadUtils::postToObject( [group,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 */
setGroup(group);
}, this );
});
}
QString WireNotifyGroupItem::groupName()
{
return QString::fromUtf8(mGroup.mMeta.mGroupName.c_str());
}
void WireNotifyGroupItem::fill()
{
/* fill in */
#ifdef DEBUG_ITEM
std::cerr << "WireNotifyGroupItem::fill()";
std::cerr << std::endl;
#endif
// No link type at this moment
RetroShareLink link = RetroShareLink::createGxsGroupLink(RetroShareLink::TYPE_WIRE, mGroup.mMeta.mGroupId, groupName());
ui->nameLabel->setText(link.toHtml());
// ui->nameLabel->setText(groupName());
ui->descLabel->setText(QString::fromUtf8(mGroup.mTagline.c_str()));
if (mGroup.mHeadshot.mData != NULL) {
QPixmap wireImage;
GxsIdDetails::loadPixmapFromData(mGroup.mHeadshot.mData, mGroup.mHeadshot.mSize, wireImage,GxsIdDetails::ORIGINAL);
ui->logoLabel->setPixmap(QPixmap(wireImage));
} else {
ui->logoLabel->setPixmap(FilesDefs::getPixmapFromQtResourcePath(":/icons/wire.png"));
}
if(mGroup.mMeta.mLastPost==0)
ui->infoLastPost->setText(tr("Never"));
else
ui->infoLastPost->setText(DateTime::formatLongDateTime(mGroup.mMeta.mLastPost));
//TODO - nice icon for subscribed group
// if (IS_GROUP_PUBLISHER(mGroup.mMeta.mSubscribeFlags)) {
// ui->logoLabel->setPixmap(FilesDefs::getPixmapFromQtResourcePath(":/icons/wire.png"));
// } else {
// ui->logoLabel->setPixmap(FilesDefs::getPixmapFromQtResourcePath(":/icons/wire.png"));
// }
if (IS_GROUP_SUBSCRIBED(mGroup.mMeta.mSubscribeFlags)) {
ui->subscribeButton->setEnabled(false);
} else {
ui->subscribeButton->setEnabled(true);
}
// if (mIsNew)
// {
ui->titleLabel->setText(tr("New Wire"));
// }
// else
// {
// ui->titleLabel->setText(tr("Updated Wire"));
// }
if (mIsHome)
{
/* disable buttons */
ui->clearButton->setEnabled(false);
}
}
void WireNotifyGroupItem::toggle()
{
expand(ui->expandFrame->isHidden());
}
void WireNotifyGroupItem::doExpand(bool open)
{
if (mFeedHolder)
{
mFeedHolder->lockLayout(this, true);
}
if (open)
{
ui->expandFrame->show();
ui->expandButton->setIcon(FilesDefs::getIconFromQtResourcePath(QString(":/icons/png/up-arrow.png")));
ui->expandButton->setToolTip(tr("Hide"));
}
else
{
ui->expandFrame->hide();
ui->expandButton->setIcon(FilesDefs::getIconFromQtResourcePath(QString(":/icons/png/down-arrow.png")));
ui->expandButton->setToolTip(tr("Expand"));
}
emit sizeChanged(this);
if (mFeedHolder)
{
mFeedHolder->lockLayout(this, false);
}
}
void WireNotifyGroupItem::subscribeWire()
{
#ifdef DEBUG_ITEM
std::cerr << "WireNotifyGroupItem::subscribeWire()";
std::cerr << std::endl;
#endif
subscribe();
}

View File

@ -0,0 +1,71 @@
/*******************************************************************************
* gui/feeds/WireNotifyGroupItem.h *
* *
* Copyright (c) 2014, 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/>. *
* *
*******************************************************************************/
#ifndef WIRENOTIFYGROUPITEM_H
#define WIRENOTIFYGROUPITEM_H
#include <retroshare/rswire.h>
#include "gui/gxs/GxsGroupFeedItem.h"
namespace Ui {
class WireNotifyGroupItem;
}
class FeedHolder;
class WireNotifyGroupItem : public GxsGroupFeedItem
{
Q_OBJECT
public:
/** Default Constructor */
WireNotifyGroupItem(FeedHolder *feedHolder, uint32_t feedId, const RsGxsGroupId &groupId, bool isHome, bool autoUpdate);
WireNotifyGroupItem(FeedHolder *feedHolder, uint32_t feedId, const RsWireGroup &group, bool isHome, bool autoUpdate);
~WireNotifyGroupItem();
bool setGroup(const RsWireGroup &group);
uint64_t uniqueIdentifier() const override { return hash_64bits("WireNotifyGroupItem " + groupId().toStdString()) ; }
protected:
/* FeedItem */
virtual void doExpand(bool open);
/* GxsGroupFeedItem */
virtual QString groupName();
virtual void loadGroup() override;
virtual RetroShareLink::enumType getLinkType() { return RetroShareLink::TYPE_UNKNOWN; }
private slots:
void toggle() override;
void subscribeWire();
private:
void fill();
void setup();
private:
RsWireGroup mGroup;
/** Qt Designer generated object */
Ui::WireNotifyGroupItem *ui;
};
#endif // WIRENOTIFYGROUPITEM_H

View File

@ -0,0 +1,399 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>WireNotifyGroupItem</class>
<widget class="QWidget" name="WireNotifyGroupItem">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>618</width>
<height>191</height>
</rect>
</property>
<layout class="QGridLayout" name="WireNotifyGroupItem_GL">
<property name="leftMargin">
<number>1</number>
</property>
<property name="topMargin">
<number>1</number>
</property>
<property name="rightMargin">
<number>1</number>
</property>
<property name="bottomMargin">
<number>1</number>
</property>
<item row="0" column="0">
<widget class="QFrame" name="feedFrame">
<property name="sizePolicy">
<sizepolicy hsizetype="Expanding" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="palette">
<palette>
<active>
<colorrole role="WindowText">
<brush brushstyle="SolidPattern">
<color alpha="255">
<red>0</red>
<green>0</green>
<blue>0</blue>
</color>
</brush>
</colorrole>
<colorrole role="Base">
<brush brushstyle="SolidPattern">
<color alpha="255">
<red>215</red>
<green>215</green>
<blue>215</blue>
</color>
</brush>
</colorrole>
<colorrole role="Window">
<brush brushstyle="SolidPattern">
<color alpha="255">
<red>215</red>
<green>215</green>
<blue>215</blue>
</color>
</brush>
</colorrole>
</active>
<inactive>
<colorrole role="WindowText">
<brush brushstyle="SolidPattern">
<color alpha="255">
<red>0</red>
<green>0</green>
<blue>0</blue>
</color>
</brush>
</colorrole>
<colorrole role="Base">
<brush brushstyle="SolidPattern">
<color alpha="255">
<red>215</red>
<green>215</green>
<blue>215</blue>
</color>
</brush>
</colorrole>
<colorrole role="Window">
<brush brushstyle="SolidPattern">
<color alpha="255">
<red>215</red>
<green>215</green>
<blue>215</blue>
</color>
</brush>
</colorrole>
</inactive>
<disabled>
<colorrole role="WindowText">
<brush brushstyle="SolidPattern">
<color alpha="255">
<red>154</red>
<green>154</green>
<blue>154</blue>
</color>
</brush>
</colorrole>
<colorrole role="Base">
<brush brushstyle="SolidPattern">
<color alpha="255">
<red>215</red>
<green>215</green>
<blue>215</blue>
</color>
</brush>
</colorrole>
<colorrole role="Window">
<brush brushstyle="SolidPattern">
<color alpha="255">
<red>215</red>
<green>215</green>
<blue>215</blue>
</color>
</brush>
</colorrole>
</disabled>
</palette>
</property>
<property name="autoFillBackground">
<bool>true</bool>
</property>
<property name="frameShape">
<enum>QFrame::Box</enum>
</property>
<property name="frameShadow">
<enum>QFrame::Sunken</enum>
</property>
<layout class="QGridLayout" name="feedFrame_GL">
<item row="0" column="0">
<layout class="QGridLayout" name="top_GL">
<item row="0" column="0" rowspan="2">
<widget class="QLabel" name="logoLabel">
<property name="minimumSize">
<size>
<width>70</width>
<height>70</height>
</size>
</property>
<property name="maximumSize">
<size>
<width>70</width>
<height>70</height>
</size>
</property>
<property name="text">
<string/>
</property>
<property name="pixmap">
<pixmap resource="../icons.qrc">:/icons/png/posted.png</pixmap>
</property>
<property name="scaledContents">
<bool>true</bool>
</property>
</widget>
</item>
<item row="0" column="1">
<layout class="QHBoxLayout" name="title_HL">
<item>
<widget class="QLabel" name="titleLabel">
<property name="sizePolicy">
<sizepolicy hsizetype="Minimum" vsizetype="Minimum">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="font">
<font>
<pointsize>11</pointsize>
<italic>true</italic>
<bold>true</bold>
</font>
</property>
<property name="text">
<string notr="true">Wire</string>
</property>
</widget>
</item>
<item>
<widget class="QLabel" name="nameLabel">
<property name="font">
<font>
<pointsize>11</pointsize>
<italic>true</italic>
<bold>true</bold>
</font>
</property>
<property name="text">
<string notr="true">name</string>
</property>
<property name="openExternalLinks">
<bool>true</bool>
</property>
</widget>
</item>
<item>
<spacer name="title_HSpacer">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
<item>
<widget class="QLabel" name="infoLastPostLabel">
<property name="font">
<font>
<bold>true</bold>
</font>
</property>
<property name="text">
<string>Last activity</string>
</property>
</widget>
</item>
<item>
<widget class="QLabel" name="infoLastPost">
<property name="font">
<font>
<italic>true</italic>
<bold>true</bold>
</font>
</property>
<property name="text">
<string>TextLabel</string>
</property>
</widget>
</item>
</layout>
</item>
<item row="1" column="1">
<layout class="QHBoxLayout" name="buttons_HL">
<item>
<widget class="QPushButton" name="subscribeButton">
<property name="sizePolicy">
<sizepolicy hsizetype="Fixed" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="focusPolicy">
<enum>Qt::NoFocus</enum>
</property>
<property name="toolTip">
<string>Subscribe to Posted</string>
</property>
<property name="text">
<string>Follow</string>
</property>
</widget>
</item>
<item>
<spacer name="buttons_HSpacer">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeType">
<enum>QSizePolicy::Expanding</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>254</width>
<height>28</height>
</size>
</property>
</spacer>
</item>
<item>
<widget class="QPushButton" name="copyLinkButton">
<property name="focusPolicy">
<enum>Qt::NoFocus</enum>
</property>
<property name="toolTip">
<string>Copy RetroShare Link</string>
</property>
<property name="icon">
<iconset resource="../icons.qrc">
<normaloff>:/icons/png/copy.png</normaloff>:/icons/png/copy.png</iconset>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="expandButton">
<property name="sizePolicy">
<sizepolicy hsizetype="Fixed" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="focusPolicy">
<enum>Qt::NoFocus</enum>
</property>
<property name="toolTip">
<string>Expand</string>
</property>
<property name="icon">
<iconset resource="../icons.qrc">
<normaloff>:/icons/png/down-arrow.png</normaloff>:/icons/png/down-arrow.png</iconset>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="clearButton">
<property name="sizePolicy">
<sizepolicy hsizetype="Fixed" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="focusPolicy">
<enum>Qt::NoFocus</enum>
</property>
<property name="toolTip">
<string>Remove Item</string>
</property>
<property name="icon">
<iconset resource="../icons.qrc">
<normaloff>:/icons/png/exit2.png</normaloff>:/icons/png/exit2.png</iconset>
</property>
</widget>
</item>
</layout>
</item>
</layout>
</item>
<item row="1" column="0">
<widget class="QFrame" name="expandFrame">
<layout class="QVBoxLayout" name="expandFrame_VL">
<property name="spacing">
<number>0</number>
</property>
<property name="leftMargin">
<number>0</number>
</property>
<property name="topMargin">
<number>0</number>
</property>
<property name="rightMargin">
<number>0</number>
</property>
<property name="bottomMargin">
<number>0</number>
</property>
<item>
<widget class="QGroupBox" name="groupBox">
<property name="title">
<string>Wire Description</string>
</property>
<layout class="QHBoxLayout" name="groupBox_HL">
<item>
<widget class="QLabel" name="iconLabel">
<property name="text">
<string/>
</property>
<property name="pixmap">
<pixmap>:/images/contacts24.png</pixmap>
</property>
</widget>
</item>
<item>
<widget class="QLabel" name="descLabel">
<property name="sizePolicy">
<sizepolicy hsizetype="MinimumExpanding" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="text">
<string notr="true">Description
of Wire</string>
</property>
</widget>
</item>
</layout>
</widget>
</item>
</layout>
</widget>
</item>
</layout>
</widget>
</item>
</layout>
</widget>
<resources>
<include location="../icons.qrc"/>
</resources>
<connections/>
</ui>

View File

@ -0,0 +1,758 @@
/*******************************************************************************
* gui/feeds/WireNotifyPostItem.cpp *
* *
* Copyright (c) 2012, Robert Fernie <retroshare.project@gmail.com> *
* *
* This program is free software: you can redistribute it and/or modify *
* it under the terms of the GNU Affero General Public License as *
* published by the Free Software Foundation, either version 3 of the *
* License, or (at your option) any later version. *
* *
* This program is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU Affero General Public License for more details. *
* *
* You should have received a copy of the GNU Affero General Public License *
* along with this program. If not, see <https://www.gnu.org/licenses/>. *
* *
*******************************************************************************/
#include "WireNotifyPostItem.h"
#include "ui_WireNotifyPostItem.h"
#include "FeedHolder.h"
#include "util/qtthreadsutils.h"
#include "gui/RetroShareLink.h"
#include "gui/common/FilesDefs.h"
#include "gui/gxs/GxsIdDetails.h"
#include "util/stringutil.h"
#include "util/DateTime.h"
#include "util/misc.h"
#include <QStyle>
#include <iostream>
#include <cmath>
WireNotifyPostItem::WireNotifyPostItem(FeedHolder *feedHolder, uint32_t feedId, const RsGxsGroupId &groupId, const RsGxsMessageId &messageId, bool isHome, bool autoUpdate, const std::set<RsGxsMessageId> &older_versions) :
GxsFeedItem(feedHolder, feedId, groupId, messageId, isHome, rsWire, autoUpdate) // this one should be in GxsFeedItem
{
mPulse.mMeta.mMsgId = messageId; // useful for uniqueIdentifer() before the post is loaded
QVector<RsGxsMessageId> v;
//bool self = false;
for(std::set<RsGxsMessageId>::const_iterator it(older_versions.begin());it!=older_versions.end();++it)
v.push_back(*it) ;
if(older_versions.find(messageId) == older_versions.end())
v.push_back(messageId);
setMessageVersions(v) ;
setup();
loadGroup();
}
WireNotifyPostItem::WireNotifyPostItem(FeedHolder *feedHolder, uint32_t feedId, const RsGroupMetaData& group_meta, const RsGxsMessageId &messageId, bool isHome, bool autoUpdate,const std::set<RsGxsMessageId>& older_versions) :
GxsFeedItem(feedHolder, feedId, group_meta.mGroupId, messageId, isHome, rsWire, autoUpdate),
mGroupMeta(group_meta)
{
mLoadingGroup = false;
mLoadingMessage = false;
mLoadingComment = false;
mPulse.mMeta.mMsgId = messageId; // useful for uniqueIdentifer() before the post is loaded
mPulse.mMeta.mGroupId = mGroupMeta.mGroupId;
QVector<RsGxsMessageId> v;
//bool self = false;
for(std::set<RsGxsMessageId>::const_iterator it(older_versions.begin());it!=older_versions.end();++it)
v.push_back(*it) ;
if(older_versions.find(messageId) == older_versions.end())
v.push_back(messageId);
setMessageVersions(v) ;
setup();
// no call to loadGroup() here because we have it already.
}
WireNotifyPostItem::~WireNotifyPostItem()
{
delete ui;
}
bool WireNotifyPostItem::isUnread() const
{
return IS_MSG_UNREAD(mPulse.mMeta.mMsgStatus) ;
}
void WireNotifyPostItem::setup()
{
/* Invoke the Qt Designer generated object setup routine */
ui = new Ui::WireNotifyPostItem;
ui->setupUi(this);
// Manually set icons to allow to use clever resource sharing that is missing in Qt for Icons loaded from Qt resource file.
// This is particularly important here because a wire may contain many posts, so duplicating the QImages here is deadly for the
// memory.
// ui->logoLabel->setPixmap(FilesDefs::getPixmapFromQtResourcePath(":/images/thumb-default-video.png"));
//ui->warn_image_label->setPixmap(FilesDefs::getPixmapFromQtResourcePath(":/images/status_unknown.png"));
ui->readButton->setIcon(FilesDefs::getIconFromQtResourcePath(":/images/message-state-unread.png"));
// ui->voteUpButton->setIcon(FilesDefs::getIconFromQtResourcePath(":/images/vote_up.png"));
// ui->voteDownButton->setIcon(FilesDefs::getIconFromQtResourcePath(":/images/vote_down.png"));
// ui->downloadButton->setIcon(FilesDefs::getIconFromQtResourcePath(":/icons/png/download.png"));
// ui->playButton->setIcon(FilesDefs::getIconFromQtResourcePath(":/icons/png/play.png"));
ui->commentButton->setIcon(FilesDefs::getIconFromQtResourcePath(":/icons/png/comment.png"));
//ui->editButton->setIcon(FilesDefs::getIconFromQtResourcePath(":/icons/png/pencil-edit-button.png"));
// ui->copyLinkButton->setIcon(FilesDefs::getIconFromQtResourcePath(":/icons/png/copy.png"));
// ui->expandButton->setIcon(FilesDefs::getIconFromQtResourcePath(":/icons/png/down-arrow.png"));
// ui->readAndClearButton->setIcon(FilesDefs::getIconFromQtResourcePath(":/icons/png/correct.png"));
// ui->clearButton->setIcon(FilesDefs::getIconFromQtResourcePath(":/icons/png/exit2.png"));
setAttribute(Qt::WA_DeleteOnClose, true);
mInFill = false;
mCloseOnRead = false;
mLoaded = false;
/* clear ui */
ui->titleLabel->setText(tr("Loading..."));
ui->datetimelabel->clear();
ui->filelabel->clear();
// ui->newCommentLabel->hide();
// ui->commLabel->hide();
/* general ones */
connect(ui->expandButton, SIGNAL(clicked()), this, SLOT(toggle()));
connect(ui->clearButton, SIGNAL(clicked()), this, SLOT(removeItem()));
/* specific */
connect(ui->readAndClearButton, SIGNAL(clicked()), this, SLOT(readAndClearItem()));
connect(ui->unsubscribeButton, SIGNAL(clicked()), this, SLOT(unsubscribeChannel()));
connect(ui->downloadButton, SIGNAL(clicked()), this, SLOT(download()));
// HACK FOR NOW.
ui->commentButton->hide();// hidden until properly enabled.
connect(ui->commentButton, SIGNAL(clicked()), this, SLOT(loadComments()));
connect(ui->playButton, SIGNAL(clicked()), this, SLOT(play(void)));
//connect(ui->editButton, SIGNAL(clicked()), this, SLOT(edit(void)));
connect(ui->copyLinkButton, SIGNAL(clicked()), this, SLOT(copyMessageLink()));
connect(ui->readButton, SIGNAL(toggled(bool)), this, SLOT(readToggled(bool)));
// hide voting buttons, backend is not implemented yet
ui->voteUpButton->hide();
ui->voteDownButton->hide();
//connect(ui-> voteUpButton, SIGNAL(clicked()), this, SLOT(makeUpVote()));
//connect(ui->voteDownButton, SIGNAL(clicked()), this, SLOT(makeDownVote()));
ui->scoreLabel->hide();
// hide unsubscribe button not necessary
ui->unsubscribeButton->hide();
ui->downloadButton->hide();
ui->playButton->hide();
//ui->warn_image_label->hide();
//ui->warning_label->hide();
ui->titleLabel->setMinimumWidth(100);
ui->subjectLabel->setMinimumWidth(100);
//ui->warning_label->setMinimumWidth(100);
ui->feedFrame->setProperty("new", false);
ui->feedFrame->style()->unpolish(ui->feedFrame);
ui->feedFrame->style()->polish( ui->feedFrame);
ui->expandFrame->hide();
}
void WireNotifyPostItem::expandFill(bool first)
{
GxsFeedItem::expandFill(first);
if (first) {
// fillExpandFrame();
}
}
QString WireNotifyPostItem::messageName()
{
return QString::fromUtf8(mPulse.mMeta.mMsgName.c_str());
}
void WireNotifyPostItem::loadMessage()
{
#ifdef DEBUG_ITEM
std::cerr << "WireNotifyPostItem::loadMessage()";
std::cerr << std::endl;
#endif
mLoadingMessage = true;
RsThread::async([this]()
{
// 1 - get group data
std::list<RsGxsGroupId> groupIds;
std::list<RsWirePulseSPtr> pulses;
// std::vector<RsGxsComment> comments;
// std::vector<RsGxsVote> votes;
groupIds.push_back(groupId());
if(! rsWire->getPulsesForGroups(groupIds, pulses))
{
RsErr() << "WireNotifyPostItem::loadGroup() ERROR getting data" << std::endl;
return;
}
if (pulses.size() == 1)
{
#ifdef DEBUG_ITEM
std::cerr << (void*)this << ": Obtained post, with msgId = " << posts[0].mMeta.mMsgId << std::endl;
#endif
const RsWirePulse& pulse(*pulses.front());
RsQThreadUtils::postToObject( [pulse,this]()
{
setPost(pulse);
mLoadingMessage = false;
}, this );
}
// else if(comments.size() == 1)
// {
// const RsGxsComment& cmt = comments[0];
//#ifdef DEBUG_ITEM
// std::cerr << (void*)this << ": Obtained comment, setting messageId to threadID = " << cmt.mMeta.mThreadId << std::endl;
//#endif
// RsQThreadUtils::postToObject( [cmt,this]()
// {
// ui->newCommentLabel->show();
// ui->commLabel->show();
// ui->commLabel->setText(QString::fromUtf8(cmt.mComment.c_str()));
// //Change this item to be uploaded with thread element.
// setMessageId(cmt.mMeta.mThreadId);
// requestMessage();
// mLoadingMessage = false;
// }, this );
// }
// else
// {
//#ifdef DEBUG_ITEM
// std::cerr << "WireNotifyPostItem::loadMessage() Wrong number of Items. Remove It.";
// std::cerr << std::endl;
//#endif
// RsQThreadUtils::postToObject( [this]()
// {
// removeItem();
// mLoadingMessage = false;
// }, this );
// }
});
}
void WireNotifyPostItem::loadComment()
{
#ifdef DEBUG_ITEM
std::cerr << "WireNotifyPostItem::loadComment()";
std::cerr << std::endl;
#endif
// mLoadingComment = true;
// RsThread::async([this]()
// {
// // 1 - get group data
// std::set<RsGxsMessageId> msgIds;
// for(auto MsgId: messageVersions())
// msgIds.insert(MsgId);
// std::vector<RsGxsChannelPost> posts;
// std::vector<RsGxsComment> comments;
// if(! rsGxsChannels->getChannelComments( groupId(),msgIds,comments))
// {
// RsErr() << "GxsGxsChannelGroupItem::loadGroup() ERROR getting data" << std::endl;
// return;
// }
// int comNb = comments.size();
// RsQThreadUtils::postToObject( [comNb,this]()
// {
// QString sComButText = tr("Comment");
// if (comNb == 1)
// sComButText = sComButText.append("(1)");
// else if(comNb > 1)
// sComButText = tr("Comments ").append("(%1)").arg(comNb);
// ui->commentButton->setText(sComButText);
// mLoadingComment = false;
// }, this );
// });
}
void WireNotifyPostItem::loadGroup()
{
#ifdef DEBUG_ITEM
std::cerr << "WireNotifyGroupItem::loadGroup()";
std::cerr << std::endl;
#endif
mLoadingGroup = true;
RsThread::async([this]()
{
// 1 - get group data
// std::vector<RsWireGroup> groups;
// std::list<std::shared_ptr<RsWireGroup>> groups;
const std::list<RsGxsGroupId> groupIds = { groupId() };
std::vector<RsWireGroup> groups;
if(!rsWire->getGroups(groupIds,groups)) // would be better to call channel Summaries for a single group
{
RsErr() << "WireNotifyPostItem::loadGroup() ERROR getting data" << std::endl;
return;
}
if (groups.size() != 1)
{
std::cerr << "WireNotifyPostItem::loadGroup() Wrong number of Items";
std::cerr << std::endl;
return;
}
RsWireGroup group = groups[0];
RsQThreadUtils::postToObject( [group,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 */
mGroupMeta = group.mMeta;
mLoadingGroup = false;
setGroup(group);
}, this );
});
}
bool WireNotifyPostItem::setPost(const RsWirePulse &pulse, bool doFill)
{
if (groupId() != pulse.mMeta.mGroupId || messageId() != pulse.mMeta.mMsgId) {
std::cerr << "WireNotifyPostItem::setPost() - Wrong id, cannot set post";
std::cerr << std::endl;
return false;
}
mPulse = pulse;
if (doFill) {
fill();
std::cout<<"filling needs to be implemented"<<std::endl;
}
// updateItem();
return true;
}
//void WireNotifyPostItem::updateItem()
//{
// /* fill in */
//#ifdef DEBUG_ITEM
// std::cerr << "WireNotifyPostItem::updateItem()";
// std::cerr << std::endl;
//#endif
// int msec_rate = 10000;
// int downloadCount = 0;
// int downloadStartable = 0;
// int playCount = 0;
// int playStartable = 0;
// bool startable;
// bool loopAgain = false;
// /* Very slow Tick to check when all files are downloaded */
// std::list<SubFileItem *>::iterator it;
// for(it = mFileItems.begin(); it != mFileItems.end(); ++it)
// {
// SubFileItem *item = *it;
// if (item->isDownloadable(startable)) {
// ++downloadCount;
// if (startable) {
// ++downloadStartable;
// }
// }
// if (item->isPlayable(startable)) {
// ++playCount;
// if (startable) {
// ++playStartable;
// }
// }
// if (!item->done())
// {
// /* loop again */
// loopAgain = true;
// }
// }
// if (downloadCount) {
// ui->downloadButton->show();
// if (downloadStartable) {
// ui->downloadButton->setEnabled(true);
// } else {
// ui->downloadButton->setEnabled(false);
// }
// } else {
// ui->downloadButton->hide();
// }
// if (playCount) {
// /* one file is playable */
// ui->playButton->show();
// if (playStartable == 1) {
// ui->playButton->setEnabled(true);
// } else {
// ui->playButton->setEnabled(false);
// }
// } else {
// ui->playButton->hide();
// }
// if (loopAgain) {
// QTimer::singleShot( msec_rate, this, SLOT(updateItem(void)));
// }
// // HACK TO DISPLAY COMMENT BUTTON FOR NOW.
// //downloadButton->show();
// //downloadButton->setEnabled(true);
//}
QString WireNotifyPostItem::groupName()
{
return QString::fromUtf8(mGroupMeta.mGroupName.c_str());
}
void WireNotifyPostItem::doExpand(bool open)
{
if (mFeedHolder)
{
mFeedHolder->lockLayout(this, true);
}
if (open)
{
ui->expandFrame->show();
ui->expandButton->setIcon(FilesDefs::getIconFromQtResourcePath(QString(":/icons/png/up-arrow.png")));
ui->expandButton->setToolTip(tr("Hide"));
// readToggled(false);
}
else
{
ui->expandFrame->hide();
ui->expandButton->setIcon(FilesDefs::getIconFromQtResourcePath(QString(":/icons/png/down-arrow.png")));
ui->expandButton->setToolTip(tr("Expand"));
}
emit sizeChanged(this);
if (mFeedHolder)
{
mFeedHolder->lockLayout(this, false);
}
}
void WireNotifyPostItem::fill()
{
/* fill in */
// if (isLoading()) {
// /* Wait for all requests */
//return;
// }
#ifdef DEBUG_ITEM
std::cerr << "WireNotifyPostItem::fill()";
std::cerr << std::endl;
#endif
std::cout<<"*************************************************filling************************************"<<std::endl;
mInFill = true;
QString title;
QString msgText;
//if( !IS_GROUP_PUBLISHER(mGroupMeta.mSubscribeFlags) )
if (!mIsHome)
{
if (mCloseOnRead && !IS_MSG_NEW(mPulse.mMeta.mMsgStatus)) {
removeItem();
}
title = tr("Wire Feed") + ": ";
RetroShareLink link = RetroShareLink::createGxsGroupLink(RetroShareLink::TYPE_WIRE, mPulse.mMeta.mGroupId, groupName());
title += link.toHtml();
ui->titleLabel->setText(title);
msgText = tr("Pulse") + ": ";
RetroShareLink msgLink = RetroShareLink::createGxsMessageLink(RetroShareLink::TYPE_WIRE, mPulse.mMeta.mGroupId, mPulse.mMeta.mMsgId, messageName());
msgText += msgLink.toHtml();
ui->subjectLabel->setText(msgText);
if (IS_GROUP_SUBSCRIBED(mGroupMeta.mSubscribeFlags) || IS_GROUP_ADMIN(mGroupMeta.mSubscribeFlags))
{
ui->unsubscribeButton->setEnabled(true);
}
else
{
ui->unsubscribeButton->setEnabled(false);
}
ui->readButton->hide();
ui->newLabel->hide();
ui->copyLinkButton->hide();
if (IS_MSG_NEW(mPulse.mMeta.mMsgStatus)) {
mCloseOnRead = true;
}
}
else
{
/* subject */
ui->titleLabel->setText(QString::fromUtf8(mPulse.mMeta.mMsgName.c_str()));
/* disable buttons: deletion facility not enabled with cache services yet */
ui->clearButton->setEnabled(false);
ui->unsubscribeButton->setEnabled(false);
ui->clearButton->hide();
ui->readAndClearButton->hide();
ui->unsubscribeButton->hide();
ui->copyLinkButton->show();
if (IS_GROUP_SUBSCRIBED(mGroupMeta.mSubscribeFlags) || IS_GROUP_ADMIN(mGroupMeta.mSubscribeFlags))
{
ui->readButton->setVisible(true);
setReadStatus(IS_MSG_NEW(mPulse.mMeta.mMsgStatus), IS_MSG_UNREAD(mPulse.mMeta.mMsgStatus) || IS_MSG_NEW(mPulse.mMeta.mMsgStatus));
}
else
{
ui->readButton->setVisible(false);
ui->newLabel->setVisible(false);
}
mCloseOnRead = false;
}
// differences between Feed or Top of Comment.
if (mFeedHolder)
{
if (mIsHome) {
ui->commentButton->show();
} else if (ui->commentButton->icon().isNull()){
//Icon is seted if a comment received.
ui->commentButton->hide();
}
// THIS CODE IS doesn't compile - disabling until fixed.
#if 0
if (post.mComments)
{
QString commentText = QString::number(post.mComments);
commentText += " ";
commentText += tr("Comments");
ui->commentButton->setText(commentText);
}
else
{
ui->commentButton->setText(tr("Comment"));
}
#endif
}
else
{
ui->commentButton->hide();
}
// disable voting buttons - if they have already voted.
/*if (post.mMeta.mMsgStatus & GXS_SERV::GXS_MSG_STATUS_VOTE_MASK)
{
voteUpButton->setEnabled(false);
voteDownButton->setEnabled(false);
}*/
// {
// QTextDocument doc;
// doc.setHtml( QString::fromUtf8(mPulse.mMsg.c_str()) );
// ui->msgFrame->setVisible(doc.toPlainText().length() > 0);
// }
// if (wasExpanded() || ui->expandFrame->isVisible()) {
// fillExpandFrame();
// }
ui->pulseMessage->setText(QString::fromUtf8(mPulse.mPulseText.c_str()));
ui->datetimelabel->setText(DateTime::formatLongDateTime(mPulse.mRefPublishTs));
// if ( (mPulse.mAttachmentCount != 0) || (mPulse.mSize != 0) ) {
// ui->filelabel->setVisible(true);
// ui->filelabel->setText(QString("(%1 %2) %3").arg(mPulse.mAttachmentCount).arg( (mPulse.mAttachmentCount > 1)?tr("Files"):tr("File")).arg(misc::friendlyUnit(mPulse.mSize)));
// } else {
// ui->filelabel->setVisible(false);
// }
// if (mFileItems.empty() == false) {
// std::list<SubFileItem *>::iterator it;
// for(it = mFileItems.begin(); it != mFileItems.end(); ++it)
// {
// delete(*it);
// }
// mFileItems.clear();
// }
// std::list<RsGxsFile>::const_iterator it;
// for(it = mPulse.mFiles.begin(); it != mPulse.mFiles.end(); ++it)
// {
// /* add file */
// std::string path;
// SubFileItem *fi = new SubFileItem(it->mHash, it->mName, path, it->mSize, SFI_STATE_REMOTE | SFI_TYPE_CHANNEL, RsPeerId());
// mFileItems.push_back(fi);
// /* check if the file is a media file */
// if (!misc::isPreviewable(QFileInfo(QString::fromUtf8(it->mName.c_str())).suffix()))
// {
// fi->mediatype();
// /* check if the file is not a media file and change text */
// ui->playButton->setText(tr("Open"));
// ui->playButton->setToolTip(tr("Open File"));
// } else {
// ui->playButton->setText(tr("Play"));
// ui->playButton->setToolTip(tr("Play Media"));
// }
// QLayout *layout = ui->expandFrame->layout();
// layout->addWidget(fi);
// }
mInFill = false;
}
void WireNotifyPostItem::paintEvent(QPaintEvent *e)
{
/* This method employs a trick to trigger a deferred loading. The post and group is requested only
* when actually displayed on the screen. */
if(!mLoaded)
{
mLoaded = true ;
std::set<RsGxsMessageId> older_versions; // not so nice. We need to use std::set everywhere
for(auto& m:messageVersions())
older_versions.insert(m);
fill();
requestMessage();
requestComment();
}
GxsFeedItem::paintEvent(e) ;
}
void WireNotifyPostItem::setGroup(const RsWireGroup &group)
{
ui->groupName->setText(QString::fromStdString(group.mMeta.mGroupName));
ui->groupName->setToolTip(QString::fromStdString(group.mMeta.mGroupName) + "@" + QString::fromStdString(group.mMeta.mAuthorId.toStdString()));
if (group.mHeadshot.mData )
{
QPixmap pixmap;
if (GxsIdDetails::loadPixmapFromData(
group.mHeadshot.mData,
group.mHeadshot.mSize,
pixmap,GxsIdDetails::ORIGINAL))
{
ui->logoLabel->setPixmap(pixmap);
}
}
else
{
// default.
QPixmap pixmap = FilesDefs::getPixmapFromQtResourcePath(":/icons/wire.png");
ui->logoLabel->setPixmap(pixmap);
}
}
void WireNotifyPostItem::setReadStatus(bool isNew, bool isUnread)
{
if (isNew)
mPulse.mMeta.mMsgStatus |= GXS_SERV::GXS_MSG_STATUS_GUI_NEW;
else
mPulse.mMeta.mMsgStatus &= ~GXS_SERV::GXS_MSG_STATUS_GUI_NEW;
if (isUnread)
{
mPulse.mMeta.mMsgStatus |= GXS_SERV::GXS_MSG_STATUS_GUI_UNREAD;
whileBlocking(ui->readButton)->setChecked(true);
ui->readButton->setIcon(FilesDefs::getIconFromQtResourcePath(":/images/message-state-unread.png"));
}
else
{
mPulse.mMeta.mMsgStatus &= ~GXS_SERV::GXS_MSG_STATUS_GUI_UNREAD;
whileBlocking(ui->readButton)->setChecked(false);
ui->readButton->setIcon(FilesDefs::getIconFromQtResourcePath(":/images/message-state-read.png"));
}
//ui->newLabel->setVisible(isNew);
//ui->feedFrame->setProperty("new", isNew);
//ui->feedFrame->style()->unpolish(ui->feedFrame);
//ui->feedFrame->style()->polish( ui->feedFrame);
}
/*********** SPECIFIC FUNCTIONS ***********************/
void WireNotifyPostItem::readAndClearItem()
{
#ifdef DEBUG_ITEM
std::cerr << "WireNotifyPostItem::readAndClearItem()";
std::cerr << std::endl;
#endif
readToggled(false);
removeItem();
}
void WireNotifyPostItem::readToggled(bool /*checked*/)
{
if (mInFill) {
return;
}
mCloseOnRead = false;
RsGxsGrpMsgIdPair msgPair = std::make_pair(groupId(), messageId());
//rsWire->setMessageReadStatus(msgPair, isUnread());
//setReadStatus(false, checked); // Updated by events
}

View File

@ -0,0 +1,106 @@
/*******************************************************************************
* gui/feeds/WireNotifyPostItem.h *
* *
* Copyright (c) 2012, 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 WIRENOTIFYPOSTITEM_H
#define WIRENOTIFYPOSTITEM_H
#include <QMetaType>
#include <QWidget>
#include <retroshare/rswire.h>
#include "gui/gxs/GxsFeedItem.h"
#include "gui/gxs/GxsGroupFeedItem.h"
namespace Ui {
class WireNotifyPostItem;
}
class FeedHolder;
class SubFileItem;
class WireNotifyPostItem : public GxsFeedItem
{
Q_OBJECT
public:
// This one is used in NewFeed for incoming Wire posts. Only the group and msg ids are known at this point.
// It can be used for all apparences of wire posts. But in rder to merge comments from the previous versions of the post, the list of
// previous posts should be supplied. It's optional. If not supplied only the comments of the new version will be displayed.
WireNotifyPostItem(FeedHolder *feedHolder, uint32_t feedId, const RsGxsGroupId& groupId, const RsGxsMessageId &messageId, bool isHome, bool autoUpdate, const std::set<RsGxsMessageId>& older_versions = std::set<RsGxsMessageId>());
WireNotifyPostItem(FeedHolder *parent, uint32_t feedId, const RsGroupMetaData& group_meta, const RsGxsMessageId& messageId, bool isHome, bool autoUpdate, const std::set<RsGxsMessageId>& older_versions = std::set<RsGxsMessageId>());
//WireNotifyPostItem(FeedHolder *feedHolder, uint32_t feedId, const RsWireGroup &group, bool isHome, bool autoUpdate);
~WireNotifyPostItem();
uint64_t uniqueIdentifier() const override { return hash_64bits("WireNotifyPostItem " + messageId().toStdString()); }
bool setPost(const RsWirePulse& pulse, bool doFill = true);
void setGroup(const RsWireGroup &group);
bool isUnread() const ;
void setReadStatus(bool isNew, bool isUnread);
protected:
/* FeedItem */
virtual void doExpand(bool open);
virtual void expandFill(bool first);
virtual void paintEvent(QPaintEvent *) override;
/* GxsGroupFeedItem */
virtual QString groupName();
virtual void loadGroup() override;
virtual RetroShareLink::enumType getLinkType() { return RetroShareLink::TYPE_WIRE; }
/* GxsFeedItem */
// virtual QString messageName();
virtual void loadMessage();
virtual void loadComment();
virtual QString messageName() override;
private slots:
/* default stuff */
//void toggle() override;
void readAndClearItem();
void readToggled(bool checked);
private:
void setup();
void fill();
private:
bool mInFill;
bool mCloseOnRead;
bool mLoaded;
bool mLoadingMessage;
bool mLoadingGroup;
bool mLoadingComment;
RsGroupMetaData mGroupMeta;
RsWirePulse mPulse;
/** Qt Designer generated object */
Ui::WireNotifyPostItem *ui;
};
Q_DECLARE_METATYPE(RsWirePulse)
#endif // WIRENOTIFYPOSTITEM_H

View File

@ -0,0 +1,492 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>WireNotifyPostItem</class>
<widget class="QWidget" name="WireNotifyPostItem">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>822</width>
<height>175</height>
</rect>
</property>
<layout class="QGridLayout" name="WireNotifyPostItem_GL">
<property name="leftMargin">
<number>1</number>
</property>
<property name="topMargin">
<number>1</number>
</property>
<property name="rightMargin">
<number>1</number>
</property>
<property name="bottomMargin">
<number>1</number>
</property>
<property name="horizontalSpacing">
<number>6</number>
</property>
<property name="verticalSpacing">
<number>1</number>
</property>
<item row="0" column="0">
<widget class="QFrame" name="feedFrame">
<property name="sizePolicy">
<sizepolicy hsizetype="Expanding" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="autoFillBackground">
<bool>true</bool>
</property>
<property name="frameShape">
<enum>QFrame::Box</enum>
</property>
<property name="frameShadow">
<enum>QFrame::Sunken</enum>
</property>
<layout class="QVBoxLayout" name="feedFrame_VL">
<item>
<layout class="QHBoxLayout" name="mainTopHLayout">
<item>
<layout class="QVBoxLayout" name="logo_VLayout">
<item>
<widget class="QLabel" name="logoLabel">
<property name="minimumSize">
<size>
<width>70</width>
<height>70</height>
</size>
</property>
<property name="maximumSize">
<size>
<width>70</width>
<height>70</height>
</size>
</property>
<property name="text">
<string>TextLabel</string>
</property>
</widget>
</item>
<item>
<spacer name="verticalSpacer">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
</layout>
</item>
<item>
<layout class="QVBoxLayout" name="mainRTopVLayout">
<item>
<layout class="QHBoxLayout" name="tilteHLayout">
<item>
<widget class="QLabel" name="groupName">
<property name="font">
<font>
<pointsize>12</pointsize>
<weight>75</weight>
<italic>true</italic>
<bold>true</bold>
</font>
</property>
<property name="text">
<string>TextLabel</string>
</property>
</widget>
</item>
<item>
<widget class="QLabel" name="titleLabel">
<property name="sizePolicy">
<sizepolicy hsizetype="MinimumExpanding" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="font">
<font>
<pointsize>11</pointsize>
<weight>75</weight>
<italic>true</italic>
<bold>true</bold>
</font>
</property>
<property name="text">
<string notr="true">Wire Subject</string>
</property>
<property name="scaledContents">
<bool>false</bool>
</property>
<property name="openExternalLinks">
<bool>true</bool>
</property>
</widget>
</item>
<item>
<widget class="QLabel" name="subjectLabel">
<property name="font">
<font>
<pointsize>11</pointsize>
<weight>75</weight>
<italic>false</italic>
<bold>true</bold>
</font>
</property>
<property name="text">
<string notr="true">TextLabel</string>
</property>
<property name="openExternalLinks">
<bool>true</bool>
</property>
</widget>
</item>
<item>
<widget class="QLabel" name="datetimelabel">
<property name="font">
<font>
<weight>75</weight>
<bold>true</bold>
</font>
</property>
<property name="text">
<string notr="true">DateTime</string>
</property>
</widget>
</item>
<item>
<widget class="QLabel" name="newLabel">
<property name="text">
<string>New</string>
</property>
</widget>
</item>
</layout>
</item>
<item>
<widget class="QLabel" name="pulseMessage">
<property name="font">
<font>
<pointsize>11</pointsize>
</font>
</property>
<property name="text">
<string>TextLabel</string>
</property>
</widget>
</item>
<item>
<layout class="QHBoxLayout" name="buttonHLayout">
<property name="spacing">
<number>8</number>
</property>
<item>
<widget class="QPushButton" name="readButton">
<property name="maximumSize">
<size>
<width>24</width>
<height>16777215</height>
</size>
</property>
<property name="focusPolicy">
<enum>Qt::NoFocus</enum>
</property>
<property name="toolTip">
<string>Toggle Message Read Status</string>
</property>
<property name="checkable">
<bool>true</bool>
</property>
<property name="checked">
<bool>false</bool>
</property>
<property name="flat">
<bool>false</bool>
</property>
</widget>
</item>
<item>
<widget class="QLabel" name="scoreLabel">
<property name="font">
<font>
<weight>75</weight>
<bold>true</bold>
</font>
</property>
<property name="text">
<string>0</string>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="voteUpButton">
<property name="toolTip">
<string>I like this</string>
</property>
<property name="text">
<string/>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="voteDownButton">
<property name="toolTip">
<string>I dislike this</string>
</property>
<property name="text">
<string/>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="downloadButton">
<property name="focusPolicy">
<enum>Qt::NoFocus</enum>
</property>
<property name="text">
<string>Download</string>
</property>
<property name="autoExclusive">
<bool>false</bool>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="playButton">
<property name="focusPolicy">
<enum>Qt::NoFocus</enum>
</property>
<property name="text">
<string>Play</string>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="commentButton">
<property name="text">
<string>Comments</string>
</property>
</widget>
</item>
<item>
<widget class="QLabel" name="filelabel">
<property name="text">
<string notr="true">fileLabel</string>
</property>
<property name="alignment">
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="unsubscribeButton">
<property name="sizePolicy">
<sizepolicy hsizetype="Fixed" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="focusPolicy">
<enum>Qt::NoFocus</enum>
</property>
<property name="toolTip">
<string>Unsubscribe From Wire</string>
</property>
<property name="text">
<string>Unsubscribe</string>
</property>
</widget>
</item>
<item>
<spacer name="buttons_HSpacer">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
<item>
<widget class="QPushButton" name="copyLinkButton">
<property name="sizePolicy">
<sizepolicy hsizetype="Fixed" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="focusPolicy">
<enum>Qt::NoFocus</enum>
</property>
<property name="toolTip">
<string>Copy RetroShare Link</string>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="expandButton">
<property name="sizePolicy">
<sizepolicy hsizetype="Fixed" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="focusPolicy">
<enum>Qt::NoFocus</enum>
</property>
<property name="toolTip">
<string>Expand</string>
</property>
<property name="icon">
<iconset resource="../icons.qrc">
<normaloff>:/icons/png/down-arrow.png</normaloff>:/icons/png/down-arrow.png</iconset>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="readAndClearButton">
<property name="sizePolicy">
<sizepolicy hsizetype="Fixed" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="focusPolicy">
<enum>Qt::NoFocus</enum>
</property>
<property name="toolTip">
<string>Set as read and remove item</string>
</property>
<property name="icon">
<iconset resource="../icons.qrc">
<normaloff>:/icons/png/correct.png</normaloff>:/icons/png/correct.png</iconset>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="clearButton">
<property name="sizePolicy">
<sizepolicy hsizetype="Fixed" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="focusPolicy">
<enum>Qt::NoFocus</enum>
</property>
<property name="toolTip">
<string>Remove Item</string>
</property>
<property name="icon">
<iconset resource="../icons.qrc">
<normaloff>:/icons/png/exit2.png</normaloff>:/icons/png/exit2.png</iconset>
</property>
</widget>
</item>
</layout>
</item>
</layout>
</item>
</layout>
</item>
<item>
<widget class="QFrame" name="expandFrame">
<layout class="QVBoxLayout" name="expandFrame_VL">
<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="QFrame" name="msgFrame">
<property name="frameShape">
<enum>QFrame::Box</enum>
</property>
<property name="frameShadow">
<enum>QFrame::Sunken</enum>
</property>
<layout class="QVBoxLayout" name="msgFrame_VL">
<property name="leftMargin">
<number>5</number>
</property>
<property name="topMargin">
<number>5</number>
</property>
<property name="rightMargin">
<number>5</number>
</property>
<property name="bottomMargin">
<number>5</number>
</property>
<item>
<widget class="QLabel" name="msgLabel">
<property name="sizePolicy">
<sizepolicy hsizetype="MinimumExpanding" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="wordWrap">
<bool>true</bool>
</property>
<property name="margin">
<number>6</number>
</property>
<property name="indent">
<number>-1</number>
</property>
<property name="openExternalLinks">
<bool>true</bool>
</property>
<property name="textInteractionFlags">
<set>Qt::LinksAccessibleByMouse|Qt::TextSelectableByKeyboard|Qt::TextSelectableByMouse</set>
</property>
</widget>
</item>
</layout>
</widget>
</item>
</layout>
</widget>
</item>
<item>
<spacer name="feedFrame_VSpacer">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
<height>0</height>
</size>
</property>
</spacer>
</item>
</layout>
</widget>
</item>
</layout>
</widget>
<resources>
<include location="../icons.qrc"/>
</resources>
<connections/>
</ui>

View File

@ -71,7 +71,7 @@ static const uint32_t DELAY_BETWEEN_GROUP_STATISTICS_UPDATE = 120; // do not upd
/** Constructor */
GxsGroupFrameDialog::GxsGroupFrameDialog(RsGxsIfaceHelper *ifaceImpl,const QString& settings_name, QWidget *parent,bool allow_dist_sync)
: MainPage(parent),mSettingsName(settings_name)
: GxsStatisticsProvider(ifaceImpl,settings_name,parent)
{
/* Invoke the Qt Designer generated object setup routine */
ui = new Ui::GxsGroupFrameDialog();
@ -466,9 +466,7 @@ void GxsGroupFrameDialog::groupTreeCustomPopupMenu(QPoint point)
uint32_t current_store_time = checkDelay(mInterface->getStoragePeriod(mGroupId))/86400 ;
uint32_t current_sync_time = checkDelay(mInterface->getSyncPeriod(mGroupId))/86400 ;
#ifdef DEBUG_GROUPFRAMEDIALOG
std::cerr << "Got sync=" << current_sync_time << ". store=" << current_store_time << std::endl;
#endif
QAction *actnn = NULL;
QMenu *ctxMenu2 = contextMnu.addMenu(tr("Synchronise posts of last...")) ;
@ -1151,45 +1149,6 @@ void GxsGroupFrameDialog::updateGroupSummary()
/*********************** **** **** **** ***********************/
/*********************** **** **** **** ***********************/
void GxsGroupFrameDialog::updateGroupStatistics(const RsGxsGroupId &groupId)
{
mGroupStatisticsToUpdate.insert(groupId);
mShouldUpdateGroupStatistics = true;
}
void GxsGroupFrameDialog::updateGroupStatisticsReal(const RsGxsGroupId &groupId)
{
RsThread::async([this,groupId]()
{
GxsGroupStatistic stats;
if(! getGroupStatistics(groupId, stats))
{
std::cerr << __PRETTY_FUNCTION__ << " failed to collect group statistics for group " << groupId << std::endl;
return;
}
RsQThreadUtils::postToObject( [this,stats, groupId]()
{
/* Here it goes any code you want to be executed on the Qt Gui
* thread, for example to update the data model with new information
* after a blocking call to RetroShare API complete, note that
* Qt::QueuedConnection is important!
*/
QTreeWidgetItem *item = ui->groupTreeWidget->getItemFromId(QString::fromStdString(stats.mGrpId.toStdString()));
if (item)
ui->groupTreeWidget->setUnreadCount(item, mCountChildMsgs ? (stats.mNumThreadMsgsUnread + stats.mNumChildMsgsUnread) : stats.mNumThreadMsgsUnread);
mCachedGroupStats[groupId] = stats;
getUserNotify()->updateIcon();
}, this );
});
}
void GxsGroupFrameDialog::getServiceStatistics(GxsServiceStatistic& stats) const
{
if(!mCachedGroupStats.empty())
@ -1274,3 +1233,41 @@ void GxsGroupFrameDialog::distantRequestGroupData()
checkRequestGroup(group_id) ;
}
void GxsGroupFrameDialog::updateGroupStatistics(const RsGxsGroupId &groupId)
{
mGroupStatisticsToUpdate.insert(groupId);
mShouldUpdateGroupStatistics = true;
}
void GxsGroupFrameDialog::updateGroupStatisticsReal(const RsGxsGroupId &groupId)
{
RsThread::async([this,groupId]()
{
GxsGroupStatistic stats;
if(! getGroupStatistics(groupId, stats))
{
std::cerr << __PRETTY_FUNCTION__ << " failed to collect group statistics for group " << groupId << std::endl;
return;
}
RsQThreadUtils::postToObject( [this,stats, groupId]()
{
/* Here it goes any code you want to be executed on the Qt Gui
* thread, for example to update the data model with new information
* after a blocking call to RetroShare API complete, note that
* Qt::QueuedConnection is important!
*/
QTreeWidgetItem *item = ui->groupTreeWidget->getItemFromId(QString::fromStdString(stats.mGrpId.toStdString()));
if (item)
ui->groupTreeWidget->setUnreadCount(item, mCountChildMsgs ? (stats.mNumThreadMsgsUnread + stats.mNumChildMsgsUnread) : stats.mNumThreadMsgsUnread);
mCachedGroupStats[groupId] = stats;
getUserNotify()->updateIcon();
}, this );
});
}

View File

@ -27,6 +27,7 @@
#include "gui/RetroShareLink.h"
#include "gui/settings/rsharesettings.h"
#include "util/RsUserdata.h"
#include "GxsStatisticsProvider.h"
#include <inttypes.h>
@ -44,7 +45,7 @@ class UIStateHelper;
struct RsGxsCommentService;
class GxsCommentDialog;
class GxsGroupFrameDialog : public MainPage
class GxsGroupFrameDialog : public GxsStatisticsProvider
{
Q_OBJECT
@ -74,7 +75,7 @@ public:
GxsGroupFrameDialog(RsGxsIfaceHelper *ifaceImpl, const QString& settings_name,QWidget *parent = 0,bool allow_dist_sync=false);
virtual ~GxsGroupFrameDialog();
bool navigate(const RsGxsGroupId &groupId, const RsGxsMessageId& msgId);
virtual bool navigate(const RsGxsGroupId &groupId, const RsGxsMessageId& msgId) override;
virtual QString getHelpString() const =0;
@ -99,17 +100,13 @@ protected:
virtual void checkRequestGroup(const RsGxsGroupId& /* grpId */) {} // overload this one in order to retrieve full group data when the group is browsed
void updateMessageSummaryList(RsGxsGroupId groupId);
void updateGroupStatistics(const RsGxsGroupId &groupId);
virtual const std::set<TurtleRequestId> getSearchRequests() const { return std::set<TurtleRequestId>(); } // overload this for subclasses that provide distant search
// These two need to be overloaded by subsclasses, possibly calling the blocking API, since they are used asynchroneously.
// This needs to be overloaded by subsclasses, possibly calling the blocking API, since it is used asynchroneously.
virtual bool getGroupData(std::list<RsGxsGenericGroupData*>& groupInfo) =0;
virtual bool getGroupData(std::list<RsGxsGenericGroupData*>& groupInfo) =0;
virtual bool getGroupStatistics(const RsGxsGroupId& groupId,GxsGroupStatistic& stat) =0;
void updateGroupStatisticsReal(const RsGxsGroupId &groupId);
void updateMessageSummaryListReal(RsGxsGroupId groupId);
void updateMessageSummaryListReal(RsGxsGroupId groupId);
private slots:
void todo();
@ -154,7 +151,6 @@ private slots:
private:
virtual QString text(TextType type) = 0;
virtual QString icon(IconType type) = 0;
virtual QString settingsGroupName() = 0;
virtual TurtleRequestId distantSearch(const QString& search_string) ;
virtual GxsGroupDialog *createNewGroupDialog() = 0;
@ -186,16 +182,17 @@ private:
// subscribe/unsubscribe ack.
GxsMessageFrameWidget *messageWidget(const RsGxsGroupId &groupId);
virtual GxsMessageFrameWidget *messageWidget(const RsGxsGroupId &groupId) override;
GxsMessageFrameWidget *createMessageWidget(const RsGxsGroupId &groupId);
GxsCommentDialog *commentWidget(const RsGxsMessageId &msgId);
protected:
void updateSearchResults(const TurtleRequestId &sid);
void updateSearchResults(); // update all searches
bool mCountChildMsgs; // Count unread child messages?
virtual void updateGroupStatistics(const RsGxsGroupId &groupId) override;
virtual void updateGroupStatisticsReal(const RsGxsGroupId &groupId) override;
private:
GxsMessageFrameWidget *currentWidget() const;
@ -203,36 +200,26 @@ private:
bool mInitialized;
bool mInFill;
bool mDistSyncAllowed;
QString mSettingsName;
RsGxsGroupId mGroupId;
RsGxsIfaceHelper *mInterface;
QTreeWidgetItem *mYourGroups;
QTreeWidgetItem *mSubscribedGroups;
QTreeWidgetItem *mPopularGroups;
QTreeWidgetItem *mOtherGroups;
RsGxsGroupId mNavigatePendingGroupId;
RsGxsMessageId mNavigatePendingMsgId;
// Message summary list update
bool mShouldUpdateMessageSummaryList ; // whether we should update the counting for groups. This takes some CPU so we only do it when needed.
std::set<RsGxsGroupId> mGroupIdsSummaryToUpdate;
// GroupStatistics update
bool mShouldUpdateGroupStatistics;
rstime_t mLastGroupStatisticsUpdateTs;
std::set<RsGxsGroupId> mGroupStatisticsToUpdate;
UIStateHelper *mStateHelper;
/** Qt Designer generated object */
Ui::GxsGroupFrameDialog *ui;
std::map<RsGxsGroupId,RsGroupMetaData> mCachedGroupMetas;
std::map<RsGxsGroupId,GxsGroupStatistic> mCachedGroupStats;
std::map<uint32_t,QTreeWidgetItem*> mSearchGroupsItems ;
std::map<uint32_t,std::set<RsGxsGroupId> > mKnownGroups;

View File

@ -62,7 +62,7 @@
<string/>
</property>
<property name="pixmap">
<pixmap resource="../images.qrc">:/images/konversation.png</pixmap>
<pixmap>:/images/konversation.png</pixmap>
</property>
<property name="scaledContents">
<bool>true</bool>
@ -74,7 +74,6 @@
<property name="font">
<font>
<pointsize>12</pointsize>
<weight>75</weight>
<bold>true</bold>
</font>
</property>

View File

@ -95,7 +95,12 @@ void ReputationItemDelegate::paint(QPainter *painter, const QStyleOptionViewItem
const QRect r = option.rect;
// get pixmap
unsigned int icon_index = qvariant_cast<unsigned int>(index.data(Qt::DecorationRole));
auto v = index.data(Qt::DecorationRole);
if(!v.canConvert(QVariant::Int))
return;
unsigned int icon_index = qvariant_cast<unsigned int>(v);
if(icon_index > mMaxLevelToDisplay)
return ;

View File

@ -0,0 +1,62 @@
/*******************************************************************************
* retroshare-gui/src/gui/gxs/GxsStatisticsProvider.cpp *
* *
* Copyright 2012-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/>. *
* *
*******************************************************************************/
#include <QMenu>
#include <QMessageBox>
#include <QToolButton>
#include "GxsStatisticsProvider.h"
#include "gui/notifyqt.h"
#include "gui/common/UserNotify.h"
#include "util/qtthreadsutils.h"
#include "retroshare/rsgxsifacetypes.h"
#define TOKEN_TYPE_GROUP_SUMMARY 1
//#define TOKEN_TYPE_SUBSCRIBE_CHANGE 2
//#define TOKEN_TYPE_CURRENTGROUP 3
#define TOKEN_TYPE_STATISTICS 4
#define MAX_COMMENT_TITLE 32
static const uint32_t DELAY_BETWEEN_GROUP_STATISTICS_UPDATE = 120; // do not update group statistics more often than once every 2 mins
/*
* Transformation Notes:
* there are still a couple of things that the new groups differ from Old version.
* these will need to be addressed in the future.
* -> Child TS (for sorting) is not handled by GXS, this will probably have to be done in the GUI.
* -> Need to handle IDs properly.
* -> Much more to do.
*/
/** Constructor */
GxsStatisticsProvider::GxsStatisticsProvider(RsGxsIfaceHelper *ifaceImpl,const QString& settings_name, QWidget *parent,bool allow_dist_sync)
: MainPage(parent),mSettingsName(settings_name)
{
mDistSyncAllowed = allow_dist_sync;
mInterface = ifaceImpl;
mShouldUpdateGroupStatistics = false;
}
GxsStatisticsProvider::~GxsStatisticsProvider()
{
}

View File

@ -0,0 +1,78 @@
/*******************************************************************************
* retroshare-gui/src/gui/gxs/GxsStatisticsProvider.h *
* *
* Copyright 2012-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 GXSSTATISTICSPROVIDER_H
#define GXSSTATISTICSPROVIDER_H
#include <retroshare-gui/RsAutoUpdatePage.h>
#include "gui/gxs/RsGxsUpdateBroadcastPage.h"
#include "gui/RetroShareLink.h"
#include "gui/settings/rsharesettings.h"
#include "util/RsUserdata.h"
#include <inttypes.h>
#include "GxsIdTreeWidgetItem.h"
#include "GxsGroupDialog.h"
class GroupTreeWidget;
class GroupItemInfo;
class GxsMessageFrameWidget;
class UIStateHelper;
struct RsGxsCommentService;
class GxsCommentDialog;
class GxsStatisticsProvider : public MainPage
{
Q_OBJECT
public:
GxsStatisticsProvider(RsGxsIfaceHelper *ifaceImpl, const QString& settings_name,QWidget *parent = 0,bool allow_dist_sync=false);
virtual ~GxsStatisticsProvider();
virtual void getServiceStatistics(GxsServiceStatistic& stats) const = 0;
virtual bool navigate(const RsGxsGroupId &groupId, const RsGxsMessageId& msgId) = 0;
protected:
virtual void updateGroupStatistics(const RsGxsGroupId &groupId) = 0;
virtual void updateGroupStatisticsReal(const RsGxsGroupId &groupId) = 0;
// This needs to be overloaded by subsclasses, possibly calling the blocking API, since it is used asynchroneously.
virtual bool getGroupStatistics(const RsGxsGroupId& groupId,GxsGroupStatistic& stat) = 0;
virtual GxsMessageFrameWidget *messageWidget(const RsGxsGroupId &groupId) = 0;
QString mSettingsName;
RsGxsIfaceHelper *mInterface;
bool mDistSyncAllowed;
std::map<RsGxsGroupId,GxsGroupStatistic> mCachedGroupStats;
bool mShouldUpdateGroupStatistics;
std::set<RsGxsGroupId> mGroupStatisticsToUpdate;
bool mCountChildMsgs; // Count unread child messages?
RsGxsGroupId mNavigatePendingGroupId;
RsGxsMessageId mNavigatePendingMsgId;
UIStateHelper *mStateHelper;
private:
virtual QString settingsGroupName() = 0;
};
#endif // GXSSTATISTICSPROVIDER_H

View File

@ -26,7 +26,7 @@
#define TOKEN_TYPE_STATISTICS 1
GxsUserNotify::GxsUserNotify(RsGxsIfaceHelper */*ifaceImpl*/, const GxsGroupFrameDialog *g,QObject *parent) : UserNotify(parent), mGroupFrameDialog(g)
GxsUserNotify::GxsUserNotify(RsGxsIfaceHelper */*ifaceImpl*/, const GxsStatisticsProvider *g,QObject *parent) : UserNotify(parent), mGxsStatisticsProvider(g)
{
mNewThreadMessageCount = 0;
mNewChildMessageCount = 0;
@ -37,12 +37,13 @@ GxsUserNotify::~GxsUserNotify() {}
void GxsUserNotify::startUpdate()
{
std::cout<<"inside the gxs user notify startUpdate function"<<std::endl;
mNewThreadMessageCount = 0;
mNewChildMessageCount = 0;
GxsServiceStatistic stats;
mGroupFrameDialog->getServiceStatistics(stats);
mGxsStatisticsProvider->getServiceStatistics(stats);
/* Here it goes any code you want to be executed on the Qt Gui
* thread, for example to update the data model with new information

View File

@ -23,6 +23,7 @@
#include <QObject>
#include "gui/common/UserNotify.h"
#include "gui/gxs/GxsStatisticsProvider.h"
#include "gui/gxs/GxsGroupFrameDialog.h"
class RsGxsIfaceHelper;
@ -33,7 +34,7 @@ class GxsUserNotify : public UserNotify
Q_OBJECT
public:
GxsUserNotify(RsGxsIfaceHelper *ifaceImpl, const GxsGroupFrameDialog *g, QObject *parent = 0);
GxsUserNotify(RsGxsIfaceHelper *ifaceImpl, const GxsStatisticsProvider *g, QObject *parent = 0);
virtual ~GxsUserNotify();
protected:
@ -46,7 +47,8 @@ protected:
bool mCountChildMsgs; // Count new child messages?
private:
const GxsGroupFrameDialog *mGroupFrameDialog;
const GxsStatisticsProvider *mGxsStatisticsProvider;
unsigned int mNewThreadMessageCount;
unsigned int mNewChildMessageCount;

View File

@ -23,7 +23,7 @@
#include "GxsForumUserNotify.h"
#include "gui/MainWindow.h"
GxsForumUserNotify::GxsForumUserNotify(RsGxsIfaceHelper *ifaceImpl, const GxsGroupFrameDialog *g, QObject *parent) :
GxsForumUserNotify::GxsForumUserNotify(RsGxsIfaceHelper *ifaceImpl, const GxsStatisticsProvider *g, QObject *parent) :
GxsUserNotify(ifaceImpl, g, parent)
{
mCountChildMsgs = true;

View File

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

View File

@ -345,7 +345,8 @@
<file>icons/fullscreen-exit.png</file>
<file>icons/notification.png</file>
<file>icons/wire.png</file>
<file>icons/wire-circle.png</file>
<file>icons/png/wire-notify.png</file>
<file>icons/png/wire-circle.png</file>
<file>icons/folder-account.svg</file>
<file>icons/notification.svg</file>
<file>icons/groups/blue.svg</file>

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.5 KiB

View File

@ -167,6 +167,10 @@ NotifyPage::NotifyPage(QWidget * parent, Qt::WindowFlags flags)
connect(ui.notify_Security, SIGNAL(toggled(bool)), this, SLOT(updateNewsFeedFlags()));
connect(ui.notify_SecurityIp, SIGNAL(toggled(bool)), this, SLOT(updateNewsFeedFlags()));
#ifdef RS_USE_WIRE
connect(ui.notify_Wire, SIGNAL(toggled(bool)), this, SLOT(updateNewsFeedFlags()));
#endif
connect(ui.systray_ChatLobby, SIGNAL(toggled(bool)), this, SLOT(updateSystrayChatLobby()));
connect(ui.systray_GroupChat, SIGNAL(toggled(bool)), this, SLOT(updateSystrayGroupChat()));
@ -194,6 +198,12 @@ uint NotifyPage::getNewsFlags()
newsFlags |= RS_FEED_TYPE_FORUM;
if (ui.notify_Posted->isChecked())
newsFlags |= RS_FEED_TYPE_POSTED;
#ifdef RS_USE_WIRE
if (ui.notify_Wire->isChecked())
newsFlags |= RS_FEED_TYPE_WIRE;
#endif
#if 0
if (ui.notify_Blogs->isChecked())
newsFlags |= RS_FEED_TYPE_BLOG;
@ -311,6 +321,11 @@ void NotifyPage::load()
whileBlocking(ui.notify_Channels)->setChecked(newsflags & RS_FEED_TYPE_CHANNEL);
whileBlocking(ui.notify_Forums)->setChecked(newsflags & RS_FEED_TYPE_FORUM);
whileBlocking(ui.notify_Posted)->setChecked(newsflags & RS_FEED_TYPE_POSTED);
#ifdef RS_USE_WIRE
whileBlocking(ui.notify_Wire)->setChecked(newsflags & RS_FEED_TYPE_WIRE);
#endif
#if 0
whileBlocking(ui.notify_Blogs)->setChecked(newsflags & RS_FEED_TYPE_BLOG);
#endif

View File

@ -7,7 +7,7 @@
<x>0</x>
<y>0</y>
<width>569</width>
<height>512</height>
<height>526</height>
</rect>
</property>
<layout class="QVBoxLayout" name="NotifyPageVLayout">
@ -86,6 +86,13 @@
</property>
</widget>
</item>
<item>
<widget class="QCheckBox" name="notify_Wire">
<property name="text">
<string>Wire</string>
</property>
</widget>
</item>
<item>
<widget class="QCheckBox" name="notify_Messages">
<property name="text">
@ -471,6 +478,13 @@
</item>
</layout>
</widget>
<customwidgets>
<customwidget>
<class>RSComboBox</class>
<extends>QComboBox</extends>
<header>gui/common/RSComboBox.h</header>
</customwidget>
</customwidgets>
<tabstops>
<tabstop>notify_Peers</tabstop>
<tabstop>notify_Channels</tabstop>
@ -495,13 +509,6 @@
<tabstop>systray_ChatLobby</tabstop>
<tabstop>pushButtonDisableAll</tabstop>
</tabstops>
<customwidgets>
<customwidget>
<class>RSComboBox</class>
<extends>QComboBox</extends>
<header>gui/common/RSComboBox.h</header>
</customwidget>
</customwidgets>
<resources/>
<connections/>
</ui>

View File

@ -139,6 +139,10 @@ void RshareSettings::initSettings()
uint defNotify = (RS_POPUP_CONNECT | RS_POPUP_MSG);
uint defNewsFeed = (RS_FEED_TYPE_MSG | RS_FEED_TYPE_FILES | RS_FEED_TYPE_SECURITY | RS_FEED_TYPE_SECURITY_IP | RS_FEED_TYPE_CIRCLE | RS_FEED_TYPE_CHANNEL |RS_FEED_TYPE_FORUM | RS_FEED_TYPE_POSTED);
#ifdef RS_USE_WIRE
defNewsFeed = (defNewsFeed | RS_FEED_TYPE_WIRE);
#endif
setDefault(SETTING_NEWSFEED_FLAGS, defNewsFeed);
setDefault(SETTING_CHAT_FLAGS, defChat);
setDefault(SETTING_NOTIFY_FLAGS, defNotify);
@ -1109,6 +1113,12 @@ static QString groupFrameSettingsTypeToString(GroupFrameSettings::Type type)
return "Channel";
case GroupFrameSettings::Posted:
return "Posted";
#ifdef RS_USE_WIRE
case GroupFrameSettings::Wire:
return "Wire" ;
#endif
}
return "";

View File

@ -43,7 +43,7 @@ class QMainWindow;
class GroupFrameSettings
{
public:
enum Type { Nothing, Forum, Channel, Posted };
enum Type { Nothing, Forum, Channel, Posted, Wire };
public:
GroupFrameSettings()

View File

@ -116,7 +116,7 @@ CONFIG += gxscircles
## To enable unfinished services
#CONFIG += wikipoos
#CONFIG += gxsthewire
CONFIG += gxsthewire
#CONFIG += gxsphotoshare
DEFINES += RS_RELEASE_VERSION
@ -614,7 +614,8 @@ HEADERS += rshare.h \
gui/NetworkDialog/pgpid_item_model.h \
gui/NetworkDialog/pgpid_item_proxy.h \
gui/common/RsCollection.h \
util/retroshareWin32.h
util/retroshareWin32.h \
gui/common/NotifyWidget.h
# gui/ForumsDialog.h \
# gui/forums/ForumDetails.h \
# gui/forums/EditForumDetails.h \
@ -736,8 +737,8 @@ FORMS += gui/StartDialog.ui \
gui/statistics/BwCtrlWindow.ui \
gui/statistics/RttStatistics.ui \
gui/GetStartedDialog.ui \
util/RichTextEdit.ui
util/RichTextEdit.ui \
gui/common/NotifyWidget.ui
# gui/ForumsDialog.ui \
# gui/forums/CreateForum.ui \
@ -982,12 +983,13 @@ SOURCES += main.cpp \
gui/statistics/BwCtrlWindow.cpp \
gui/statistics/RttStatistics.cpp \
gui/statistics/BWGraph.cpp \
util/RsSyntaxHighlighter.cpp \
util/imageutil.cpp \
gui/NetworkDialog/pgpid_item_model.cpp \
gui/NetworkDialog/pgpid_item_proxy.cpp \
gui/common/RsCollection.cpp \
util/retroshareWin32.cpp
util/RsSyntaxHighlighter.cpp \
util/imageutil.cpp \
gui/NetworkDialog/pgpid_item_model.cpp \
gui/NetworkDialog/pgpid_item_proxy.cpp \
gui/common/RsCollection.cpp \
util/retroshareWin32.cpp \
gui/common/NotifyWidget.cpp
# gui/ForumsDialog.cpp \
# gui/forums/ForumDetails.cpp \
# gui/forums/EditForumDetails.cpp \
@ -1225,7 +1227,10 @@ gxsthewire {
gui/TheWire/PulseReply.h \
gui/TheWire/PulseReplySeperator.h \
gui/TheWire/PulseMessage.h \
gui/TheWire/CustomFrame.h \
gui/TheWire/CustomFrame.h \
gui/feeds/WireNotifyGroupItem.h \
gui/TheWire/WireUserNotify.h \
gui/feeds/WireNotifyPostItem.h \
FORMS += gui/TheWire/WireDialog.ui \
gui/TheWire/WireGroupItem.ui \
@ -1236,7 +1241,9 @@ gxsthewire {
gui/TheWire/PulseReply.ui \
gui/TheWire/PulseReplySeperator.ui \
gui/TheWire/PulseMessage.ui \
gui/feeds/WireNotifyGroupItem.ui \
gui/feeds/WireNotifyPostItem.ui \
SOURCES += gui/TheWire/WireDialog.cpp \
gui/TheWire/WireGroupItem.cpp \
gui/TheWire/WireGroupDialog.cpp \
@ -1248,7 +1255,10 @@ gxsthewire {
gui/TheWire/PulseReply.cpp \
gui/TheWire/PulseReplySeperator.cpp \
gui/TheWire/PulseMessage.cpp \
gui/TheWire/CustomFrame.cpp \
gui/TheWire/CustomFrame.cpp \
gui/feeds/WireNotifyGroupItem.cpp \
gui/TheWire/WireUserNotify.cpp \
gui/feeds/WireNotifyPostItem.cpp \
RESOURCES += gui/TheWire/TheWire_images.qrc
}
@ -1442,7 +1452,8 @@ gxsgui {
gui/gxs/GxsFeedWidget.h \
util/TokenQueue.h \
util/RsGxsUpdateBroadcast.h \
gui/gxs/GxsStatisticsProvider.h \
# gui/gxs/GxsMsgDialog.h \
FORMS += gui/gxs/GxsGroupDialog.ui \
@ -1475,7 +1486,8 @@ gxsgui {
gui/gxs/GxsFeedWidget.cpp \
util/TokenQueue.cpp \
util/RsGxsUpdateBroadcast.cpp \
gui/gxs/GxsStatisticsProvider.cpp \
# gui/gxs/GxsMsgDialog.cpp \