- added three new classes for automatic refresh of ui
  - RsGxsUpdateBroadcastBase
  - RsGxsUpdateBroadcastWidget
  - RsGxsUpdateBroadcastPage
- prevent call to :singleShot on RsProtectedTimer
- extend RsGxsUpdateBroadcast
- added automatic refresh to Identity and Forums (except subscribe/unsubscribe)

git-svn-id: http://svn.code.sf.net/p/retroshare/code/trunk@6503 b45a01b8-16f6-495d-af2f-9b41ad6348cc
This commit is contained in:
thunder2 2013-07-14 18:48:40 +00:00
parent 14890ef007
commit 621c8037bc
19 changed files with 551 additions and 255 deletions

View File

@ -58,7 +58,6 @@
* Transformation Notes:
* there are still a couple of things that the new forums differ from Old version.
* these will need to be addressed in the future.
* -> Missing Messages are not handled yet.
* -> Child TS (for sorting) is not handled by GXS, this will probably have to be done in the GUI.
* -> Need to handle IDs properly.
* -> Popularity not handled in GXS yet.
@ -67,7 +66,7 @@
/** Constructor */
GxsForumsDialog::GxsForumsDialog(QWidget *parent)
: RsAutoUpdatePage(1000,parent)
: RsGxsUpdateBroadcastPage(rsGxsForums, parent)
{
/* Invoke the Qt Designer generated object setup routine */
ui.setupUi(this);
@ -111,11 +110,6 @@ GxsForumsDialog::GxsForumsDialog(QWidget *parent)
processSettings(true);
settingsChanged();
/* Hide platform specific features */
#ifdef Q_WS_WIN
#endif
}
GxsForumsDialog::~GxsForumsDialog()
@ -135,12 +129,11 @@ void GxsForumsDialog::todo()
{
QMessageBox::information(this, "Todo",
"<b>Open points:</b><ul>"
"<li>Automatic update"
"<li>Automatic refresh after subscribe/unsubscibe"
"<li>Restore forum keys"
"<li>Display AUTHD"
"<li>Copy/navigate forum link"
"<li>Display count of unread messages"
"<li>Show missing messages"
"<li>Show/Edit forum details"
"<li>Don't show own posts as unread"
"<li>Remove messages"
@ -266,35 +259,10 @@ void GxsForumsDialog::restoreForumKeys(void)
#endif
}
void GxsForumsDialog::updateDisplay()
void GxsForumsDialog::updateDisplay(bool /*initialFill*/)
{
std::list<std::string> forumIds;
std::list<std::string>::iterator it;
if (!rsGxsForums)
return;
#if 0
// TODO groupsChanged... HACK XXX.
if ((rsGxsForums->groupsChanged(forumIds)) || (rsGxsForums->updated()))
{
/* update Forums List */
insertForums();
it = std::find(forumIds.begin(), forumIds.end(), mCurrForumId);
if (it != forumIds.end())
{
/* update threads as well */
insertThreads();
}
}
#endif
/* The proper version (above) can be done with a data request -> TODO */
if (rsGxsForums->updated())
{
/* update Forums List */
insertForums();
}
/* Update forums list */
insertForums();
}
// HACK until update works.

View File

@ -24,7 +24,7 @@
#include <QThread>
#include "mainpage.h"
#include "gui/gxs/RsGxsUpdateBroadcastPage.h"
#include "RsAutoUpdatePage.h"
#include "ui_GxsForumsDialog.h"
@ -39,7 +39,7 @@ class RsGxsForumMsg;
class GxsForumThreadWidget;
class UIStateHelper;
class GxsForumsDialog : public RsAutoUpdatePage, public TokenResponse
class GxsForumsDialog : public RsGxsUpdateBroadcastPage, public TokenResponse
{
Q_OBJECT
@ -51,12 +51,12 @@ public:
bool navigate(const std::string& forumId, const std::string& msgId);
/* overloaded from RsAuthUpdatePage */
virtual void updateDisplay();
// Callback for all Loads.
virtual void loadRequest(const TokenQueue *queue, const TokenRequest &req);
protected:
virtual void updateDisplay(bool initialFill);
private slots:
void settingsChanged();
void forceUpdateDisplay(); // TEMP HACK FN.

View File

@ -26,7 +26,6 @@
#include "IdDialog.h"
#include "gui/gxs/GxsIdTreeWidgetItem.h"
#include "gui/common/UIStateHelper.h"
#include <util/RsProtectedTimer.h>
#include <retroshare/rspeers.h>
#include <retroshare/rsidentity.h>
@ -63,7 +62,7 @@
/** Constructor */
IdDialog::IdDialog(QWidget *parent)
: MainPage(parent)
: RsGxsUpdateBroadcastPage(rsIdentity, parent)
{
ui.setupUi(this);
@ -138,10 +137,6 @@ IdDialog::IdDialog(QWidget *parent)
/* Setup tree */
ui.treeWidget_IdList->sortByColumn(RSID_COL_NICKNAME, Qt::AscendingOrder);
QTimer *timer = new RsProtectedTimer(this);
timer->connect(timer, SIGNAL(timeout()), this, SLOT(checkUpdate()));
timer->start(1000);
mIdQueue = new TokenQueue(rsIdentity->getTokenService(), this);
mStateHelper->setActive(IDDIALOG_IDDETAILS, false);
@ -152,7 +147,6 @@ void IdDialog::todo()
{
QMessageBox::information(this, "Todo",
"<b>Open points:</b><ul>"
"<li>Initial fill of data"
"<li>Delete ID"
"<li>Edit ID"
"<li>Reputation"
@ -511,16 +505,10 @@ void IdDialog::insertIdDetails(uint32_t token)
requestRepList(data.mMeta.mGroupId);
}
void IdDialog::checkUpdate()
void IdDialog::updateDisplay(bool /*initialFill*/)
{
/* update */
if (!rsIdentity)
return;
if (rsIdentity->updated())
{
requestIdList();
}
/* Update identity list */
requestIdList();
}
void IdDialog::addIdentity()

View File

@ -24,7 +24,7 @@
#ifndef IDENTITYDIALOG_H
#define IDENTITYDIALOG_H
#include "retroshare-gui/mainpage.h"
#include "gui/gxs/RsGxsUpdateBroadcastPage.h"
#include "ui_IdDialog.h"
#include <retroshare/rsidentity.h>
@ -36,7 +36,7 @@
class UIStateHelper;
class IdDialog : public MainPage, public TokenResponse
class IdDialog : public RsGxsUpdateBroadcastPage, public TokenResponse
{
Q_OBJECT
@ -45,11 +45,13 @@ public:
void loadRequest(const TokenQueue *queue, const TokenRequest &req);
protected:
virtual void updateDisplay(bool initialFill);
private slots:
void filterComboBoxChanged();
void filterChanged(const QString &text);
void checkUpdate();
void addIdentity();
void editIdentity();

View File

@ -0,0 +1,90 @@
#include <QTimer>
#include "RsGxsUpdateBroadcastBase.h"
#include "RsAutoUpdatePage.h"
#include "util/RsGxsUpdateBroadcast.h"
#include <algorithm>
RsGxsUpdateBroadcastBase::RsGxsUpdateBroadcastBase(RsGxsIfaceHelper *ifaceImpl, QWidget *parent)
: QObject(parent)
{
mUpdateWhenInvisible = false;
mFirstVisible = true;
mUpdateBroadcast = RsGxsUpdateBroadcast::get(ifaceImpl);
connect(mUpdateBroadcast, SIGNAL(changed()), this, SLOT(updateBroadcastChanged()));
connect(mUpdateBroadcast, SIGNAL(grpsChanged(std::list<RsGxsGroupId>)), this, SLOT(updateBroadcastGrpsChanged(std::list<RsGxsGroupId>)));
connect(mUpdateBroadcast, SIGNAL(msgsChanged(std::map<RsGxsGroupId,std::vector<RsGxsMessageId> >)), this, SLOT(updateBroadcastMsgsChanged(std::map<RsGxsGroupId,std::vector<RsGxsMessageId> >)));
}
RsGxsUpdateBroadcastBase::~RsGxsUpdateBroadcastBase()
{
}
void RsGxsUpdateBroadcastBase::securedUpdateDisplay()
{
if (RsAutoUpdatePage::eventsLocked()) {
/* Wait until events are not locked */
QTimer::singleShot(500, this, SLOT(securedUpdateDisplay()));
return;
}
emit fillDisplay(mFirstVisible);
mFirstVisible = false;
/* Clear updated ids */
mGrpIds.clear();
mMsgIds.clear();
}
void RsGxsUpdateBroadcastBase::showEvent(QShowEvent */*event*/)
{
if (mFirstVisible) {
/* Initial fill */
securedUpdateDisplay();
}
if (!mUpdateWhenInvisible) {
if (!mGrpIds.empty() || !mMsgIds.empty()) {
securedUpdateDisplay();
}
}
}
void RsGxsUpdateBroadcastBase::updateBroadcastChanged()
{
QWidget *widget = qobject_cast<QWidget *>(parent());
/* Update only update when the widget is visible. */
if (mUpdateWhenInvisible || !widget || widget->isVisible()) {
securedUpdateDisplay();
}
}
void RsGxsUpdateBroadcastBase::updateBroadcastGrpsChanged(const std::list<RsGxsGroupId> &grpIds)
{
std::list<RsGxsGroupId>::const_iterator it;
for (it = grpIds.begin(); it != grpIds.end(); ++it) {
if (std::find(mGrpIds.begin(), mGrpIds.end(), *it) == mGrpIds.end()) {
mGrpIds.push_back(*it);
}
}
}
void RsGxsUpdateBroadcastBase::updateBroadcastMsgsChanged(const std::map<RsGxsGroupId, std::vector<RsGxsMessageId> > &msgIds)
{
std::map<RsGxsGroupId, std::vector<RsGxsMessageId> >::const_iterator mapIt;
for (mapIt = msgIds.begin(); mapIt != msgIds.end(); ++mapIt) {
const RsGxsGroupId &grpId = mapIt->first;
const std::vector<RsGxsMessageId> &srcMsgIds = mapIt->second;
std::vector<RsGxsMessageId> &destMsgIds = mMsgIds[grpId];
std::vector<RsGxsMessageId>::const_iterator msgIt;
for (msgIt = srcMsgIds.begin(); msgIt != srcMsgIds.end(); ++msgIt) {
if (std::find(destMsgIds.begin(), destMsgIds.end(), *msgIt) == destMsgIds.end()) {
destMsgIds.push_back(*msgIt);
}
}
}
}

View File

@ -0,0 +1,42 @@
#pragma once
#include <QObject>
#include <retroshare/rsgxsifacetypes.h>
class QShowEvent;
class RsGxsIfaceHelper;
class RsGxsUpdateBroadcast;
class RsGxsUpdateBroadcastBase : public QObject
{
friend class RsGxsUpdateBroadcastPage;
friend class RsGxsUpdateBroadcastWidget;
Q_OBJECT
protected:
RsGxsUpdateBroadcastBase(RsGxsIfaceHelper* ifaceImpl, QWidget *parent = NULL);
virtual ~RsGxsUpdateBroadcastBase();
void setUpdateWhenInvisible(bool update) { mUpdateWhenInvisible = update; }
std::list<RsGxsGroupId> &getGrpIds() { return mGrpIds; }
std::map<RsGxsGroupId, std::vector<RsGxsMessageId> > &getMsgIds() { return mMsgIds; }
void showEvent(QShowEvent *e);
signals:
void fillDisplay(bool initialFill);
private slots:
void updateBroadcastChanged();
void updateBroadcastGrpsChanged(const std::list<RsGxsGroupId>& grpIds);
void updateBroadcastMsgsChanged(const std::map<RsGxsGroupId, std::vector<RsGxsMessageId> >& msgIds);
void securedUpdateDisplay();
private:
RsGxsUpdateBroadcast *mUpdateBroadcast;
bool mFirstVisible;
bool mUpdateWhenInvisible; // Update also when not visible
std::list<RsGxsGroupId> mGrpIds;
std::map<RsGxsGroupId, std::vector<RsGxsMessageId> > mMsgIds;
};

View File

@ -0,0 +1,40 @@
#include "RsGxsUpdateBroadcastPage.h"
#include "RsGxsUpdateBroadcastBase.h"
RsGxsUpdateBroadcastPage::RsGxsUpdateBroadcastPage(RsGxsIfaceHelper *ifaceImpl, QWidget *parent, Qt::WindowFlags flags)
: MainPage(parent, flags)
{
mBase = new RsGxsUpdateBroadcastBase(ifaceImpl, this);
connect(mBase, SIGNAL(fillDisplay(bool)), this, SLOT(fillDisplay(bool)));
}
RsGxsUpdateBroadcastPage::~RsGxsUpdateBroadcastPage()
{
}
void RsGxsUpdateBroadcastPage::setUpdateWhenInvisible(bool update)
{
mBase->setUpdateWhenInvisible(update);
}
std::list<RsGxsGroupId> &RsGxsUpdateBroadcastPage::getGrpIds()
{
return mBase->getGrpIds();
}
std::map<RsGxsGroupId, std::vector<RsGxsMessageId> > &RsGxsUpdateBroadcastPage::getMsgIds()
{
return mBase->getMsgIds();
}
void RsGxsUpdateBroadcastPage::fillDisplay(bool initialFill)
{
updateDisplay(initialFill);
update(); // Qt flush
}
void RsGxsUpdateBroadcastPage::showEvent(QShowEvent *event)
{
mBase->showEvent(event);
MainPage::showEvent(event);
}

View File

@ -0,0 +1,40 @@
#pragma once
#include "mainpage.h"
#include <retroshare/rsgxsifacetypes.h>
// This class implement a basic RS functionality which is that widgets displaying info
// should update regularly. They also should update only when visible, to save CPU time.
//
// Using this class simply needs to derive your widget from RsGxsUpdateBroadcastPage
// and oveload the updateDisplay() function with the actual code that updates the
// widget.
//
class RsGxsIfaceHelper;
class RsGxsUpdateBroadcastBase;
class RsGxsUpdateBroadcastPage : public MainPage
{
Q_OBJECT
public:
RsGxsUpdateBroadcastPage(RsGxsIfaceHelper* ifaceImpl, QWidget *parent = NULL, Qt::WindowFlags flags = 0);
virtual ~RsGxsUpdateBroadcastPage();
void setUpdateWhenInvisible(bool update);
std::list<RsGxsGroupId> &getGrpIds();
std::map<RsGxsGroupId, std::vector<RsGxsMessageId> > &getMsgIds();
protected:
virtual void showEvent(QShowEvent *event);
// This is overloaded in subclasses.
virtual void updateDisplay(bool initialFill) = 0;
private slots:
void fillDisplay(bool initialFill);
private:
RsGxsUpdateBroadcastBase *mBase;
};

View File

@ -0,0 +1,40 @@
#include "RsGxsUpdateBroadcastWidget.h"
#include "RsGxsUpdateBroadcastBase.h"
RsGxsUpdateBroadcastWidget::RsGxsUpdateBroadcastWidget(RsGxsIfaceHelper *ifaceImpl, QWidget *parent, Qt::WindowFlags flags)
: QWidget(parent, flags)
{
mBase = new RsGxsUpdateBroadcastBase(ifaceImpl, this);
connect(mBase, SIGNAL(fillDisplay(bool)), this, SLOT(fillDisplay(bool)));
}
RsGxsUpdateBroadcastWidget::~RsGxsUpdateBroadcastWidget()
{
}
void RsGxsUpdateBroadcastWidget::setUpdateWhenInvisible(bool update)
{
mBase->setUpdateWhenInvisible(update);
}
std::list<RsGxsGroupId> &RsGxsUpdateBroadcastWidget::getGrpIds()
{
return mBase->getGrpIds();
}
std::map<RsGxsGroupId, std::vector<RsGxsMessageId> > &RsGxsUpdateBroadcastWidget::getMsgIds()
{
return mBase->getMsgIds();
}
void RsGxsUpdateBroadcastWidget::fillDisplay(bool initialFill)
{
updateDisplay(initialFill);
update(); // Qt flush
}
void RsGxsUpdateBroadcastWidget::showEvent(QShowEvent *event)
{
mBase->showEvent(event);
QWidget::showEvent(event);
}

View File

@ -0,0 +1,40 @@
#pragma once
#include <QWidget>
#include <retroshare/rsgxsifacetypes.h>
// This class implement a basic RS functionality which is that widgets displaying info
// should update regularly. They also should update only when visible, to save CPU time.
//
// Using this class simply needs to derive your widget from RsGxsUpdateBroadcastWidget
// and oveload the updateDisplay() function with the actual code that updates the
// widget.
//
class RsGxsIfaceHelper;
class RsGxsUpdateBroadcastBase;
class RsGxsUpdateBroadcastWidget : public QWidget
{
Q_OBJECT
public:
RsGxsUpdateBroadcastWidget(RsGxsIfaceHelper* ifaceImpl, QWidget *parent = NULL, Qt::WindowFlags flags = 0);
virtual ~RsGxsUpdateBroadcastWidget();
void setUpdateWhenInvisible(bool update);
std::list<RsGxsGroupId> &getGrpIds();
std::map<RsGxsGroupId, std::vector<RsGxsMessageId> > &getMsgIds();
protected:
virtual void showEvent(QShowEvent *event);
// This is overloaded in subclasses.
virtual void updateDisplay(bool initialFill) = 0;
private slots:
void fillDisplay(bool initialFill);
private:
RsGxsUpdateBroadcastBase *mBase;
};

View File

@ -86,7 +86,7 @@
#define TOKEN_TYPE_REPLY_MESSAGE 3
GxsForumThreadWidget::GxsForumThreadWidget(const std::string &forumId, QWidget *parent) :
QWidget(parent),
RsGxsUpdateBroadcastWidget(rsGxsForums, parent),
ui(new Ui::GxsForumThreadWidget)
{
ui->setupUi(this);
@ -94,6 +94,8 @@ GxsForumThreadWidget::GxsForumThreadWidget(const std::string &forumId, QWidget *
/* Setup UI helper */
mStateHelper = new UIStateHelper(this);
setUpdateWhenInvisible(true);
mStateHelper->addWidget(TOKEN_TYPE_CURRENTFORUM, ui->progressBar, UISTATE_LOADING_VISIBLE);
mStateHelper->addWidget(TOKEN_TYPE_CURRENTFORUM, ui->progressText, UISTATE_LOADING_VISIBLE);
mStateHelper->addWidget(TOKEN_TYPE_CURRENTFORUM, ui->newthreadButton);
@ -141,9 +143,6 @@ GxsForumThreadWidget::GxsForumThreadWidget(const std::string &forumId, QWidget *
connect(ui->nextUnreadButton, SIGNAL(clicked()), this, SLOT(nextUnreadMessage()));
connect(ui->downloadButton, SIGNAL(clicked()), this, SLOT(downloadAllFiles()));
// HACK - TEMPORARY HIJACKING THIS BUTTON FOR REFRESH.
connect(ui->refreshButton, SIGNAL(clicked()), this, SLOT(forceUpdateDisplay()));
connect(ui->filterLineEdit, SIGNAL(textChanged(QString)), this, SLOT(filterItems(QString)));
connect(ui->filterLineEdit, SIGNAL(filterChanged(int)), this, SLOT(filterColumnChanged(int)));
@ -299,7 +298,7 @@ QIcon GxsForumThreadWidget::forumIcon()
void GxsForumThreadWidget::changeEvent(QEvent *e)
{
QWidget::changeEvent(e);
RsGxsUpdateBroadcastWidget::changeEvent(e);
switch (e->type()) {
case QEvent::StyleChange:
calculateIconsAndFonts();
@ -310,38 +309,25 @@ void GxsForumThreadWidget::changeEvent(QEvent *e)
}
}
#ifdef TODO
void GxsForumThreadWidget::updateDisplay()
void GxsForumThreadWidget::updateDisplay(bool initialFill)
{
std::list<std::string> forumIds;
std::list<std::string>::iterator it;
if (!rsGxsForums)
if (initialFill) {
/* Not needed */
return;
}
#if 0
// TODO groupsChanged... HACK XXX.
if ((rsGxsForums->groupsChanged(forumIds)) || (rsGxsForums->updated()))
{
/* update Forums List */
insertForums();
it = std::find(forumIds.begin(), forumIds.end(), mCurrForumId);
if (it != forumIds.end())
{
/* update threads as well */
std::list<RsGxsGroupId> &grpIds = getGrpIds();
if (std::find(grpIds.begin(), grpIds.end(), mForumId) != grpIds.end()) {
/* Update threads */
insertThreads();
} else {
std::map<RsGxsGroupId, std::vector<RsGxsMessageId> > &msgIds = getMsgIds();
if (msgIds.find(mForumId) != msgIds.end()) {
/* Update threads */
insertThreads();
}
}
#endif
/* The proper version (above) can be done with a data request -> TODO */
if (rsGxsForums->updated())
{
/* update Forums List */
insertThreads();
}
}
#endif
void GxsForumThreadWidget::threadListCustomPopupMenu(QPoint /*point*/)
{
@ -453,7 +439,7 @@ bool GxsForumThreadWidget::eventFilter(QObject *obj, QEvent *event)
}
}
// pass the event on to the parent class
return QWidget::eventFilter(obj, event);
return RsGxsUpdateBroadcastWidget::eventFilter(obj, event);
}
void GxsForumThreadWidget::togglethreadview()
@ -786,16 +772,6 @@ void GxsForumThreadWidget::fillThreadStatus(QString text)
ui->progressText->setText(text);
}
// HACK until update works.
void GxsForumThreadWidget::forceUpdateDisplay()
{
std::cerr << "GxsForumThreadWidget::forceUpdateDisplay()";
std::cerr << std::endl;
/* update Thread List */
insertThreads();
}
QTreeWidgetItem *GxsForumThreadWidget::convertMsgToThreadWidget(const RsGxsForumMsg &msg, bool useChildTS, uint32_t filterColumn)
{
GxsIdRSTreeWidgetItem *item = new GxsIdRSTreeWidgetItem(mThreadCompareRole);

View File

@ -1,8 +1,7 @@
#ifndef GXSFORUMTHREADWIDGET_H
#define GXSFORUMTHREADWIDGET_H
#include <QWidget>
#include "gui/gxs/RsGxsUpdateBroadcastWidget.h"
#include "util/TokenQueue.h"
class QTreeWidgetItem;
@ -15,7 +14,7 @@ namespace Ui {
class GxsForumThreadWidget;
}
class GxsForumThreadWidget : public QWidget, public TokenResponse
class GxsForumThreadWidget : public RsGxsUpdateBroadcastWidget, public TokenResponse
{
Q_OBJECT
@ -62,12 +61,9 @@ signals:
protected:
bool eventFilter(QObject *obj, QEvent *ev);
void changeEvent(QEvent *e);
virtual void updateDisplay(bool initialFill);
private slots:
void forceUpdateDisplay(); // TEMP HACK FN.
// void updateDisplay();
/** Create the context popup menu and it's submenus */
void threadListCustomPopupMenu(QPoint point);
@ -143,7 +139,6 @@ private:
int mLastViewType;
RSTreeWidgetItemCompareRole *mThreadCompareRole;
TokenQueue *mThreadQueue;
// QTimer *mTimer;
GxsForumsFillThread *mFillThread;
unsigned int mUnreadCount;
unsigned int mNewCount;

View File

@ -268,6 +268,31 @@
</item>
<item>
<layout class="QGridLayout" name="postLayout">
<item row="0" column="7">
<widget class="QLabel" name="time_label">
<property name="font">
<font>
<pointsize>10</pointsize>
</font>
</property>
<property name="text">
<string notr="true"/>
</property>
</widget>
</item>
<item row="0" column="11">
<widget class="QPushButton" name="nextUnreadButton">
<property name="sizePolicy">
<sizepolicy hsizetype="Maximum" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="text">
<string>Next unread</string>
</property>
</widget>
</item>
<item row="0" column="1">
<widget class="QToolButton" name="newmessageButton">
<property name="maximumSize">
@ -291,47 +316,6 @@
</property>
</widget>
</item>
<item row="0" column="3">
<widget class="QPushButton" name="previousButton">
<property name="enabled">
<bool>false</bool>
</property>
<property name="sizePolicy">
<sizepolicy hsizetype="Minimum" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="minimumSize">
<size>
<width>24</width>
<height>24</height>
</size>
</property>
<property name="maximumSize">
<size>
<width>24</width>
<height>24</height>
</size>
</property>
<property name="focusPolicy">
<enum>Qt::NoFocus</enum>
</property>
<property name="toolTip">
<string>Previous Thread</string>
</property>
<property name="text">
<string/>
</property>
<property name="icon">
<iconset resource="../images.qrc">
<normaloff>:/images/back.png</normaloff>:/images/back.png</iconset>
</property>
<property name="flat">
<bool>true</bool>
</property>
</widget>
</item>
<item row="0" column="4">
<widget class="QPushButton" name="nextButton">
<property name="enabled">
@ -373,6 +357,32 @@
</property>
</widget>
</item>
<item row="0" column="13">
<widget class="QPushButton" name="expandButton">
<property name="maximumSize">
<size>
<width>24</width>
<height>24</height>
</size>
</property>
<property name="focusPolicy">
<enum>Qt::NoFocus</enum>
</property>
<property name="text">
<string/>
</property>
<property name="icon">
<iconset resource="../images.qrc">
<normaloff>:/images/edit_remove24.png</normaloff>:/images/edit_remove24.png</iconset>
</property>
<property name="checkable">
<bool>true</bool>
</property>
<property name="checked">
<bool>true</bool>
</property>
</widget>
</item>
<item row="0" column="5">
<widget class="QToolButton" name="downloadButton">
<property name="maximumSize">
@ -403,15 +413,10 @@
</property>
</widget>
</item>
<item row="0" column="7">
<widget class="QLabel" name="time_label">
<property name="font">
<font>
<pointsize>10</pointsize>
</font>
</property>
<property name="text">
<string notr="true"/>
<item row="0" column="8">
<widget class="Line" name="line">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
</widget>
</item>
@ -440,21 +445,23 @@
</property>
</spacer>
</item>
<item row="0" column="12">
<widget class="QPushButton" name="nextUnreadButton">
<item row="0" column="3">
<widget class="QPushButton" name="previousButton">
<property name="enabled">
<bool>false</bool>
</property>
<property name="sizePolicy">
<sizepolicy hsizetype="Maximum" vsizetype="Fixed">
<sizepolicy hsizetype="Minimum" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="text">
<string>Next unread</string>
<property name="minimumSize">
<size>
<width>24</width>
<height>24</height>
</size>
</property>
</widget>
</item>
<item row="0" column="14">
<widget class="QPushButton" name="expandButton">
<property name="maximumSize">
<size>
<width>24</width>
@ -464,33 +471,19 @@
<property name="focusPolicy">
<enum>Qt::NoFocus</enum>
</property>
<property name="toolTip">
<string>Previous Thread</string>
</property>
<property name="text">
<string/>
</property>
<property name="icon">
<iconset resource="../images.qrc">
<normaloff>:/images/edit_remove24.png</normaloff>:/images/edit_remove24.png</iconset>
<normaloff>:/images/back.png</normaloff>:/images/back.png</iconset>
</property>
<property name="checkable">
<property name="flat">
<bool>true</bool>
</property>
<property name="checked">
<bool>true</bool>
</property>
</widget>
</item>
<item row="0" column="8">
<widget class="Line" name="line">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
</widget>
</item>
<item row="0" column="11">
<widget class="QPushButton" name="refreshButton">
<property name="text">
<string>Refresh</string>
</property>
</widget>
</item>
</layout>

View File

@ -45,6 +45,7 @@
#include "gui/SoundManager.h"
#include "gui/NetworkView.h"
#include "lang/languagesupport.h"
#include "util/RsGxsUpdateBroadcast.h"
/*** WINDOWS DON'T LIKE THIS - REDEFINES VER numbers.
#include <gui/qskinobject/qskinobject.h>
@ -374,6 +375,9 @@ int main(int argc, char *argv[])
/* cleanup */
ChatDialog::cleanupChat();
#ifdef RS_ENABLE_GXS
RsGxsUpdateBroadcast::cleanup();
#endif
rsicontrol->rsGlobalShutDown();

View File

@ -17,6 +17,8 @@ gxs {
# thewire is incomplete - dont enable
#CONFIG += thewire
#CONFIG += photoshare
DEFINES += RS_ENABLE_GXS
}
@ -273,7 +275,7 @@ HEADERS += rshare.h \
gui/RSHumanReadableDelegate.h \
gui/AboutDialog.h \
gui/ForumsDialog.h \
gui/CreateMsgLinkDialog.h \
gui/CreateMsgLinkDialog.h \
gui/forums/ForumDetails.h \
gui/forums/EditForumDetails.h \
gui/forums/CreateForum.h \
@ -481,7 +483,7 @@ FORMS += gui/StartDialog.ui \
gui/FileTransfer/DetailsDialog.ui \
gui/ForumsDialog.ui \
gui/MainWindow.ui \
gui/CreateMsgLinkDialog.ui \
gui/CreateMsgLinkDialog.ui \
gui/forums/CreateForum.ui \
gui/forums/CreateForumMsg.ui \
gui/forums/ForumDetails.ui \
@ -584,7 +586,7 @@ SOURCES += main.cpp \
gui/mainpagestack.cpp \
gui/MainWindow.cpp \
gui/ForumsDialog.cpp \
gui/CreateMsgLinkDialog.cpp \
gui/CreateMsgLinkDialog.cpp \
gui/forums/ForumDetails.cpp \
gui/forums/EditForumDetails.cpp \
gui/forums/CreateForum.cpp \
@ -624,6 +626,7 @@ SOURCES += main.cpp \
gui/HelpDialog.cpp \
gui/LogoBar.cpp \
lang/languagesupport.cpp \
util/RsProtectedTimer.cpp \
util/stringutil.cpp \
util/DateTime.cpp \
util/win32.cpp \
@ -1132,7 +1135,11 @@ gxsgui {
gui/gxs/GxsCommentDialog.h \
gui/gxs/GxsCreateCommentDialog.h \
gui/gxs/GxsFeedItem.h \
gui/gxs/RsGxsUpdateBroadcastBase.h \
gui/gxs/RsGxsUpdateBroadcastWidget.h \
gui/gxs/RsGxsUpdateBroadcastPage.h \
util/TokenQueue.h \
util/RsGxsUpdateBroadcast.h \
# gui/gxs/GxsMsgDialog.h \
@ -1156,7 +1163,11 @@ gxsgui {
gui/gxs/GxsCommentDialog.cpp \
gui/gxs/GxsCreateCommentDialog.cpp \
gui/gxs/GxsFeedItem.cpp \
gui/gxs/RsGxsUpdateBroadcastBase.cpp \
gui/gxs/RsGxsUpdateBroadcastWidget.cpp \
gui/gxs/RsGxsUpdateBroadcastPage.cpp \
util/TokenQueue.cpp \
util/RsGxsUpdateBroadcast.cpp \
# gui/gxs/GxsMsgDialog.cpp \

View File

@ -1,44 +1,67 @@
#include <QTimer>
//#include <QTimer>
#include <QMap>
#include "RsGxsUpdateBroadcast.h"
#include "RsProtectedTimer.h"
#include <retroshare/rsgxsifacehelper.h>
RsGxsUpdateBroadcast::RsGxsUpdateBroadcast(RsGxsIfaceHelper *ifaceImpl, float dt, QObject *parent) :
QObject(parent), mIfaceImpl(ifaceImpl), mDt(dt)
QMap<RsGxsIfaceHelper*, RsGxsUpdateBroadcast*> updateBroadcastMap;
RsGxsUpdateBroadcast::RsGxsUpdateBroadcast(RsGxsIfaceHelper *ifaceImpl) :
QObject(NULL), mIfaceImpl(ifaceImpl)
{
mTimer = new RsProtectedTimer(this);
mTimer->setInterval(1000);
mTimer->setSingleShot(true);
connect(mTimer, SIGNAL(timeout()), this, SLOT(poll()));
}
void RsGxsUpdateBroadcast::startMonitor()
void RsGxsUpdateBroadcast::cleanup()
{
slowPoll();
QMap<RsGxsIfaceHelper*, RsGxsUpdateBroadcast*>::iterator it;
for (it = updateBroadcastMap.begin(); it != updateBroadcastMap.end(); ++it) {
delete(it.value());
}
updateBroadcastMap.clear();
}
void RsGxsUpdateBroadcast::fastPoll()
RsGxsUpdateBroadcast *RsGxsUpdateBroadcast::get(RsGxsIfaceHelper *ifaceImpl)
{
QMap<RsGxsIfaceHelper*, RsGxsUpdateBroadcast*>::iterator it = updateBroadcastMap.find(ifaceImpl);
if (it != updateBroadcastMap.end()) {
return it.value();
}
RsGxsUpdateBroadcast *updateBroadcast = new RsGxsUpdateBroadcast(ifaceImpl);
updateBroadcastMap.insert(ifaceImpl, updateBroadcast);
updateBroadcast->poll();
return updateBroadcast;
}
void RsGxsUpdateBroadcast::slowPoll()
void RsGxsUpdateBroadcast::poll()
{
std::map<RsGxsGroupId, std::vector<RsGxsMessageId> > msgs;
std::list<RsGxsGroupId> grps;
std::map<RsGxsGroupId, std::vector<RsGxsMessageId> > msgs;
std::list<RsGxsGroupId> grps;
if(mIfaceImpl->updated())
{
mIfaceImpl->msgsChanged(msgs);
if(!msgs.empty())
{
emit msgsChanged(msgs);
}
if (mIfaceImpl->updated(true, true))
{
mIfaceImpl->msgsChanged(msgs);
if (!msgs.empty())
{
emit msgsChanged(msgs);
}
mIfaceImpl->groupsChanged(grps);
mIfaceImpl->groupsChanged(grps);
if (!grps.empty())
{
emit grpsChanged(grps);
}
if(!grps.empty())
{
emit grpsChanged(grps);
}
emit changed();
}
QTimer::singleShot((int) (mDt * 1000.0), this, SLOT(slowPoll()));
}
mTimer->start();
}

View File

@ -3,31 +3,34 @@
#include <QObject>
#include <retroshare/rsgxsifacehelper.h>
#include <retroshare/rsgxsifacetypes.h>
class RsGxsIfaceHelper;
class QTimer;
class RsGxsUpdateBroadcast : public QObject
{
Q_OBJECT
public:
explicit RsGxsUpdateBroadcast(RsGxsIfaceHelper* ifaceImpl, float dt, QObject *parent = 0);
Q_OBJECT
void startMonitor();
void update();
public:
static void cleanup();
static RsGxsUpdateBroadcast *get(RsGxsIfaceHelper* ifaceImpl);
signals:
void changed();
void msgsChanged(const std::map<RsGxsGroupId, std::vector<RsGxsMessageId> >& msgIds);
void grpsChanged(const std::list<RsGxsGroupId>& grpIds);
void msgsChanged(const std::map<RsGxsGroupId, std::vector<RsGxsMessageId> > & msgIds);
void grpsChanged(const std::list<RsGxsGroupId>& grpIds);
public slots:
void fastPoll();
void slowPoll();
private slots:
void poll();
private:
explicit RsGxsUpdateBroadcast(RsGxsIfaceHelper* ifaceImpl);
RsGxsIfaceHelper* mIfaceImpl;
float mDt;
private:
RsGxsIfaceHelper* mIfaceImpl;
QTimer *mTimer;
};
#endif // RSGXSUPDATEBROADCAST_H

View File

@ -0,0 +1,59 @@
/****************************************************************
* RetroShare is distributed under the following license:
*
* Copyright (C) 2013 Cyril Soler
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* 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 General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor,
* Boston, MA 02110-1301, USA.
****************************************************************/
#include <retroshare-gui/RsAutoUpdatePage.h>
#include <iostream>
#include "RsProtectedTimer.h"
//#define PROTECTED_TIMER_DEBUG
RsProtectedTimer::RsProtectedTimer(QObject *parent)
: QTimer(parent)
{
}
void RsProtectedTimer::timerEvent(QTimerEvent *e)
{
if(RsAutoUpdatePage::eventsLocked())
{
#ifdef PROTECTED_TIMER_DEBUG
if (isSingleShot()) {
/* Singleshot timer will be stopped in QTimer::timerEvent */
std::cerr << "Singleshot timer is blocked!" << std::endl;
} else {
std::cerr << "Timer is blocked!" << std::endl;
}
#endif
return ;
}
#ifdef PROTECTED_TIMER_DEBUG
if (isSingleShot()) {
std::cerr << "Singleshot timer has passed protection." << std::endl;
} else {
std::cerr << "Timer has passed protection." << std::endl;
}
#endif
QTimer::timerEvent(e) ;
}

View File

@ -22,33 +22,15 @@
#pragma once
#include <QTimer>
#include <retroshare-gui/RsAutoUpdatePage.h>
#include <iostream>
#define PROTECTED_TIMER_DEBUG
class RsProtectedTimer: public QTimer
class RsProtectedTimer : public QTimer
{
public:
RsProtectedTimer(QObject *parent)
: QTimer(parent)
{
}
public:
RsProtectedTimer(QObject *parent);
virtual void timerEvent(QTimerEvent *e)
{
if(RsAutoUpdatePage::eventsLocked())
{
#ifdef PROTECTED_TIMER_DEBUG
std::cerr << "Timer is blocked!." << std::endl;
#endif
return ;
}
protected:
virtual void timerEvent(QTimerEvent *e);
#ifdef PROTECTED_TIMER_DEBUG
std::cerr << "Timer has passed protection." << std::endl;
#endif
QTimer::timerEvent(e) ;
}
// do not use, please use setInterval, setSingleShot and connect signal timeout
static void singleShot(int /*msec*/, QObject */*receiver*/, const char */*member*/) {}
};