qdbusviewer.cpp

来自「奇趣公司比较新的qt/emd版本」· C++ 代码 · 共 530 行 · 第 1/2 页

CPP
530
字号
/******************************************************************************** Copyright (C) 2004-2007 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://trolltech.com/products/qt/licenses/licensing/opensource/**** If you are unsure which license is appropriate for your use, please** review the following information:** http://trolltech.com/products/qt/licenses/licensing/licensingoverview** or contact the sales department at sales@trolltech.com.**** In addition, as a special exception, Trolltech gives you certain** additional rights. These rights are described in the Trolltech GPL** Exception version 1.0, which can be found at** http://www.trolltech.com/products/qt/gplexception/ and in the file** GPL_EXCEPTION.txt in this package.**** In addition, as a special exception, Trolltech, as the sole copyright** holder for Qt Designer, grants users of the Qt/Eclipse Integration** plug-in the right for the Qt/Eclipse Integration to link to** functionality provided by Qt Designer and its related libraries.**** Trolltech reserves all rights not expressly granted herein.**** 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 "qdbusviewer.h"#include "qdbusmodel.h"#include "propertydialog.h"#include <QtXml/QtXml>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){    services = new QTreeWidget;    services->setRootIsDecorated(false);    services->setHeaderLabels(QStringList("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("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("Cannot connect to D-Bus: " + c.lastError().message());    }}void QDBusViewer::logMessage(const QString &msg){    log->append(msg + "\n");}void QDBusViewer::logError(const QString &msg){    log->append("<font color=\"red\">Error: </font>" + Qt::escape(msg) + "<br>");}void QDBusViewer::refresh(){    services->clear();    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, "org.freedesktop.DBus.Properties", "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, "Arguments",                    QString("Please enter the value of the property %1 (type %2)").arg(                        sig.mName).arg(prop.typeName()),                    QLineEdit::Normal, QString(), &ok);    if (!ok)        return;    QVariant value = input;    if (!value.convert(prop.type())) {        QMessageBox::warning(this, "Unable to marshall",                "Value conversion failed, unable to set property");        return;    }    QDBusMessage message = QDBusMessage::createMethodCall(sig.mService, sig.mPath, "org.freedesktop.DBus.Properties", "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()) == '(')            method = mo->method(i);    }    if (!method.signature()) {        QMessageBox::warning(this, "Unable to find method",                QString("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("Please enter parameters for the method \"" + 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);

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?