#include #include #include #include #include "responsewaiter.h" Q_DECLARE_METATYPE(QDBusPendingReply<>) Q_DECLARE_METATYPE(QDBusPendingReply) Q_DECLARE_METATYPE(QDBusPendingReply) Q_DECLARE_METATYPE(QDBusPendingReply) Q_DECLARE_METATYPE(QDBusPendingReply) DBusResponseWaiter* DBusResponseWaiter::m_instance = 0; DBusResponseWaiter* DBusResponseWaiter::instance() { if (!m_instance) { m_instance = new DBusResponseWaiter(); } return m_instance; } DBusResponseWaiter::DBusResponseWaiter() : QObject() { m_registered << qRegisterMetaType >("QDBusPendingReply<>") << qRegisterMetaType >("QDBusPendingReply") << qRegisterMetaType >("QDBusPendingReply") << qRegisterMetaType >("QDBusPendingReply") << qRegisterMetaType >("QDBusPendingReply") ; } QVariant DBusResponseWaiter::waitForReply(QVariant variant) const { if (QDBusPendingCall* call = const_cast(extractPendingCall(variant))) { call->waitForFinished(); if (call->isError()) { return QVariant("error"); } QDBusMessage reply = call->reply(); if (reply.arguments().count() > 0) { return reply.arguments().first(); } } return QVariant(); } void DBusAsyncResponse::setPendingCall(QVariant variant) { if (QDBusPendingCall* call = const_cast(DBusResponseWaiter::instance()->extractPendingCall(variant))) { QDBusPendingCallWatcher* watcher = new QDBusPendingCallWatcher(*call); watcher->setProperty("pengingCall", variant); connect(watcher, SIGNAL(finished(QDBusPendingCallWatcher*)), this, SLOT(onCallFinished(QDBusPendingCallWatcher*))); connect(watcher, SIGNAL(finished(QDBusPendingCallWatcher*)), watcher, SLOT(deleteLater())); }; } void DBusAsyncResponse::onCallFinished(QDBusPendingCallWatcher* watcher) { QVariant variant = watcher->property("pengingCall"); if (QDBusPendingCall* call = const_cast(DBusResponseWaiter::instance()->extractPendingCall(variant))) { if (call->isError()) { Q_EMIT error(call->error().message()); } else { QDBusMessage reply = call->reply(); if (reply.arguments().count() > 0) { Q_EMIT success(reply.arguments().first()); } else { Q_EMIT success(QVariant()); } } } if (m_autodelete) { deleteLater(); } } const QDBusPendingCall* DBusResponseWaiter::extractPendingCall(QVariant& variant) const { Q_FOREACH(int type, m_registered) { if (variant.canConvert(QVariant::Type(type))) { return reinterpret_cast(variant.constData()); } } return 0; }