mirror of
https://gitlab.freedesktop.org/dbus/dbus.git
synced 2026-04-30 23:48:05 +02:00
* qt/dbusidl2cpp.cpp: There's no callAsync. Use the correct
call (r535506)
* qt/dbusidl2cpp.cpp:
* qt/qdbusabstractadaptor.cpp:
* qt/qdbusabstractadaptor.h: Make QDBusAdaptorConnector be a
sibling of the QDBusAbstractAdaptor objects instead of the
parent. (r535848)
* qt/dbusidl2cpp.cpp:
* qt/qdbusabstractinterface.cpp:
* qt/qdbusabstractinterface.h:
* qt/qdbusabstractinterface_p.h:
* qt/qdbusinterface.cpp: Make properties in interfaces
actually work. The code that was generated would not compile,
due to moc calls to functions that did not exist. They now
shall. (r536571)
This commit is contained in:
parent
86bb5584d3
commit
838a740ea6
8 changed files with 219 additions and 121 deletions
20
ChangeLog
20
ChangeLog
|
|
@ -1,3 +1,23 @@
|
|||
2006-05-02 Thiago Macieira <thiago.macieira@trolltech.com>
|
||||
|
||||
* qt/dbusidl2cpp.cpp: There's no callAsync. Use the correct
|
||||
call (r535506)
|
||||
|
||||
* qt/dbusidl2cpp.cpp:
|
||||
* qt/qdbusabstractadaptor.cpp:
|
||||
* qt/qdbusabstractadaptor.h: Make QDBusAdaptorConnector be a
|
||||
sibling of the QDBusAbstractAdaptor objects instead of the
|
||||
parent. (r535848)
|
||||
|
||||
* qt/dbusidl2cpp.cpp:
|
||||
* qt/qdbusabstractinterface.cpp:
|
||||
* qt/qdbusabstractinterface.h:
|
||||
* qt/qdbusabstractinterface_p.h:
|
||||
* qt/qdbusinterface.cpp: Make properties in interfaces
|
||||
actually work. The code that was generated would not compile,
|
||||
due to moc calls to functions that did not exist. They now
|
||||
shall. (r536571)
|
||||
|
||||
2006-04-30 Thiago Macieira <thiago.macieira@trolltech.com>
|
||||
|
||||
* Makefile.am:
|
||||
|
|
|
|||
|
|
@ -37,7 +37,7 @@
|
|||
#include "qdbusintrospection_p.h"
|
||||
|
||||
#define PROGRAMNAME "dbusidl2cpp"
|
||||
#define PROGRAMVERSION "0.3"
|
||||
#define PROGRAMVERSION "0.4"
|
||||
#define PROGRAMCOPYRIGHT "Copyright (C) 2006 Trolltech AS. All rights reserved."
|
||||
|
||||
#define ANNOTATION_NO_WAIT "org.freedesktop.DBus.Method.NoReply"
|
||||
|
|
@ -344,6 +344,26 @@ static void writeArgList(QTextStream &ts, const QStringList &argNames,
|
|||
}
|
||||
}
|
||||
|
||||
static QString propertyGetter(const QDBusIntrospection::Property &property)
|
||||
{
|
||||
QString getter = property.annotations.value("com.trolltech.QtDBus.propertyGetter");
|
||||
if (getter.isEmpty()) {
|
||||
getter = property.name;
|
||||
getter[0] = getter[0].toLower();
|
||||
}
|
||||
return getter;
|
||||
}
|
||||
|
||||
static QString propertySetter(const QDBusIntrospection::Property &property)
|
||||
{
|
||||
QString setter = property.annotations.value("com.trolltech.QtDBus.propertySetter");
|
||||
if (setter.isEmpty()) {
|
||||
setter = "set" + property.name;
|
||||
setter[3] = setter[3].toUpper();
|
||||
}
|
||||
return setter;
|
||||
}
|
||||
|
||||
static QString stringify(const QString &data)
|
||||
{
|
||||
QString retval;
|
||||
|
|
@ -425,31 +445,6 @@ static void writeProxy(const char *proxyFile, const QDBusIntrospection::Interfac
|
|||
<< "{" << endl
|
||||
<< " Q_OBJECT" << endl;
|
||||
|
||||
// properties:
|
||||
foreach (const QDBusIntrospection::Property &property, interface->properties) {
|
||||
QByteArray type = qtTypeName(property.type);
|
||||
QString templateType = templateArg(type);
|
||||
QString constRefType = constRefArg(type);
|
||||
QString getter = property.name;
|
||||
QString setter = "set" + property.name;
|
||||
getter[0] = getter[0].toLower();
|
||||
setter[3] = setter[3].toUpper();
|
||||
|
||||
hs << " Q_PROPERTY(" << type << " " << property.name;
|
||||
|
||||
// getter:
|
||||
if (property.access != QDBusIntrospection::Property::Write)
|
||||
// it's readble
|
||||
hs << " READ" << getter;
|
||||
|
||||
// setter
|
||||
if (property.access != QDBusIntrospection::Property::Read)
|
||||
// it's writeable
|
||||
hs << " WRITE" << setter;
|
||||
|
||||
hs << ")" << endl;
|
||||
}
|
||||
|
||||
// the interface name
|
||||
hs << "public:" << endl
|
||||
<< " static inline const char *staticInterfaceName()" << endl
|
||||
|
|
@ -472,9 +467,50 @@ static void writeProxy(const char *proxyFile, const QDBusIntrospection::Interfac
|
|||
<< "}" << endl
|
||||
<< endl;
|
||||
|
||||
// properties:
|
||||
foreach (const QDBusIntrospection::Property &property, interface->properties) {
|
||||
QByteArray type = qtTypeName(property.type);
|
||||
QString templateType = templateArg(type);
|
||||
QString constRefType = constRefArg(type);
|
||||
QString getter = propertyGetter(property);
|
||||
QString setter = propertySetter(property);
|
||||
|
||||
hs << " Q_PROPERTY(" << type << " " << property.name;
|
||||
|
||||
// getter:
|
||||
if (property.access != QDBusIntrospection::Property::Write)
|
||||
// it's readble
|
||||
hs << " READ " << getter;
|
||||
|
||||
// setter
|
||||
if (property.access != QDBusIntrospection::Property::Read)
|
||||
// it's writeable
|
||||
hs << " WRITE " << setter;
|
||||
|
||||
hs << ")" << endl;
|
||||
|
||||
// getter:
|
||||
if (property.access != QDBusIntrospection::Property::Write) {
|
||||
hs << " inline " << type << " " << getter << "() const" << endl;
|
||||
if (type != "QVariant")
|
||||
hs << " { return qvariant_cast< " << type << " >(internalPropGet(\""
|
||||
<< property.name << "\")); }" << endl;
|
||||
else
|
||||
hs << " { return internalPropGet(\"" << property.name << "\"); }" << endl;
|
||||
}
|
||||
|
||||
// setter:
|
||||
if (property.access != QDBusIntrospection::Property::Read) {
|
||||
hs << " inline void " << setter << "(" << constRefArg(type) << "value)" << endl
|
||||
<< " { internalPropSet(\"" << property.name
|
||||
<< "\", qVariantFromValue(value)); }" << endl;
|
||||
}
|
||||
|
||||
hs << endl;
|
||||
}
|
||||
|
||||
// methods:
|
||||
hs << "public slots: // METHODS" << endl;
|
||||
hs << "public Q_SLOTS: // METHODS" << endl;
|
||||
foreach (const QDBusIntrospection::Method &method, interface->methods) {
|
||||
bool isAsync = method.annotations.value(ANNOTATION_NO_WAIT) == "true";
|
||||
if (isAsync && !method.outputArgs.isEmpty()) {
|
||||
|
|
@ -544,7 +580,7 @@ static void writeProxy(const char *proxyFile, const QDBusIntrospection::Interfac
|
|||
<< endl;
|
||||
}
|
||||
|
||||
hs << "signals: // SIGNALS" << endl;
|
||||
hs << "Q_SIGNALS: // SIGNALS" << endl;
|
||||
foreach (const QDBusIntrospection::Signal &signal, interface->signals_) {
|
||||
hs << " ";
|
||||
if (signal.annotations.value("org.freedesktop.DBus.Deprecated") == "true")
|
||||
|
|
@ -720,12 +756,10 @@ static void writeAdaptor(const char *adaptorFile, const QDBusIntrospection::Inte
|
|||
foreach (const QDBusIntrospection::Property &property, interface->properties) {
|
||||
QByteArray type = qtTypeName(property.type);
|
||||
QString constRefType = constRefArg(type);
|
||||
QString getter = property.name;
|
||||
QString setter = "set" + property.name;
|
||||
getter[0] = getter[0].toLower();
|
||||
setter[3] = setter[3].toUpper();
|
||||
QString getter = propertyGetter(property);
|
||||
QString setter = propertySetter(property);
|
||||
|
||||
hs << " Q_PROPERTY(" << type << " " << property.name;
|
||||
hs << " Q_PROPERTY(" << type << " " << property.name;
|
||||
if (property.access != QDBusIntrospection::Property::Write)
|
||||
hs << " READ " << getter;
|
||||
if (property.access != QDBusIntrospection::Property::Read)
|
||||
|
|
@ -739,7 +773,7 @@ static void writeAdaptor(const char *adaptorFile, const QDBusIntrospection::Inte
|
|||
<< className << "::" << getter << "() const" << endl
|
||||
<< "{" << endl
|
||||
<< " // get the value of property " << property.name << endl
|
||||
<< " return qvariant_cast< " << type <<" >(object()->property(\"" << getter << "\"));" << endl
|
||||
<< " return qvariant_cast< " << type <<" >(parent()->property(\"" << property.name << "\"));" << endl
|
||||
<< "}" << endl
|
||||
<< endl;
|
||||
}
|
||||
|
|
@ -750,7 +784,7 @@ static void writeAdaptor(const char *adaptorFile, const QDBusIntrospection::Inte
|
|||
cs << "void " << className << "::" << setter << "(" << constRefType << "value)" << endl
|
||||
<< "{" << endl
|
||||
<< " // set the value of property " << property.name << endl
|
||||
<< " object()->setProperty(\"" << getter << "\", value);" << endl
|
||||
<< " parent()->setProperty(\"" << property.name << "\", value);" << endl
|
||||
<< "}" << endl
|
||||
<< endl;
|
||||
}
|
||||
|
|
@ -758,7 +792,7 @@ static void writeAdaptor(const char *adaptorFile, const QDBusIntrospection::Inte
|
|||
hs << endl;
|
||||
}
|
||||
|
||||
hs << "public slots: // METHODS" << endl;
|
||||
hs << "public Q_SLOTS: // METHODS" << endl;
|
||||
foreach (const QDBusIntrospection::Method &method, interface->methods) {
|
||||
bool isAsync = method.annotations.value(ANNOTATION_NO_WAIT) == "true";
|
||||
if (isAsync && !method.outputArgs.isEmpty()) {
|
||||
|
|
@ -805,7 +839,7 @@ static void writeAdaptor(const char *adaptorFile, const QDBusIntrospection::Inte
|
|||
// make the call
|
||||
if (method.inputArgs.count() <= 10 && method.outputArgs.count() <= 1) {
|
||||
// we can use QMetaObject::invokeMethod
|
||||
static const char invoke[] = " QMetaObject::invokeMethod(object(), \"";
|
||||
static const char invoke[] = " QMetaObject::invokeMethod(parent(), \"";
|
||||
cs << invoke << name << "\"";
|
||||
|
||||
if (!method.outputArgs.isEmpty())
|
||||
|
|
@ -830,7 +864,7 @@ static void writeAdaptor(const char *adaptorFile, const QDBusIntrospection::Inte
|
|||
<< " //";
|
||||
if (!method.outputArgs.isEmpty())
|
||||
cs << argNames.at(method.inputArgs.count()) << " = ";
|
||||
cs << "static_cast<YourObjectType *>(object())->" << name << "(";
|
||||
cs << "static_cast<YourObjectType *>(parent())->" << name << "(";
|
||||
|
||||
int argPos = 0;
|
||||
bool first = true;
|
||||
|
|
@ -851,7 +885,7 @@ static void writeAdaptor(const char *adaptorFile, const QDBusIntrospection::Inte
|
|||
<< endl;
|
||||
}
|
||||
|
||||
hs << "signals: // SIGNALS" << endl;
|
||||
hs << "Q_SIGNALS: // SIGNALS" << endl;
|
||||
foreach (const QDBusIntrospection::Signal &signal, interface->signals_) {
|
||||
hs << " ";
|
||||
if (signal.annotations.value("org.freedesktop.DBus.Deprecated") == "true")
|
||||
|
|
|
|||
|
|
@ -51,12 +51,7 @@ Q_GLOBAL_STATIC(QDBusAdaptorInit, qAdaptorInit)
|
|||
|
||||
QDBusAdaptorConnector *qDBusFindAdaptorConnector(QObject *obj)
|
||||
{
|
||||
qAdaptorInit();
|
||||
|
||||
#if 0
|
||||
if (caller->metaObject() == QDBusAdaptorConnector::staticMetaObject)
|
||||
return 0; // it's a QDBusAdaptorConnector
|
||||
#endif
|
||||
(void)qAdaptorInit();
|
||||
|
||||
if (!obj)
|
||||
return 0;
|
||||
|
|
@ -66,9 +61,14 @@ QDBusAdaptorConnector *qDBusFindAdaptorConnector(QObject *obj)
|
|||
return connector;
|
||||
}
|
||||
|
||||
QDBusAdaptorConnector *qDBusFindAdaptorConnector(QDBusAbstractAdaptor *adaptor)
|
||||
{
|
||||
return qDBusFindAdaptorConnector(adaptor->parent());
|
||||
}
|
||||
|
||||
QDBusAdaptorConnector *qDBusCreateAdaptorConnector(QObject *obj)
|
||||
{
|
||||
qAdaptorInit();
|
||||
(void)qAdaptorInit();
|
||||
|
||||
QDBusAdaptorConnector *connector = qDBusFindAdaptorConnector(obj);
|
||||
if (connector)
|
||||
|
|
@ -122,15 +122,11 @@ void QDBusAbstractAdaptorPrivate::saveIntrospectionXml(QDBusAbstractAdaptor *ada
|
|||
|
||||
/*!
|
||||
Constructs a QDBusAbstractAdaptor with \a parent as the object we refer to.
|
||||
|
||||
\warning Use object() to retrieve the object passed as \a parent to this constructor. The real
|
||||
parent object (as retrieved by QObject::parent()) may be something else.
|
||||
*/
|
||||
QDBusAbstractAdaptor::QDBusAbstractAdaptor(QObject* parent)
|
||||
: d(new QDBusAbstractAdaptorPrivate)
|
||||
: QObject(parent), d(new QDBusAbstractAdaptorPrivate)
|
||||
{
|
||||
QDBusAdaptorConnector *connector = qDBusCreateAdaptorConnector(parent);
|
||||
setParent(connector);
|
||||
|
||||
connector->waitingForPolish = true;
|
||||
QTimer::singleShot(0, connector, SLOT(polish()));
|
||||
|
|
@ -153,7 +149,7 @@ QDBusAbstractAdaptor::~QDBusAbstractAdaptor()
|
|||
*/
|
||||
QObject* QDBusAbstractAdaptor::object() const
|
||||
{
|
||||
return parent()->parent();
|
||||
return parent();
|
||||
}
|
||||
|
||||
/*!
|
||||
|
|
@ -167,7 +163,7 @@ QObject* QDBusAbstractAdaptor::object() const
|
|||
void QDBusAbstractAdaptor::setAutoRelaySignals(bool enable)
|
||||
{
|
||||
const QMetaObject *us = metaObject();
|
||||
const QMetaObject *them = object()->metaObject();
|
||||
const QMetaObject *them = parent()->metaObject();
|
||||
for (int idx = staticMetaObject.methodCount(); idx < us->methodCount(); ++idx) {
|
||||
QMetaMethod mm = us->method(idx);
|
||||
|
||||
|
|
@ -179,9 +175,9 @@ void QDBusAbstractAdaptor::setAutoRelaySignals(bool enable)
|
|||
if (them->indexOfSignal(sig) == -1)
|
||||
continue;
|
||||
sig.prepend(QSIGNAL_CODE + '0');
|
||||
object()->disconnect(sig, this, sig);
|
||||
parent()->disconnect(sig, this, sig);
|
||||
if (enable)
|
||||
connect(object(), sig, sig);
|
||||
connect(parent(), sig, sig);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -274,7 +270,7 @@ void QDBusAdaptorConnector::relay(QObject *sender)
|
|||
qWarning("Inconsistency detected: QDBusAdaptorConnector::relay got called with unexpected sender object!");
|
||||
} else {
|
||||
QMetaMethod mm = senderMetaObject->method(lastSignalIdx);
|
||||
QObject *object = static_cast<QDBusAbstractAdaptor *>(sender)->object();
|
||||
QObject *object = static_cast<QDBusAbstractAdaptor *>(sender)->parent();
|
||||
|
||||
// break down the parameter list
|
||||
QList<int> types;
|
||||
|
|
@ -316,8 +312,9 @@ void QDBusAdaptorConnector::relay(QObject *sender)
|
|||
|
||||
void QDBusAdaptorConnector::signalBeginCallback(QObject *caller, int method_index, void **argv)
|
||||
{
|
||||
QDBusAdaptorConnector *data = qobject_cast<QDBusAdaptorConnector *>(caller->parent());
|
||||
if (data) {
|
||||
QDBusAbstractAdaptor *adaptor = qobject_cast<QDBusAbstractAdaptor *>(caller);
|
||||
if (adaptor) {
|
||||
QDBusAdaptorConnector *data = qDBusFindAdaptorConnector(adaptor);
|
||||
data->lastSignalIdx = method_index;
|
||||
data->argv = argv;
|
||||
data->senderMetaObject = caller->metaObject();
|
||||
|
|
@ -327,8 +324,9 @@ void QDBusAdaptorConnector::signalBeginCallback(QObject *caller, int method_inde
|
|||
|
||||
void QDBusAdaptorConnector::signalEndCallback(QObject *caller, int)
|
||||
{
|
||||
QDBusAdaptorConnector *data = qobject_cast<QDBusAdaptorConnector *>(caller->parent());
|
||||
if (data) {
|
||||
QDBusAbstractAdaptor *adaptor = qobject_cast<QDBusAbstractAdaptor *>(caller);
|
||||
if (adaptor) {
|
||||
QDBusAdaptorConnector *data = qDBusFindAdaptorConnector(adaptor);
|
||||
data->lastSignalIdx = 0;
|
||||
data->argv = 0;
|
||||
data->senderMetaObject = 0;
|
||||
|
|
|
|||
|
|
@ -37,7 +37,7 @@ protected:
|
|||
public:
|
||||
~QDBusAbstractAdaptor();
|
||||
|
||||
QObject *object() const;
|
||||
Q_DECL_DEPRECATED QObject *object() const;
|
||||
|
||||
protected:
|
||||
void setAutoRelaySignals(bool enable);
|
||||
|
|
|
|||
|
|
@ -28,6 +28,60 @@
|
|||
#include "qdbusmetaobject_p.h"
|
||||
#include "qdbusconnection_p.h"
|
||||
|
||||
QVariant QDBusAbstractInterfacePrivate::property(const QMetaProperty &mp) const
|
||||
{
|
||||
// try to read this property
|
||||
QDBusMessage msg = QDBusMessage::methodCall(service, path, DBUS_INTERFACE_PROPERTIES,
|
||||
QLatin1String("Get"));
|
||||
msg << interface << QString::fromUtf8(mp.name());
|
||||
QDBusMessage reply = connp->sendWithReply(msg, QDBusConnection::NoUseEventLoop);
|
||||
|
||||
if (reply.type() == QDBusMessage::ReplyMessage && reply.count() == 1 &&
|
||||
reply.signature() == QLatin1String("v")) {
|
||||
QVariant value = QDBusTypeHelper<QVariant>::fromVariant(reply.at(0));
|
||||
|
||||
// make sure the type is right
|
||||
if (qstrcmp(mp.typeName(), value.typeName()) == 0) {
|
||||
if (mp.type() == QVariant::LastType)
|
||||
// QVariant is special in this context
|
||||
return QDBusTypeHelper<QVariant>::fromVariant(value);
|
||||
|
||||
return value;
|
||||
}
|
||||
}
|
||||
|
||||
// there was an error...
|
||||
if (reply.type() == QDBusMessage::ErrorMessage)
|
||||
lastError = reply;
|
||||
else if (reply.signature() != QLatin1String("v")) {
|
||||
QString errmsg = QLatin1String("Invalid signature `%1' in return from call to "
|
||||
DBUS_INTERFACE_PROPERTIES);
|
||||
lastError = QDBusError(QDBusError::InvalidSignature, errmsg.arg(reply.signature()));
|
||||
} else {
|
||||
QString errmsg = QLatin1String("Unexpected type `%1' when retrieving property "
|
||||
"`%2 %3.%4'");
|
||||
lastError = QDBusError(QDBusError::InvalidSignature,
|
||||
errmsg.arg(QLatin1String(reply.at(0).typeName()),
|
||||
QLatin1String(mp.typeName()),
|
||||
interface, QString::fromUtf8(mp.name())));
|
||||
}
|
||||
|
||||
return QVariant();
|
||||
}
|
||||
|
||||
void QDBusAbstractInterfacePrivate::setProperty(const QMetaProperty &mp, const QVariant &value)
|
||||
{
|
||||
// send the value
|
||||
QDBusMessage msg = QDBusMessage::methodCall(service, path, DBUS_INTERFACE_PROPERTIES,
|
||||
QLatin1String("Set"));
|
||||
msg.setSignature(QLatin1String("ssv"));
|
||||
msg << interface << QString::fromUtf8(mp.name()) << value;
|
||||
QDBusMessage reply = connp->sendWithReply(msg, QDBusConnection::NoUseEventLoop);
|
||||
|
||||
if (reply.type() != QDBusMessage::ReplyMessage)
|
||||
lastError = reply;
|
||||
}
|
||||
|
||||
/*!
|
||||
\class QDBusAbstractInterface
|
||||
\brief Base class for all D-Bus interfaces in the QtDBus binding, allowing access to remote interfaces.
|
||||
|
|
@ -246,6 +300,40 @@ void QDBusAbstractInterface::disconnectNotify(const char *signal)
|
|||
d->connp->disconnectRelay(d->service, d->path, d->interface, this, signal);
|
||||
}
|
||||
|
||||
/*!
|
||||
\internal
|
||||
Get the value of the property \a propname.
|
||||
*/
|
||||
QVariant QDBusAbstractInterface::internalPropGet(const char *propname) const
|
||||
{
|
||||
// assume this property exists and is readable
|
||||
// we're only called from generated code anyways
|
||||
|
||||
int idx = metaObject()->indexOfProperty(propname);
|
||||
if (idx != -1)
|
||||
return d_func()->property(metaObject()->property(idx));
|
||||
qWarning("QDBusAbstractInterface::internalPropGet called with unknown property '%s'", propname);
|
||||
return QVariant(); // error
|
||||
}
|
||||
|
||||
/*!
|
||||
\internal
|
||||
Set the value of the property \a propname to \a value.
|
||||
*/
|
||||
void QDBusAbstractInterface::internalPropSet(const char *propname, const QVariant &value)
|
||||
{
|
||||
Q_D(QDBusAbstractInterface);
|
||||
|
||||
// assume this property exists and is writeable
|
||||
// we're only called from generated code anyways
|
||||
|
||||
int idx = metaObject()->indexOfProperty(propname);
|
||||
if (idx != -1)
|
||||
d->setProperty(metaObject()->property(idx), value);
|
||||
else
|
||||
qWarning("QDBusAbstractInterface::internalPropGet called with unknown property '%s'", propname);
|
||||
}
|
||||
|
||||
/*!
|
||||
\overload
|
||||
\fn QDBusMessage QDBusAbstractInterface::call(const QString &method)
|
||||
|
|
|
|||
|
|
@ -242,6 +242,8 @@ protected:
|
|||
QDBusAbstractInterface(QDBusAbstractInterfacePrivate *);
|
||||
void connectNotify(const char *signal);
|
||||
void disconnectNotify(const char *signal);
|
||||
QVariant internalPropGet(const char *propname) const;
|
||||
void internalPropSet(const char *propname, const QVariant &value);
|
||||
|
||||
private:
|
||||
friend class QDBusInterface;
|
||||
|
|
|
|||
|
|
@ -54,7 +54,7 @@ public:
|
|||
QString service;
|
||||
QString path;
|
||||
QString interface;
|
||||
QDBusError lastError;
|
||||
mutable QDBusError lastError;
|
||||
bool isValid;
|
||||
|
||||
inline QDBusAbstractInterfacePrivate(const QDBusConnection& con, QDBusConnectionPrivate *conp,
|
||||
|
|
@ -62,6 +62,10 @@ public:
|
|||
: conn(con), connp(conp), service(serv), path(p), interface(iface), isValid(true)
|
||||
{ }
|
||||
virtual ~QDBusAbstractInterfacePrivate() { }
|
||||
|
||||
// these functions do not check if the property is valid
|
||||
QVariant property(const QMetaProperty &mp) const;
|
||||
void setProperty(const QMetaProperty &mp, const QVariant &value);
|
||||
};
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -180,72 +180,24 @@ int QDBusInterfacePrivate::metacall(QMetaObject::Call c, int id, void **argv)
|
|||
if (!mp.isReadable())
|
||||
return -1; // don't read
|
||||
|
||||
// try to read this property
|
||||
QDBusMessage msg = QDBusMessage::methodCall(service, path, DBUS_INTERFACE_PROPERTIES,
|
||||
QLatin1String("Get"));
|
||||
msg << interface << QString::fromUtf8(mp.name());
|
||||
QVariant value = property(mp);
|
||||
if (value.type() == QVariant::Invalid)
|
||||
// an error occurred -- property already set lastError
|
||||
return -1;
|
||||
else if (mp.type() == QVariant::LastType)
|
||||
// QVariant is special in this context
|
||||
*reinterpret_cast<QVariant *>(argv[0]) = value;
|
||||
else
|
||||
QDBusMetaObject::assign(argv[0], value);
|
||||
|
||||
QPointer<QDBusAbstractInterface> qq = q;
|
||||
QDBusMessage reply = connp->sendWithReply(msg, QDBusConnection::UseEventLoop);
|
||||
|
||||
// access to "this" or to "q" below this point must check for "qq"
|
||||
// we may have been deleted!
|
||||
|
||||
if (reply.type() == QDBusMessage::ReplyMessage && reply.count() == 1 &&
|
||||
reply.signature() == QLatin1String("v")) {
|
||||
QVariant value = QDBusTypeHelper<QVariant>::fromVariant(reply.at(0));
|
||||
|
||||
// make sure the type is right
|
||||
if (strcmp(mp.typeName(), value.typeName()) == 0) {
|
||||
if (mp.type() == QVariant::LastType)
|
||||
// QVariant is special in this context
|
||||
*reinterpret_cast<QVariant *>(argv[0]) = value;
|
||||
else
|
||||
QDBusMetaObject::assign(argv[0], value);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
// got an error
|
||||
if (qq.isNull())
|
||||
return -1; // bail out
|
||||
|
||||
if (reply.type() == QDBusMessage::ErrorMessage)
|
||||
lastError = reply;
|
||||
else if (reply.signature() != QLatin1String("v")) {
|
||||
QString errmsg = QLatin1String("Invalid signature `%1' in return from call to "
|
||||
DBUS_INTERFACE_PROPERTIES);
|
||||
lastError = QDBusError(QDBusError::InvalidSignature, errmsg.arg(reply.signature()));
|
||||
} else {
|
||||
QString errmsg = QLatin1String("Unexpected type `%1' when retrieving property "
|
||||
"`%2 %3.%4'");
|
||||
lastError = QDBusError(QDBusError::InvalidSignature,
|
||||
errmsg.arg(QLatin1String(reply.at(0).typeName()),
|
||||
QLatin1String(mp.typeName()),
|
||||
interface, QString::fromUtf8(mp.name())));
|
||||
}
|
||||
return -1;
|
||||
return -1; // handled
|
||||
} else if (c == QMetaObject::WriteProperty) {
|
||||
// QMetaProperty::write has already checked that we're writable
|
||||
// it has also checked that the type is right
|
||||
QVariant value(metaObject->propertyMetaType(id), argv[0]);
|
||||
QMetaProperty mp = metaObject->property(id + metaObject->propertyOffset());
|
||||
|
||||
// send the value
|
||||
QDBusMessage msg = QDBusMessage::methodCall(service, path, DBUS_INTERFACE_PROPERTIES,
|
||||
QLatin1String("Set"));
|
||||
msg.setSignature(QLatin1String("ssv"));
|
||||
msg << interface << QString::fromUtf8(mp.name()) << value;
|
||||
|
||||
QPointer<QDBusAbstractInterface> qq = q;
|
||||
QDBusMessage reply = connp->sendWithReply(msg, QDBusConnection::UseEventLoop);
|
||||
|
||||
// access to "this" or to "q" below this point must check for "qq"
|
||||
// we may have been deleted!
|
||||
|
||||
if (!qq.isNull() && reply.type() != QDBusMessage::ReplyMessage)
|
||||
lastError = reply;
|
||||
|
||||
setProperty(mp, value);
|
||||
return -1;
|
||||
}
|
||||
return id;
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue