summaryrefslogtreecommitdiffstats
path: root/tools/qdbus
diff options
context:
space:
mode:
Diffstat (limited to 'tools/qdbus')
-rw-r--r--tools/qdbus/qdbus.pro3
-rw-r--r--tools/qdbus/qdbus/qdbus.cpp191
-rw-r--r--tools/qdbus/qdbuscpp2xml/qdbuscpp2xml.cpp2
-rw-r--r--tools/qdbus/qdbusviewer/qdbusmodel.cpp14
-rw-r--r--tools/qdbus/qdbusviewer/qdbusmodel.h1
-rw-r--r--tools/qdbus/qdbusviewer/qdbusviewer.cpp97
-rw-r--r--tools/qdbus/qdbusviewer/qdbusviewer.h7
-rw-r--r--tools/qdbus/qdbusxml2cpp/qdbusxml2cpp.cpp9
8 files changed, 202 insertions, 122 deletions
diff --git a/tools/qdbus/qdbus.pro b/tools/qdbus/qdbus.pro
index 01cd246..a264882 100644
--- a/tools/qdbus/qdbus.pro
+++ b/tools/qdbus/qdbus.pro
@@ -1,2 +1,3 @@
TEMPLATE = subdirs
-SUBDIRS = qdbus qdbusxml2cpp qdbuscpp2xml qdbusviewer
+SUBDIRS = qdbus qdbusxml2cpp qdbuscpp2xml
+!contains(QT_CONFIG, no-gui): SUBDIRS += qdbusviewer
diff --git a/tools/qdbus/qdbus/qdbus.cpp b/tools/qdbus/qdbus/qdbus.cpp
index 48b0dad..ce18cb9 100644
--- a/tools/qdbus/qdbus/qdbus.cpp
+++ b/tools/qdbus/qdbus/qdbus.cpp
@@ -248,123 +248,153 @@ static QStringList readList(QStringList &args)
return retval;
}
-static void placeCall(const QString &service, const QString &path, const QString &interface,
- const QString &member, QStringList args)
+static int placeCall(const QString &service, const QString &path, const QString &interface,
+ const QString &member, const QStringList& arguments, bool try_prop=true)
{
QDBusInterface iface(service, path, interface, connection);
// Don't check whether the interface is valid to allow DBus try to
// activate the service if possible.
+ QList<int> knownIds;
+ bool matchFound = false;
+ QStringList args = arguments;
QVariantList params;
if (!args.isEmpty()) {
const QMetaObject *mo = iface.metaObject();
QByteArray match = member.toLatin1();
match += '(';
- int midx = -1;
for (int i = mo->methodOffset(); i < mo->methodCount(); ++i) {
QMetaMethod mm = mo->method(i);
QByteArray signature = mm.signature();
- if (signature.startsWith(match)) {
- midx = i;
- break;
- }
+ if (signature.startsWith(match))
+ knownIds += i;
}
- if (midx == -1) {
- fprintf(stderr, "Cannot find '%s.%s' in object %s at %s\n",
- qPrintable(interface), qPrintable(member), qPrintable(path),
- qPrintable(service));
- exit(1);
- }
- QMetaMethod mm = mo->method(midx);
- QList<QByteArray> types = mm.parameterTypes();
- for (int i = 0; i < types.count(); ++i) {
- if (types.at(i).endsWith('&')) {
- // reference (and not a reference to const): output argument
- // we're done with the inputs
- while (types.count() > i)
- types.removeLast();
- break;
+ while (!matchFound) {
+ args = arguments; // reset
+ params.clear();
+ if (knownIds.isEmpty()) {
+ // Failed to set property after falling back?
+ // Bail out without displaying an error
+ if (!try_prop)
+ return 1;
+ if (try_prop && args.size() == 1) {
+ QStringList proparg;
+ proparg += interface;
+ proparg += member;
+ proparg += args.first();
+ if (!placeCall(service, path, "org.freedesktop.DBus.Properties", "Set", proparg, false))
+ return 0;
+ }
+ fprintf(stderr, "Cannot find '%s.%s' in object %s at %s\n",
+ qPrintable(interface), qPrintable(member), qPrintable(path),
+ qPrintable(service));
+ return 1;
}
- }
- for (int i = 0; !args.isEmpty() && i < types.count(); ++i) {
- int id = QVariant::nameToType(types.at(i));
- if (id == QVariant::UserType)
- id = QMetaType::type(types.at(i));
- Q_ASSERT(id);
-
- QVariant p;
- QString argument;
- if ((id == QVariant::List || id == QVariant::StringList)
- && args.at(0) == QLatin1String("("))
- p = readList(args);
- else
- p = argument = args.takeFirst();
-
- if (id == int(QMetaType::UChar)) {
- // special case: QVariant::convert doesn't convert to/from
- // UChar because it can't decide if it's a character or a number
- p = qVariantFromValue<uchar>(p.toUInt());
- } else if (id < int(QMetaType::User) && id != int(QVariant::Map)) {
- p.convert(QVariant::Type(id));
- if (p.type() == QVariant::Invalid) {
- fprintf(stderr, "Could not convert '%s' to type '%s'.\n",
- qPrintable(argument), types.at(i).constData());
- exit(1);
- }
- } else if (id == qMetaTypeId<QDBusVariant>()) {
- QDBusVariant tmp(p);
- p = qVariantFromValue(tmp);
- } else if (id == qMetaTypeId<QDBusObjectPath>()) {
- QDBusObjectPath path(argument);
- if (path.path().isNull()) {
- fprintf(stderr, "Cannot pass argument '%s' because it is not a valid object path.\n",
- qPrintable(argument));
- exit(1);
+ QMetaMethod mm = mo->method(knownIds.takeFirst());
+ QList<QByteArray> types = mm.parameterTypes();
+ for (int i = 0; i < types.count(); ++i) {
+ if (types.at(i).endsWith('&')) {
+ // reference (and not a reference to const): output argument
+ // we're done with the inputs
+ while (types.count() > i)
+ types.removeLast();
+ break;
}
- p = qVariantFromValue(path);
- } else if (id == qMetaTypeId<QDBusSignature>()) {
- QDBusSignature sig(argument);
- if (sig.signature().isNull()) {
- fprintf(stderr, "Cannot pass argument '%s' because it is not a valid signature.\n",
- qPrintable(argument));
- exit(1);
+ }
+
+ for (int i = 0; !args.isEmpty() && i < types.count(); ++i) {
+ int id = QVariant::nameToType(types.at(i));
+ if (id == QVariant::UserType)
+ id = QMetaType::type(types.at(i));
+ Q_ASSERT(id);
+
+ QVariant p;
+ QString argument;
+ if ((id == QVariant::List || id == QVariant::StringList)
+ && args.at(0) == QLatin1String("("))
+ p = readList(args);
+ else
+ p = argument = args.takeFirst();
+
+ if (id == int(QMetaType::UChar)) {
+ // special case: QVariant::convert doesn't convert to/from
+ // UChar because it can't decide if it's a character or a number
+ p = qVariantFromValue<uchar>(p.toUInt());
+ } else if (id < int(QMetaType::User) && id != int(QVariant::Map)) {
+ p.convert(QVariant::Type(id));
+ if (p.type() == QVariant::Invalid) {
+ fprintf(stderr, "Could not convert '%s' to type '%s'.\n",
+ qPrintable(argument), types.at(i).constData());
+ return 1 ;
+ }
+ } else if (id == qMetaTypeId<QDBusVariant>()) {
+ QDBusVariant tmp(p);
+ p = qVariantFromValue(tmp);
+ } else if (id == qMetaTypeId<QDBusObjectPath>()) {
+ QDBusObjectPath path(argument);
+ if (path.path().isNull()) {
+ fprintf(stderr, "Cannot pass argument '%s' because it is not a valid object path.\n",
+ qPrintable(argument));
+ return 1;
+ }
+ p = qVariantFromValue(path);
+ } else if (id == qMetaTypeId<QDBusSignature>()) {
+ QDBusSignature sig(argument);
+ if (sig.signature().isNull()) {
+ fprintf(stderr, "Cannot pass argument '%s' because it is not a valid signature.\n",
+ qPrintable(argument));
+ return 1;
+ }
+ p = qVariantFromValue(sig);
+ } else {
+ fprintf(stderr, "Sorry, can't pass arg of type '%s'.\n",
+ types.at(i).constData());
+ return 1;
}
- p = qVariantFromValue(sig);
- } else {
- fprintf(stderr, "Sorry, can't pass arg of type '%s'.\n",
- types.at(i).constData());
- exit(1);
+ params += p;
}
- params += p;
- }
- if (params.count() != types.count() || !args.isEmpty()) {
- fprintf(stderr, "Invalid number of parameters\n");
- exit(1);
- }
- }
+ if (params.count() == types.count() && args.isEmpty())
+ matchFound = true;
+ else if (knownIds.isEmpty()) {
+ fprintf(stderr, "Invalid number of parameters\n");
+ return 1;
+ }
+ } // while (!matchFound)
+ } // if (!args.isEmpty()
QDBusMessage reply = iface.callWithArgumentList(QDBus::Block, member, params);
if (reply.type() == QDBusMessage::ErrorMessage) {
QDBusError err = reply;
+ // Failed to retrieve property after falling back?
+ // Bail out without displaying an error
+ if (!try_prop)
+ return 1;
+ if (err.type() == QDBusError::UnknownMethod && try_prop) {
+ QStringList proparg;
+ proparg += interface;
+ proparg += member;
+ if (!placeCall(service, path, "org.freedesktop.DBus.Properties", "Get", proparg, false))
+ return 0;
+ }
if (err.type() == QDBusError::ServiceUnknown)
fprintf(stderr, "Service '%s' does not exist.\n", qPrintable(service));
else
printf("Error: %s\n%s\n", qPrintable(err.name()), qPrintable(err.message()));
- exit(2);
+ return 2;
} else if (reply.type() != QDBusMessage::ReplyMessage) {
fprintf(stderr, "Invalid reply type %d\n", int(reply.type()));
- exit(1);
+ return 1;
}
foreach (QVariant v, reply.arguments())
printArg(v);
- exit(0);
+ return 0;
}
static bool globServices(QDBusConnectionInterface *bus, const QString &glob)
@@ -483,6 +513,7 @@ int main(int argc, char **argv)
exit(1);
}
- placeCall(service, path, interface, member, args);
+ int ret = placeCall(service, path, interface, member, args);
+ exit(ret);
}
diff --git a/tools/qdbus/qdbuscpp2xml/qdbuscpp2xml.cpp b/tools/qdbus/qdbuscpp2xml/qdbuscpp2xml.cpp
index 3a80019..ba2bdd8 100644
--- a/tools/qdbus/qdbuscpp2xml/qdbuscpp2xml.cpp
+++ b/tools/qdbus/qdbuscpp2xml/qdbuscpp2xml.cpp
@@ -64,7 +64,7 @@ static const char docTypeHeader[] =
// in qdbusxmlgenerator.cpp
QT_BEGIN_NAMESPACE
-extern QDBUS_EXPORT QString qDBusGenerateMetaObjectXml(QString interface, const QMetaObject *mo,
+extern Q_DBUS_EXPORT QString qDBusGenerateMetaObjectXml(QString interface, const QMetaObject *mo,
const QMetaObject *base, int flags);
QT_END_NAMESPACE
diff --git a/tools/qdbus/qdbusviewer/qdbusmodel.cpp b/tools/qdbus/qdbusviewer/qdbusmodel.cpp
index befe4b4..f85e288 100644
--- a/tools/qdbus/qdbusviewer/qdbusmodel.cpp
+++ b/tools/qdbus/qdbusviewer/qdbusmodel.cpp
@@ -75,6 +75,7 @@ struct QDBusItem
bool isPrefetched;
QString name;
QString caption;
+ QString typeSignature;
};
QDomDocument QDBusModel::introspect(const QString &path)
@@ -118,6 +119,13 @@ void QDBusModel::addMethods(QDBusItem *parent, const QDomElement &iface)
item = new QDBusItem(QDBusModel::MethodItem,
child.attribute(QLatin1String("name")), parent);
item->caption = QLatin1String("Method: ") + item->name;
+ //get "type" from <arg> where "direction" is "in"
+ QDomElement n = child.firstChildElement();
+ while (!n.isNull()) {
+ if (n.attribute(QLatin1String("direction")) == QLatin1String("in"))
+ item->typeSignature += n.attribute(QLatin1String("type"));
+ n = n.nextSiblingElement();
+ }
} else if (child.tagName() == QLatin1String("signal")) {
item = new QDBusItem(QDBusModel::SignalItem,
child.attribute(QLatin1String("name")), parent);
@@ -298,6 +306,12 @@ QString QDBusModel::dBusMethodName(const QModelIndex &index) const
return item ? item->name : QString();
}
+QString QDBusModel::dBusTypeSignature(const QModelIndex &index) const
+{
+ QDBusItem *item = static_cast<QDBusItem *>(index.internalPointer());
+ return item ? item->typeSignature : QString();
+}
+
QModelIndex QDBusModel::findObject(const QDBusObjectPath &objectPath)
{
QStringList path = objectPath.path().split(QLatin1Char('/'), QString::SkipEmptyParts);
diff --git a/tools/qdbus/qdbusviewer/qdbusmodel.h b/tools/qdbus/qdbusviewer/qdbusmodel.h
index 1a3d8f0..e83c381 100644
--- a/tools/qdbus/qdbusviewer/qdbusmodel.h
+++ b/tools/qdbus/qdbusviewer/qdbusmodel.h
@@ -72,6 +72,7 @@ public:
QString dBusPath(const QModelIndex &index) const;
QString dBusInterface(const QModelIndex &index) const;
QString dBusMethodName(const QModelIndex &index) const;
+ QString dBusTypeSignature(const QModelIndex &index) const;
void refresh(const QModelIndex &index = QModelIndex());
diff --git a/tools/qdbus/qdbusviewer/qdbusviewer.cpp b/tools/qdbus/qdbusviewer/qdbusviewer.cpp
index e9695dc..9878aff 100644
--- a/tools/qdbus/qdbusviewer/qdbusviewer.cpp
+++ b/tools/qdbus/qdbusviewer/qdbusviewer.cpp
@@ -69,9 +69,16 @@ QDBusViewer::QDBusViewer(const QDBusConnection &connection, QWidget *parent) :
c(connection),
objectPathRegExp(QLatin1String("\\[ObjectPath: (.*)\\]"))
{
- services = new QTreeWidget;
- services->setRootIsDecorated(false);
- services->setHeaderLabels(QStringList(QLatin1String("Services")));
+ servicesModel = new QStringListModel(this);
+ servicesFilterModel = new QSortFilterProxyModel(this);
+ servicesFilterModel->setSourceModel(servicesModel);
+ servicesFilterModel->setFilterCaseSensitivity(Qt::CaseInsensitive);
+ serviceFilterLine = new QLineEdit(this);
+ serviceFilterLine->setPlaceholderText(tr("Search..."));
+ servicesView = new QListView(this);
+ servicesView->setModel(servicesFilterModel);
+
+ connect(serviceFilterLine, SIGNAL(textChanged(QString)), servicesFilterModel, SLOT(setFilterFixedString(QString)));
tree = new QTreeView;
tree->setContextMenuPolicy(Qt::CustomContextMenu);
@@ -86,19 +93,28 @@ QDBusViewer::QDBusViewer(const QDBusConnection &connection, QWidget *parent) :
QShortcut *refreshShortcut = new QShortcut(QKeySequence::Refresh, tree);
connect(refreshShortcut, SIGNAL(activated()), this, SLOT(refreshChildren()));
- QVBoxLayout *topLayout = new QVBoxLayout(this);
+ QVBoxLayout *layout = new QVBoxLayout(this);
+ QSplitter *topSplitter = new QSplitter(Qt::Vertical, this);
+ layout->addWidget(topSplitter);
+
log = new QTextBrowser;
connect(log, SIGNAL(anchorClicked(QUrl)), this, SLOT(anchorClicked(QUrl)));
- QHBoxLayout *layout = new QHBoxLayout;
- layout->addWidget(services, 1);
- layout->addWidget(tree, 2);
+ QSplitter *splitter = new QSplitter(topSplitter);
+ splitter->addWidget(servicesView);
+
+ QWidget *servicesWidget = new QWidget;
+ QVBoxLayout *servicesLayout = new QVBoxLayout(servicesWidget);
+ servicesLayout->addWidget(serviceFilterLine);
+ servicesLayout->addWidget(servicesView);
+ splitter->addWidget(servicesWidget);
+ splitter->addWidget(tree);
- topLayout->addLayout(layout);
- topLayout->addWidget(log);
+ topSplitter->addWidget(splitter);
+ topSplitter->addWidget(log);
- connect(services, SIGNAL(currentItemChanged(QTreeWidgetItem*,QTreeWidgetItem*)),
- this, SLOT(serviceChanged(QTreeWidgetItem*)));
+ connect(servicesView->selectionModel(), SIGNAL(currentChanged(QModelIndex,QModelIndex)),
+ this, SLOT(serviceChanged(QModelIndex)));
connect(tree, SIGNAL(customContextMenuRequested(QPoint)),
this, SLOT(showContextMenu(QPoint)));
@@ -133,12 +149,11 @@ void QDBusViewer::logError(const QString &msg)
void QDBusViewer::refresh()
{
- services->clear();
+ servicesModel->removeRows(0, servicesModel->rowCount());
if (c.isConnected()) {
const QStringList serviceNames = c.interface()->registeredServiceNames();
- foreach (QString service, serviceNames)
- new QTreeWidgetItem(services, QStringList(service));
+ servicesModel->setStringList(serviceNames);
}
}
@@ -154,6 +169,7 @@ void QDBusViewer::activate(const QModelIndex &item)
sig.mPath = model->dBusPath(item);
sig.mInterface = model->dBusInterface(item);
sig.mName = model->dBusMethodName(item);
+ sig.mTypeSig = model->dBusTypeSignature(item);
switch (model->itemType(item)) {
case QDBusModel::SignalItem:
@@ -207,6 +223,17 @@ void QDBusViewer::setProperty(const BusSignature &sig)
}
+static QString getDbusSignature(const QMetaMethod& method)
+{
+ // create a D-Bus type signature from QMetaMethod's parameters
+ QString sig;
+ for (int i = 0; i < method.parameterTypes().count(); ++i) {
+ QVariant::Type type = QVariant::nameToType(method.parameterTypes().at(i));
+ sig.append(QString::fromLatin1(QDBusMetaType::typeToSignature(type)));
+ }
+ return sig;
+}
+
void QDBusViewer::callMethod(const BusSignature &sig)
{
QDBusInterface iface(sig.mService, sig.mPath, sig.mInterface, c);
@@ -217,7 +244,8 @@ void QDBusViewer::callMethod(const BusSignature &sig)
for (int i = 0; i < mo->methodCount(); ++i) {
const QString signature = QString::fromLatin1(mo->method(i).signature());
if (signature.startsWith(sig.mName) && signature.at(sig.mName.length()) == QLatin1Char('('))
- method = mo->method(i);
+ if (getDbusSignature(mo->method(i)) == sig.mTypeSig)
+ method = mo->method(i);
}
if (!method.signature()) {
QMessageBox::warning(this, tr("Unable to find method"),
@@ -277,6 +305,7 @@ void QDBusViewer::showContextMenu(const QPoint &point)
sig.mPath = model->dBusPath(item);
sig.mInterface = model->dBusInterface(item);
sig.mName = model->dBusMethodName(item);
+ sig.mTypeSig = model->dBusTypeSignature(item);
QMenu menu;
menu.addAction(refreshAction);
@@ -379,14 +408,14 @@ void QDBusViewer::dumpMessage(const QDBusMessage &message)
log->append(out);
}
-void QDBusViewer::serviceChanged(QTreeWidgetItem *item)
+void QDBusViewer::serviceChanged(const QModelIndex &index)
{
delete tree->model();
currentService.clear();
- if (!item)
+ if (!index.isValid())
return;
- currentService = item->text(0);
+ currentService = index.data().toString();
tree->setModel(new QDBusViewModel(currentService, c));
connect(tree->model(), SIGNAL(busError(QString)), this, SLOT(logError(QString)));
@@ -397,34 +426,38 @@ void QDBusViewer::serviceRegistered(const QString &service)
if (service == c.baseService())
return;
- new QTreeWidgetItem(services, QStringList(service));
+ servicesModel->insertRows(0, 1);
+ servicesModel->setData(servicesModel->index(0, 0), service);
}
-static QTreeWidgetItem *findItem(const QTreeWidget *services, const QString &name)
+static QModelIndex findItem(QStringListModel *servicesModel, const QString &name)
{
- for (int i = 0; i < services->topLevelItemCount(); ++i) {
- if (services->topLevelItem(i)->text(0) == name)
- return services->topLevelItem(i);
- }
- return 0;
+ QModelIndexList hits = servicesModel->match(servicesModel->index(0, 0), Qt::DisplayRole, name);
+ if (hits.isEmpty())
+ return QModelIndex();
+
+ return hits.first();
}
void QDBusViewer::serviceUnregistered(const QString &name)
{
- delete findItem(services, name);
+ QModelIndex hit = findItem(servicesModel, name);
+ if (!hit.isValid())
+ return;
+ servicesModel->removeRows(hit.row(), 1);
}
void QDBusViewer::serviceOwnerChanged(const QString &name, const QString &oldOwner,
const QString &newOwner)
{
- QTreeWidgetItem *item = findItem(services, name);
+ QModelIndex hit = findItem(servicesModel, name);
- if (!item && oldOwner.isEmpty() && !newOwner.isEmpty())
+ if (!hit.isValid() && oldOwner.isEmpty() && !newOwner.isEmpty())
serviceRegistered(name);
- else if (item && !oldOwner.isEmpty() && newOwner.isEmpty())
- delete item;
- else if (item && !oldOwner.isEmpty() && !newOwner.isEmpty()) {
- delete item;
+ else if (hit.isValid() && !oldOwner.isEmpty() && newOwner.isEmpty())
+ servicesModel->removeRows(hit.row(), 1);
+ else if (hit.isValid() && !oldOwner.isEmpty() && !newOwner.isEmpty()) {
+ servicesModel->removeRows(hit.row(), 1);
serviceRegistered(name);
}
}
diff --git a/tools/qdbus/qdbusviewer/qdbusviewer.h b/tools/qdbus/qdbusviewer/qdbusviewer.h
index 207f7a3..d5d1a69 100644
--- a/tools/qdbus/qdbusviewer/qdbusviewer.h
+++ b/tools/qdbus/qdbusviewer/qdbusviewer.h
@@ -52,6 +52,7 @@ QT_FORWARD_DECLARE_CLASS(QDomElement);
struct BusSignature
{
QString mService, mPath, mInterface, mName;
+ QString mTypeSig;
};
class QDBusViewer: public QWidget
@@ -65,7 +66,7 @@ public slots:
void about();
private slots:
- void serviceChanged(QTreeWidgetItem *item);
+ void serviceChanged(const QModelIndex &index);
void showContextMenu(const QPoint &);
void connectionRequested(const BusSignature &sig);
void callMethod(const BusSignature &sig);
@@ -91,6 +92,10 @@ private:
QTreeView *tree;
QAction *refreshAction;
QTreeWidget *services;
+ QStringListModel *servicesModel;
+ QSortFilterProxyModel *servicesFilterModel;
+ QLineEdit *serviceFilterLine;
+ QListView *servicesView;
QTextBrowser *log;
QRegExp objectPathRegExp;
};
diff --git a/tools/qdbus/qdbusxml2cpp/qdbusxml2cpp.cpp b/tools/qdbus/qdbusxml2cpp/qdbusxml2cpp.cpp
index 8251e2c..a259096 100644
--- a/tools/qdbus/qdbusxml2cpp/qdbusxml2cpp.cpp
+++ b/tools/qdbus/qdbusxml2cpp/qdbusxml2cpp.cpp
@@ -53,14 +53,9 @@
#include "private/qdbusmetaobject_p.h"
#include "private/qdbusintrospection_p.h"
-#include <sys/types.h>
#include <stdio.h>
#include <stdlib.h>
-#ifdef Q_WS_WIN
-#include <process.h>
-#endif
-
#define PROGRAMNAME "qdbusxml2cpp"
#define PROGRAMVERSION "0.7"
#define PROGRAMCOPYRIGHT "Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies)."
@@ -1135,11 +1130,11 @@ int main(int argc, char **argv)
static code representing those interfaces, which can then be used to make calls to remote
objects or implement said interfaces.
- \c qdbusxml2dcpp has two modes of operation, that correspond to the two possible outputs it can
+ \c qdbusxml2cpp has two modes of operation, that correspond to the two possible outputs it can
produce: the interface (proxy) class or the adaptor class. The latter consists of both a C++
header and a source file, which are meant to be edited and adapted to your needs.
- The \c qdbusxml2dcpp tool is not meant to be run every time you compile your
+ The \c qdbusxml2cpp tool is not meant to be run every time you compile your
application. Instead, it's meant to be used when developing the code or when the interface
changes.