2006-04-23 Thiago Macieira <thiago.macieira@trolltech.com>
+ * qt/qdbusconnection_p.h:
+ * qt/qdbusmetaobject.cpp:
+ * qt/qdbusmetaobject_p.h:
+ * qt/qdbusintegrator.cpp: Use the new merged-interface mode
+ for the dynamic meta object. No need to guess which
+ interface to call.
+ * qt/qdbusabstractinterface_p.h:
+ * qt/qdbusconnection.cpp:
+ * qt/qdbusintegrator.cpp:
+ * qt/qdbusinterface.cpp:
+ * qt/qdbusinterface.h: Make findInterface always return a non-null pointer.
+ Add a QDBusRef that looks and behaves like DCOPRef.
+
+2006-04-23 Thiago Macieira <thiago.macieira@trolltech.com>
+
* dbus/dbus-connection.c: Interfaces are optional in method
calls, so don't give up if the interface parameter is NULL.
Patch reviewed by Havoc Pennington.
QString path;
QString interface;
QDBusError lastError;
+ bool isValid;
inline QDBusAbstractInterfacePrivate(const QDBusConnection& con, QDBusConnectionPrivate *conp,
const QString &serv, const QString &p, const QString &iface)
- : conn(con), connp(conp), service(serv), path(p), interface(iface)
+ : conn(con), connp(conp), service(serv), path(p), interface(iface), isValid(true)
{ }
virtual ~QDBusAbstractInterfacePrivate() { }
};
return 0;
QDBusInterfacePrivate *p = d->findInterface(service, path, interface);
- if (!p)
- return 0;
QDBusInterface *retval = new QDBusInterface(p);
retval->setParent(d);
return retval;
private:
QDBusMetaObject *findMetaObject(const QString &service, const QString &path,
- QString &interface);
+ const QString &interface);
public slots:
// public slots
const QString &path,
const QString &interface)
{
-
- if (!connection || !QDBusUtil::isValidObjectPath(path))
- return 0;
- if (!interface.isEmpty() && !QDBusUtil::isValidInterfaceName(interface))
- return 0;
-
// check if it's there first -- FIXME: add binding mode
+ QDBusMetaObject *mo = 0;
QString owner = getNameOwner(service);
- if (owner.isEmpty())
- return 0;
+ if (connection && !owner.isEmpty() && QDBusUtil::isValidObjectPath(path) &&
+ (interface.isEmpty() || QDBusUtil::isValidInterfaceName(interface)))
+ mo = findMetaObject(owner, path, interface);
+
+ QDBusInterfacePrivate *p = new QDBusInterfacePrivate(QDBusConnection(name), this, owner, path, interface, mo);
+
+ if (!mo) {
+ // invalid object
+ p->isValid = false;
+ p->lastError = lastError;
+ if (!lastError.isValid()) {
+ // try to determine why we couldn't get the data
+ if (!connection)
+ p->lastError = QDBusError(QDBusError::Disconnected,
+ QLatin1String("Not connected to D-Bus server"));
+ else if (owner.isEmpty())
+ p->lastError = QDBusError(QDBusError::ServiceUnknown,
+ QString(QLatin1String("Service %1 is unknown")).arg(service));
+ else if (!QDBusUtil::isValidObjectPath(path))
+ p->lastError = QDBusError(QDBusError::InvalidArgs,
+ QString(QLatin1String("Object path %1 is invalid")).arg(path));
+ else if (!interface.isEmpty() && !QDBusUtil::isValidInterfaceName(interface))
+ p->lastError = QDBusError(QDBusError::InvalidArgs,
+ QString(QLatin1String("Interface %1 is invalid")).arg(interface));
+ else
+ p->lastError = QDBusError(QDBusError::Other, QLatin1String("Unknown error"));
+ }
+ }
- QString tmp(interface);
- QDBusMetaObject *mo = findMetaObject(owner, path, tmp);
- if (mo)
- return new QDBusInterfacePrivate(QDBusConnection(name), this, owner, path, tmp, mo);
- return 0; // error has been set
+ return p;
}
QDBusMetaObject *
QDBusConnectionPrivate::findMetaObject(const QString &service, const QString &path,
- QString &interface)
+ const QString &interface)
{
if (!interface.isEmpty()) {
QReadLocker locker(&lock);
*/
const QMetaObject *QDBusInterface::metaObject() const
{
- return d_func()->metaObject;
+ return d_func()->isValid ? d_func()->metaObject : &QDBusAbstractInterface::staticMetaObject;
}
/*!
int QDBusInterface::qt_metacall(QMetaObject::Call _c, int _id, void **_a)
{
_id = QDBusAbstractInterface::qt_metacall(_c, _id, _a);
- if (_id < 0)
+ if (_id < 0 || !d_func()->isValid)
return _id;
return d_func()->metacall(_c, _id, _a);
}
return id;
}
+QDBusRef::QDBusRef(QDBusConnection &conn, const QString &service, const QString &path,
+ const QString &interface)
+ : d(conn.findInterface(service, path, interface))
+{
+}
+
+QDBusRef::QDBusRef(const QString &service, const QString &path, const QString &interface)
+ : d(QDBus::sessionBus().findInterface(service, path, interface))
+{
+}
+
Q_DECLARE_PRIVATE(QDBusInterface);
};
+struct QDBUS_EXPORT QDBusRef
+{
+ QDBusRef(QDBusConnection &conn, const QString &service, const QString &path,
+ const QString &interface = QString());
+ QDBusRef(const QString &service, const QString &path, const QString &interface = QString());
+ ~QDBusRef() { delete d; }
+
+ QDBusInterface* operator->() const { return d; }
+private:
+ QDBusInterface *const d;
+};
+
#endif
/////////
// class QDBusMetaObject
-QDBusMetaObject *QDBusMetaObject::createMetaObject(QString &interface, const QString &xml,
+QDBusMetaObject *QDBusMetaObject::createMetaObject(const QString &interface, const QString &xml,
QHash<QString, QDBusMetaObject *> &cache,
QDBusError &error)
{
}
- if (it.key() == interface) {
+ if (it.key() == interface)
// it's us
we = obj;
- } else if (interface.isEmpty() &&
- !it.key().startsWith(QLatin1String("org.freedesktop.DBus."))) {
- // also us
- we = obj;
- interface = it.key();
- }
}
if (we)
generator.write(we);
we->cached = false;
return we;
+ } else if (interface.isEmpty()) {
+ // merge all interfaces
+ it = parsed.constBegin();
+ QDBusIntrospection::Interface merged = *it.value().constData();
+
+ for (++it; it != end; ++it) {
+ merged.annotations.unite(it.value()->annotations);
+ merged.methods.unite(it.value()->methods);
+ merged.signals_.unite(it.value()->signals_);
+ merged.properties.unite(it.value()->properties);
+ }
+
+ merged.name = QLatin1String("local.Merged");
+ merged.introspection.clear();
+
+ we = new QDBusMetaObject;
+ QDBusMetaObjectGenerator generator(merged.name, &merged);
+ generator.write(we);
+ we->cached = false;
+ return we;
}
// mark as an error
{
bool cached;
- static QDBusMetaObject *createMetaObject(QString &interface, const QString &xml,
+ static QDBusMetaObject *createMetaObject(const QString &interface, const QString &xml,
QHash<QString, QDBusMetaObject *> &map,
QDBusError &error);
~QDBusMetaObject()