diff options
| -rw-r--r-- | ChangeLog | 20 | ||||
| -rw-r--r-- | qt/dbusidl2cpp.cpp | 112 | ||||
| -rw-r--r-- | qt/qdbusabstractadaptor.cpp | 40 | ||||
| -rw-r--r-- | qt/qdbusabstractadaptor.h | 2 | ||||
| -rw-r--r-- | qt/qdbusabstractinterface.cpp | 88 | ||||
| -rw-r--r-- | qt/qdbusabstractinterface.h | 2 | ||||
| -rw-r--r-- | qt/qdbusabstractinterface_p.h | 6 | ||||
| -rw-r--r-- | qt/qdbusinterface.cpp | 70 | 
8 files changed, 219 insertions, 121 deletions
| @@ -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: diff --git a/qt/dbusidl2cpp.cpp b/qt/dbusidl2cpp.cpp index eb1a1b1e..8097a075 100644 --- a/qt/dbusidl2cpp.cpp +++ b/qt/dbusidl2cpp.cpp @@ -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") diff --git a/qt/qdbusabstractadaptor.cpp b/qt/qdbusabstractadaptor.cpp index e2ab0964..2794293d 100644 --- a/qt/qdbusabstractadaptor.cpp +++ b/qt/qdbusabstractadaptor.cpp @@ -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; diff --git a/qt/qdbusabstractadaptor.h b/qt/qdbusabstractadaptor.h index cc85a891..16fbf5d9 100644 --- a/qt/qdbusabstractadaptor.h +++ b/qt/qdbusabstractadaptor.h @@ -37,7 +37,7 @@ protected:  public:      ~QDBusAbstractAdaptor(); -    QObject *object() const; +    Q_DECL_DEPRECATED QObject *object() const;  protected:      void setAutoRelaySignals(bool enable); diff --git a/qt/qdbusabstractinterface.cpp b/qt/qdbusabstractinterface.cpp index eec373a3..7c09b510 100644 --- a/qt/qdbusabstractinterface.cpp +++ b/qt/qdbusabstractinterface.cpp @@ -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. @@ -247,6 +301,40 @@ void QDBusAbstractInterface::disconnectNotify(const char *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) diff --git a/qt/qdbusabstractinterface.h b/qt/qdbusabstractinterface.h index 23f928a2..1ad1a532 100644 --- a/qt/qdbusabstractinterface.h +++ b/qt/qdbusabstractinterface.h @@ -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; diff --git a/qt/qdbusabstractinterface_p.h b/qt/qdbusabstractinterface_p.h index 8f4d8dc3..43807071 100644 --- a/qt/qdbusabstractinterface_p.h +++ b/qt/qdbusabstractinterface_p.h @@ -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);  }; diff --git a/qt/qdbusinterface.cpp b/qt/qdbusinterface.cpp index 48b1011c..0afa452b 100644 --- a/qt/qdbusinterface.cpp +++ b/qt/qdbusinterface.cpp @@ -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()); - -        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 +        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); -        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; | 
