diff --git a/retroshare-gui/src/CMakeLists.txt b/retroshare-gui/src/CMakeLists.txt
index dc70d7c09..71dd6770f 100644
--- a/retroshare-gui/src/CMakeLists.txt
+++ b/retroshare-gui/src/CMakeLists.txt
@@ -999,7 +999,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 +1015,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 +1033,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 +1120,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 +1156,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)
diff --git a/retroshare-gui/src/gui/MainWindow.cpp b/retroshare-gui/src/gui/MainWindow.cpp
index cbbbff8b2..8c50230cf 100644
--- a/retroshare-gui/src/gui/MainWindow.cpp
+++ b/retroshare-gui/src/gui/MainWindow.cpp
@@ -463,7 +463,6 @@ void MainWindow::initStackedPage()
#endif
#ifdef RS_USE_WIRE
- WireDialog *wireDialog = NULL;
addPage(wireDialog = new WireDialog(ui->stackPages), grp, ¬ify);
#endif
@@ -1081,6 +1080,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;
}
@@ -1118,6 +1122,11 @@ void SetForegroundWindowInternal(HWND hWnd)
if (page == _instance->messagesDialog) {
return Messages;
}
+#ifdef RS_USE_WIRE
+ if (page == _instance->wireDialog) {
+ return Wire;
+ }
+#endif
#if 0
if (page == _instance->channelFeed) {
return Channels;
@@ -1157,6 +1166,7 @@ void SetForegroundWindowInternal(HWND hWnd)
return _instance->transfersDialog->searchDialog;
case Messages:
return _instance->messagesDialog;
+
case Channels:
return _instance->gxschannelDialog;
case Forums:
@@ -1165,6 +1175,10 @@ void SetForegroundWindowInternal(HWND hWnd)
return _instance->postedDialog;
case Home:
return _instance->homePage;
+#ifdef RS_USE_WIRE
+ case Wire:
+ return _instance->wireDialog;
+#endif
}
return NULL;
diff --git a/retroshare-gui/src/gui/MainWindow.h b/retroshare-gui/src/gui/MainWindow.h
index 0fbdcec46..bec08c5ed 100644
--- a/retroshare-gui/src/gui/MainWindow.h
+++ b/retroshare-gui/src/gui/MainWindow.h
@@ -71,7 +71,9 @@ class BandwidthGraph;
class MainPage;
class NewsFeed;
class UserNotify;
-
+#ifdef RS_USE_WIRE
+class WireDialog;
+#endif
#ifdef MESSENGER_WINDOW
class MessengerWindow;
#endif
@@ -107,7 +109,10 @@ public:
Posted = 11, /** Posted links */
People = 12, /** People page. */
Options = 13, /** People page. */
- Home = 14 /** Home page. */
+ Home = 14, /** Home page. */
+#ifdef RS_USE_WIRE
+ Wire = 15 /** Wire page. */
+#endif
};
@@ -167,7 +172,9 @@ public:
GxsChannelDialog *gxschannelDialog ;
GxsForumsDialog *gxsforumDialog ;
PostedDialog *postedDialog;
-
+#ifdef RS_USE_WIRE
+ WireDialog *wireDialog;
+#endif
// ForumsDialog *forumsDialog;
// ChannelFeed *channelFeed;
Idle *idle;
diff --git a/retroshare-gui/src/gui/NewsFeed.cpp b/retroshare-gui/src/gui/NewsFeed.cpp
index cf901d1e7..069548356 100644
--- a/retroshare-gui/src/gui/NewsFeed.cpp
+++ b/retroshare-gui/src/gui/NewsFeed.cpp
@@ -31,6 +31,7 @@
#include
#include
#include
+#include
#include "util/misc.h"
#include "util/qtthreadsutils.h"
@@ -49,6 +50,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"
@@ -83,7 +86,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 */
@@ -129,6 +133,9 @@ NewsFeed::NewsFeed(QWidget *parent) : MainPage(parent), ui(new Ui::NewsFeed),
" Channel and Board comments"
" New Mail messages"
" Private messages from your friends"
+#ifdef RS_USE_WIRE
+ " New Wire pulses and mentions"
+#endif
"
"
).arg(QString::number(2*H));
@@ -216,6 +223,10 @@ void NewsFeed::handleEvent_main_thread(std::shared_ptr event)
if(event->mType == RsEventType::MAIL_STATUS && (!!(flags & RsFeedTypeFlags::RS_FEED_TYPE_MSG)))
handleMailEvent(event);
+
+ if(event->mType == RsEventType::WIRE && (!!(flags & RsFeedTypeFlags::RS_FEED_TYPE_WIRE)))
+ handleWireEvent(event);
+
}
void NewsFeed::handleMailEvent(std::shared_ptr event)
@@ -503,6 +514,35 @@ void NewsFeed::handleSecurityEvent(std::shared_ptr event)
MessageComposer::addConnectAttemptMsg(e.mPgpId, e.mSslId, QString::fromStdString(det.name + "(" + det.location + ")"));
}
+void NewsFeed::handleWireEvent(std::shared_ptr event)
+{
+ const RsWireEvent *pe =
+ dynamic_cast(event.get());
+ if(!pe) return;
+
+ switch(pe->mWireEventCode)
+ {
+ case RsWireEventCode::FOLLOW_STATUS_CHANGED:
+ addFeedItem( new WireNotifyGroupItem(this, NEWSFEED_WIRELIST, pe->mWireGroupId, false, true, RsWireEventCode::FOLLOW_STATUS_CHANGED));
+ break;
+ case RsWireEventCode::NEW_WIRE:
+ addFeedItem( new WireNotifyGroupItem(this, NEWSFEED_WIRELIST, pe->mWireGroupId, false, true, RsWireEventCode::NEW_WIRE));
+ break;
+ case RsWireEventCode::NEW_POST:
+ addFeedItem( new WireNotifyPostItem(this, NEWSFEED_WIRELIST, pe->mWireGroupId, pe->mWireMsgId, true));
+ break;
+ case RsWireEventCode::WIRE_UPDATED:
+ addFeedItem( new WireNotifyGroupItem(this, NEWSFEED_WIRELIST, pe->mWireGroupId, false, true, RsWireEventCode::WIRE_UPDATED));
+ break;
+// case RsWireEventCode::POST_UPDATED:
+// addFeedItem( new WireNotifyGroupItem(this, NEWSFEED_WIRELIST, pe->mWireGroupId, false, true));
+// break;
+ default: break;
+ }
+ sendNewsFeedChanged();
+}
+
+
void NewsFeed::testFeeds(RsFeedTypeFlags /*notifyFlags*/)
{
RsFeedTypeFlags flags = RsFeedTypeFlags(Settings->getNewsFeedFlags());
diff --git a/retroshare-gui/src/gui/NewsFeed.h b/retroshare-gui/src/gui/NewsFeed.h
index fed1d41b5..876eef95a 100644
--- a/retroshare-gui/src/gui/NewsFeed.h
+++ b/retroshare-gui/src/gui/NewsFeed.h
@@ -49,6 +49,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 = 0x0010;
namespace Ui {
class NewsFeed;
@@ -107,6 +108,7 @@ private:
void handleMailEvent(std::shared_ptr event);
void handlePostedEvent(std::shared_ptr event);
void handleChannelEvent(std::shared_ptr event);
+ void handleWireEvent(std::shared_ptr event);
void addFeedItem(FeedItem *item);
void addFeedItemIfUnique(FeedItem *item, bool replace);
diff --git a/retroshare-gui/src/gui/Posted/PostedDialog.h b/retroshare-gui/src/gui/Posted/PostedDialog.h
index 9f764dff6..97fc8e648 100644
--- a/retroshare-gui/src/gui/Posted/PostedDialog.h
+++ b/retroshare-gui/src/gui/Posted/PostedDialog.h
@@ -54,7 +54,7 @@ private:
/* GxsGroupFrameDialog */
virtual QString text(TextType type) override;
virtual QString icon(IconType type) override;
- virtual QString settingsGroupName() override{ return "PostedDialog"; }
+ virtual QString settingsGroupName() { return "PostedDialog"; }
virtual GxsGroupDialog *createNewGroupDialog() override;
virtual GxsGroupDialog *createGroupDialog(GxsGroupDialog::Mode mode, RsGxsGroupId groupId) override;
virtual int shareKeyType() override;
diff --git a/retroshare-gui/src/gui/Posted/PostedUserNotify.cpp b/retroshare-gui/src/gui/Posted/PostedUserNotify.cpp
index ce6e49835..305bc6fac 100644
--- a/retroshare-gui/src/gui/Posted/PostedUserNotify.cpp
+++ b/retroshare-gui/src/gui/Posted/PostedUserNotify.cpp
@@ -23,7 +23,7 @@
#include "gui/MainWindow.h"
#include "gui/common/FilesDefs.h"
-PostedUserNotify::PostedUserNotify(RsGxsIfaceHelper *ifaceImpl, const GxsGroupFrameDialog *g, QObject *parent) :
+PostedUserNotify::PostedUserNotify(RsGxsIfaceHelper *ifaceImpl, const GxsStatisticsProvider *g, QObject *parent) :
GxsUserNotify(ifaceImpl, g, parent)
{
}
diff --git a/retroshare-gui/src/gui/Posted/PostedUserNotify.h b/retroshare-gui/src/gui/Posted/PostedUserNotify.h
index b7631bc37..26bb08e22 100644
--- a/retroshare-gui/src/gui/Posted/PostedUserNotify.h
+++ b/retroshare-gui/src/gui/Posted/PostedUserNotify.h
@@ -28,7 +28,7 @@ class PostedUserNotify : public GxsUserNotify
Q_OBJECT
public:
- explicit PostedUserNotify(RsGxsIfaceHelper *ifaceImpl, const GxsGroupFrameDialog *g, QObject *parent = 0);
+ explicit PostedUserNotify(RsGxsIfaceHelper *ifaceImpl, const GxsStatisticsProvider *g, QObject *parent = 0);
virtual bool hasSetting(QString *name, QString *group) override;
diff --git a/retroshare-gui/src/gui/RetroShareLink.cpp b/retroshare-gui/src/gui/RetroShareLink.cpp
index 5f9ba9339..66f9397aa 100644
--- a/retroshare-gui/src/gui/RetroShareLink.cpp
+++ b/retroshare-gui/src/gui/RetroShareLink.cpp
@@ -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"
@@ -74,7 +75,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"
@@ -92,6 +94,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"
@@ -289,6 +295,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);
@@ -468,7 +487,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;
@@ -793,6 +812,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;
@@ -886,6 +916,8 @@ QString RetroShareLink::title() const
return QString("Forum id: %1").arg(hash());
case TYPE_CHANNEL:
return QString("Channel id: %1").arg(hash());
+ case TYPE_WIRE:
+ return QString("Wire id: %1").arg(hash());
case TYPE_SEARCH:
return QString("Search files");
@@ -1073,6 +1105,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)
@@ -1307,6 +1350,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:
@@ -1355,6 +1399,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;
@@ -1381,9 +1431,9 @@ static void processList(const QStringList &list, const QString &textSingular, co
QList processedList;
QList 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
@@ -1475,6 +1525,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(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
@@ -1764,7 +1842,7 @@ static void processList(const QStringList &list, const QString &textSingular, co
}
else
{
- ChatDialog* chatDialog = ChatDialog::getChat(chatId, (RsChatFlags)Settings->getChatFlags());
+ ChatDialog* chatDialog = ChatDialog::getChat(chatId, (RsChatFlags)Settings->getChatFlags());
if (chatDialog) {
chatroomFound.append(link.name());
} else {
@@ -1861,6 +1939,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()) {
@@ -2044,3 +2132,4 @@ void RSLinkClipboard::parseText(QString text, QList &links,Retro
pos += rx.matchedLength();
}
}
+
diff --git a/retroshare-gui/src/gui/RetroShareLink.h b/retroshare-gui/src/gui/RetroShareLink.h
index 2225392fe..d3cdfda16 100644
--- a/retroshare-gui/src/gui/RetroShareLink.h
+++ b/retroshare-gui/src/gui/RetroShareLink.h
@@ -75,7 +75,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:
diff --git a/retroshare-gui/src/gui/TheWire/PulseAddDialog.cpp b/retroshare-gui/src/gui/TheWire/PulseAddDialog.cpp
index d3b666a7e..6e681329a 100644
--- a/retroshare-gui/src/gui/TheWire/PulseAddDialog.cpp
+++ b/retroshare-gui/src/gui/TheWire/PulseAddDialog.cpp
@@ -54,7 +54,7 @@ PulseAddDialog::PulseAddDialog(QWidget *parent)
ui.pushButton_remove->setIcon(FilesDefs::getIconFromQtResourcePath(QString(":/icons/mail/delete.png")));
ui.frame_picture->hide();
- ui.pushButton_picture->hide();
+ //ui.pushButton_picture->hide();
// initially hiding the browse button as the attach image button is not pressed
//ui.frame_PictureBrowse->hide();
@@ -135,29 +135,35 @@ void PulseAddDialog::cleanup()
std::cerr << "PulseAddDialog::cleanup() cleaning up old replyto";
std::cerr << std::endl;
QLayout *layout = ui.widget_replyto->layout();
- // completely delete layout and sublayouts
- QLayoutItem * item;
- while ((item = layout->takeAt(0)))
+ if (layout)
{
- if (QWidget *widget = item->widget())
+ // completely delete layout and sublayouts
+ QLayoutItem * item;
+ while ((item = layout->takeAt(0)))
{
- std::cerr << "PulseAddDialog::cleanup() removing widget";
- std::cerr << std::endl;
- widget->hide();
- delete widget;
- }
- else
- {
- std::cerr << "PulseAddDialog::cleanup() removing item";
- std::cerr << std::endl;
- delete item;
+ if (QWidget *widget = item->widget())
+ {
+ std::cerr << "PulseAddDialog::cleanup() removing widget";
+ std::cerr << std::endl;
+ widget->hide();
+ delete widget;
+ }
+ else
+ {
+ std::cerr << "PulseAddDialog::cleanup() removing item";
+ std::cerr << std::endl;
+ delete item;
+ }
}
+ // then finally
+ delete layout;
}
- // then finally
- delete layout;
mIsReply = false;
}
+ mReplyToPulse = RsWirePulse();
+ mReplyType = 0;
+
ui.frame_reply->setVisible(false);
ui.comboBox_sentiment->setCurrentIndex(0);
ui.lineEdit_URL->setText("");
@@ -260,6 +266,13 @@ void PulseAddDialog::setReplyTo(const RsGxsGroupId &grpId, const RsGxsMessageId
if(grpId.isNull()){
return;
}
+
+ mIsReply = true;
+ mReplyType = replyType;
+ ui.postButton->setEnabled(false);
+ ui.postButton->setText(tr("Loading..."));
+ show();
+
/* fetch in the background */
RsThread::async([this,grpId,msgId,replyType](){
@@ -269,12 +282,14 @@ void PulseAddDialog::setReplyTo(const RsGxsGroupId &grpId, const RsGxsMessageId
if(!rsWire->getWireGroup(grpId,pGroup))
{
std::cerr << __PRETTY_FUNCTION__ << "PulseAddDialog::setRplyTo() failed to fetch group id: " << grpId << std::endl;
+ RsQThreadUtils::postToObject([this]() { hide(); }, this);
return;
}
if (!rsWire->getWirePulse(grpId, msgId, pPulse))
{
std::cerr << "PulseAddDialog::setRplyTo() failed to fetch pulse of group id: " << grpId << std::endl;
+ RsQThreadUtils::postToObject([this]() { hide(); }, this);
return;
}
@@ -292,6 +307,7 @@ void PulseAddDialog::setReplyTo(const RsGxsGroupId &grpId, const RsGxsMessageId
* Qt::QueuedConnection is important!
*/
+ mGroup = *pGroup;
setReplyTo(*pPulse, pPulse, pGroup->mMeta.mGroupName, replyType);
}, this );
@@ -408,6 +424,21 @@ void PulseAddDialog::postReplyPulse()
std::cerr << "PulseAddDialog::postReplyPulse()";
std::cerr << std::endl;
+ if (mReplyToPulse.mMeta.mGroupId.isNull()) {
+ std::cerr << "PulseAddDialog::postReplyPulse() reply data not ready yet";
+ std::cerr << std::endl;
+ return;
+ }
+
+ if (mGroup.mMeta.mGroupId.isNull()) {
+ std::cerr << "PulseAddDialog::postReplyPulse() group not set";
+ std::cerr << std::endl;
+ return;
+ }
+
+ ui.postButton->setEnabled(false);
+ setCursor(Qt::WaitCursor);
+
RsWirePulseSPtr pPulse(new RsWirePulse());
pPulse->mSentiment = toPulseSentiment(ui.comboBox_sentiment->currentIndex());
@@ -440,6 +471,11 @@ void PulseAddDialog::postReplyPulse()
{
std::cerr << "PulseAddDialog::postReplyPulse() FAILED";
std::cerr << std::endl;
+ RsQThreadUtils::postToObject([this]()
+ {
+ setCursor(Qt::ArrowCursor);
+ ui.postButton->setEnabled(true);
+ }, this);
return;
}
@@ -451,6 +487,7 @@ void PulseAddDialog::postReplyPulse()
* Qt::QueuedConnection is important!
*/
+ setCursor(Qt::ArrowCursor);
clearDialog();
hide();
}, this );
diff --git a/retroshare-gui/src/gui/TheWire/PulseAddDialog.h b/retroshare-gui/src/gui/TheWire/PulseAddDialog.h
index b1e8eca47..8be4b6462 100644
--- a/retroshare-gui/src/gui/TheWire/PulseAddDialog.h
+++ b/retroshare-gui/src/gui/TheWire/PulseAddDialog.h
@@ -44,6 +44,7 @@ public:
void setReplyTo(const RsGxsGroupId &grpId, const RsGxsMessageId &msgId, uint32_t replyType);
void setGroup(const RsGxsGroupId &grpId);
+ void setGroup(RsWireGroup &group);
private slots:
void addURL();
@@ -57,8 +58,6 @@ private slots:
void removePictures();
private:
- // OLD VERSIONs, private now.
- void setGroup(RsWireGroup &group);
void setReplyTo(const RsWirePulse &pulse, RsWirePulseSPtr pPulse, std::string &groupName, uint32_t replyType);
void postOriginalPulse();
diff --git a/retroshare-gui/src/gui/TheWire/PulseReply.cpp b/retroshare-gui/src/gui/TheWire/PulseReply.cpp
index 5067b5f9b..0ad0c2419 100644
--- a/retroshare-gui/src/gui/TheWire/PulseReply.cpp
+++ b/retroshare-gui/src/gui/TheWire/PulseReply.cpp
@@ -57,6 +57,8 @@ void PulseReply::setup()
connect(toolButton_republish, SIGNAL(clicked()), this, SLOT(actionRepublish()));
connect(toolButton_like, SIGNAL(clicked()), this, SLOT(actionLike()));
connect(toolButton_view, SIGNAL(clicked()), this, SLOT(actionViewPulse()));
+ // hided it takes to much space
+ label_authorName->hide();
}
void PulseReply::showReplyLine(bool enable)
@@ -150,6 +152,26 @@ void PulseReply::setReferenceString(QString ref)
void PulseReply::mousePressEvent(QMouseEvent *event)
{
+ if (event->button() == Qt::LeftButton && IS_MSG_UNPROCESSED(mPulse->mMeta.mMsgStatus))
+ {
+ uint32_t token;
+ RsGxsGrpMsgIdPair msgPair = std::make_pair(mPulse->mMeta.mGroupId, mPulse->mMeta.mMsgId);
+ rsWire->setMessageReadStatus(token, msgPair, true);
+ }
+ 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);
+// }
+//}
+
diff --git a/retroshare-gui/src/gui/TheWire/PulseReply.ui b/retroshare-gui/src/gui/TheWire/PulseReply.ui
index 497d606de..774948559 100644
--- a/retroshare-gui/src/gui/TheWire/PulseReply.ui
+++ b/retroshare-gui/src/gui/TheWire/PulseReply.ui
@@ -511,7 +511,7 @@
Qt::Horizontal
- QSizePolicy::Fixed
+ QSizePolicy::Expanding
@@ -532,21 +532,11 @@
<html><head/><body><p><span style=" color:#2e3436;">· Apr 13 ·</span></p></body></html>
+
+ Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter
+
- -
-
-
- Qt::Horizontal
-
-
-
- 64
- 18
-
-
-
-
diff --git a/retroshare-gui/src/gui/TheWire/PulseTopLevel.cpp b/retroshare-gui/src/gui/TheWire/PulseTopLevel.cpp
index 0948e745b..a9270c729 100644
--- a/retroshare-gui/src/gui/TheWire/PulseTopLevel.cpp
+++ b/retroshare-gui/src/gui/TheWire/PulseTopLevel.cpp
@@ -56,6 +56,7 @@ void PulseTopLevel::setup()
connect(toolButton_republish, SIGNAL(clicked()), this, SLOT(actionRepublish()));
connect(toolButton_like, SIGNAL(clicked()), this, SLOT(actionLike()));
connect(toolButton_view, SIGNAL(clicked()), this, SLOT(actionViewPulse()));
+ connect(toolButton_copyLink, SIGNAL(clicked()), this, SLOT(actionCopyLink()));
}
void PulseTopLevel::setRefMessage(QString /*msg*/, uint32_t /*image_count*/)
diff --git a/retroshare-gui/src/gui/TheWire/PulseTopLevel.ui b/retroshare-gui/src/gui/TheWire/PulseTopLevel.ui
index 1959244d3..ec1c67373 100644
--- a/retroshare-gui/src/gui/TheWire/PulseTopLevel.ui
+++ b/retroshare-gui/src/gui/TheWire/PulseTopLevel.ui
@@ -731,6 +731,53 @@
+ -
+
+
-
+
+
+ Qt::Horizontal
+
+
+
+ 40
+ 20
+
+
+
+
+ -
+
+
+ COPY LINK
+
+
+
+ :/images/link.svg:/images/link.svg
+
+
+ Qt::ToolButtonTextBesideIcon
+
+
+ true
+
+
+
+ -
+
+
+ Qt::Horizontal
+
+
+
+ 40
+ 20
+
+
+
+
+
+
diff --git a/retroshare-gui/src/gui/TheWire/PulseViewGroup.cpp b/retroshare-gui/src/gui/TheWire/PulseViewGroup.cpp
index 475c74034..39739a6d9 100644
--- a/retroshare-gui/src/gui/TheWire/PulseViewGroup.cpp
+++ b/retroshare-gui/src/gui/TheWire/PulseViewGroup.cpp
@@ -28,6 +28,7 @@
#include "WireGroupDialog.h"
#include "gui/gxs/GxsIdDetails.h"
+#include "gui/RetroShareLink.h"
#include "gui/common/FilesDefs.h"
#include "util/DateTime.h"
@@ -50,6 +51,7 @@ void PulseViewGroup::setup()
{
if (mGroup) {
connect(followButton, SIGNAL(clicked()), this, SLOT(actionFollow()));
+ connect(toolButton_copyProfileLink, SIGNAL(clicked()), this, SLOT(actionCopyProfileLink()));
label_groupName->setText("@" + QString::fromStdString(mGroup->mMeta.mGroupName));
label_authorName->setText(BoldString(QString::fromStdString(mGroup->mMeta.mAuthorId.toStdString())));
@@ -116,8 +118,14 @@ void PulseViewGroup::setup()
label_extra_republishes->setText(BoldString(ToNumberUnits(republishes)));
label_extra_likes->setText(BoldString(ToNumberUnits(likes)));
- // hide follow.
- widget_actions->setVisible(false);
+ uint32_t following = mGroup->mGroupFollowing;
+ label_extra_following->setText(BoldString(ToNumberUnits(following)));
+
+ uint32_t followers = mGroup->mGroupFollowers;
+ label_extra_followers->setText(BoldString(ToNumberUnits(followers)));
+
+ // hide follow button but keep copy link visible.
+ followButton->setVisible(false);
}
else
{
@@ -133,14 +141,17 @@ void PulseViewGroup::setGroupSet()
{
if (mGroup->mMeta.mSubscribeFlags & GXS_SERV::GROUP_SUBSCRIBE_ADMIN) {
editButton->show();
+ toolButton_copyProfileLink->show();
}
else if (mGroup->mMeta.mSubscribeFlags & GXS_SERV::GROUP_SUBSCRIBE_SUBSCRIBED)
{
editButton->hide();
+ toolButton_copyProfileLink->show();
}
else
{
editButton->hide();
+ toolButton_copyProfileLink->show();
}
}
@@ -156,6 +167,29 @@ void PulseViewGroup::actionFollow()
}
}
+void PulseViewGroup::actionCopyProfileLink()
+{
+ std::cerr << "PulseViewGroup::actionCopyProfileLink()";
+ std::cerr << std::endl;
+
+ if (!mGroup) {
+ std::cerr << "PulseViewGroup::actionCopyProfileLink() GROUP invalid";
+ std::cerr << std::endl;
+ return;
+ }
+
+ RetroShareLink link = RetroShareLink::createGxsGroupLink(
+ RetroShareLink::TYPE_WIRE,
+ mGroup->mMeta.mGroupId,
+ QString::fromStdString(mGroup->mMeta.mGroupName));
+
+ if (link.valid()) {
+ QList urls;
+ urls.push_back(link);
+ RSLinkClipboard::copyLinks(urls);
+ }
+}
+
void PulseViewGroup::editProfile()
{
RsGxsGroupId groupId = mGroup->mMeta.mGroupId;
diff --git a/retroshare-gui/src/gui/TheWire/PulseViewGroup.h b/retroshare-gui/src/gui/TheWire/PulseViewGroup.h
index 62da0a228..4a4b4fd53 100644
--- a/retroshare-gui/src/gui/TheWire/PulseViewGroup.h
+++ b/retroshare-gui/src/gui/TheWire/PulseViewGroup.h
@@ -35,6 +35,7 @@ public:
private slots:
void actionFollow();
+ void actionCopyProfileLink();
void editProfile();
protected:
diff --git a/retroshare-gui/src/gui/TheWire/PulseViewGroup.ui b/retroshare-gui/src/gui/TheWire/PulseViewGroup.ui
index 79d9964f6..bb4075bd3 100644
--- a/retroshare-gui/src/gui/TheWire/PulseViewGroup.ui
+++ b/retroshare-gui/src/gui/TheWire/PulseViewGroup.ui
@@ -25,6 +25,18 @@
+
+ 0
+
+
+ 0
+
+
+ 0
+
+
+ 0
+
-
@@ -210,6 +222,27 @@
+ -
+
+
+
+ 10
+ 75
+ true
+
+
+
+ COPY LINK
+
+
+
+ :/images/link.svg:/images/link.svg
+
+
+ Qt::ToolButtonTextBesideIcon
+
+
+
@@ -481,6 +514,74 @@
+ -
+
+
-
+
+
+ <html><head/><body><p><span style=" font-weight:600;">0</span></p></body></html>
+
+
+
+ -
+
+
+ <html><head/><body><p><span style=" color:#2e3436;">Following</span></p></body></html>
+
+
+
+ -
+
+
+ Qt::Horizontal
+
+
+ QSizePolicy::Preferred
+
+
+
+ 40
+ 20
+
+
+
+
+
+
+ -
+
+
-
+
+
+ <html><head/><body><p><span style=" font-weight:600;">0</span></p></body></html>
+
+
+
+ -
+
+
+ <html><head/><body><p><span style=" color:#2e3436;">Followers</span></p></body></html>
+
+
+
+ -
+
+
+ Qt::Horizontal
+
+
+ QSizePolicy::Preferred
+
+
+
+ 40
+ 20
+
+
+
+
+
+
-
diff --git a/retroshare-gui/src/gui/TheWire/PulseViewItem.cpp b/retroshare-gui/src/gui/TheWire/PulseViewItem.cpp
index b46737bfd..1549d4008 100644
--- a/retroshare-gui/src/gui/TheWire/PulseViewItem.cpp
+++ b/retroshare-gui/src/gui/TheWire/PulseViewItem.cpp
@@ -25,8 +25,11 @@
#include "PulseViewItem.h"
+#include "retroshare/rsgxsflags.h"
+
#include "gui/gxs/GxsIdDetails.h"
#include "gui/common/FilesDefs.h"
+#include "gui/RetroShareLink.h"
#include "util/DateTime.h"
/** Constructor */
@@ -238,6 +241,35 @@ void PulseDataItem::actionRate()
}
}
+void PulseDataItem::actionCopyLink()
+{
+ std::cerr << "PulseDataItem::actionCopyLink()";
+ std::cerr << std::endl;
+
+ if (!mPulse) {
+ std::cerr << "PulseDataItem::actionCopyLink() PULSE invalid";
+ std::cerr << std::endl;
+ return;
+ }
+
+ std::string linkName = mPulse->mMeta.mMsgName;
+ if (linkName.empty()) {
+ linkName = mPulse->mPulseText.substr(0, 50);
+ }
+
+ RetroShareLink link = RetroShareLink::createGxsMessageLink(
+ RetroShareLink::TYPE_WIRE,
+ mPulse->mMeta.mGroupId,
+ mPulse->mMeta.mMsgId,
+ QString::fromStdString(linkName));
+
+ if (link.valid()) {
+ QList urls;
+ urls.push_back(link);
+ RSLinkClipboard::copyLinks(urls);
+ }
+}
+
void PulseDataItem::showPulse()
@@ -463,3 +495,13 @@ QString ToNumberUnits(uint32_t count)
return ans;
}
+void PulseDataItem::mousePressEvent(QMouseEvent *event)
+{
+ if (event->button() == Qt::LeftButton && IS_MSG_UNPROCESSED(mPulse->mMeta.mMsgStatus))
+ {
+ uint32_t token;
+ RsGxsGrpMsgIdPair msgPair = std::make_pair(mPulse->mMeta.mGroupId, mPulse->mMeta.mMsgId);
+ rsWire->setMessageReadStatus(token, msgPair, true);
+ }
+ QWidget::mousePressEvent(event);
+}
diff --git a/retroshare-gui/src/gui/TheWire/PulseViewItem.h b/retroshare-gui/src/gui/TheWire/PulseViewItem.h
index bee96f14b..b057656fe 100644
--- a/retroshare-gui/src/gui/TheWire/PulseViewItem.h
+++ b/retroshare-gui/src/gui/TheWire/PulseViewItem.h
@@ -114,6 +114,7 @@ private slots:
void actionFollow();
void actionFollowParent();
void actionRate();
+ void actionCopyLink();
// Action interfaces --------------------------
protected:
@@ -137,8 +138,11 @@ protected:
//
void setReference(uint32_t flags, RsGxsGroupId groupId, std::string groupName);
+ void mousePressEvent(QMouseEvent *event);
+
// DATA.
RsWirePulseSPtr mPulse;
+
};
diff --git a/retroshare-gui/src/gui/TheWire/WireDialog.cpp b/retroshare-gui/src/gui/TheWire/WireDialog.cpp
index 36a201a7f..10d0c6b4d 100644
--- a/retroshare-gui/src/gui/TheWire/WireDialog.cpp
+++ b/retroshare-gui/src/gui/TheWire/WireDialog.cpp
@@ -25,20 +25,27 @@
#include "gui/settings/rsharesettings.h"
#include "gui/gxs/GxsIdDetails.h"
#include "gui/common/FilesDefs.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
#include
+#include
#include
#include
#include
#include
+#include
+#include
/****************************************************************
* TheWire Display Widget.
@@ -54,19 +61,24 @@
// #define GROUP_SET_RECOMMENDED (5)
-#define WIRE_TOKEN_TYPE_SUBSCRIBE_CHANGE 1
-
-
/** Constructor */
WireDialog::WireDialog(QWidget *parent)
: MainPage(parent), mGroupSet(GROUP_SET_ALL)
- , mAddDialog(nullptr), mGroupSelected(nullptr), mWireQueue(nullptr)
- , mHistoryIndex(-1), mEventHandlerId(0)
+ , mAddDialog(nullptr), mGroupSelected(nullptr)
+ , mHistoryIndex(-1), mEventHandlerId(0), mSortAscending(false)
+ , mAccountSortType(0), mHideInactiveAccounts(false)
{
ui.setupUi(this);
+ mInterface = rsWire;
+ mSettingsName = "WireDialog";
+ mDistSyncAllowed = true;
+ mStateHelper = nullptr;
+
connect( ui.toolButton_createAccount, SIGNAL(clicked()), this, SLOT(createGroup()));
connect( ui.toolButton_createPulse, SIGNAL(clicked()), this, SLOT(createPulse()));
+ connect( ui.toolButton_home, SIGNAL(clicked()), this, SLOT(showHomeFeed()));
+ connect( ui.lineEdit_searchUsers, SIGNAL(textChanged(const QString&)), this, SLOT(filterUsers(const QString&)));
connect(ui.comboBox_groupSet, SIGNAL(currentIndexChanged(int)), this, SLOT(selectGroupSet(int)));
connect(ui.comboBox_filterTime, SIGNAL(currentIndexChanged(int)), this, SLOT(selectFilterTime(int)));
@@ -76,12 +88,48 @@ WireDialog::WireDialog(QWidget *parent)
ui.toolButton_back->setEnabled(false);
ui.toolButton_forward->setEnabled(false);
+ // Setup filter menu
+ QMenu *filterMenu = new QMenu(this);
+ QAction *sortAscAction = filterMenu->addAction(tr("Sort by Ascending"));
+ sortAscAction->setCheckable(true);
+ sortAscAction->setChecked(mSortAscending);
+ connect(sortAscAction, SIGNAL(triggered()), this, SLOT(toggleSortAscending()));
+
+ ui.toolButton_filter->setMenu(filterMenu);
+
+ // Setup account filter menu
+ QMenu *accountMenu = new QMenu(this);
+ QActionGroup *sortGroup = new QActionGroup(this);
+
+ QAction *sortByName = accountMenu->addAction(tr("Sort by Name"));
+ sortByName->setCheckable(true);
+ sortByName->setChecked(true);
+ sortByName->setData(0);
+ sortGroup->addAction(sortByName);
+
+ QAction *sortByActivity = accountMenu->addAction(tr("Sort by Activity"));
+ sortByActivity->setCheckable(true);
+ sortByActivity->setData(1);
+ sortGroup->addAction(sortByActivity);
+
+ accountMenu->addSeparator();
+
+ QAction *hideInactiveAction = accountMenu->addAction(tr("Hide inactive (>30d)"));
+ hideInactiveAction->setCheckable(true);
+ hideInactiveAction->setChecked(false);
+
+ connect(sortGroup, SIGNAL(triggered(QAction*)), this, SLOT(sortAccountsChanged(QAction*)));
+ connect(hideInactiveAction, SIGNAL(toggled(bool)), this, SLOT(hideInactiveChanged(bool)));
+
+ ui.toolButton_accountFilter->setMenu(accountMenu);
+
QTimer *timer = new QTimer(this);
timer->connect(timer, SIGNAL(timeout()), this, SLOT(checkUpdate()));
timer->start(1000);
- /* setup TokenQueue */
- mWireQueue = new TokenQueue(rsWire->getTokenService(), this);
+ mCountChildMsgs = false;
+ mShouldUpdateGroupStatistics = false;
+ mDistSyncAllowed = true;
requestGroupData();
@@ -110,27 +158,33 @@ void WireDialog::handleEvent_main_thread(std::shared_ptr event)
#endif
// The following switch statements refresh the wire feed whenever there is a new event
+
switch(e->mWireEventCode)
{
+
+ case RsWireEventCode::READ_STATUS_CHANGED:
+ updateGroupStatisticsReal(e->mWireGroupId); // update the list immediately
+ return;
+
+ case RsWireEventCode::STATISTICS_CHANGED:
case RsWireEventCode::NEW_POST:
-
case RsWireEventCode::NEW_REPLY:
-
case RsWireEventCode::NEW_LIKE:
-
case RsWireEventCode::NEW_REPUBLISH:
-
case RsWireEventCode::POST_UPDATED:
-
- case RsWireEventCode::NEW_WIRE:
-
case RsWireEventCode::FOLLOW_STATUS_CHANGED:
+ case RsWireEventCode::NEW_WIRE:
+ updateGroupStatisticsReal(e->mWireGroupId);
+ break;
default:
- refreshGroups();
+#ifdef GXSWIRE_DEBUG
+ RsDbg() << " Unknown event occured: "<< e->mWireEventCode << std::endl;
+#endif
break;
}
+ refreshGroups();
}
}
@@ -140,12 +194,148 @@ 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(
+// "
Boards
"
+// "The wire service is a day to day social network service.
"
+// "The Wire service allows you to share your pulses, republish someone else's pulses, like "
+// "a pulse.
"
+// "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.
"
+// "Wire posts are kept for %2 days, and sync-ed over the last %3 days, unless you change this.
"
+// ).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 "Open points:"
+//// "- Subreddits/tag to posts support"
+//// "
- Picture Support"
+//// "
- Navigate channel link"
+//// "
";
+
+// 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& groupInfo)
+//{
+// std::vector groups;
+
+// // request all group infos at once
+
+// if(! rsWire->getGroups(std::list(),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");
@@ -177,6 +367,33 @@ void WireDialog::refreshGroups()
requestGroupData();
}
+void WireDialog::showHomeFeed()
+{
+ mGroupSet = GROUP_SET_SUBSCRIBED;
+ ui.comboBox_groupSet->setCurrentIndex(GROUP_SET_SUBSCRIBED);
+ mGroupSelected = nullptr;
+ showGroups();
+}
+
+void WireDialog::filterUsers(const QString &text)
+{
+ QLayout *alayout = ui.groupsWidget->layout();
+ QString filterText = text.toLower();
+
+ for (int i = 0; i < alayout->count(); ++i)
+ {
+ QLayoutItem *item = alayout->itemAt(i);
+ QWidget *widget = item->widget();
+ WireGroupItem *groupItem = dynamic_cast(widget);
+
+ if (groupItem)
+ {
+ bool visible = filterText.isEmpty() || groupItem->matchesFilter(filterText);
+ groupItem->setVisible(visible);
+ }
+ }
+}
+
void WireDialog::addGroup(QWidget *item)
{
QLayout *alayout = ui.groupsWidget->layout();
@@ -197,7 +414,7 @@ bool WireDialog::setupPulseAddDialog()
mAddDialog->cleanup();
int idx = ui.groupChooser->currentIndex();
- if (idx < 0) {
+ if (idx < 0 || idx >= (int)mOwnGroups.size()) {
std::cerr << "WireDialog::setupPulseAddDialog() ERROR GETTING AuthorId!";
std::cerr << std::endl;
@@ -205,9 +422,8 @@ bool WireDialog::setupPulseAddDialog()
return false;
}
- // publishing group.
RsWireGroup group = mOwnGroups[idx];
- mAddDialog->setGroup(group.mMeta.mGroupId);
+ mAddDialog->setGroup(group);
return true;
}
@@ -217,14 +433,12 @@ void WireDialog::subscribe(RsGxsGroupId &groupId)
{
uint32_t token;
rsWire->subscribeToGroup(token, groupId, true);
- mWireQueue->queueRequest(token, TOKENREQ_GROUPINFO, RS_TOKREQ_ANSTYPE_ACK, WIRE_TOKEN_TYPE_SUBSCRIBE_CHANGE);
}
void WireDialog::unsubscribe(RsGxsGroupId &groupId)
{
uint32_t token;
rsWire->subscribeToGroup(token, groupId, false);
- mWireQueue->queueRequest(token, TOKENREQ_GROUPINFO, RS_TOKREQ_ANSTYPE_ACK, WIRE_TOKEN_TYPE_SUBSCRIBE_CHANGE);
}
void WireDialog::notifyGroupSelection(WireGroupItem *item)
@@ -388,6 +602,12 @@ void WireDialog::selectGroupSet(int index)
if (mGroupSet < 0) {
mGroupSet = GROUP_SET_ALL;
}
+
+ // show follow label and account filter only when All is selected
+ bool showFollow = (mGroupSet == GROUP_SET_ALL);
+ ui.followLabel->setVisible(showFollow);
+ ui.toolButton_accountFilter->setVisible(showFollow);
+
showGroups();
}
@@ -399,9 +619,26 @@ void WireDialog::selectFilterTime(int index)
showSelectedGroups();
}
+void WireDialog::toggleSortAscending()
+{
+ mSortAscending = !mSortAscending;
+ showSelectedGroups();
+}
+
+void WireDialog::sortAccountsChanged(QAction *action)
+{
+ mAccountSortType = action->data().toInt();
+ showGroups();
+}
+
+void WireDialog::hideInactiveChanged(bool checked)
+{
+ mHideInactiveAccounts = checked;
+ showGroups();
+}
+
void WireDialog::showSelectedGroups()
{
- ui.comboBox_filterTime->setEnabled(false);
if (mGroupSelected)
{
// request data.
@@ -419,12 +656,15 @@ void WireDialog::showSelectedGroups()
void WireDialog::showGroups()
{
- ui.comboBox_filterTime->setEnabled(false);
deleteGroups();
std::list allGroupIds;
+ std::vector groupsToShow;
+
+ // Collect groups that match the current filter
+ rstime_t now = time(nullptr);
+ rstime_t thirtyDaysAgo = now - (30 * 24 * 60 * 60);
- /* depends on the comboBox */
for (auto &it : mAllGroups)
{
bool add = (mGroupSet == GROUP_SET_ALL);
@@ -444,13 +684,39 @@ void WireDialog::showGroups()
}
}
- if (add) {
- addGroup(it.second);
- // request data.
- std::list grpIds;
- grpIds.push_back(it.second.mMeta.mGroupId);
- allGroupIds.push_back(it.second.mMeta.mGroupId);
+ // Filter inactive accounts if checkbox is checked
+ if (add && mHideInactiveAccounts) {
+ rstime_t lastPost = it.second.mMeta.mLastPost;
+ if (lastPost == 0 || lastPost < thirtyDaysAgo) {
+ add = false;
+ }
}
+
+ if (add) {
+ groupsToShow.push_back(it.second);
+ }
+ }
+
+ // Sort groups based on selection
+ if (mAccountSortType == 0) {
+ // Sort by name (alphabetical)
+ std::sort(groupsToShow.begin(), groupsToShow.end(),
+ [](const RsWireGroup &a, const RsWireGroup &b) {
+ return QString::fromStdString(a.mMeta.mGroupName).toLower() <
+ QString::fromStdString(b.mMeta.mGroupName).toLower();
+ });
+ } else {
+ // Sort by activity (most recent first)
+ std::sort(groupsToShow.begin(), groupsToShow.end(),
+ [](const RsWireGroup &a, const RsWireGroup &b) {
+ return a.mMeta.mLastPost > b.mMeta.mLastPost;
+ });
+ }
+
+ // Add sorted groups to UI
+ for (auto &group : groupsToShow) {
+ addGroup(group);
+ allGroupIds.push_back(group.mMeta.mGroupId);
}
requestGroupsPulses(allGroupIds);
@@ -464,24 +730,21 @@ void WireDialog::requestGroupData()
std::cerr << "WireDialog::requestGroupData()";
std::cerr << std::endl;
- RsTokReqOptions opts;
- uint32_t token;
- opts.mReqType = GXS_REQUEST_TYPE_GROUP_DATA;
- mWireQueue->requestGroupInfo(token, RS_TOKREQ_ANSTYPE_DATA, opts, 0);
-}
+ std::vector groups;
+ rsWire->getGroups({}, groups);
-bool WireDialog::loadGroupData(const uint32_t &token)
-{
- std::cerr << "WireDialog::loadGroupData()";
- std::cerr << std::endl;
+ updateGroups(groups);
+ showGroups();
- std::vector groups;
- rsWire->getGroupData(token, groups);
-
- // save list of groups.
- updateGroups(groups);
- showGroups();
- return true;
+ if (!mNavigatePendingGroupId.isNull()) {
+ if (!mNavigatePendingMsgId.isNull()) {
+ requestPulseFocus(mNavigatePendingGroupId, mNavigatePendingMsgId);
+ } else {
+ requestGroupFocus(mNavigatePendingGroupId);
+ }
+ mNavigatePendingGroupId.clear();
+ mNavigatePendingMsgId.clear();
+ }
}
rstime_t WireDialog::getFilterTimestamp()
@@ -507,60 +770,6 @@ rstime_t WireDialog::getFilterTimestamp()
return filterTimestamp;
}
-void WireDialog::acknowledgeGroup(const uint32_t &token, const uint32_t &userType)
-{
- /* reload groups */
- std::cerr << "WireDialog::acknowledgeGroup(usertype: " << userType << ")";
- std::cerr << std::endl;
-
- RsGxsGroupId grpId;
- rsWire->acknowledgeGrp(token, grpId);
-
- refreshGroups();
-}
-
-
-/**************************** Request / Response Filling of Data ************************/
-
-void WireDialog::loadRequest(const TokenQueue *queue, const TokenRequest &req)
-{
- std::cerr << "WireDialog::loadRequest()";
- std::cerr << std::endl;
-
- if (queue == mWireQueue)
- {
- /* now switch on req */
- switch(req.mType)
- {
- case TOKENREQ_GROUPINFO:
- switch(req.mAnsType)
- {
- case RS_TOKREQ_ANSTYPE_DATA:
- loadGroupData(req.mToken);
- break;
- case RS_TOKREQ_ANSTYPE_ACK:
- acknowledgeGroup(req.mToken, req.mUserType);
- break;
- default:
- std::cerr << "WireDialog::loadRequest() ERROR: GROUP: INVALID ANS TYPE";
- std::cerr << std::endl;
- break;
- }
- break;
- default:
- std::cerr << "WireDialog::loadRequest() ERROR: INVALID TYPE";
- std::cerr << std::endl;
- break;
- }
- }
-}
-
-
-/**************************** Request / Response Filling of Data ************************/
-
-
-
-
/****************************************************************************************/
// TWITTER VIEW.
@@ -598,39 +807,36 @@ void WireDialog::loadRequest(const TokenQueue *queue, const TokenRequest &req)
void WireDialog::PVHreply(const RsGxsGroupId &groupId, const RsGxsMessageId &msgId)
{
std::cerr << "WireDialog::PVHreply() GroupId: " << groupId;
- std::cerr << "MsgId: " << msgId;
+ std::cerr << " MsgId: " << msgId;
std::cerr << std::endl;
if (setupPulseAddDialog())
{
mAddDialog->setReplyTo(groupId, msgId, WIRE_PULSE_TYPE_REPLY);
- mAddDialog->show();
}
}
void WireDialog::PVHrepublish(const RsGxsGroupId &groupId, const RsGxsMessageId &msgId)
{
std::cerr << "WireDialog::PVHrepublish() GroupId: " << groupId;
- std::cerr << "MsgId: " << msgId;
+ std::cerr << " MsgId: " << msgId;
std::cerr << std::endl;
if (setupPulseAddDialog())
{
mAddDialog->setReplyTo(groupId, msgId, WIRE_PULSE_TYPE_REPUBLISH);
- mAddDialog->show();
}
}
void WireDialog::PVHlike(const RsGxsGroupId &groupId, const RsGxsMessageId &msgId)
{
std::cerr << "WireDialog::PVHlike() GroupId: " << groupId;
- std::cerr << "MsgId: " << msgId;
+ std::cerr << " MsgId: " << msgId;
std::cerr << std::endl;
if (setupPulseAddDialog())
{
mAddDialog->setReplyTo(groupId, msgId, WIRE_PULSE_TYPE_LIKE);
- mAddDialog->show();
}
}
@@ -675,7 +881,6 @@ void WireDialog::PVHfollow(const RsGxsGroupId &groupId)
uint32_t token;
rsWire->subscribeToGroup(token, groupId, true);
- mWireQueue->queueRequest(token, TOKENREQ_GROUPINFO, RS_TOKREQ_ANSTYPE_ACK, WIRE_TOKEN_TYPE_SUBSCRIBE_CHANGE);
}
void WireDialog::PVHrate(const RsGxsId &authorId)
@@ -689,7 +894,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 +1050,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 +1079,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 +1151,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 +1181,8 @@ void WireDialog::showGroupFocus(const RsGxsGroupId groupId)
void WireDialog::postGroupFocus(RsWireGroupSPtr group, std::list pulses)
{
+ clearTwitterView();
+
std::cerr << "WireDialog::postGroupFocus()";
std::cerr << std::endl;
@@ -1027,7 +1230,6 @@ void WireDialog::requestGroupsPulses(const std::list& groupIds)
void WireDialog::showGroupsPulses(const std::list& groupIds)
{
clearTwitterView();
- std::cerr << "WireDialog::showGroupPulses()" << std::endl;
// background thread for loading.
RsThread::async([this, groupIds]()
@@ -1054,6 +1256,7 @@ void WireDialog::showGroupsPulses(const std::list& groupIds)
void WireDialog::postGroupsPulses(std::list pulses)
{
+ clearTwitterView();
std::cerr << "WireDialog::postGroupsPulses()";
std::cerr << std::endl;
@@ -1077,3 +1280,166 @@ void WireDialog::postGroupsPulses(std::list pulses)
}
}
+
+void WireDialog::getServiceStatistics(GxsServiceStatistic& stats) const
+{
+ 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 ;
+ }
+
+ // 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 groups not loaded yet, save for later
+ if (mAllGroups.empty()) {
+ mNavigatePendingGroupId = groupId;
+ mNavigatePendingMsgId = msgId;
+ return true;
+ }
+
+ if (!msgId.isNull()) {
+ requestPulseFocus(groupId, msgId);
+ } else {
+ requestGroupFocus(groupId);
+ }
+
+ return true;
+}
+
+GxsMessageFrameWidget *WireDialog::messageWidget(const RsGxsGroupId &groupId)
+{
+// int tabCount = ui.tabWidget->count();
+
+// for (int index = 0; index < tabCount; ++index)
+// {
+// GxsMessageFrameWidget *childWidget = dynamic_cast(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);
+// }
+//}
diff --git a/retroshare-gui/src/gui/TheWire/WireDialog.h b/retroshare-gui/src/gui/TheWire/WireDialog.h
index fcd33ad37..d3ec5347d 100644
--- a/retroshare-gui/src/gui/TheWire/WireDialog.h
+++ b/retroshare-gui/src/gui/TheWire/WireDialog.h
@@ -34,9 +34,11 @@
#include "gui/TheWire/PulseViewItem.h"
#include "gui/TheWire/PulseTopLevel.h"
#include "gui/TheWire/PulseReply.h"
+#include "gui/gxs/GxsStatisticsProvider.h"
-
-#include "util/TokenQueue.h"
+class UIStateHelper;
+class GxsMessageFrameWidget;
+class RsGxsIfaceHelper;
#define IMAGE_WIRE ":/icons/wire.png"
@@ -68,7 +70,7 @@ public:
};
//---------------------------------------------------------
-class WireDialog : public MainPage, public TokenResponse, public WireGroupHolder, public PulseViewHolder
+class WireDialog : public MainPage, public GxsStatisticsProvider, public WireGroupHolder, public PulseViewHolder
{
Q_OBJECT
@@ -118,15 +120,35 @@ public:
void showGroupsPulses(const std::list& groupIds);
void postGroupsPulses(std::list pulses);
+ void getServiceStatistics(GxsServiceStatistic& stats) const override;
+
+ virtual bool navigate(const RsGxsGroupId &groupId, const RsGxsMessageId& msgId);
+
+protected:
+
+ bool getGroupStatistics(const RsGxsGroupId& groupId,GxsGroupStatistic& stat);
+ UserNotify *createUserNotify(QObject *parent) override;
+ virtual void updateGroupStatistics(const RsGxsGroupId &groupId);
+ virtual void updateGroupStatisticsReal(const RsGxsGroupId &groupId);
+
private slots:
void createGroup();
void createPulse();
+ void showHomeFeed();
+ void filterUsers(const QString &text);
void checkUpdate();
void refreshGroups();
void selectGroupSet(int index);
void selectFilterTime(int index);
+ // Filter menu actions
+ void toggleSortAscending();
+
+ // Account filter slots
+ void sortAccountsChanged(QAction *action);
+ void hideInactiveChanged(bool checked);
+
// history navigation.
void back();
void forward();
@@ -150,16 +172,13 @@ private:
// Loading Data.
void requestGroupData();
- 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;
+ GxsMessageFrameWidget *messageWidget(const RsGxsGroupId &groupId);
int mGroupSet;
PulseAddDialog *mAddDialog;
WireGroupItem *mGroupSelected;
- TokenQueue *mWireQueue;
std::map mAllGroups;
std::vector mOwnGroups;
@@ -170,6 +189,21 @@ private:
int32_t mHistoryIndex;
std::vector mHistory;
+ bool mSortAscending;
+ int mAccountSortType;
+ bool mHideInactiveAccounts;
+
+ // Members for GxsStatisticsProvider interface support
+ QString mSettingsName;
+ RsGxsIfaceHelper *mInterface;
+ bool mDistSyncAllowed;
+ std::map mCachedGroupStats;
+ bool mShouldUpdateGroupStatistics;
+ std::set mGroupStatisticsToUpdate;
+ bool mCountChildMsgs;
+ RsGxsGroupId mNavigatePendingGroupId;
+ RsGxsMessageId mNavigatePendingMsgId;
+ UIStateHelper *mStateHelper;
/* UI - from Designer */
Ui::WireDialog ui;
diff --git a/retroshare-gui/src/gui/TheWire/WireDialog.ui b/retroshare-gui/src/gui/TheWire/WireDialog.ui
index 4cdf4a174..3621c54b5 100644
--- a/retroshare-gui/src/gui/TheWire/WireDialog.ui
+++ b/retroshare-gui/src/gui/TheWire/WireDialog.ui
@@ -87,6 +87,20 @@
+ -
+
+
+ Home
+
+
+
+ :/icons/png/home.png:/icons/png/home.png
+
+
+ Qt::ToolButtonTextBesideIcon
+
+
+
-
@@ -178,18 +192,49 @@
-
-
-
-
- 10
- true
-
+
+
+ Search...
-
- Who to Follow
+
+ true
+ -
+
+
-
+
+
+
+ 10
+ true
+
+
+
+ Who to Follow
+
+
+
+ -
+
+
+
+
+
+
+ :/icons/png/options.png:/icons/png/options.png
+
+
+ QToolButton::InstantPopup
+
+
+ true
+
+
+
+
+
-
@@ -224,7 +269,7 @@
-
+
3
@@ -363,6 +408,20 @@
+ -
+
+
+
+
+
+
+ :/icons/mail/filter24.png:/icons/mail/filter24.png
+
+
+ QToolButton::InstantPopup
+
+
+
@@ -432,6 +491,12 @@
QComboBox
+
+ RSTabWidget
+ QTabWidget
+
+ 1
+
diff --git a/retroshare-gui/src/gui/TheWire/WireGroupDialog.cpp b/retroshare-gui/src/gui/TheWire/WireGroupDialog.cpp
index e832540de..586ea6e7d 100644
--- a/retroshare-gui/src/gui/TheWire/WireGroupDialog.cpp
+++ b/retroshare-gui/src/gui/TheWire/WireGroupDialog.cpp
@@ -34,7 +34,7 @@ const uint32_t WireCreateEnabledFlags = (
GXS_GROUP_FLAGS_DISTRIBUTION |
// GXS_GROUP_FLAGS_PUBLISHSIGN |
// GXS_GROUP_FLAGS_SHAREKEYS | // disabled because the UI doesn't handle it yet.
- // GXS_GROUP_FLAGS_PERSONALSIGN |
+ GXS_GROUP_FLAGS_PERSONALSIGN |
// GXS_GROUP_FLAGS_COMMENTS |
GXS_GROUP_FLAGS_EXTRA |
0);
diff --git a/retroshare-gui/src/gui/TheWire/WireGroupItem.cpp b/retroshare-gui/src/gui/TheWire/WireGroupItem.cpp
index 1759103f6..de4ac6061 100644
--- a/retroshare-gui/src/gui/TheWire/WireGroupItem.cpp
+++ b/retroshare-gui/src/gui/TheWire/WireGroupItem.cpp
@@ -210,6 +210,15 @@ const QPixmap *WireGroupItem::getPixmap()
return NULL;
}
+bool WireGroupItem::matchesFilter(const QString &filterText) const
+{
+ if (filterText.isEmpty())
+ return true;
+
+ QString groupName = QString::fromStdString(mGroup.mMeta.mGroupName).toLower();
+ return groupName.contains(filterText);
+}
+
void WireGroupItem::editGroupDetails()
{
RsGxsGroupId groupId = mGroup.mMeta.mGroupId;
diff --git a/retroshare-gui/src/gui/TheWire/WireGroupItem.h b/retroshare-gui/src/gui/TheWire/WireGroupItem.h
index a7ae14326..522a1ccc2 100644
--- a/retroshare-gui/src/gui/TheWire/WireGroupItem.h
+++ b/retroshare-gui/src/gui/TheWire/WireGroupItem.h
@@ -51,6 +51,7 @@ public:
const QPixmap *getPixmap();
RsGxsGroupId &groupId();
+ bool matchesFilter(const QString &filterText) const;
private slots:
void show();
diff --git a/retroshare-gui/src/gui/TheWire/WireUserNotify.cpp b/retroshare-gui/src/gui/TheWire/WireUserNotify.cpp
new file mode 100644
index 000000000..59db49d00
--- /dev/null
+++ b/retroshare-gui/src/gui/TheWire/WireUserNotify.cpp
@@ -0,0 +1,62 @@
+/*******************************************************************************
+ * retroshare-gui/src/gui/TheWire/WireUserNotify.cpp *
+ * *
+ * Copyright (C) 2014 by Retroshare Team *
+ * *
+ * 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 . *
+ * *
+ *******************************************************************************/
+
+#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 WireUserNotify::getTrayMessage(bool plural)
+//{
+// return plural ? tr("You have %1 new wire pulse") : tr("You have %1 new wire pulse");
+//}
+
+//QString WireUserNotify::getNotifyMessage(bool plural)
+//{
+// return plural ? tr("%1 new wire pulse") : tr("%1 new wire pulse");
+//}
+
+void WireUserNotify::iconClicked()
+{
+ MainWindow::showWindow(MainWindow::Wire);
+}
diff --git a/retroshare-gui/src/gui/TheWire/WireUserNotify.h b/retroshare-gui/src/gui/TheWire/WireUserNotify.h
new file mode 100644
index 000000000..bf160bec2
--- /dev/null
+++ b/retroshare-gui/src/gui/TheWire/WireUserNotify.h
@@ -0,0 +1,45 @@
+/*******************************************************************************
+ * retroshare-gui/src/gui/TheWire/WireUserNotify.h *
+ * *
+ * Copyright (C) 2014 by Retroshare Team *
+ * *
+ * 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 . *
+ * *
+ *******************************************************************************/
+
+#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 QString getTrayMessage(bool plural) override;
+ //virtual QString getNotifyMessage(bool plural) override;
+
+ virtual void iconClicked() override;
+};
+
+#endif // WIREUSERNOTIFY_H
\ No newline at end of file
diff --git a/retroshare-gui/src/gui/feeds/FeedItem.h b/retroshare-gui/src/gui/feeds/FeedItem.h
index f11424520..0d3876da6 100644
--- a/retroshare-gui/src/gui/feeds/FeedItem.h
+++ b/retroshare-gui/src/gui/feeds/FeedItem.h
@@ -38,6 +38,9 @@ enum class RsFeedTypeFlags: uint32_t {
RS_FEED_TYPE_POSTED = 0x1000,
RS_FEED_TYPE_SECURITY_IP = 0x2000,
RS_FEED_TYPE_CIRCLE = 0x4000,
+#ifdef RS_USE_WIRE
+ RS_FEED_TYPE_WIRE = 0x8000,
+#endif
RS_FEED_ITEM_PEER_CONNECT = RS_FEED_TYPE_PEER | 0x0001,
RS_FEED_ITEM_PEER_DISCONNECT = RS_FEED_TYPE_PEER | 0x0002,
diff --git a/retroshare-gui/src/gui/feeds/WireNotifyGroupItem.cpp b/retroshare-gui/src/gui/feeds/WireNotifyGroupItem.cpp
new file mode 100644
index 000000000..7a0674d09
--- /dev/null
+++ b/retroshare-gui/src/gui/feeds/WireNotifyGroupItem.cpp
@@ -0,0 +1,281 @@
+/*******************************************************************************
+ * gui/feeds/WireNotifyGroupItem.cpp *
+ * *
+ * Copyright (c) 2014, Retroshare Team *
+ * *
+ * 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 . *
+ * *
+ *******************************************************************************/
+
+#include "WireNotifyGroupItem.h"
+#include "ui_WireNotifyGroupItem.h"
+
+#include "FeedHolder.h"
+#include "util/qtthreadsutils.h"
+#include "gui/common/FilesDefs.h"
+#include "gui/RetroShareLink.h"
+#include "gui/gxs/GxsIdDetails.h"
+#include "gui/MainWindow.h"
+#include "gui/TheWire/WireDialog.h"
+#include "util/DateTime.h"
+
+/****
+ * #define DEBUG_ITEM 1
+ ****/
+
+WireNotifyGroupItem::WireNotifyGroupItem(FeedHolder *feedHolder, uint32_t feedId, const RsGxsGroupId &groupId, bool isHome, bool autoUpdate, RsWireEventCode eventCode) :
+ GxsGroupFeedItem(feedHolder, feedId, groupId, isHome, rsWire, autoUpdate),
+ mEventCode(eventCode)
+{
+ setup();
+ requestGroup();
+ addEventHandler();
+}
+
+void WireNotifyGroupItem::addEventHandler()
+{
+ mEventHandlerId = 0;
+ rsEvents->registerEventsHandler( [this](std::shared_ptr event)
+ {
+ RsQThreadUtils::postToObject([=]()
+ {
+ const auto *e = dynamic_cast(event.get());
+
+ if(!e || e->mWireGroupId != this->groupId())
+ return;
+
+ switch(e->mWireEventCode)
+ {
+ case RsWireEventCode::FOLLOW_STATUS_CHANGED:
+ case RsWireEventCode::WIRE_UPDATED:
+ mGroup = RsWireGroup();
+ requestGroup();
+ break;
+ default:
+ break;
+ }
+ }, this );
+ }, mEventHandlerId, RsEventType::WIRE );
+}
+
+WireNotifyGroupItem::~WireNotifyGroupItem()
+{
+ rsEvents->unregisterEventsHandler(mEventHandlerId);
+ 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()));
+ connect(ui->nameLabel, SIGNAL(linkActivated(QString)), this, SLOT(openWireGroup()));
+
+ //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_ITEM
+ std::cerr << "Retrieving post data for post " << mThreadId << std::endl;
+#endif
+
+ std::vector groups;
+ const std::list groupIds = { groupId() };
+
+ if(!rsWire->getGroups(groupIds,groups))
+ {
+ RsErr() << "WireNotifyGroupItem::loadGroup() ERROR getting data" << std::endl;
+ deferred_update();
+ return;
+ }
+
+ if (groups.size() != 1)
+ {
+ std::cerr << "WireNotifyGroupItem::loadGroup() Wrong number of Items";
+ std::cerr << std::endl;
+ deferred_update();
+ 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->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"));
+ }
+
+ //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(mGroup.mMeta.mLastPost==0)
+ ui->infoLastPost->setText(tr("Never"));
+ else
+ ui->infoLastPost->setText(DateTime::formatLongDateTime(mGroup.mMeta.mLastPost));
+
+ // Set title based on event type
+ switch(mEventCode)
+ {
+ case RsWireEventCode::FOLLOW_STATUS_CHANGED:
+ ui->titleLabel->setText(tr("Now Following"));
+ break;
+ case RsWireEventCode::WIRE_UPDATED:
+ ui->titleLabel->setText(tr("Wire Updated"));
+ break;
+ case RsWireEventCode::NEW_WIRE:
+ default:
+ ui->titleLabel->setText(tr("New Wire"));
+ break;
+ }
+
+ 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(); does not work for wire, bug? -> GxsGroupFeedItem::subscribe()
+
+ uint32_t token;
+ rsWire->subscribeToGroup(token, mGroup.mMeta.mGroupId, true);
+}
+
+void WireNotifyGroupItem::openWireGroup()
+{
+ MainWindow::showWindow(MainWindow::Wire);
+ WireDialog *wireDialog = dynamic_cast(MainWindow::getPage(MainWindow::Wire));
+ if (wireDialog)
+ {
+ wireDialog->navigate(mGroup.mMeta.mGroupId, RsGxsMessageId());
+ }
+ removeItem();
+}
\ No newline at end of file
diff --git a/retroshare-gui/src/gui/feeds/WireNotifyGroupItem.h b/retroshare-gui/src/gui/feeds/WireNotifyGroupItem.h
new file mode 100644
index 000000000..7110feb4f
--- /dev/null
+++ b/retroshare-gui/src/gui/feeds/WireNotifyGroupItem.h
@@ -0,0 +1,74 @@
+/*******************************************************************************
+ * gui/feeds/WireNotifyGroupItem.h *
+ * *
+ * Copyright (c) 2014, Retroshare Team *
+ * *
+ * 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 . *
+ * *
+ *******************************************************************************/
+
+#ifndef WIRENOTIFYGROUPITEM_H
+#define WIRENOTIFYGROUPITEM_H
+
+#include
+#include "gui/feeds/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, RsWireEventCode eventCode = RsWireEventCode::NEW_WIRE);
+ ~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_WIRE; }
+
+private slots:
+ void toggle() override;
+ void subscribeWire();
+ void openWireGroup();
+
+private:
+ void fill();
+ void setup();
+ void addEventHandler();
+
+private:
+ RsWireGroup mGroup;
+ RsWireEventCode mEventCode;
+
+ /** Qt Designer generated object */
+ Ui::WireNotifyGroupItem *ui;
+ RsEventsHandlerId_t mEventHandlerId;
+};
+
+#endif // WIRENOTIFYGROUPITEM_H
\ No newline at end of file
diff --git a/retroshare-gui/src/gui/feeds/WireNotifyGroupItem.ui b/retroshare-gui/src/gui/feeds/WireNotifyGroupItem.ui
new file mode 100644
index 000000000..7c3548c12
--- /dev/null
+++ b/retroshare-gui/src/gui/feeds/WireNotifyGroupItem.ui
@@ -0,0 +1,403 @@
+
+
+ WireNotifyGroupItem
+
+
+
+ 0
+ 0
+ 618
+ 191
+
+
+
+
+ 1
+
+
+ 1
+
+
+ 1
+
+
+ 1
+
+ -
+
+
+
+ 0
+ 0
+
+
+
+
+
+
+
+
+ 0
+ 0
+ 0
+
+
+
+
+
+
+ 215
+ 215
+ 215
+
+
+
+
+
+
+ 215
+ 215
+ 215
+
+
+
+
+
+
+
+
+ 0
+ 0
+ 0
+
+
+
+
+
+
+ 215
+ 215
+ 215
+
+
+
+
+
+
+ 215
+ 215
+ 215
+
+
+
+
+
+
+
+
+ 154
+ 154
+ 154
+
+
+
+
+
+
+ 215
+ 215
+ 215
+
+
+
+
+
+
+ 215
+ 215
+ 215
+
+
+
+
+
+
+
+ true
+
+
+ QFrame::Box
+
+
+ QFrame::Sunken
+
+
+
-
+
+
-
+
+
+
+ 70
+ 70
+
+
+
+
+ 70
+ 70
+
+
+
+
+
+
+ :/icons/png/posted.png
+
+
+ true
+
+
+
+ -
+
+
-
+
+
+
+ 0
+ 0
+
+
+
+
+ 11
+ 75
+ true
+ true
+
+
+
+ Wire
+
+
+
+ -
+
+
+
+ 11
+ 75
+ true
+ true
+
+
+
+ name
+
+
+ true
+
+
+
+ -
+
+
+ Qt::Horizontal
+
+
+
+ 40
+ 20
+
+
+
+
+ -
+
+
+
+ 75
+ true
+
+
+
+ Last activity
+
+
+
+ -
+
+
+
+ 75
+ true
+ true
+
+
+
+ TextLabel
+
+
+
+
+
+ -
+
+
-
+
+
+
+ 0
+ 0
+
+
+
+ Qt::NoFocus
+
+
+ <html><head/><body><p>Follow to User</p></body></html>
+
+
+ Follow
+
+
+
+ -
+
+
+ Qt::Horizontal
+
+
+ QSizePolicy::Expanding
+
+
+
+ 254
+ 28
+
+
+
+
+ -
+
+
+ Qt::NoFocus
+
+
+ Copy RetroShare Link
+
+
+
+ :/icons/png/copy.png:/icons/png/copy.png
+
+
+
+ -
+
+
+
+ 0
+ 0
+
+
+
+ Qt::NoFocus
+
+
+ Expand
+
+
+
+ :/icons/png/down-arrow.png:/icons/png/down-arrow.png
+
+
+
+ -
+
+
+
+ 0
+ 0
+
+
+
+ Qt::NoFocus
+
+
+ Remove Item
+
+
+
+ :/icons/png/exit2.png:/icons/png/exit2.png
+
+
+
+
+
+
+
+ -
+
+
+
+ 0
+
+
+ 0
+
+
+ 0
+
+
+ 0
+
+
+ 0
+
+
-
+
+
+ Wire Description
+
+
+
-
+
+
+
+
+
+ :/images/contacts24.png
+
+
+
+ -
+
+
+
+ 0
+ 0
+
+
+
+ Description
+ of Wire
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/retroshare-gui/src/gui/feeds/WireNotifyPostItem.cpp b/retroshare-gui/src/gui/feeds/WireNotifyPostItem.cpp
new file mode 100644
index 000000000..824af3131
--- /dev/null
+++ b/retroshare-gui/src/gui/feeds/WireNotifyPostItem.cpp
@@ -0,0 +1,522 @@
+/*******************************************************************************
+ * gui/feeds/WireNotifyPostItem.cpp *
+ * *
+ * Copyright (c) 2012, Robert Fernie *
+ * *
+ * 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 . *
+ * *
+ *******************************************************************************/
+
+#include
+
+#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
+#include
+
+WireNotifyPostItem::WireNotifyPostItem(FeedHolder *feedHolder, uint32_t feedId, const RsGxsGroupId& groupId, const RsGxsMessageId &messageId, bool autoUpdate, const std::set &older_versions) :
+ GxsFeedItem(feedHolder, feedId, groupId, messageId, false, rsWire, autoUpdate)
+{
+ mLoadingStatus = LOADING_STATUS_NO_DATA;
+ mLoadingGroup = false;
+ mLoadingMessage = false;
+ mLoadingComment = false;
+
+ QVector v;
+ //bool self = false;
+
+ for(std::set::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();
+}
+
+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(mLoadingStatus != LOADING_STATUS_FILLED && !mGroupMeta.mGroupId.isNull() && !mPulse.mMeta.mMsgId.isNull() )
+ mLoadingStatus = LOADING_STATUS_HAS_DATA;
+
+ if(mGroupMeta.mGroupId.isNull() && !mLoadingGroup)
+ requestGroup();
+
+ if(mPulse.mMeta.mMsgId.isNull() && !mLoadingMessage)
+ requestMessage();
+
+ switch(mLoadingStatus)
+ {
+ case LOADING_STATUS_FILLED:
+ case LOADING_STATUS_NO_DATA:
+ default:
+ break;
+
+ case LOADING_STATUS_HAS_DATA:
+ fill();
+ setGroup(mGroup);
+ mLoadingStatus = LOADING_STATUS_FILLED;
+ break;
+ }
+
+ GxsFeedItem::paintEvent(e) ;
+}
+
+WireNotifyPostItem::~WireNotifyPostItem()
+{
+ auto timeout = std::chrono::steady_clock::now() + std::chrono::milliseconds(GROUP_ITEM_LOADING_TIMEOUT_ms);
+
+ while( (mLoadingGroup || mLoadingMessage || mLoadingComment)
+ && std::chrono::steady_clock::now() < timeout)
+ {
+ RsDbg() << __PRETTY_FUNCTION__ << " is Waiting for "
+ << (mLoadingGroup ? "Group " : "")
+ << (mLoadingMessage ? "Message " : "")
+ << (mLoadingComment ? "Comment " : "")
+ << "loading." << std::endl;
+ std::this_thread::sleep_for(std::chrono::milliseconds(100));
+ }
+
+ 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->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;
+
+ /* clear ui */
+ ui->titleLabel->setText(tr("Loading..."));
+ ui->titleLabel->setOpenExternalLinks(false); //To get linkActivated working
+ connect(ui->titleLabel, SIGNAL(linkActivated(QString)), this, SLOT(on_linkActivated(QString)));
+ ui->datetimelabel->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(unsubscribe()));
+
+ //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 unsubscribe button not necessary
+ ui->unsubscribeButton->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();
+}
+
+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();
+ }
+
+// updateItem();
+
+ return true;
+}
+
+void WireNotifyPostItem::expandFill(bool first)
+{
+ GxsFeedItem::expandFill(first);
+
+ if (first) {
+// fillExpandFrame();
+ }
+}
+
+QString WireNotifyPostItem::messageName()
+{
+ if (!mPulse.mMeta.mMsgName.empty())
+ return QString::fromUtf8(mPulse.mMeta.mMsgName.c_str());
+
+ return tr("New Pulse");
+}
+
+void WireNotifyPostItem::loadMessage()
+{
+#ifdef DEBUG_ITEM
+ std::cerr << "WireNotifyPostItem::loadMessage()";
+ std::cerr << std::endl;
+#endif
+ mLoadingMessage = true;
+
+ RsGxsGroupId grpId = groupId();
+ RsGxsMessageId msgId = messageId();
+
+ RsThread::async([this, grpId, msgId]()
+ {
+ RsWirePulseSPtr pPulse;
+
+ if (!rsWire->getWirePulse(grpId, msgId, pPulse))
+ {
+ RsErr() << "WireNotifyPostItem::loadMessage() ERROR getting pulse" << std::endl;
+ mLoadingMessage = false;
+ deferred_update();
+ return;
+ }
+
+ if (pPulse)
+ {
+#ifdef DEBUG_ITEM
+ std::cerr << (void*)this << ": Obtained post, with msgId = " << pPulse->mMeta.mMsgId << std::endl;
+#endif
+ const RsWirePulse pulse(*pPulse);
+
+ RsQThreadUtils::postToObject([pulse, this]()
+ {
+ mPulse = pulse;
+ mLoadingMessage = false;
+ update(); // triggers paintEvent if needed
+ }, this);
+ }
+ else
+ {
+ RsQThreadUtils::postToObject([this]()
+ {
+ removeItem();
+ mLoadingMessage = false;
+ update();
+ }, this);
+ }
+ });
+}
+
+void WireNotifyPostItem::loadComment()
+{
+ // TODO: implement Wire comment loading when Wire comments are supported
+}
+
+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 groups;
+// std::list> groups;
+ const std::list groupIds = { groupId() };
+ std::vector 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;
+ mLoadingGroup = false;
+ deferred_update();
+ return;
+ }
+
+ if (groups.size() != 1)
+ {
+ std::cerr << "WireNotifyPostItem::loadGroup() Wrong number of Items";
+ std::cerr << std::endl;
+ mLoadingGroup = false;
+ deferred_update();
+ 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 */
+
+ mGroup = group;
+ mGroupMeta = group.mMeta;
+ mLoadingGroup = false;
+
+ update(); // triggers paintEvent if needed
+
+ }, this );
+ });
+}
+
+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
+
+ mInFill = true;
+
+ QString title;
+ QString msgText;
+
+ // Determine pulse type for display
+ QString pulseTypeStr;
+ if (mPulse.mPulseType & WIRE_PULSE_TYPE_LIKE) {
+ pulseTypeStr = tr("Like");
+ } else if (mPulse.mPulseType & WIRE_PULSE_TYPE_REPUBLISH) {
+ pulseTypeStr = tr("Republish");
+ } else if (mPulse.mPulseType & WIRE_PULSE_TYPE_REPLY) {
+ pulseTypeStr = tr("Reply");
+ } else {
+ pulseTypeStr = tr("Pulse");
+ }
+
+ if (mCloseOnRead && !IS_MSG_NEW(mPulse.mMeta.mMsgStatus)) {
+ removeItem();
+ }
+
+ msgText = pulseTypeStr + ": ";
+ RetroShareLink msgLink = RetroShareLink::createGxsMessageLink(RetroShareLink::TYPE_WIRE, mPulse.mMeta.mGroupId, mPulse.mMeta.mMsgId, messageName());
+ msgText += msgLink.toHtml();
+ ui->subjectLabel->setText(msgText);
+
+ ui->pulseMessage->setText(QString::fromUtf8(mPulse.mPulseText.c_str()));
+ ui->datetimelabel->setText(DateTime::formatLongDateTime(mPulse.mRefPublishTs));
+
+ 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;
+ }
+
+ mInFill = false;
+}
+
+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);
+}
+
+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()));
+ ui->groupName->hide();
+
+ QString title;
+
+ // Determine pulse type for title
+ QString pulseTypeStr;
+ if (mPulse.mPulseType & WIRE_PULSE_TYPE_LIKE) {
+ pulseTypeStr = tr("New Like");
+ } else if (mPulse.mPulseType & WIRE_PULSE_TYPE_REPUBLISH) {
+ pulseTypeStr = tr("New Republish");
+ } else if (mPulse.mPulseType & WIRE_PULSE_TYPE_REPLY) {
+ pulseTypeStr = tr("New Reply");
+ } else {
+ pulseTypeStr = tr("Wire Feed");
+ }
+
+ title = pulseTypeStr + ": ";
+ RetroShareLink link = RetroShareLink::createGxsGroupLink(RetroShareLink::TYPE_WIRE, group.mMeta.mGroupId, groupName());
+ title += link.toHtml();
+ ui->titleLabel->setText(title);
+
+ 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);
+ }
+
+}
+
+/*********** 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
+}
+
+void WireNotifyPostItem::on_linkActivated(QString link)
+{
+ RetroShareLink rsLink(link);
+
+ if (rsLink.valid() ) {
+ QList rsLinks;
+ rsLinks.append(rsLink);
+ RetroShareLink::process(rsLinks);
+ removeItem();
+ return;
+ }
+}
diff --git a/retroshare-gui/src/gui/feeds/WireNotifyPostItem.h b/retroshare-gui/src/gui/feeds/WireNotifyPostItem.h
new file mode 100644
index 000000000..1dbb4c5ad
--- /dev/null
+++ b/retroshare-gui/src/gui/feeds/WireNotifyPostItem.h
@@ -0,0 +1,104 @@
+/*******************************************************************************
+ * gui/feeds/WireNotifyPostItem.h *
+ * *
+ * Copyright (c) 2012, Robert Fernie *
+ * *
+ * 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 . *
+ * *
+ *******************************************************************************/
+#ifndef WIRENOTIFYPOSTITEM_H
+#define WIRENOTIFYPOSTITEM_H
+
+#include
+#include
+#include
+#include "gui/feeds/GxsFeedItem.h"
+#include "gui/feeds/GxsGroupFeedItem.h"
+
+namespace Ui {
+class WireNotifyPostItem;
+}
+
+class FeedHolder;
+class SubFileItem;
+
+class WireNotifyPostItem : public GxsFeedItem
+{
+ Q_OBJECT
+
+public:
+ WireNotifyPostItem(FeedHolder *feedHolder, uint32_t feedId, const RsGxsGroupId& groupId, const RsGxsMessageId &messageId, bool autoUpdate, const std::set& older_versions = std::set());
+
+ virtual ~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);
+
+ void on_linkActivated(QString link);
+private:
+ void setup();
+ void fill();
+
+private:
+ bool mInFill;
+ bool mCloseOnRead;
+
+ LoadingStatus mLoadingStatus;
+
+ bool mLoadingMessage;
+ bool mLoadingGroup;
+ bool mLoadingComment;
+
+
+ RsGroupMetaData mGroupMeta;
+ RsWirePulse mPulse;
+ RsWireGroup mGroup;
+
+ /** Qt Designer generated object */
+ Ui::WireNotifyPostItem *ui;
+};
+
+Q_DECLARE_METATYPE(RsWirePulse)
+
+#endif // WIRENOTIFYPOSTITEM_H
diff --git a/retroshare-gui/src/gui/feeds/WireNotifyPostItem.ui b/retroshare-gui/src/gui/feeds/WireNotifyPostItem.ui
new file mode 100644
index 000000000..fbbf716cb
--- /dev/null
+++ b/retroshare-gui/src/gui/feeds/WireNotifyPostItem.ui
@@ -0,0 +1,418 @@
+
+
+ WireNotifyPostItem
+
+
+
+ 0
+ 0
+ 822
+ 175
+
+
+
+
+ 1
+
+
+ 1
+
+
+ 1
+
+
+ 1
+
+
+ 6
+
+
+ 1
+
+ -
+
+
+
+ 0
+ 0
+
+
+
+ true
+
+
+ QFrame::Shape::Box
+
+
+ QFrame::Shadow::Sunken
+
+
+
-
+
+
-
+
+
-
+
+
+
+ 70
+ 70
+
+
+
+
+ 70
+ 70
+
+
+
+ TextLabel
+
+
+ true
+
+
+
+ -
+
+
+ Qt::Orientation::Vertical
+
+
+
+ 20
+ 20
+
+
+
+
+
+
+ -
+
+
-
+
+
-
+
+
+
+ 12
+ true
+ true
+
+
+
+ TextLabel
+
+
+
+ -
+
+
+
+ 0
+ 0
+
+
+
+
+ 11
+ true
+ true
+
+
+
+ Wire Subject
+
+
+ false
+
+
+ true
+
+
+
+ -
+
+
+
+ true
+
+
+
+ DateTime
+
+
+
+ -
+
+
+ New
+
+
+
+
+
+ -
+
+
+
+ 11
+
+
+
+ TextLabel
+
+
+
+ -
+
+
+ 8
+
+
-
+
+
+
+ 11
+ false
+ true
+
+
+
+ TextLabel
+
+
+ true
+
+
+
+ -
+
+
+
+ 24
+ 16777215
+
+
+
+ Qt::FocusPolicy::NoFocus
+
+
+ Toggle Message Read Status
+
+
+ true
+
+
+ false
+
+
+ false
+
+
+
+ -
+
+
+
+ 0
+ 0
+
+
+
+ Qt::FocusPolicy::NoFocus
+
+
+ Unsubscribe From Wire
+
+
+ Unsubscribe
+
+
+
+ -
+
+
+ Qt::Orientation::Horizontal
+
+
+
+ 40
+ 20
+
+
+
+
+ -
+
+
+
+ 0
+ 0
+
+
+
+ Qt::FocusPolicy::NoFocus
+
+
+ Copy RetroShare Link
+
+
+
+ -
+
+
+
+ 0
+ 0
+
+
+
+ Qt::FocusPolicy::NoFocus
+
+
+ Expand
+
+
+
+ :/icons/png/down-arrow.png:/icons/png/down-arrow.png
+
+
+
+ -
+
+
+
+ 0
+ 0
+
+
+
+ Qt::FocusPolicy::NoFocus
+
+
+ Set as read and remove item
+
+
+
+ :/icons/png/correct.png:/icons/png/correct.png
+
+
+
+ -
+
+
+
+ 0
+ 0
+
+
+
+ Qt::FocusPolicy::NoFocus
+
+
+ Remove Item
+
+
+
+ :/icons/png/exit2.png:/icons/png/exit2.png
+
+
+
+
+
+
+
+
+
+ -
+
+
+
+ 0
+
+
+ 0
+
+
+ 0
+
+
+ 0
+
+
-
+
+
+ QFrame::Shape::Box
+
+
+ QFrame::Shadow::Sunken
+
+
+
+ 5
+
+
+ 5
+
+
+ 5
+
+
+ 5
+
+
-
+
+
+
+ 0
+ 0
+
+
+
+ true
+
+
+ 6
+
+
+ -1
+
+
+ true
+
+
+ Qt::TextInteractionFlag::LinksAccessibleByMouse|Qt::TextInteractionFlag::TextSelectableByKeyboard|Qt::TextInteractionFlag::TextSelectableByMouse
+
+
+
+
+
+
+
+
+
+ -
+
+
+ Qt::Orientation::Vertical
+
+
+
+ 20
+ 0
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/retroshare-gui/src/gui/gxs/GxsGroupFrameDialog.cpp b/retroshare-gui/src/gui/gxs/GxsGroupFrameDialog.cpp
index 69fb0dcb7..ef2089b4c 100644
--- a/retroshare-gui/src/gui/gxs/GxsGroupFrameDialog.cpp
+++ b/retroshare-gui/src/gui/gxs/GxsGroupFrameDialog.cpp
@@ -72,7 +72,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)
+: MainPage(parent), mSettingsName(settings_name)
{
/* Invoke the Qt Designer generated object setup routine */
ui = new Ui::GxsGroupFrameDialog();
@@ -173,7 +173,7 @@ void GxsGroupFrameDialog::initUi()
processSettings(true);
if (groupFrameSettingsType() != GroupFrameSettings::Nothing) {
- connect(RsGUIEventManager::getInstance(), SIGNAL(settingsChanged()), this, SLOT(settingsChanged()));
+ connect(RsGUIEventManager::getInstance(), SIGNAL(settingsChanged()), this, SLOT(settingsChanged()));
settingsChanged();
}
@@ -470,9 +470,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...")) ;
diff --git a/retroshare-gui/src/gui/gxs/GxsGroupFrameDialog.h b/retroshare-gui/src/gui/gxs/GxsGroupFrameDialog.h
index 81bba553d..c2d75a23c 100644
--- a/retroshare-gui/src/gui/gxs/GxsGroupFrameDialog.h
+++ b/retroshare-gui/src/gui/gxs/GxsGroupFrameDialog.h
@@ -27,6 +27,7 @@
#include "gui/RetroShareLink.h"
#include "gui/settings/rsharesettings.h"
#include "util/RsUserdata.h"
+#include "GxsStatisticsProvider.h"
#include
@@ -44,7 +45,7 @@ class UIStateHelper;
struct RsGxsCommentService;
class GxsCommentDialog;
-class GxsGroupFrameDialog : public MainPage
+class GxsGroupFrameDialog : public MainPage, public GxsStatisticsProvider
{
Q_OBJECT
@@ -74,13 +75,13 @@ 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);
virtual QString getHelpString() const =0;
virtual void getGroupList(std::map &groups) ;
- void getServiceStatistics(GxsServiceStatistic& stats) const ;
+ void getServiceStatistics(GxsServiceStatistic& stats) const override;
static uint32_t checkDelay(uint32_t time_in_secs);
@@ -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 getSearchRequests() const { return std::set(); } // 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& groupInfo) =0;
- virtual bool getGroupData(std::list& 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,31 @@ private:
// subscribe/unsubscribe ack.
- GxsMessageFrameWidget *messageWidget(const RsGxsGroupId &groupId);
+ virtual GxsMessageFrameWidget *messageWidget(const RsGxsGroupId &groupId);
GxsMessageFrameWidget *createMessageWidget(const RsGxsGroupId &groupId);
GxsCommentDialog *commentWidget(const RsGxsMessageId &msgId);
protected:
+
void updateSearchResults(const TurtleRequestId &sid);
void updateSearchResults(); // update all searches
+ virtual void updateGroupStatistics(const RsGxsGroupId &groupId);
+ virtual void updateGroupStatisticsReal(const RsGxsGroupId &groupId);
- bool mCountChildMsgs; // Count unread child messages?
+ // This needs to be overloaded by subclasses, possibly calling the blocking API, since it is used asynchronously.
+ virtual bool getGroupStatistics(const RsGxsGroupId& groupId, GxsGroupStatistic& stat) = 0;
+
+ QString mSettingsName;
+ RsGxsIfaceHelper *mInterface;
+ bool mDistSyncAllowed;
+ std::map mCachedGroupStats;
+ bool mShouldUpdateGroupStatistics;
+ std::set mGroupStatisticsToUpdate;
+ bool mCountChildMsgs;
+ RsGxsGroupId mNavigatePendingGroupId;
+ RsGxsMessageId mNavigatePendingMsgId;
+ UIStateHelper *mStateHelper;
private:
GxsMessageFrameWidget *currentWidget() const;
@@ -203,36 +214,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 mGroupIdsSummaryToUpdate;
// GroupStatistics update
- bool mShouldUpdateGroupStatistics;
rstime_t mLastGroupStatisticsUpdateTs;
- std::set mGroupStatisticsToUpdate;
-
- UIStateHelper *mStateHelper;
/** Qt Designer generated object */
Ui::GxsGroupFrameDialog *ui;
std::map mCachedGroupMetas;
- std::map mCachedGroupStats;
std::map mSearchGroupsItems ;
std::map > mKnownGroups;
diff --git a/retroshare-gui/src/gui/gxs/GxsGroupFrameDialog.ui b/retroshare-gui/src/gui/gxs/GxsGroupFrameDialog.ui
index 8cb249020..d73871619 100644
--- a/retroshare-gui/src/gui/gxs/GxsGroupFrameDialog.ui
+++ b/retroshare-gui/src/gui/gxs/GxsGroupFrameDialog.ui
@@ -62,7 +62,7 @@
- :/images/konversation.png
+ :/images/konversation.png
true
@@ -74,7 +74,6 @@
12
- 75
true
diff --git a/retroshare-gui/src/gui/gxs/GxsStatisticsProvider.cpp b/retroshare-gui/src/gui/gxs/GxsStatisticsProvider.cpp
new file mode 100644
index 000000000..47a77e983
--- /dev/null
+++ b/retroshare-gui/src/gui/gxs/GxsStatisticsProvider.cpp
@@ -0,0 +1,21 @@
+/*******************************************************************************
+ * retroshare-gui/src/gui/gxs/GxsStatisticsProvider.cpp *
+ * *
+ * Copyright 2012-2013 by Robert Fernie *
+ * *
+ * 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 . *
+ * *
+ *******************************************************************************/
+
+#include "GxsStatisticsProvider.h"
diff --git a/retroshare-gui/src/gui/gxs/GxsStatisticsProvider.h b/retroshare-gui/src/gui/gxs/GxsStatisticsProvider.h
new file mode 100644
index 000000000..3309e795b
--- /dev/null
+++ b/retroshare-gui/src/gui/gxs/GxsStatisticsProvider.h
@@ -0,0 +1,35 @@
+/*******************************************************************************
+ * retroshare-gui/src/gui/gxs/GxsStatisticsProvider.h *
+ * *
+ * Copyright 2012-2013 by Robert Fernie *
+ * *
+ * 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 . *
+ * *
+ *******************************************************************************/
+
+#ifndef GXSSTATISTICSPROVIDER_H
+#define GXSSTATISTICSPROVIDER_H
+
+#include "retroshare/rsgxsifacetypes.h"
+
+// Interface for GxsUserNotify to query service statistics.
+
+class GxsStatisticsProvider
+{
+public:
+ virtual ~GxsStatisticsProvider() = default;
+ virtual void getServiceStatistics(GxsServiceStatistic& stats) const = 0;
+};
+
+#endif // GXSSTATISTICSPROVIDER_H
diff --git a/retroshare-gui/src/gui/gxs/GxsUserNotify.cpp b/retroshare-gui/src/gui/gxs/GxsUserNotify.cpp
index 1784a6f8c..143a06ae5 100644
--- a/retroshare-gui/src/gui/gxs/GxsUserNotify.cpp
+++ b/retroshare-gui/src/gui/gxs/GxsUserNotify.cpp
@@ -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;
@@ -42,7 +42,7 @@ void GxsUserNotify::startUpdate()
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
diff --git a/retroshare-gui/src/gui/gxs/GxsUserNotify.h b/retroshare-gui/src/gui/gxs/GxsUserNotify.h
index 66890a1c3..27f5099e2 100644
--- a/retroshare-gui/src/gui/gxs/GxsUserNotify.h
+++ b/retroshare-gui/src/gui/gxs/GxsUserNotify.h
@@ -23,7 +23,7 @@
#include
#include "gui/common/UserNotify.h"
-#include "gui/gxs/GxsGroupFrameDialog.h"
+#include "gui/gxs/GxsStatisticsProvider.h"
class RsGxsIfaceHelper;
class RsGxsUpdateBroadcastBase;
@@ -33,7 +33,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 +46,8 @@ protected:
bool mCountChildMsgs; // Count new child messages?
private:
- const GxsGroupFrameDialog *mGroupFrameDialog;
+
+ const GxsStatisticsProvider *mGxsStatisticsProvider;
unsigned int mNewThreadMessageCount;
unsigned int mNewChildMessageCount;
diff --git a/retroshare-gui/src/gui/gxschannels/GxsChannelDialog.h b/retroshare-gui/src/gui/gxschannels/GxsChannelDialog.h
index 285afaa9d..36fd73cdd 100644
--- a/retroshare-gui/src/gui/gxschannels/GxsChannelDialog.h
+++ b/retroshare-gui/src/gui/gxschannels/GxsChannelDialog.h
@@ -71,7 +71,7 @@ private:
/* GxsGroupFrameDialog */
virtual QString text(TextType type) override;
virtual QString icon(IconType type) override;
- virtual QString settingsGroupName() override { return "ChannelDialog"; }
+ virtual QString settingsGroupName() { return "ChannelDialog"; }
virtual GxsGroupDialog *createNewGroupDialog() override;
virtual GxsGroupDialog *createGroupDialog(GxsGroupDialog::Mode mode, RsGxsGroupId groupId) override;
virtual int shareKeyType() override;
diff --git a/retroshare-gui/src/gui/gxschannels/GxsChannelUserNotify.cpp b/retroshare-gui/src/gui/gxschannels/GxsChannelUserNotify.cpp
index ce88231fc..46c5afaab 100644
--- a/retroshare-gui/src/gui/gxschannels/GxsChannelUserNotify.cpp
+++ b/retroshare-gui/src/gui/gxschannels/GxsChannelUserNotify.cpp
@@ -23,7 +23,7 @@
#include "gui/MainWindow.h"
#include "gui/common/FilesDefs.h"
-GxsChannelUserNotify::GxsChannelUserNotify(RsGxsIfaceHelper *ifaceImpl, const GxsGroupFrameDialog *g, QObject *parent) :
+GxsChannelUserNotify::GxsChannelUserNotify(RsGxsIfaceHelper *ifaceImpl, const GxsStatisticsProvider *g, QObject *parent) :
GxsUserNotify(ifaceImpl, g, parent)
{
}
diff --git a/retroshare-gui/src/gui/gxschannels/GxsChannelUserNotify.h b/retroshare-gui/src/gui/gxschannels/GxsChannelUserNotify.h
index 2604f5d34..94a787e91 100644
--- a/retroshare-gui/src/gui/gxschannels/GxsChannelUserNotify.h
+++ b/retroshare-gui/src/gui/gxschannels/GxsChannelUserNotify.h
@@ -22,14 +22,13 @@
#define GXSCHANNELUSERNOTIFY_H
#include "gui/gxs/GxsUserNotify.h"
-#include "gui/gxs/GxsGroupFrameDialog.h"
class GxsChannelUserNotify : public GxsUserNotify
{
Q_OBJECT
public:
- explicit GxsChannelUserNotify(RsGxsIfaceHelper *ifaceImpl, const GxsGroupFrameDialog *g, QObject *parent = 0);
+ explicit GxsChannelUserNotify(RsGxsIfaceHelper *ifaceImpl, const GxsStatisticsProvider *g, QObject *parent = 0);
virtual bool hasSetting(QString *name, QString *group) override;
diff --git a/retroshare-gui/src/gui/gxsforums/GxsForumUserNotify.cpp b/retroshare-gui/src/gui/gxsforums/GxsForumUserNotify.cpp
index b2e5bcc8e..ef890f350 100644
--- a/retroshare-gui/src/gui/gxsforums/GxsForumUserNotify.cpp
+++ b/retroshare-gui/src/gui/gxsforums/GxsForumUserNotify.cpp
@@ -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;
diff --git a/retroshare-gui/src/gui/gxsforums/GxsForumUserNotify.h b/retroshare-gui/src/gui/gxsforums/GxsForumUserNotify.h
index 4d681767f..69cca1960 100644
--- a/retroshare-gui/src/gui/gxsforums/GxsForumUserNotify.h
+++ b/retroshare-gui/src/gui/gxsforums/GxsForumUserNotify.h
@@ -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;
diff --git a/retroshare-gui/src/gui/gxsforums/GxsForumsDialog.h b/retroshare-gui/src/gui/gxsforums/GxsForumsDialog.h
index 98297e712..d6451c779 100644
--- a/retroshare-gui/src/gui/gxsforums/GxsForumsDialog.h
+++ b/retroshare-gui/src/gui/gxsforums/GxsForumsDialog.h
@@ -53,7 +53,7 @@ private:
/* GxsGroupFrameDialog */
QString text(TextType type)override ;
QString icon(IconType type)override ;
- QString settingsGroupName() override { return "ForumsDialog"; }
+ QString settingsGroupName() { return "ForumsDialog"; }
GxsGroupDialog *createNewGroupDialog() override;
GxsGroupDialog *createGroupDialog(GxsGroupDialog::Mode mode, RsGxsGroupId groupId) override;
diff --git a/retroshare-gui/src/gui/icons.qrc b/retroshare-gui/src/gui/icons.qrc
index 5d11f372b..b9b0aabce 100644
--- a/retroshare-gui/src/gui/icons.qrc
+++ b/retroshare-gui/src/gui/icons.qrc
@@ -356,7 +356,8 @@
icons/fullscreen-exit.png
icons/notification.png
icons/wire.png
- icons/wire-circle.png
+ icons/png/wire-notify.png
+ icons/png/wire-circle.png
icons/folder-account.svg
icons/notification.svg
icons/groups/blue.svg
diff --git a/retroshare-gui/src/gui/icons/png/wire-circle.png b/retroshare-gui/src/gui/icons/png/wire-circle.png
new file mode 100644
index 000000000..128159150
Binary files /dev/null and b/retroshare-gui/src/gui/icons/png/wire-circle.png differ
diff --git a/retroshare-gui/src/gui/icons/png/wire-notify.png b/retroshare-gui/src/gui/icons/png/wire-notify.png
new file mode 100644
index 000000000..c241bf55f
Binary files /dev/null and b/retroshare-gui/src/gui/icons/png/wire-notify.png differ
diff --git a/retroshare-gui/src/gui/settings/NotifyPage.cpp b/retroshare-gui/src/gui/settings/NotifyPage.cpp
index 189a93cc2..568804e24 100755
--- a/retroshare-gui/src/gui/settings/NotifyPage.cpp
+++ b/retroshare-gui/src/gui/settings/NotifyPage.cpp
@@ -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()));
@@ -207,6 +211,11 @@ RsFeedTypeFlags NotifyPage::getNewsFlags()
if (ui.notify_SecurityIp->isChecked())
newsFlags |= RsFeedTypeFlags::RS_FEED_TYPE_SECURITY_IP;
+#ifdef RS_USE_WIRE
+ if (ui.notify_Wire->isChecked())
+ newsFlags |= RsFeedTypeFlags::RS_FEED_TYPE_WIRE;
+#endif
+
return newsFlags;
}
@@ -312,8 +321,13 @@ void NotifyPage::load()
whileBlocking(ui.notify_Forums )->setChecked(!!(newsflags & RsFeedTypeFlags::RS_FEED_TYPE_FORUM));
whileBlocking(ui.notify_Posted )->setChecked(!!(newsflags & RsFeedTypeFlags::RS_FEED_TYPE_POSTED));
#if 0
- whileBlocking(ui.notify_Blogs)->setChecked(newsflags & RS_FEED_TYPE_BLOG);
+ whileBlocking(ui.notify_Blogs)->setChecked(newsflags & RsFeedTypeFlags::RS_FEED_TYPE_BLOG);
#endif
+
+#ifdef RS_USE_WIRE
+ whileBlocking(ui.notify_Wire)->setChecked(!!(newsflags & RsFeedTypeFlags::RS_FEED_TYPE_WIRE));
+#endif
+
whileBlocking(ui.notify_Chat )->setChecked(!!(newsflags & RsFeedTypeFlags::RS_FEED_TYPE_CHAT));
whileBlocking(ui.notify_Messages )->setChecked(!!(newsflags & RsFeedTypeFlags::RS_FEED_TYPE_MSG));
whileBlocking(ui.notify_Chat )->setChecked(!!(newsflags & RsFeedTypeFlags::RS_FEED_TYPE_CHAT));
diff --git a/retroshare-gui/src/gui/settings/NotifyPage.ui b/retroshare-gui/src/gui/settings/NotifyPage.ui
index fba357bcf..6eda7d5a3 100755
--- a/retroshare-gui/src/gui/settings/NotifyPage.ui
+++ b/retroshare-gui/src/gui/settings/NotifyPage.ui
@@ -7,7 +7,7 @@
0
0
569
- 512
+ 526
@@ -86,6 +86,13 @@
+ -
+
+
+ Wire
+
+
+
-
@@ -471,6 +478,13 @@
+
+
+ RSComboBox
+ QComboBox
+
+
+
notify_Peers
notify_Channels
@@ -495,13 +509,6 @@
systray_ChatLobby
pushButtonDisableAll
-
-
- RSComboBox
- QComboBox
-
-
-
diff --git a/retroshare-gui/src/gui/settings/rsharesettings.cpp b/retroshare-gui/src/gui/settings/rsharesettings.cpp
index 32d3a4764..2c1f28598 100644
--- a/retroshare-gui/src/gui/settings/rsharesettings.cpp
+++ b/retroshare-gui/src/gui/settings/rsharesettings.cpp
@@ -143,6 +143,10 @@ void RshareSettings::initSettings()
RsNotifyPopupFlags defNotify = (RsNotifyPopupFlags::RS_POPUP_CONNECT | RsNotifyPopupFlags::RS_POPUP_MSG);
RsFeedTypeFlags defNewsFeed = (RsFeedTypeFlags::RS_FEED_TYPE_MSG | RsFeedTypeFlags::RS_FEED_TYPE_FILES | RsFeedTypeFlags::RS_FEED_TYPE_SECURITY | RsFeedTypeFlags::RS_FEED_TYPE_SECURITY_IP | RsFeedTypeFlags::RS_FEED_TYPE_CIRCLE | RsFeedTypeFlags::RS_FEED_TYPE_CHANNEL |RsFeedTypeFlags::RS_FEED_TYPE_FORUM | RsFeedTypeFlags::RS_FEED_TYPE_POSTED);
+#ifdef RS_USE_WIRE
+ defNewsFeed = (defNewsFeed | RsFeedTypeFlags::RS_FEED_TYPE_WIRE);
+#endif
+
setDefault(SETTING_NEWSFEED_FLAGS, (int)defNewsFeed);
setDefault(SETTING_CHAT_FLAGS, defChat);
setDefault(SETTING_NOTIFY_FLAGS, (int)defNotify);
@@ -1114,6 +1118,10 @@ static QString groupFrameSettingsTypeToString(GroupFrameSettings::Type type)
return "Channel";
case GroupFrameSettings::Posted:
return "Posted";
+#ifdef RS_USE_WIRE
+ case GroupFrameSettings::Wire:
+ return "Wire";
+#endif
}
return "";
diff --git a/retroshare-gui/src/gui/settings/rsharesettings.h b/retroshare-gui/src/gui/settings/rsharesettings.h
index 3c87e6aaf..77c7e625e 100644
--- a/retroshare-gui/src/gui/settings/rsharesettings.h
+++ b/retroshare-gui/src/gui/settings/rsharesettings.h
@@ -44,7 +44,7 @@ class QMainWindow;
class GroupFrameSettings
{
public:
- enum Type { Nothing, Forum, Channel, Posted };
+ enum Type { Nothing, Forum, Channel, Posted, Wire };
public:
GroupFrameSettings()
diff --git a/retroshare-gui/src/retroshare-gui.pro b/retroshare-gui/src/retroshare-gui.pro
index 96dde5400..b33ada159 100644
--- a/retroshare-gui/src/retroshare-gui.pro
+++ b/retroshare-gui/src/retroshare-gui.pro
@@ -117,7 +117,7 @@ CONFIG += gxscircles
## To enable unfinished services
#CONFIG += wikipoos
-#CONFIG += gxsthewire
+CONFIG += gxsthewire
#CONFIG += gxsphotoshare
DEFINES += RS_RELEASE_VERSION
@@ -1228,7 +1228,10 @@ gxsthewire {
gui/TheWire/PulseReply.h \
gui/TheWire/PulseReplySeperator.h \
gui/TheWire/PulseMessage.h \
- gui/TheWire/CustomFrame.h \
+ gui/TheWire/CustomFrame.h \
+ gui/TheWire/WireUserNotify.h \
+ gui/feeds/WireNotifyGroupItem.h \
+ gui/feeds/WireNotifyPostItem.h \
FORMS += gui/TheWire/WireDialog.ui \
gui/TheWire/WireGroupItem.ui \
@@ -1239,7 +1242,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 \
@@ -1251,7 +1256,10 @@ gxsthewire {
gui/TheWire/PulseReply.cpp \
gui/TheWire/PulseReplySeperator.cpp \
gui/TheWire/PulseMessage.cpp \
- gui/TheWire/CustomFrame.cpp \
+ gui/TheWire/CustomFrame.cpp \
+ gui/TheWire/WireUserNotify.cpp \
+ gui/feeds/WireNotifyGroupItem.cpp \
+ gui/feeds/WireNotifyPostItem.cpp \
RESOURCES += gui/TheWire/TheWire_images.qrc
}
@@ -1447,7 +1455,7 @@ gxsgui {
# gui/gxs/GxsFeedWidget.h \
util/TokenQueue.h \
util/RsGxsUpdateBroadcast.h \
-
+ gui/gxs/GxsStatisticsProvider.h \
# gui/gxs/GxsMsgDialog.h \
FORMS += gui/gxs/GxsGroupDialog.ui \
@@ -1478,7 +1486,7 @@ gxsgui {
# gui/gxs/GxsFeedWidget.cpp \
util/TokenQueue.cpp \
util/RsGxsUpdateBroadcast.cpp \
-
+ gui/gxs/GxsStatisticsProvider.cpp \
# gui/gxs/GxsMsgDialog.cpp \
diff --git a/retroshare.pri b/retroshare.pri
index 983fda4e9..a92414f26 100644
--- a/retroshare.pri
+++ b/retroshare.pri
@@ -33,6 +33,9 @@
CONFIG *= retroshare_gui
no_retroshare_gui:CONFIG -= retroshare_gui
+# Enable TheWire - RsWire - is intended to be a Twitter clone
+CONFIG *= gxsthewire
+
# Enable GXS distant syncronization
CONFIG *= gxsdistsync