Fix compilation with Qt older then 5.10

This commit is contained in:
Gioacchino Mazzurco 2018-11-01 14:51:57 +01:00
parent ea86fe2615
commit 367c5182cf
No known key found for this signature in database
GPG Key ID: A1FBCA3872E87051
4 changed files with 116 additions and 5 deletions

View File

@ -35,6 +35,7 @@
#include "gui/settings/rsharesettings.h"
#include "gui/notifyqt.h"
#include "gui/common/GroupTreeWidget.h"
#include "util/qtthreadsutils.h"
class GxsChannelGroupInfoData : public RsUserdata
{
@ -296,14 +297,17 @@ void GxsChannelDialog::toggleAutoDownload()
return;
}
QMetaObject::invokeMethod(this, [=]()
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!
*/
}, Qt::QueuedConnection);
std::cerr << __PRETTY_FUNCTION__ << " Has been executed on GUI "
<< "thread but was scheduled by async thread" << std::endl;
}, this );
});
}

View File

@ -32,8 +32,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"
@ -661,14 +663,17 @@ void GxsChannelPostsWidget::toggleAutoDownload()
return;
}
QMetaObject::invokeMethod(this, [=]()
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!
*/
}, Qt::QueuedConnection);
std::cerr << __PRETTY_FUNCTION__ << " Has been executed on GUI "
<< "thread but was scheduled by async thread" << std::endl;
}, this );
});
}

View File

@ -406,6 +406,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 \

View File

@ -0,0 +1,101 @@
/*
* 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)
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 );
}
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()
{
// ensure that the object is not being destructed
if (obj->metaObject()->inherits(type)) fun();
}
};
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)));
}
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)
}