diff options
author | Lars Knoll <lars.knoll@nokia.com> | 2009-03-23 09:18:55 (GMT) |
---|---|---|
committer | Simon Hausmann <simon.hausmann@nokia.com> | 2009-03-23 09:18:55 (GMT) |
commit | e5fcad302d86d316390c6b0f62759a067313e8a9 (patch) | |
tree | c2afbf6f1066b6ce261f14341cf6d310e5595bc1 /tools/qdbus/qdbusviewer | |
download | Qt-e5fcad302d86d316390c6b0f62759a067313e8a9.zip Qt-e5fcad302d86d316390c6b0f62759a067313e8a9.tar.gz Qt-e5fcad302d86d316390c6b0f62759a067313e8a9.tar.bz2 |
Long live Qt 4.5!
Diffstat (limited to 'tools/qdbus/qdbusviewer')
-rw-r--r-- | tools/qdbus/qdbusviewer/Info_mac.plist | 18 | ||||
-rw-r--r-- | tools/qdbus/qdbusviewer/images/qdbusviewer-128.png | bin | 0 -> 9850 bytes | |||
-rw-r--r-- | tools/qdbus/qdbusviewer/images/qdbusviewer.icns | bin | 0 -> 146951 bytes | |||
-rw-r--r-- | tools/qdbus/qdbusviewer/images/qdbusviewer.ico | bin | 0 -> 355574 bytes | |||
-rw-r--r-- | tools/qdbus/qdbusviewer/images/qdbusviewer.png | bin | 0 -> 1231 bytes | |||
-rw-r--r-- | tools/qdbus/qdbusviewer/main.cpp | 85 | ||||
-rw-r--r-- | tools/qdbus/qdbusviewer/propertydialog.cpp | 114 | ||||
-rw-r--r-- | tools/qdbus/qdbusviewer/propertydialog.h | 70 | ||||
-rw-r--r-- | tools/qdbus/qdbusviewer/qdbusmodel.cpp | 336 | ||||
-rw-r--r-- | tools/qdbus/qdbusviewer/qdbusmodel.h | 94 | ||||
-rw-r--r-- | tools/qdbus/qdbusviewer/qdbusviewer.cpp | 509 | ||||
-rw-r--r-- | tools/qdbus/qdbusviewer/qdbusviewer.h | 98 | ||||
-rw-r--r-- | tools/qdbus/qdbusviewer/qdbusviewer.pro | 30 | ||||
-rw-r--r-- | tools/qdbus/qdbusviewer/qdbusviewer.qrc | 6 | ||||
-rw-r--r-- | tools/qdbus/qdbusviewer/qdbusviewer.rc | 1 |
15 files changed, 1361 insertions, 0 deletions
diff --git a/tools/qdbus/qdbusviewer/Info_mac.plist b/tools/qdbus/qdbusviewer/Info_mac.plist new file mode 100644 index 0000000..b351409 --- /dev/null +++ b/tools/qdbus/qdbusviewer/Info_mac.plist @@ -0,0 +1,18 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!DOCTYPE plist SYSTEM "file://localhost/System/Library/DTDs/PropertyList.dtd"> +<plist version="0.9"> +<dict> + <key>CFBundleIconFile</key> + <string>@ICON@</string> + <key>CFBundlePackageType</key> + <string>APPL</string> + <key>CFBundleGetInfoString</key> + <string>Created by Qt/QMake</string> + <key>CFBundleSignature</key> + <string>????</string> + <key>CFBundleIdentifier</key> + <string>com.trolltech.dbusviewer</string> + <key>CFBundleExecutable</key> + <string>@EXECUTABLE@</string> +</dict> +</plist> diff --git a/tools/qdbus/qdbusviewer/images/qdbusviewer-128.png b/tools/qdbus/qdbusviewer/images/qdbusviewer-128.png Binary files differnew file mode 100644 index 0000000..0754912 --- /dev/null +++ b/tools/qdbus/qdbusviewer/images/qdbusviewer-128.png diff --git a/tools/qdbus/qdbusviewer/images/qdbusviewer.icns b/tools/qdbus/qdbusviewer/images/qdbusviewer.icns Binary files differnew file mode 100644 index 0000000..b6f39b9 --- /dev/null +++ b/tools/qdbus/qdbusviewer/images/qdbusviewer.icns diff --git a/tools/qdbus/qdbusviewer/images/qdbusviewer.ico b/tools/qdbus/qdbusviewer/images/qdbusviewer.ico Binary files differnew file mode 100644 index 0000000..49edb09 --- /dev/null +++ b/tools/qdbus/qdbusviewer/images/qdbusviewer.ico diff --git a/tools/qdbus/qdbusviewer/images/qdbusviewer.png b/tools/qdbus/qdbusviewer/images/qdbusviewer.png Binary files differnew file mode 100644 index 0000000..5a8c5a3 --- /dev/null +++ b/tools/qdbus/qdbusviewer/images/qdbusviewer.png diff --git a/tools/qdbus/qdbusviewer/main.cpp b/tools/qdbus/qdbusviewer/main.cpp new file mode 100644 index 0000000..b670337 --- /dev/null +++ b/tools/qdbus/qdbusviewer/main.cpp @@ -0,0 +1,85 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the tools applications of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.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 the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include <QtGui/qapplication.h> +#include <QtGui/qmainwindow.h> +#include <QtGui/qtabwidget.h> +#include <QtDBus/qdbusconnection.h> +#include "qdbusviewer.h" + +#include <stdio.h> + +int main(int argc, char *argv[]) +{ + QApplication app(argc, argv); + QMainWindow mw; +#ifndef Q_WS_MAC + app.setWindowIcon(QIcon(QLatin1String(":/trolltech/qdbusviewer/images/qdbusviewer.png"))); +#else + mw.setWindowTitle(qApp->translate("QtDBusViewer", "Qt D-Bus Viewer")); +#endif + + + QTabWidget *mainWidget = new QTabWidget; + mw.setCentralWidget(mainWidget); + QDBusViewer *sessionBusViewer = new QDBusViewer(QDBusConnection::sessionBus()); + QDBusViewer *systemBusViewer = new QDBusViewer(QDBusConnection::systemBus()); + mainWidget->addTab(sessionBusViewer, QObject::tr("Session Bus")); + mainWidget->addTab(systemBusViewer, QObject::tr("System Bus")); + + QMenu *fileMenu = mw.menuBar()->addMenu(QObject::tr("&File")); + QAction *quitAction = fileMenu->addAction(QObject::tr("&Quit"), &mw, SLOT(close())); + Q_UNUSED(quitAction); + + QMenu *helpMenu = mw.menuBar()->addMenu(QObject::tr("&Help")); + QAction *aboutAction = helpMenu->addAction(QObject::tr("&About")); + aboutAction->setMenuRole(QAction::AboutRole); + QObject::connect(aboutAction, SIGNAL(triggered()), sessionBusViewer, SLOT(about())); + + QAction *aboutQtAction = helpMenu->addAction(QObject::tr("About &Qt")); + aboutQtAction->setMenuRole(QAction::AboutQtRole); + QObject::connect(aboutQtAction, SIGNAL(triggered()), &app, SLOT(aboutQt())); + + mw.show(); + + return app.exec(); +} + diff --git a/tools/qdbus/qdbusviewer/propertydialog.cpp b/tools/qdbus/qdbusviewer/propertydialog.cpp new file mode 100644 index 0000000..6359cd7 --- /dev/null +++ b/tools/qdbus/qdbusviewer/propertydialog.cpp @@ -0,0 +1,114 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the tools applications of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.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 the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "propertydialog.h" + +#include <QHeaderView> +#include <QLayout> +#include <QDebug> + +PropertyDialog::PropertyDialog(QWidget *parent, Qt::WindowFlags f) + : QDialog(parent, f) +{ + buttonBox = new QDialogButtonBox; + propertyTable = new QTableWidget; + label = new QLabel; + + buttonBox->setStandardButtons(QDialogButtonBox::Ok | QDialogButtonBox::Cancel); + propertyTable->setColumnCount(2); + const QStringList labels = QStringList() << QLatin1String("Name") << QLatin1String("Value"); + propertyTable->setHorizontalHeaderLabels(labels); + propertyTable->horizontalHeader()->setStretchLastSection(true); + propertyTable->setEditTriggers(QAbstractItemView::AllEditTriggers); + + connect(buttonBox, SIGNAL(accepted()), SLOT(accept()), Qt::QueuedConnection); + connect(buttonBox, SIGNAL(rejected()), SLOT(reject()), Qt::QueuedConnection); + + QVBoxLayout *layout = new QVBoxLayout(this); + layout->addWidget(label); + layout->addWidget(propertyTable); + layout->addWidget(buttonBox); +} + +void PropertyDialog::setInfo(const QString &caption) +{ + label->setText(caption); +} + +void PropertyDialog::addProperty(const QString &aname, QVariant::Type type) +{ + int rowCount = propertyTable->rowCount(); + propertyTable->setRowCount(rowCount + 1); + + QString name = aname; + if (name.isEmpty()) + name = QLatin1String("argument ") + QString::number(rowCount + 1); + name += QLatin1String(" ("); + name += QLatin1String(QVariant::typeToName(type)); + name += QLatin1String(")"); + QTableWidgetItem *nameItem = new QTableWidgetItem(name); + nameItem->setFlags(nameItem->flags() & + ~(Qt::ItemIsEditable | Qt::ItemIsSelectable)); + propertyTable->setItem(rowCount, 0, nameItem); + + QTableWidgetItem *valueItem = new QTableWidgetItem; + valueItem->setData(Qt::DisplayRole, QVariant(type)); + propertyTable->setItem(rowCount, 1, valueItem); +} + +int PropertyDialog::exec() +{ + propertyTable->resizeColumnToContents(0); + propertyTable->setFocus(); + propertyTable->setCurrentCell(0, 1); + return QDialog::exec(); +} + +QList<QVariant> PropertyDialog::values() const +{ + QList<QVariant> result; + + for (int i = 0; i < propertyTable->rowCount(); ++i) + result << propertyTable->item(i, 1)->data(Qt::EditRole); + + return result; +} + diff --git a/tools/qdbus/qdbusviewer/propertydialog.h b/tools/qdbus/qdbusviewer/propertydialog.h new file mode 100644 index 0000000..2ba30e17 --- /dev/null +++ b/tools/qdbus/qdbusviewer/propertydialog.h @@ -0,0 +1,70 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the tools applications of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.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 the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef PROPERTYDIALOG_H +#define PROPERTYDIALOG_H + +#include <QLabel> +#include <QDialog> +#include <QTableWidget> +#include <QDialogButtonBox> + +class PropertyDialog: public QDialog +{ + Q_OBJECT +public: + explicit PropertyDialog(QWidget *parent = 0, Qt::WindowFlags f = 0); + + void addProperty(const QString &name, QVariant::Type type); + void setInfo(const QString &caption); + + QList<QVariant> values() const; + + int exec(); + +private: + QLabel *label; + QTableWidget *propertyTable; + QDialogButtonBox *buttonBox; +}; + +#endif + diff --git a/tools/qdbus/qdbusviewer/qdbusmodel.cpp b/tools/qdbus/qdbusviewer/qdbusmodel.cpp new file mode 100644 index 0000000..88e3524 --- /dev/null +++ b/tools/qdbus/qdbusviewer/qdbusmodel.cpp @@ -0,0 +1,336 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the tools applications of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.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 the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qdbusmodel.h" + +#include <QtCore/qvector.h> +#include <QtXml/QtXml> + +struct QDBusItem +{ + inline QDBusItem(QDBusModel::Type aType, const QString &aName, QDBusItem *aParent = 0) + : type(aType), parent(aParent), isPrefetched(type != QDBusModel::PathItem), name(aName) + {} + inline ~QDBusItem() + { + qDeleteAll(children); + } + + QString path() const + { + Q_ASSERT(type == QDBusModel::PathItem); + + QString s; + const QDBusItem *item = this; + while (item) { + s.prepend(item->name); + item = item->parent; + } + if (s.length() > 1) + s.chop(1); // remove tailing slash + return s; + } + + QDBusModel::Type type; + QDBusItem *parent; + QVector<QDBusItem *> children; + bool isPrefetched; + QString name; + QString caption; +}; + +QDomDocument QDBusModel::introspect(const QString &path) +{ + QDomDocument doc; + + QDBusInterface iface(service, path, QLatin1String("org.freedesktop.DBus.Introspectable"), c); + if (!iface.isValid()) { + QDBusError err(iface.lastError()); + emit busError(QString::fromLatin1("Cannot introspect object %1 at %2:\n %3 (%4)\n").arg(path).arg( + service).arg(err.name()).arg(err.message())); + return doc; + } + + QDBusReply<QString> xml = iface.call(QLatin1String("Introspect")); + + if (!xml.isValid()) { + QDBusError err(xml.error()); + if (err.isValid()) { + emit busError(QString::fromLatin1("Call to object %1 at %2:\n %3 (%4) failed\n").arg( + path).arg(service).arg(err.name()).arg(err.message())); + } else { + emit busError(QString::fromLatin1("Invalid XML received from object %1 at %2\n").arg( + path).arg(service)); + } + return doc; + } + + doc.setContent(xml); + return doc; +} + +void QDBusModel::addMethods(QDBusItem *parent, const QDomElement &iface) +{ + Q_ASSERT(parent); + + QDomElement child = iface.firstChildElement(); + while (!child.isNull()) { + QDBusItem *item = 0; + if (child.tagName() == QLatin1String("method")) { + item = new QDBusItem(QDBusModel::MethodItem, + child.attribute(QLatin1String("name")), parent); + item->caption = QLatin1String("Method: ") + item->name; + } else if (child.tagName() == QLatin1String("signal")) { + item = new QDBusItem(QDBusModel::SignalItem, + child.attribute(QLatin1String("name")), parent); + item->caption = QLatin1String("Signal: ") + item->name; + } else if (child.tagName() == QLatin1String("property")) { + item = new QDBusItem(QDBusModel::PropertyItem, + child.attribute(QLatin1String("name")), parent); + item->caption = QLatin1String("Property: ") + item->name; + } else { + qDebug() << "addMethods: unknown tag:" << child.tagName(); + } + if (item) + parent->children.append(item); + + child = child.nextSiblingElement(); + } +} + +void QDBusModel::addPath(QDBusItem *parent) +{ + Q_ASSERT(parent); + + QString path = parent->path(); + + QDomDocument doc = introspect(path); + QDomElement node = doc.documentElement(); + QDomElement child = node.firstChildElement(); + while (!child.isNull()) { + if (child.tagName() == QLatin1String("node")) { + QDBusItem *item = new QDBusItem(QDBusModel::PathItem, + child.attribute(QLatin1String("name")) + QLatin1Char('/'), parent); + parent->children.append(item); + + addMethods(item, child); + } else if (child.tagName() == QLatin1String("interface")) { + QDBusItem *item = new QDBusItem(QDBusModel::InterfaceItem, + child.attribute(QLatin1String("name")), parent); + parent->children.append(item); + + addMethods(item, child); + } else { + qDebug() << "addPath: Unknown tag name:" << child.tagName(); + } + child = child.nextSiblingElement(); + } + + parent->isPrefetched = true; +} + +QDBusModel::QDBusModel(const QString &aService, const QDBusConnection &connection) + : service(aService), c(connection), root(0) +{ + root = new QDBusItem(QDBusModel::PathItem, QLatin1String("/")); +} + +QDBusModel::~QDBusModel() +{ + delete root; +} + +QModelIndex QDBusModel::index(int row, int column, const QModelIndex &parent) const +{ + const QDBusItem *item = static_cast<QDBusItem *>(parent.internalPointer()); + if (!item) + item = root; + + if (column != 0 || row < 0 || row >= item->children.count()) + return QModelIndex(); + + return createIndex(row, 0, item->children.at(row)); +} + +QModelIndex QDBusModel::parent(const QModelIndex &child) const +{ + QDBusItem *item = static_cast<QDBusItem *>(child.internalPointer()); + if (!item || !item->parent || !item->parent->parent) + return QModelIndex(); + + return createIndex(item->parent->parent->children.indexOf(item->parent), 0, item->parent); +} + +int QDBusModel::rowCount(const QModelIndex &parent) const +{ + QDBusItem *item = static_cast<QDBusItem *>(parent.internalPointer()); + if (!item) + item = root; + if (!item->isPrefetched) + const_cast<QDBusModel *>(this)->addPath(item); + + return item->children.count(); +} + +int QDBusModel::columnCount(const QModelIndex &) const +{ + return 1; +} + +QVariant QDBusModel::data(const QModelIndex &index, int role) const +{ + const QDBusItem *item = static_cast<QDBusItem *>(index.internalPointer()); + if (!item) + return QVariant(); + + if (role != Qt::DisplayRole) + return QVariant(); + + return item->caption.isEmpty() ? item->name : item->caption; +} + +QVariant QDBusModel::headerData(int section, Qt::Orientation orientation, int role) const +{ + if (role != Qt::DisplayRole || orientation == Qt::Vertical || section != 0) + return QVariant(); + + return QLatin1String("Methods"); +} + +QDBusModel::Type QDBusModel::itemType(const QModelIndex &index) const +{ + const QDBusItem *item = static_cast<QDBusItem *>(index.internalPointer()); + return item ? item->type : PathItem; +} + +void QDBusModel::refresh(const QModelIndex &aIndex) +{ + QModelIndex index = aIndex; + while (index.isValid() && static_cast<QDBusItem *>(index.internalPointer())->type != PathItem) { + index = index.parent(); + } + + QDBusItem *item = static_cast<QDBusItem *>(index.internalPointer()); + if (!item) + item = root; + + if (!item->children.isEmpty()) { + beginRemoveRows(index, 0, item->children.count() - 1); + qDeleteAll(item->children); + item->children.clear(); + endRemoveRows(); + } + + addPath(item); + if (!item->children.isEmpty()) { + beginInsertRows(index, 0, item->children.count() - 1); + endInsertRows(); + } +} + +QString QDBusModel::dBusPath(const QModelIndex &aIndex) const +{ + QModelIndex index = aIndex; + while (index.isValid() && static_cast<QDBusItem *>(index.internalPointer())->type != PathItem) { + index = index.parent(); + } + + QDBusItem *item = static_cast<QDBusItem *>(index.internalPointer()); + if (!item) + item = root; + + return item->path(); +} + +QString QDBusModel::dBusInterface(const QModelIndex &index) const +{ + QDBusItem *item = static_cast<QDBusItem *>(index.internalPointer()); + if (!item) + return QString(); + if (item->type == InterfaceItem) + return item->name; + if (item->parent && item->parent->type == InterfaceItem) + return item->parent->name; + return QString(); +} + +QString QDBusModel::dBusMethodName(const QModelIndex &index) const +{ + QDBusItem *item = static_cast<QDBusItem *>(index.internalPointer()); + return item ? item->name : QString(); +} + +QModelIndex QDBusModel::findObject(const QDBusObjectPath &objectPath) +{ + QStringList path = objectPath.path().split(QLatin1Char('/'), QString::SkipEmptyParts); + + QDBusItem *item = root; + int childIdx = -1; + while (item && !path.isEmpty()) { + const QString branch = path.takeFirst() + QLatin1Char('/'); + childIdx = -1; + + // do a linear search over all the children + for (int i = 0; i < item->children.count(); ++i) { + QDBusItem *child = item->children.at(i); + if (child->type == PathItem && child->name == branch) { + item = child; + childIdx = i; + + // prefetch the found branch + if (!item->isPrefetched) + addPath(item); + break; + } + } + + // branch not found - bail out + if (childIdx == -1) + return QModelIndex(); + } + + // found the right item + if (childIdx != -1 && item && path.isEmpty()) + return createIndex(childIdx, 0, item); + + return QModelIndex(); +} + diff --git a/tools/qdbus/qdbusviewer/qdbusmodel.h b/tools/qdbus/qdbusviewer/qdbusmodel.h new file mode 100644 index 0000000..50f928e --- /dev/null +++ b/tools/qdbus/qdbusviewer/qdbusmodel.h @@ -0,0 +1,94 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the tools applications of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.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 the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QDBUSMODEL_H +#define QDBUSMODEL_H + +#include <QtCore/qabstractitemmodel.h> +#include <QtDBus/QtDBus> + +struct QDBusItem; + +QT_FORWARD_DECLARE_CLASS(QDomDocument); +QT_FORWARD_DECLARE_CLASS(QDomElement); + + +class QDBusModel: public QAbstractItemModel +{ + Q_OBJECT + +public: + enum Type { InterfaceItem, PathItem, MethodItem, SignalItem, PropertyItem }; + + QDBusModel(const QString &service, const QDBusConnection &connection); + ~QDBusModel(); + + QModelIndex index(int row, int column, const QModelIndex &parent = QModelIndex()) const; + QModelIndex parent(const QModelIndex &child) const; + int rowCount(const QModelIndex &parent = QModelIndex()) const; + int columnCount(const QModelIndex &parent = QModelIndex()) const; + QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const; + QVariant headerData(int section, Qt::Orientation orientation, int role = Qt::DisplayRole) const; + + Type itemType(const QModelIndex &index) const; + QString dBusPath(const QModelIndex &index) const; + QString dBusInterface(const QModelIndex &index) const; + QString dBusMethodName(const QModelIndex &index) const; + + void refresh(const QModelIndex &index = QModelIndex()); + + QModelIndex findObject(const QDBusObjectPath &objectPath); + +Q_SIGNALS: + void busError(const QString &text); + +private: + QDomDocument introspect(const QString &path); + void addMethods(QDBusItem *parent, const QDomElement &iface); + void addPath(QDBusItem *parent); + + QString service; + QDBusConnection c; + QDBusItem *root; +}; + +#endif + diff --git a/tools/qdbus/qdbusviewer/qdbusviewer.cpp b/tools/qdbus/qdbusviewer/qdbusviewer.cpp new file mode 100644 index 0000000..e8ac3a6 --- /dev/null +++ b/tools/qdbus/qdbusviewer/qdbusviewer.cpp @@ -0,0 +1,509 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the tools applications of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.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 the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qdbusviewer.h" +#include "qdbusmodel.h" +#include "propertydialog.h" + +#include <QtXml/QtXml> +#include <QtDBus/private/qdbusutil_p.h> + +class QDBusViewModel: public QDBusModel +{ +public: + inline QDBusViewModel(const QString &service, const QDBusConnection &connection) + : QDBusModel(service, connection) + {} + + QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const + { + if (role == Qt::FontRole && itemType(index) == InterfaceItem) { + QFont f; + f.setItalic(true); + return f; + } + return QDBusModel::data(index, role); + } +}; + +QDBusViewer::QDBusViewer(const QDBusConnection &connection, QWidget *parent) : + QWidget(parent), + c(connection), + objectPathRegExp(QLatin1String("\\[ObjectPath: (.*)\\]")) +{ + services = new QTreeWidget; + services->setRootIsDecorated(false); + services->setHeaderLabels(QStringList(QLatin1String("Services"))); + + tree = new QTreeView; + tree->setContextMenuPolicy(Qt::CustomContextMenu); + + connect(tree, SIGNAL(activated(const QModelIndex&)), this, SLOT(activate(const QModelIndex&))); + + refreshAction = new QAction(tr("&Refresh"), tree); + refreshAction->setData(42); // increase the amount of 42 used as magic number by one + refreshAction->setShortcut(QKeySequence::Refresh); + connect(refreshAction, SIGNAL(triggered()), this, SLOT(refreshChildren())); + + QShortcut *refreshShortcut = new QShortcut(QKeySequence::Refresh, tree); + connect(refreshShortcut, SIGNAL(activated()), this, SLOT(refreshChildren())); + + QVBoxLayout *topLayout = new QVBoxLayout(this); + log = new QTextBrowser; + connect(log, SIGNAL(anchorClicked(QUrl)), this, SLOT(anchorClicked(QUrl))); + + QHBoxLayout *layout = new QHBoxLayout; + layout->addWidget(services, 1); + layout->addWidget(tree, 2); + + topLayout->addLayout(layout); + topLayout->addWidget(log); + + connect(services, SIGNAL(currentItemChanged(QTreeWidgetItem*,QTreeWidgetItem*)), + this, SLOT(serviceChanged(QTreeWidgetItem*))); + connect(tree, SIGNAL(customContextMenuRequested(QPoint)), + this, SLOT(showContextMenu(QPoint))); + + QMetaObject::invokeMethod(this, "refresh", Qt::QueuedConnection); + + if (c.isConnected()) { + logMessage(QLatin1String("Connected to D-Bus.")); + QDBusConnectionInterface *iface = c.interface(); + connect(iface, SIGNAL(serviceRegistered(QString)), + this, SLOT(serviceRegistered(QString))); + connect(iface, SIGNAL(serviceUnregistered(QString)), + this, SLOT(serviceUnregistered(QString))); + connect(iface, SIGNAL(serviceOwnerChanged(QString,QString,QString)), + this, SLOT(serviceOwnerChanged(QString,QString,QString))); + } else { + logError(QLatin1String("Cannot connect to D-Bus: ") + c.lastError().message()); + } + + objectPathRegExp.setMinimal(true); + +} + +void QDBusViewer::logMessage(const QString &msg) +{ + log->append(msg + QLatin1Char('\n')); +} + +void QDBusViewer::logError(const QString &msg) +{ + log->append(QLatin1String("<font color=\"red\">Error: </font>") + Qt::escape(msg) + QLatin1String("<br>")); +} + +void QDBusViewer::refresh() +{ + services->clear(); + + if (c.isConnected()) { + const QStringList serviceNames = c.interface()->registeredServiceNames(); + foreach (QString service, serviceNames) + new QTreeWidgetItem(services, QStringList(service)); + } +} + +void QDBusViewer::activate(const QModelIndex &item) +{ + if (!item.isValid()) + return; + + const QDBusModel *model = static_cast<const QDBusModel *>(item.model()); + + BusSignature sig; + sig.mService = currentService; + sig.mPath = model->dBusPath(item); + sig.mInterface = model->dBusInterface(item); + sig.mName = model->dBusMethodName(item); + + switch (model->itemType(item)) { + case QDBusModel::SignalItem: + connectionRequested(sig); + break; + case QDBusModel::MethodItem: + callMethod(sig); + break; + case QDBusModel::PropertyItem: + getProperty(sig); + break; + default: + break; + } +} + +void QDBusViewer::getProperty(const BusSignature &sig) +{ + QDBusMessage message = QDBusMessage::createMethodCall(sig.mService, sig.mPath, QLatin1String("org.freedesktop.DBus.Properties"), QLatin1String("Get")); + QList<QVariant> arguments; + arguments << sig.mInterface << sig.mName; + message.setArguments(arguments); + c.callWithCallback(message, this, SLOT(dumpMessage(QDBusMessage))); +} + +void QDBusViewer::setProperty(const BusSignature &sig) +{ + QDBusInterface iface(sig.mService, sig.mPath, sig.mInterface, c); + QMetaProperty prop = iface.metaObject()->property(iface.metaObject()->indexOfProperty(sig.mName.toLatin1())); + + bool ok; + QString input = QInputDialog::getText(this, tr("Arguments"), + tr("Please enter the value of the property %1 (type %2)").arg( + sig.mName, QString::fromLatin1(prop.typeName())), + QLineEdit::Normal, QString(), &ok); + if (!ok) + return; + + QVariant value = input; + if (!value.convert(prop.type())) { + QMessageBox::warning(this, tr("Unable to marshall"), + tr("Value conversion failed, unable to set property")); + return; + } + + QDBusMessage message = QDBusMessage::createMethodCall(sig.mService, sig.mPath, QLatin1String("org.freedesktop.DBus.Properties"), QLatin1String("Set")); + QList<QVariant> arguments; + arguments << sig.mInterface << sig.mName << qVariantFromValue(QDBusVariant(value)); + message.setArguments(arguments); + c.callWithCallback(message, this, SLOT(dumpMessage(QDBusMessage))); + +} + +void QDBusViewer::callMethod(const BusSignature &sig) +{ + QDBusInterface iface(sig.mService, sig.mPath, sig.mInterface, c); + const QMetaObject *mo = iface.metaObject(); + + // find the method + QMetaMethod method; + 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 (!method.signature()) { + QMessageBox::warning(this, tr("Unable to find method"), + tr("Unable to find method %1 on path %2 in interface %3").arg( + sig.mName).arg(sig.mPath).arg(sig.mInterface)); + return; + } + + PropertyDialog dialog; + QList<QVariant> args; + + const QList<QByteArray> paramTypes = method.parameterTypes(); + const QList<QByteArray> paramNames = method.parameterNames(); + QList<int> types; // remember the low-level D-Bus type + for (int i = 0; i < paramTypes.count(); ++i) { + const QByteArray paramType = paramTypes.at(i); + if (paramType.endsWith('&')) + continue; // ignore OUT parameters + + QVariant::Type type = QVariant::nameToType(paramType); + dialog.addProperty(QString::fromLatin1(paramNames.value(i)), type); + types.append(QMetaType::type(paramType)); + } + + if (!types.isEmpty()) { + dialog.setInfo(tr("Please enter parameters for the method \"%1\"").arg(sig.mName)); + + if (dialog.exec() != QDialog::Accepted) + return; + + args = dialog.values(); + } + + // Special case - convert a value to a QDBusVariant if the + // interface wants a variant + for (int i = 0; i < args.count(); ++i) { + if (types.at(i) == qMetaTypeId<QDBusVariant>()) + args[i] = qVariantFromValue(QDBusVariant(args.at(i))); + } + + QDBusMessage message = QDBusMessage::createMethodCall(sig.mService, sig.mPath, sig.mInterface, + sig.mName); + message.setArguments(args); + c.callWithCallback(message, this, SLOT(dumpMessage(QDBusMessage))); +} + +void QDBusViewer::showContextMenu(const QPoint &point) +{ + QModelIndex item = tree->indexAt(point); + if (!item.isValid()) + return; + + const QDBusModel *model = static_cast<const QDBusModel *>(item.model()); + + BusSignature sig; + sig.mService = currentService; + sig.mPath = model->dBusPath(item); + sig.mInterface = model->dBusInterface(item); + sig.mName = model->dBusMethodName(item); + + QMenu menu; + menu.addAction(refreshAction); + + switch (model->itemType(item)) { + case QDBusModel::SignalItem: { + QAction *action = new QAction(tr("&Connect"), &menu); + action->setData(1); + menu.addAction(action); + break; } + case QDBusModel::MethodItem: { + QAction *action = new QAction(tr("&Call"), &menu); + action->setData(2); + menu.addAction(action); + break; } + case QDBusModel::PropertyItem: { + QAction *actionSet = new QAction(tr("&Set value"), &menu); + actionSet->setData(3); + QAction *actionGet = new QAction(tr("&Get value"), &menu); + actionGet->setData(4); + menu.addAction(actionSet); + menu.addAction(actionGet); + break; } + default: + break; + } + + QAction *selectedAction = menu.exec(tree->viewport()->mapToGlobal(point)); + if (!selectedAction) + return; + + switch (selectedAction->data().toInt()) { + case 1: + connectionRequested(sig); + break; + case 2: + callMethod(sig); + break; + case 3: + setProperty(sig); + break; + case 4: + getProperty(sig); + break; + } +} + +void QDBusViewer::connectionRequested(const BusSignature &sig) +{ + if (!c.connect(sig.mService, QString(), sig.mInterface, sig.mName, this, + SLOT(dumpMessage(QDBusMessage)))) { + logError(tr("Unable to connect to service %1, path %2, interface %3, signal %4").arg( + sig.mService).arg(sig.mPath).arg(sig.mInterface).arg(sig.mName)); + } +} + +void QDBusViewer::dumpMessage(const QDBusMessage &message) +{ + QList<QVariant> args = message.arguments(); + QString out = QLatin1String("Received "); + + switch (message.type()) { + case QDBusMessage::SignalMessage: + out += QLatin1String("signal "); + break; + case QDBusMessage::ErrorMessage: + out += QLatin1String("error message "); + break; + case QDBusMessage::ReplyMessage: + out += QLatin1String("reply "); + break; + default: + out += QLatin1String("message "); + break; + } + + out += QLatin1String("from "); + out += message.service(); + if (!message.path().isEmpty()) + out += QLatin1String(", path ") + message.path(); + if (!message.interface().isEmpty()) + out += QLatin1String(", interface <i>") + message.interface() + QLatin1String("</i>"); + if (!message.member().isEmpty()) + out += QLatin1String(", member ") + message.member(); + out += QLatin1String("<br>"); + if (args.isEmpty()) { + out += QLatin1String(" (no arguments)"); + } else { + out += QLatin1String(" Arguments: "); + foreach (QVariant arg, args) { + QString str = Qt::escape(QDBusUtil::argumentToString(arg)); + // turn object paths into clickable links + str.replace(objectPathRegExp, QLatin1String("[ObjectPath: <a href=\"qdbus://bus\\1\">\\1</a>]")); + out += str; + out += QLatin1String(", "); + } + out.chop(2); + } + + log->append(out); +} + +void QDBusViewer::serviceChanged(QTreeWidgetItem *item) +{ + delete tree->model(); + + currentService.clear(); + if (!item) + return; + currentService = item->text(0); + + tree->setModel(new QDBusViewModel(currentService, c)); + connect(tree->model(), SIGNAL(busError(QString)), this, SLOT(logError(QString))); +} + +void QDBusViewer::serviceRegistered(const QString &service) +{ + if (service == c.baseService()) + return; + + new QTreeWidgetItem(services, QStringList(service)); +} + +static QTreeWidgetItem *findItem(const QTreeWidget *services, const QString &name) +{ + for (int i = 0; i < services->topLevelItemCount(); ++i) { + if (services->topLevelItem(i)->text(0) == name) + return services->topLevelItem(i); + } + return 0; +} + +void QDBusViewer::serviceUnregistered(const QString &name) +{ + delete findItem(services, name); +} + +void QDBusViewer::serviceOwnerChanged(const QString &name, const QString &oldOwner, + const QString &newOwner) +{ + QTreeWidgetItem *item = findItem(services, name); + + if (!item && oldOwner.isEmpty() && !newOwner.isEmpty()) + serviceRegistered(name); + else if (item && !oldOwner.isEmpty() && newOwner.isEmpty()) + delete item; + else if (item && !oldOwner.isEmpty() && !newOwner.isEmpty()) { + delete item; + serviceRegistered(name); + } +} + +void QDBusViewer::refreshChildren() +{ + QDBusModel *model = qobject_cast<QDBusModel *>(tree->model()); + if (!model) + return; + model->refresh(tree->currentIndex()); +} + +void QDBusViewer::about() +{ + QMessageBox box(this); +#if QT_EDITION == QT_EDITION_OPENSOURCE + QString edition = tr("Open Source Edition"); + QString info = tr("This version of Qt's D-Bus Viewer is part of the Qt Open Source Edition. " + "Qt is a comprehensive C++ framework for cross-platform application " + "development."); + QString moreInfo = tr("You need a commercial Qt license for development of proprietary (closed " + "source) applications. Please see <a href=\"http://qtsoftware.com/company/model" + ".html\">qtsoftware.com/company/model.html</a> for an overview of Qt licensing."); +#else + QString edition; + QString info; + QString moreInfo(tr("This program is licensed to you under the terms of the " + "Qt Commercial License Agreement. For details, see the file LICENSE " + "that came with this software distribution.")); + +#endif + + box.setText(QString::fromLatin1("<center><img src=\":/trolltech/qdbusviewer/images/qdbusviewer-128.png\">" + "<h3>%1</h3>" + "<p>Version %2 %3</p></center>" + "<p>%4</p>" + "<p>%5</p>" + "<p>Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).</p>" + "<p>The program is provided AS IS with NO WARRANTY OF ANY KIND," + " INCLUDING THE WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A" + " PARTICULAR PURPOSE.<p/>") + .arg(tr("D-Bus Viewer")).arg(QLatin1String(QT_VERSION_STR)).arg(edition).arg(info).arg(moreInfo)); + box.setWindowTitle(tr("D-Bus Viewer")); + box.exec(); +} + +void QDBusViewer::anchorClicked(const QUrl &url) +{ + if (url.scheme() != QLatin1String("qdbus")) + // not ours + return; + + // swallow the click without setting a new document + log->setSource(QUrl()); + + QDBusModel *model = qobject_cast<QDBusModel *>(tree->model()); + if (!model) + return; + + QModelIndex idx = model->findObject(QDBusObjectPath(url.path())); + if (!idx.isValid()) + return; + + tree->scrollTo(idx); + tree->setCurrentIndex(idx); +} + +/*! + \page qdbusviewer.html + \title D-Bus Viewer + \keyword qdbusviewer + + The Qt D-Bus Viewer is a tool that lets you introspect D-Bus objects and messages. You can + choose between the system bus and the session bus. Click on any service on the list + on the left side to see all the exported objects. + + You can invoke methods by double-clicking on them. If a method takes one or more IN parameters, + a property editor opens. + + Right-click on a signal to connect to it. All emitted signals including their parameters + are output in the message view on the lower side of the window. +*/ diff --git a/tools/qdbus/qdbusviewer/qdbusviewer.h b/tools/qdbus/qdbusviewer/qdbusviewer.h new file mode 100644 index 0000000..75511b7 --- /dev/null +++ b/tools/qdbus/qdbusviewer/qdbusviewer.h @@ -0,0 +1,98 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the tools applications of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.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 the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QDBUSVIEWER_H +#define QDBUSVIEWER_H + +#include <QtGui/QtGui> +#include <QtDBus/QtDBus> + +QT_FORWARD_DECLARE_CLASS(QTreeView); +QT_FORWARD_DECLARE_CLASS(QDomDocument); +QT_FORWARD_DECLARE_CLASS(QDomElement); + +struct BusSignature +{ + QString mService, mPath, mInterface, mName; +}; + +class QDBusViewer: public QWidget +{ + Q_OBJECT +public: + QDBusViewer(const QDBusConnection &connection, QWidget *parent = 0); + +public slots: + void refresh(); + void about(); + +private slots: + void serviceChanged(QTreeWidgetItem *item); + void showContextMenu(const QPoint &); + void connectionRequested(const BusSignature &sig); + void callMethod(const BusSignature &sig); + void getProperty(const BusSignature &sig); + void setProperty(const BusSignature &sig); + void dumpMessage(const QDBusMessage &msg); + void refreshChildren(); + + void serviceRegistered(const QString &service); + void serviceUnregistered(const QString &service); + void serviceOwnerChanged(const QString &name, const QString &oldOwner, const QString &newOwner); + + void activate(const QModelIndex &item); + + void logError(const QString &msg); + void anchorClicked(const QUrl &url); + +private: + void logMessage(const QString &msg); + + QDBusConnection c; + QString currentService; + QTreeView *tree; + QAction *refreshAction; + QTreeWidget *services; + QTextBrowser *log; + QRegExp objectPathRegExp; +}; + +#endif diff --git a/tools/qdbus/qdbusviewer/qdbusviewer.pro b/tools/qdbus/qdbusviewer/qdbusviewer.pro new file mode 100644 index 0000000..6727691 --- /dev/null +++ b/tools/qdbus/qdbusviewer/qdbusviewer.pro @@ -0,0 +1,30 @@ +TEMPLATE = app +TARGET = qdbusviewer + +HEADERS = qdbusviewer.h \ + qdbusmodel.h \ + propertydialog.h + +SOURCES = qdbusviewer.cpp \ + qdbusmodel.cpp \ + propertydialog.cpp \ + main.cpp + +RESOURCES += qdbusviewer.qrc + +DESTDIR = ../../../bin + +CONFIG += qdbus +QT += xml + +target.path=$$[QT_INSTALL_BINS] +INSTALLS += target + +mac { + ICON = images/qdbusviewer.icns + QMAKE_INFO_PLIST = Info_mac.plist +} + +win32 { + RC_FILE = qdbusviewer.rc +} diff --git a/tools/qdbus/qdbusviewer/qdbusviewer.qrc b/tools/qdbus/qdbusviewer/qdbusviewer.qrc new file mode 100644 index 0000000..7d592f3 --- /dev/null +++ b/tools/qdbus/qdbusviewer/qdbusviewer.qrc @@ -0,0 +1,6 @@ +<RCC> + <qresource prefix="/trolltech/qdbusviewer" > + <file>images/qdbusviewer-128.png</file> + <file>images/qdbusviewer.png</file> + </qresource> +</RCC> diff --git a/tools/qdbus/qdbusviewer/qdbusviewer.rc b/tools/qdbus/qdbusviewer/qdbusviewer.rc new file mode 100644 index 0000000..c4b1d60 --- /dev/null +++ b/tools/qdbus/qdbusviewer/qdbusviewer.rc @@ -0,0 +1 @@ +IDI_ICON1 ICON DISCARDABLE "images/qdbusviewer.ico" |