📄 qdbusabstractinterface.cpp
字号:
/******************************************************************************** Copyright (C) 1992-2006 Trolltech ASA. All rights reserved.**** This file is part of the tools applications of the Qt Toolkit.**** This file may be used under the terms of the GNU General Public** License version 2.0 as published by the Free Software Foundation** and appearing in the file LICENSE.GPL included in the packaging of** this file. Please review the following information to ensure GNU** General Public Licensing requirements will be met:** http://www.trolltech.com/products/qt/opensource.html**** If you are unsure which license is appropriate for your use, please** review the following information:** http://www.trolltech.com/products/qt/licensing.html or contact the** sales department at sales@trolltech.com.**** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.******************************************************************************/#include "qdbusabstractinterface.h"#include "qdbusabstractinterface_p.h"#include "qdbusmetaobject_p.h"#include "qdbusutil_p.h"#include <QDebug>QDBusAbstractInterfacePrivate::QDBusAbstractInterfacePrivate(const QString &serv, const QString &p, const QString &iface, const QDBusConnection& con, bool isDynamic) : connection(con), service(serv), path(p), interface(iface), isValid(true){ if (isDynamic) { // QDBusInterface: service and object path can't be empty, but interface can Q_ASSERT_X(QDBusUtil::isValidBusName(service), "QDBusInterface::QDBusInterface", "Invalid service name"); Q_ASSERT_X(QDBusUtil::isValidObjectPath(path), "QDBusInterface::QDBusInterface", "Invalid object path given"); Q_ASSERT_X(interface.isEmpty() || QDBusUtil::isValidInterfaceName(interface), "QDBusInterface::QDBusInterface", "Invalid interface name"); } else { // all others: service and path can be empty here, but interface can't Q_ASSERT_X(service.isEmpty() || QDBusUtil::isValidBusName(service), "QDBusAbstractInterface::QDBusAbstractInterface", "Invalid service name"); Q_ASSERT_X(path.isEmpty() || QDBusUtil::isValidObjectPath(path), "QDBusAbstractInterface::QDBusAbstractInterface", "Invalid object path given"); Q_ASSERT_X(QDBusUtil::isValidInterfaceName(interface), "QDBusAbstractInterface::QDBusAbstractInterface", "Invalid interface class!"); } if (!connection.isConnected()) { lastError = QDBusError(QDBusError::Disconnected, QLatin1String("Not connected to D-Bus server")); isValid = false; } else if (!service.isEmpty()) { // check if it's there first -- FIXME: add binding mode QString owner = connectionPrivate()->getNameOwner(service); // verify the name owner if (owner.isEmpty()) { isValid = false; lastError = connectionPrivate()->lastError; } }}QVariant QDBusAbstractInterfacePrivate::property(const QMetaProperty &mp) const{ if (!connection.isConnected()) // not connected return QVariant(); // try to read this property QDBusMessage msg = QDBusMessage::createMethodCall(service, path, QLatin1String(DBUS_INTERFACE_PROPERTIES), QLatin1String("Get")); msg << interface << QString::fromUtf8(mp.name()); QDBusMessage reply = connection.call(msg, QDBus::Block); if (reply.type() == QDBusMessage::ReplyMessage && reply.arguments().count() == 1 && reply.signature() == QLatin1String("v")) { QVariant value = qvariant_cast<QDBusVariant>(reply.arguments().at(0)).variant(); // 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 qvariant_cast<QDBusVariant>(reply.arguments().at(0)).variant(); 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.arguments().at(0).typeName()), QLatin1String(mp.typeName()), interface, QString::fromUtf8(mp.name()))); } return QVariant();}void QDBusAbstractInterfacePrivate::setProperty(const QMetaProperty &mp, const QVariant &value){ if (!connection.isConnected()) // not connected return; // send the value QDBusMessage msg = QDBusMessage::createMethodCall(service, path, QLatin1String(DBUS_INTERFACE_PROPERTIES), QLatin1String("Set")); msg << interface << QString::fromUtf8(mp.name()) << qVariantFromValue(QDBusVariant(value)); QDBusMessage reply = connection.call(msg, QDBus::Block); if (reply.type() != QDBusMessage::ReplyMessage) lastError = reply;}void QDBusAbstractInterfacePrivate::_q_serviceOwnerChanged(const QString &name, const QString &oldOwner, const QString &newOwner){ Q_UNUSED(oldOwner); //qDebug() << "QDBusAbstractInterfacePrivate serviceOwnerChanged" << name << oldOwner << newOwner; if (name == service) isValid = !newOwner.isEmpty();}/*! \class QDBusAbstractInterface \inmodule QtDBus \since 4.2 \brief The QDBusAbstractInterface class is the base class for all D-Bus interfaces in the QtDBus binding, allowing access to remote interfaces Generated-code classes also derive from QDBusAbstractInterface, all methods described here are also valid for generated-code classes. In addition to those described here, generated-code classes provide member functions for the remote methods, which allow for compile-time checking of the correct parameters and return values, as well as property type-matching and signal parameter-matching. \sa {dbusxml2cpp.html}{The dbusxml2cpp compiler}, QDBusInterface*//*! \internal This is the constructor called from QDBusInterface::QDBusInterface.*/QDBusAbstractInterface::QDBusAbstractInterface(QDBusAbstractInterfacePrivate &d, QObject *parent) : QObject(d, parent){ // keep track of the service owner QObject::connect(d_func()->connectionPrivate(), SIGNAL(serviceOwnerChanged(QString,QString,QString)), this, SLOT(_q_serviceOwnerChanged(QString,QString,QString)));}/*! \internal This is the constructor called from static classes derived from QDBusAbstractInterface (i.e., those generated by dbusxml2cpp).*/QDBusAbstractInterface::QDBusAbstractInterface(const QString &service, const QString &path, const char *interface, const QDBusConnection &con, QObject *parent) : QObject(*new QDBusAbstractInterfacePrivate(service, path, QString::fromLatin1(interface), con, false), parent){ // keep track of the service owner QObject::connect(d_func()->connectionPrivate(), SIGNAL(serviceOwnerChanged(QString,QString,QString)), this, SLOT(_q_serviceOwnerChanged(QString,QString,QString)));}/*! Releases this object's resources.*/QDBusAbstractInterface::~QDBusAbstractInterface(){}/*! Returns true if this is a valid reference to a remote object. It returns false if there was an error during the creation of this interface (for instance, if the remote application does not exist). Note: when dealing with remote objects, it is not always possible to determine if it exists when creating a QDBusInterface.*/bool QDBusAbstractInterface::isValid() const{ return d_func()->isValid;}/*! Returns the connection this interface is assocated with.*/QDBusConnection QDBusAbstractInterface::connection() const{ return d_func()->connection;}/*! Returns the name of the service this interface is associated with.*/QString QDBusAbstractInterface::service() const{ return d_func()->service;}/*! Returns the object path that this interface is associated with.*/QString QDBusAbstractInterface::path() const{ return d_func()->path;}/*! Returns the name of this interface.*/QString QDBusAbstractInterface::interface() const{ return d_func()->interface;}/*! Returns the error the last operation produced, or an invalid error if the last operation did not produce an error.*/QDBusError QDBusAbstractInterface::lastError() const{ return d_func()->lastError;}/*! Places a call to the remote method specified by \a method on this interface, using \a args as arguments. This function returns the message that was received as a reply, which can be a normal QDBusMessage::ReplyMessage (indicating success) or QDBusMessage::ErrorMessage (if the call failed). The \a mode parameter specifies how this call should be placed. If the call succeeds, lastError() will be cleared; otherwise, it will contain the error this call produced. Normally, you should place calls using call().
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -