#include <qdbusviewer.h>
Inheritance diagram for QDBusViewer:


Definition at line 39 of file qdbusviewer.h.
Public Slots | |
| void | refresh () |
Public Member Functions | |
| QDBusViewer (const QDBusConnection &connection, QWidget *parent=0) | |
Private Slots | |
| void | serviceChanged (QTreeWidgetItem *item) |
| void | showContextMenu (const QPoint &) |
| void | connectionRequested (const BusSignature &sig) |
| void | callMethod (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) |
Private Member Functions | |
| void | logMessage (const QString &msg) |
Private Attributes | |
| QDBusConnection | c |
| QString | currentService |
| QTreeView * | tree |
| QAction * | refreshAction |
| QTreeWidget * | services |
| QTextEdit * | log |
| QDBusViewer::QDBusViewer | ( | const QDBusConnection & | connection, | |
| QWidget * | parent = 0 | |||
| ) |
Definition at line 47 of file qdbusviewer.cpp.
References activate(), QBoxLayout::addLayout(), QLayout::addWidget(), QBoxLayout::addWidget(), c, QObject::connect(), Qt::CustomContextMenu, QWidget::customContextMenuRequested(), QDBusConnection::interface(), QMetaObject::invokeMethod(), QDBusConnection::isConnected(), QDBusConnection::lastError(), QWidget::layout(), log, logError(), logMessage(), QDBusError::message(), Qt::QueuedConnection, QKeySequence::Refresh, refreshAction, refreshChildren(), serviceChanged(), serviceOwnerChanged(), serviceRegistered(), services, serviceUnregistered(), QWidget::setContextMenuPolicy(), QAction::setData(), QTreeWidget::setHeaderLabels(), QTextEdit::setReadOnly(), QTreeView::setRootIsDecorated(), QAction::setShortcut(), showContextMenu(), SIGNAL, SLOT, and tree.
00048 : QWidget(parent), c(connection) 00049 { 00050 services = new QTreeWidget; 00051 services->setRootIsDecorated(false); 00052 services->setHeaderLabels(QStringList("Services")); 00053 00054 tree = new QTreeView; 00055 tree->setContextMenuPolicy(Qt::CustomContextMenu); 00056 00057 connect(tree, SIGNAL(activated(const QModelIndex&)), this, SLOT(activate(const QModelIndex&))); 00058 00059 refreshAction = new QAction(tr("&Refresh"), tree); 00060 refreshAction->setData(42); // increase the amount of 42 used as magic number by one 00061 refreshAction->setShortcut(QKeySequence::Refresh); 00062 connect(refreshAction, SIGNAL(triggered()), this, SLOT(refreshChildren())); 00063 00064 QShortcut *refreshShortcut = new QShortcut(QKeySequence::Refresh, tree); 00065 connect(refreshShortcut, SIGNAL(activated()), this, SLOT(refreshChildren())); 00066 00067 QVBoxLayout *topLayout = new QVBoxLayout(this); 00068 log = new QTextEdit; 00069 log->setReadOnly(true); 00070 00071 QHBoxLayout *layout = new QHBoxLayout; 00072 layout->addWidget(services, 1); 00073 layout->addWidget(tree, 2); 00074 00075 topLayout->addLayout(layout); 00076 topLayout->addWidget(log); 00077 00078 connect(services, SIGNAL(currentItemChanged(QTreeWidgetItem*,QTreeWidgetItem*)), 00079 this, SLOT(serviceChanged(QTreeWidgetItem*))); 00080 connect(tree, SIGNAL(customContextMenuRequested(QPoint)), 00081 this, SLOT(showContextMenu(QPoint))); 00082 00083 QMetaObject::invokeMethod(this, "refresh", Qt::QueuedConnection); 00084 00085 if (c.isConnected()) { 00086 logMessage("Connected to D-Bus."); 00087 QDBusConnectionInterface *iface = c.interface(); 00088 connect(iface, SIGNAL(serviceRegistered(QString)), 00089 this, SLOT(serviceRegistered(QString))); 00090 connect(iface, SIGNAL(serviceUnregistered(QString)), 00091 this, SLOT(serviceUnregistered(QString))); 00092 connect(iface, SIGNAL(serviceOwnerChanged(QString,QString,QString)), 00093 this, SLOT(serviceOwnerChanged(QString,QString,QString))); 00094 } else { 00095 logError("Cannot connect to D-Bus: " + c.lastError().message()); 00096 } 00097 }
Here is the call graph for this function:

| void QDBusViewer::refresh | ( | ) | [slot] |
Definition at line 109 of file qdbusviewer.cpp.
References c, QTreeWidget::clear(), QDBusConnection::interface(), QDBusConnectionInterface::registeredServiceNames(), and services.
00110 { 00111 services->clear(); 00112 00113 const QStringList serviceNames = c.interface()->registeredServiceNames(); 00114 foreach (QString service, serviceNames) 00115 new QTreeWidgetItem(services, QStringList(service)); 00116 }
| void QDBusViewer::serviceChanged | ( | QTreeWidgetItem * | item | ) | [private, slot] |
Definition at line 345 of file qdbusviewer.cpp.
References c, QString::clear(), QObject::connect(), currentService, logError(), QAbstractItemView::model(), QTreeView::setModel(), SIGNAL, SLOT, QTreeWidgetItem::text(), and tree.
Referenced by QDBusViewer().
00346 { 00347 delete tree->model(); 00348 00349 currentService.clear(); 00350 if (!item) 00351 return; 00352 currentService = item->text(0); 00353 00354 tree->setModel(new QDBusViewModel(currentService, c)); 00355 connect(tree->model(), SIGNAL(busError(QString)), this, SLOT(logError(QString))); 00356 }
| void QDBusViewer::showContextMenu | ( | const QPoint & | ) | [private, slot] |
Definition at line 218 of file qdbusviewer.cpp.
References QMenu::addAction(), callMethod(), connectionRequested(), currentService, QAction::data(), QDBusModel::dBusInterface(), QDBusModel::dBusMethodName(), QDBusModel::dBusPath(), QMenu::exec(), QTreeView::indexAt(), QModelIndex::isValid(), QDBusModel::itemType(), QWidget::mapToGlobal(), QDBusModel::MethodItem, QModelIndex::model(), refreshAction, QAction::setData(), QDBusModel::SignalItem, QVariant::toInt(), tree, and QAbstractScrollArea::viewport().
Referenced by QDBusViewer().
00219 { 00220 QModelIndex item = tree->indexAt(point); 00221 if (!item.isValid()) 00222 return; 00223 00224 const QDBusModel *model = static_cast<const QDBusModel *>(item.model()); 00225 00226 BusSignature sig; 00227 sig.mService = currentService; 00228 sig.mPath = model->dBusPath(item); 00229 sig.mInterface = model->dBusInterface(item); 00230 sig.mName = model->dBusMethodName(item); 00231 00232 QMenu menu; 00233 menu.addAction(refreshAction); 00234 00235 switch (model->itemType(item)) { 00236 case QDBusModel::SignalItem: { 00237 QAction *action = new QAction("&Connect", &menu); 00238 action->setData(1); 00239 menu.addAction(action); 00240 break; } 00241 case QDBusModel::MethodItem: { 00242 QAction *action = new QAction("&Call", &menu); 00243 action->setData(2); 00244 menu.addAction(action); 00245 break; } 00246 #if 0 00247 case PropertyItem: { 00248 QAction *actionSet = new QAction("&Set value", &menu); 00249 actionSet->setData(3); 00250 QAction *actionGet = new QAction("&Get value", &menu); 00251 actionGet->setData(4); 00252 menu.addAction(actionSet); 00253 menu.addAction(actionGet); 00254 break; } 00255 #endif 00256 default: 00257 break; 00258 } 00259 00260 QAction *selectedAction = menu.exec(tree->viewport()->mapToGlobal(point)); 00261 if (!selectedAction) 00262 return; 00263 00264 switch (selectedAction->data().toInt()) { 00265 case 1: 00266 connectionRequested(sig); 00267 break; 00268 case 2: 00269 callMethod(sig); 00270 break; 00271 } 00272 }
| void QDBusViewer::connectionRequested | ( | const BusSignature & | sig | ) | [private, slot] |
Definition at line 274 of file qdbusviewer.cpp.
References c, QDBusConnection::connect(), dumpMessage(), logError(), BusSignature::mInterface, BusSignature::mName, BusSignature::mPath, BusSignature::mService, and SLOT.
Referenced by activate(), and showContextMenu().
00275 { 00276 if (!c.connect(sig.mService, QString(), sig.mInterface, sig.mName, this, 00277 SLOT(dumpMessage(QDBusMessage)))) { 00278 logError(QString("Unable to connect to service %1, path %2, interface %3, signal %4").arg( 00279 sig.mService).arg(sig.mPath).arg(sig.mInterface).arg(sig.mName)); 00280 } 00281 }
| void QDBusViewer::callMethod | ( | const BusSignature & | sig | ) | [private, slot] |
Definition at line 147 of file qdbusviewer.cpp.
References QList< T >::at(), c, QDBusConnection::callWithCallback(), QList< T >::clear(), QVariant::convert(), QList< T >::count(), QDBusMessage::createMethodCall(), dumpMessage(), QByteArray::endsWith(), Qt::escape(), QString::fromLatin1(), QString::fromUtf8(), QInputDialog::getText(), i, QList< T >::isEmpty(), QString::length(), message, QDBusInterface::metaObject(), QMetaObject::method(), method, QMetaObject::methodCount(), BusSignature::mInterface, BusSignature::mName, BusSignature::mPath, BusSignature::mService, QVariant::nameToType(), QLineEdit::Normal, QMetaMethod::signature(), SLOT, QString::split(), QVariant::String, and QMessageBox::warning().
Referenced by activate(), and showContextMenu().
00148 { 00149 QDBusInterface iface(sig.mService, sig.mPath, sig.mInterface, c); 00150 const QMetaObject *mo = iface.metaObject(); 00151 00152 // find the method 00153 QMetaMethod method; 00154 for (int i = 0; i < mo->methodCount(); ++i) { 00155 const QString signature = QString::fromLatin1(mo->method(i).signature()); 00156 if (signature.startsWith(sig.mName) && signature.at(sig.mName.length()) == '(') 00157 method = mo->method(i); 00158 } 00159 if (!method.signature()) { 00160 QMessageBox::warning(this, "Unable to find method", 00161 QString("Unable to find method %1 on path %2 in interface %3").arg( 00162 sig.mName).arg(sig.mPath).arg(sig.mInterface)); 00163 return; 00164 } 00165 00166 QList<QByteArray> paramTypes = method.parameterTypes(); 00167 int paramTypeCount = 0; 00168 foreach (QByteArray paramType, paramTypes) { 00169 if (paramType.endsWith('&')) 00170 continue; // ignore OUT parameters 00171 00172 if (!QVariant(QVariant::nameToType(paramType)).canConvert(QVariant::String)) { 00173 QMessageBox::warning(this, "Unable to call method", 00174 QString("Cannot marshall parameter of type %1").arg( 00175 QVariant::nameToType(paramType))); 00176 return; 00177 } 00178 ++paramTypeCount; 00179 } 00180 00181 QList<QVariant> arguments; 00182 if (!paramTypes.isEmpty()) { 00183 QString input; 00184 bool ok = true; 00185 while (arguments.isEmpty()) { 00186 input = QInputDialog::getText(this, "Arguments", 00187 "Please enter the arguments for the call, separated by comma." 00188 "<br>Example: <i>hello,world,2.3,-34</i><br><br><b>Signature:</b> " 00189 + Qt::escape(QString::fromUtf8(method.signature())), 00190 QLineEdit::Normal, input, &ok); 00191 if (!ok) 00192 return; 00193 00194 QStringList argStrings = input.split(','); 00195 if (argStrings.count() != paramTypeCount) 00196 continue; 00197 00198 for (int i = 0; i < argStrings.count(); ++i) { 00199 if (paramTypes.at(i).endsWith('&')) 00200 continue; // ignore OUT paramters 00201 00202 QVariant v = argStrings.at(i); 00203 if (!v.convert(QVariant::nameToType(paramTypes.at(i)))) { 00204 arguments.clear(); 00205 break; 00206 } 00207 arguments += v; 00208 } 00209 } 00210 } 00211 00212 QDBusMessage message = QDBusMessage::createMethodCall(sig.mService, sig.mPath, sig.mInterface, 00213 sig.mName); 00214 message.setArguments(arguments); 00215 c.callWithCallback(message, this, SLOT(dumpMessage(QDBusMessage))); 00216 }
| void QDBusViewer::dumpMessage | ( | const QDBusMessage & | msg | ) | [private, slot] |
Definition at line 283 of file qdbusviewer.cpp.
References QTextEdit::append(), QString::arg(), QVariant::canConvert(), QString::chop(), QDBusMessage::ErrorMessage, Qt::escape(), QString::fromLatin1(), QList< T >::isEmpty(), log, message, QVariant::Rect, QDBusMessage::ReplyMessage, QDBusMessage::SignalMessage, QVariant::String, QVariant::StringList, QVariant::toRect(), and QVariant::toStringList().
Referenced by callMethod(), and connectionRequested().
00284 { 00285 QList<QVariant> args = message.arguments(); 00286 QString out = "Received "; 00287 00288 switch (message.type()) { 00289 case QDBusMessage::SignalMessage: 00290 out += "signal "; 00291 break; 00292 case QDBusMessage::ErrorMessage: 00293 out += "error message "; 00294 break; 00295 case QDBusMessage::ReplyMessage: 00296 out += "reply "; 00297 break; 00298 default: 00299 out += "message "; 00300 break; 00301 } 00302 00303 out += "from "; 00304 out += message.service(); 00305 if (!message.path().isEmpty()) 00306 out += ", path " + message.path(); 00307 if (!message.interface().isEmpty()) 00308 out += ", interface <i>" + message.interface() + "</i>"; 00309 if (!message.member().isEmpty()) 00310 out += ", member " + message.member(); 00311 out += "<br>"; 00312 if (!args.isEmpty()) { 00313 out += " Parameters: "; 00314 foreach (QVariant arg, args) { 00315 if (arg.canConvert(QVariant::StringList)) { 00316 out += "<b>{</b>"; 00317 QStringList list = arg.toStringList(); 00318 foreach (QString item, list) 00319 out += "<b>\"</b>" + Qt::escape(item) + "<b>\"</b>, "; 00320 if (!list.isEmpty()) 00321 out.chop(2); 00322 out += "<b>}</b>"; 00323 } else if (arg.canConvert(QVariant::Rect)) { 00324 QRect r = arg.toRect(); 00325 out += QString::fromLatin1("QRect(%1, %2, %3, %4)").arg(r.left()).arg(r.top()).arg( 00326 r.right()).arg(r.bottom()); 00327 } else if (qVariantCanConvert<QDBusArgument>(arg)) { 00328 out += "[QDBusArgument: " + qvariant_cast<QDBusArgument>(arg).currentSignature(); 00329 out += "]"; 00330 } else if (arg.canConvert(QVariant::String)) { 00331 out += "<b>\"</b>" + Qt::escape(arg.toString()) + "<b>\"</b>"; 00332 } else { 00333 out += "["; 00334 out += arg.typeName(); 00335 out += "]"; 00336 } 00337 out += ", "; 00338 } 00339 out.chop(2); 00340 } 00341 00342 log->append(out); 00343 }
| void QDBusViewer::refreshChildren | ( | ) | [private, slot] |
Definition at line 395 of file qdbusviewer.cpp.
References QAbstractItemView::currentIndex(), QAbstractItemView::model(), QDBusModel::refresh(), and tree.
Referenced by QDBusViewer().
00396 { 00397 QDBusModel *model = qobject_cast<QDBusModel *>(tree->model()); 00398 if (!model) 00399 return; 00400 model->refresh(tree->currentIndex()); 00401 }
| void QDBusViewer::serviceRegistered | ( | const QString & | service | ) | [private, slot] |
Definition at line 358 of file qdbusviewer.cpp.
References QDBusConnection::baseService(), c, and services.
Referenced by QDBusViewer(), and serviceOwnerChanged().
00359 { 00360 if (service == c.baseService()) 00361 return; 00362 00363 new QTreeWidgetItem(services, QStringList(service)); 00364 }
| void QDBusViewer::serviceUnregistered | ( | const QString & | service | ) | [private, slot] |
Definition at line 375 of file qdbusviewer.cpp.
References findItem(), name, and services.
Referenced by QDBusViewer().
| void QDBusViewer::serviceOwnerChanged | ( | const QString & | name, | |
| const QString & | oldOwner, | |||
| const QString & | newOwner | |||
| ) | [private, slot] |
Definition at line 380 of file qdbusviewer.cpp.
References findItem(), QString::isEmpty(), name, serviceRegistered(), and services.
Referenced by QDBusViewer().
00382 { 00383 QTreeWidgetItem *item = findItem(services, name); 00384 00385 if (!item && oldOwner.isEmpty() && !newOwner.isEmpty()) 00386 serviceRegistered(name); 00387 else if (item && !oldOwner.isEmpty() && newOwner.isEmpty()) 00388 delete item; 00389 else if (item && !oldOwner.isEmpty() && !newOwner.isEmpty()) { 00390 delete item; 00391 serviceRegistered(name); 00392 } 00393 }
| void QDBusViewer::activate | ( | const QModelIndex & | item | ) | [private, slot] |
Definition at line 118 of file qdbusviewer.cpp.
References callMethod(), connectionRequested(), currentService, QDBusModel::dBusInterface(), QDBusModel::dBusMethodName(), QDBusModel::dBusPath(), QModelIndex::isValid(), QDBusModel::itemType(), QDBusModel::MethodItem, QModelIndex::model(), QDBusModel::PropertyItem, and QDBusModel::SignalItem.
Referenced by QDBusViewer().
00119 { 00120 if (!item.isValid()) 00121 return; 00122 00123 const QDBusModel *model = static_cast<const QDBusModel *>(item.model()); 00124 00125 BusSignature sig; 00126 sig.mService = currentService; 00127 sig.mPath = model->dBusPath(item); 00128 sig.mInterface = model->dBusInterface(item); 00129 sig.mName = model->dBusMethodName(item); 00130 00131 switch (model->itemType(item)) { 00132 case QDBusModel::SignalItem: 00133 connectionRequested(sig); 00134 break; 00135 case QDBusModel::MethodItem: 00136 callMethod(sig); 00137 break; 00138 #if 0 00139 case QDBusModel::PropertyItem: 00140 break; 00141 #endif 00142 default: 00143 break; 00144 } 00145 }
| void QDBusViewer::logError | ( | const QString & | msg | ) | [private, slot] |
Definition at line 104 of file qdbusviewer.cpp.
References QTextEdit::append(), Qt::escape(), and log.
Referenced by connectionRequested(), QDBusViewer(), and serviceChanged().
00105 { 00106 log->append("<font color=\"red\">Error: </font>" + Qt::escape(msg) + "<br>"); 00107 }
| void QDBusViewer::logMessage | ( | const QString & | msg | ) | [private] |
Definition at line 99 of file qdbusviewer.cpp.
References QTextEdit::append(), and log.
Referenced by QDBusViewer().
QDBusConnection QDBusViewer::c [private] |
Definition at line 67 of file qdbusviewer.h.
Referenced by callMethod(), connectionRequested(), QDBusViewer(), refresh(), serviceChanged(), and serviceRegistered().
QString QDBusViewer::currentService [private] |
Definition at line 68 of file qdbusviewer.h.
Referenced by activate(), serviceChanged(), and showContextMenu().
QTreeView* QDBusViewer::tree [private] |
Definition at line 69 of file qdbusviewer.h.
Referenced by QDBusViewer(), refreshChildren(), serviceChanged(), and showContextMenu().
QAction* QDBusViewer::refreshAction [private] |
QTreeWidget* QDBusViewer::services [private] |
Definition at line 71 of file qdbusviewer.h.
Referenced by QDBusViewer(), refresh(), serviceOwnerChanged(), serviceRegistered(), and serviceUnregistered().
QTextEdit* QDBusViewer::log [private] |
Definition at line 72 of file qdbusviewer.h.
Referenced by dumpMessage(), logError(), logMessage(), and QDBusViewer().
1.5.1