mirror of
https://github.com/RetroShare/RetroShare.git
synced 2025-07-27 08:25:53 -04:00
Merge pull request #1385 from G10h4ck/safer_api
0.6.5 Safer rsGxsChannel API
This commit is contained in:
commit
8c8ce53e4b
16 changed files with 966 additions and 539 deletions
|
@ -20,6 +20,7 @@
|
|||
|
||||
#include <QMenu>
|
||||
#include <QFileDialog>
|
||||
#include <QMetaObject>
|
||||
|
||||
#include <retroshare/rsfiles.h>
|
||||
|
||||
|
@ -33,6 +34,7 @@
|
|||
#include "gui/settings/rsharesettings.h"
|
||||
#include "gui/notifyqt.h"
|
||||
#include "gui/common/GroupTreeWidget.h"
|
||||
#include "util/qtthreadsutils.h"
|
||||
|
||||
class GxsChannelGroupInfoData : public RsUserdata
|
||||
{
|
||||
|
@ -275,17 +277,37 @@ QWidget *GxsChannelDialog::createCommentHeaderWidget(const RsGxsGroupId &grpId,
|
|||
void GxsChannelDialog::toggleAutoDownload()
|
||||
{
|
||||
RsGxsGroupId grpId = groupId();
|
||||
if (grpId.isNull()) {
|
||||
if (grpId.isNull()) return;
|
||||
|
||||
bool autoDownload;
|
||||
if(!rsGxsChannels->getChannelAutoDownload(grpId, autoDownload))
|
||||
{
|
||||
std::cerr << __PRETTY_FUNCTION__ << " failed to get autodownload value "
|
||||
<< "for channel: " << grpId.toStdString() << std::endl;
|
||||
return;
|
||||
}
|
||||
|
||||
bool autoDownload ;
|
||||
|
||||
if(!rsGxsChannels->getChannelAutoDownload(grpId,autoDownload) || !rsGxsChannels->setChannelAutoDownload(grpId, !autoDownload))
|
||||
RsThread::async([this, grpId, autoDownload]()
|
||||
{
|
||||
std::cerr << "GxsChannelDialog::toggleAutoDownload() Auto Download failed to set";
|
||||
std::cerr << std::endl;
|
||||
}
|
||||
if(!rsGxsChannels->setChannelAutoDownload(grpId, !autoDownload))
|
||||
{
|
||||
std::cerr << __PRETTY_FUNCTION__ << " failed to set autodownload "
|
||||
<< "for channel: " << grpId << std::endl;
|
||||
return;
|
||||
}
|
||||
|
||||
RsQThreadUtils::postToObject( [=]()
|
||||
{
|
||||
/* 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!
|
||||
*/
|
||||
|
||||
std::cerr << __PRETTY_FUNCTION__ << " Has been executed on GUI "
|
||||
<< "thread but was scheduled by async thread" << std::endl;
|
||||
}, this );
|
||||
});
|
||||
}
|
||||
|
||||
void GxsChannelDialog::loadGroupSummaryToken(const uint32_t &token, std::list<RsGroupMetaData> &groupInfo, RsUserdata *&userdata)
|
||||
|
|
|
@ -31,8 +31,10 @@
|
|||
#include "gui/settings/rsharesettings.h"
|
||||
#include "gui/feeds/SubFileItem.h"
|
||||
#include "gui/notifyqt.h"
|
||||
#include <algorithm>
|
||||
#include "util/DateTime.h"
|
||||
#include "util/qtthreadsutils.h"
|
||||
|
||||
#include <algorithm>
|
||||
|
||||
#define CHAN_DEFAULT_IMAGE ":/images/channels.png"
|
||||
|
||||
|
@ -621,13 +623,13 @@ bool GxsChannelPostsWidget::navigatePostItem(const RsGxsMessageId &msgId)
|
|||
|
||||
void GxsChannelPostsWidget::subscribeGroup(bool subscribe)
|
||||
{
|
||||
if (groupId().isNull()) {
|
||||
return;
|
||||
}
|
||||
RsGxsGroupId grpId(groupId());
|
||||
if (grpId.isNull()) return;
|
||||
|
||||
uint32_t token;
|
||||
rsGxsChannels->subscribeToGroup(token, groupId(), subscribe);
|
||||
// mChannelQueue->queueRequest(token, 0, RS_TOKREQ_ANSTYPE_ACK, TOKEN_TYPE_SUBSCRIBE_CHANGE);
|
||||
RsThread::async([=]()
|
||||
{
|
||||
rsGxsChannels->subscribeToChannel(grpId, subscribe);
|
||||
} );
|
||||
}
|
||||
|
||||
void GxsChannelPostsWidget::setAutoDownload(bool autoDl)
|
||||
|
@ -643,12 +645,35 @@ void GxsChannelPostsWidget::toggleAutoDownload()
|
|||
return;
|
||||
}
|
||||
|
||||
bool autoDownload ;
|
||||
if(!rsGxsChannels->getChannelAutoDownload(grpId,autoDownload) || !rsGxsChannels->setChannelAutoDownload(grpId, !autoDownload))
|
||||
bool autoDownload;
|
||||
if(!rsGxsChannels->getChannelAutoDownload(grpId, autoDownload))
|
||||
{
|
||||
std::cerr << "GxsChannelDialog::toggleAutoDownload() Auto Download failed to set";
|
||||
std::cerr << std::endl;
|
||||
std::cerr << __PRETTY_FUNCTION__ << " failed to get autodownload value "
|
||||
<< "for channel: " << grpId.toStdString() << std::endl;
|
||||
return;
|
||||
}
|
||||
|
||||
RsThread::async([this, grpId, autoDownload]()
|
||||
{
|
||||
if(!rsGxsChannels->setChannelAutoDownload(grpId, !autoDownload))
|
||||
{
|
||||
std::cerr << __PRETTY_FUNCTION__ << " failed to set autodownload "
|
||||
<< "for channel: " << grpId.toStdString() << std::endl;
|
||||
return;
|
||||
}
|
||||
|
||||
RsQThreadUtils::postToObject( [=]()
|
||||
{
|
||||
/* 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!
|
||||
*/
|
||||
|
||||
std::cerr << __PRETTY_FUNCTION__ << " Has been executed on GUI "
|
||||
<< "thread but was scheduled by async thread" << std::endl;
|
||||
}, this );
|
||||
});
|
||||
}
|
||||
|
||||
bool GxsChannelPostsWidget::insertGroupData(const uint32_t &token, RsGroupMetaData &metaData)
|
||||
|
|
|
@ -424,6 +424,7 @@ HEADERS += rshare.h \
|
|||
util/ObjectPainter.h \
|
||||
util/QtVersion.h \
|
||||
util/RsFile.h \
|
||||
util/qtthreadsutils.h \
|
||||
gui/profile/ProfileWidget.h \
|
||||
gui/profile/ProfileManager.h \
|
||||
gui/profile/StatusMessage.h \
|
||||
|
|
117
retroshare-gui/src/util/qtthreadsutils.h
Normal file
117
retroshare-gui/src/util/qtthreadsutils.h
Normal file
|
@ -0,0 +1,117 @@
|
|||
/*
|
||||
* RetroShare
|
||||
* Copyright (C) 2018 Gioacchino Mazzurco <gio@eigenlab.org>
|
||||
*
|
||||
* 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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
/* Thanks to KubaO which realeased original C++14 versions of this functions
|
||||
* under public domain license
|
||||
* https://github.com/KubaO/stackoverflown/blob/master/questions/metacall-21646467/main.cpp
|
||||
* https://github.com/KubaO/stackoverflown/blob/master/LICENSE
|
||||
*/
|
||||
|
||||
#include <QtGlobal>
|
||||
#include <QtCore>
|
||||
#include <type_traits>
|
||||
|
||||
namespace RsQThreadUtils {
|
||||
|
||||
#if QT_VERSION >= QT_VERSION_CHECK(5, 10, 0)
|
||||
|
||||
/**
|
||||
* @brief execute given function in the QThread where given QObject belongs
|
||||
*/
|
||||
template <typename F>
|
||||
void postToObject(F &&fun, QObject *obj = qApp)
|
||||
{
|
||||
if (qobject_cast<QThread*>(obj))
|
||||
qWarning() << "posting a call to a thread object - consider using postToThread";
|
||||
QObject src;
|
||||
auto type = obj->metaObject();
|
||||
QObject::connect( &src, &QObject::destroyed, obj,
|
||||
[fun, type, obj]
|
||||
{
|
||||
// ensure that the object is not being destructed
|
||||
if (obj->metaObject()->inherits(type)) fun();
|
||||
}, Qt::QueuedConnection );
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief execute given function in the given QThread
|
||||
*/
|
||||
template <typename F>
|
||||
void postToThread(F &&fun, QThread *thread = qApp->thread())
|
||||
{
|
||||
QObject * obj = QAbstractEventDispatcher::instance(thread);
|
||||
Q_ASSERT(obj);
|
||||
QObject src;
|
||||
auto type = obj->metaObject();
|
||||
QObject::connect( &src, &QObject::destroyed, obj,
|
||||
[fun, type, obj]
|
||||
{
|
||||
// ensure that the object is not being destructed
|
||||
if (obj->metaObject()->inherits(type)) fun();
|
||||
}, Qt::QueuedConnection );
|
||||
}
|
||||
|
||||
#else // QT_VERSION >= QT_VERSION_CHECK(5, 10, 0)
|
||||
|
||||
template <typename F>
|
||||
struct FEvent : QEvent
|
||||
{
|
||||
using Fun = typename std::decay<F>::type;
|
||||
const QObject *const obj;
|
||||
const QMetaObject *const type = obj->metaObject();
|
||||
Fun fun;
|
||||
template <typename Fun>
|
||||
FEvent(const QObject *obj, Fun &&fun) :
|
||||
QEvent(QEvent::None), obj(obj), fun(std::forward<Fun>(fun)) {}
|
||||
~FEvent()
|
||||
{
|
||||
#if QT_VERSION >= QT_VERSION_CHECK(5, 7, 0)
|
||||
// ensure that the object is not being destructed
|
||||
if (obj->metaObject()->inherits(type)) fun();
|
||||
#else // QT_VERSION >= QT_VERSION_CHECK(5, 7, 0)
|
||||
fun();
|
||||
#endif // QT_VERSION >= QT_VERSION_CHECK(5, 7, 0)
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief execute given function in the QThread where given QObject belongs
|
||||
*/
|
||||
template <typename F>
|
||||
static void postToObject(F &&fun, QObject *obj = qApp)
|
||||
{
|
||||
if (qobject_cast<QThread*>(obj))
|
||||
qWarning() << "posting a call to a thread object - consider using postToThread";
|
||||
QCoreApplication::postEvent(obj, new FEvent<F>(obj, std::forward<F>(fun)));
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief execute given function in the given QThread
|
||||
*/
|
||||
template <typename F>
|
||||
static void postToThread(F &&fun, QThread *thread = qApp->thread())
|
||||
{
|
||||
QObject * obj = QAbstractEventDispatcher::instance(thread);
|
||||
Q_ASSERT(obj);
|
||||
QCoreApplication::postEvent(obj, new FEvent<F>(obj, std::forward<F>(fun)));
|
||||
}
|
||||
#endif // QT_VERSION >= QT_VERSION_CHECK(5, 10, 0)
|
||||
|
||||
}
|
||||
|
Loading…
Add table
Add a link
Reference in a new issue