source: trunk/src/dbus/qdbusabstractinterface.cpp@ 858

Last change on this file since 858 was 846, checked in by Dmitry A. Kuminov, 14 years ago

trunk: Merged in qt 4.7.2 sources from branches/vendor/nokia/qt.

File size: 28.9 KB
Line 
1/****************************************************************************
2**
3** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
4** All rights reserved.
5** Contact: Nokia Corporation ([email protected])
6**
7** This file is part of the QtDBus module of the Qt Toolkit.
8**
9** $QT_BEGIN_LICENSE:LGPL$
10** Commercial Usage
11** Licensees holding valid Qt Commercial licenses may use this file in
12** accordance with the Qt Commercial License Agreement provided with the
13** Software or, alternatively, in accordance with the terms contained in
14** a written agreement between you and Nokia.
15**
16** GNU Lesser General Public License Usage
17** Alternatively, this file may be used under the terms of the GNU Lesser
18** General Public License version 2.1 as published by the Free Software
19** Foundation and appearing in the file LICENSE.LGPL included in the
20** packaging of this file. Please review the following information to
21** ensure the GNU Lesser General Public License version 2.1 requirements
22** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
23**
24** In addition, as a special exception, Nokia gives you certain additional
25** rights. These rights are described in the Nokia Qt LGPL Exception
26** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
27**
28** GNU General Public License Usage
29** Alternatively, this file may be used under the terms of the GNU
30** General Public License version 3.0 as published by the Free Software
31** Foundation and appearing in the file LICENSE.GPL included in the
32** packaging of this file. Please review the following information to
33** ensure the GNU General Public License version 3.0 requirements will be
34** met: http://www.gnu.org/copyleft/gpl.html.
35**
36** If you have questions regarding the use of this file, please contact
37** Nokia at [email protected].
38** $QT_END_LICENSE$
39**
40****************************************************************************/
41
42#include "qdbusabstractinterface.h"
43#include "qdbusabstractinterface_p.h"
44
45#include <qthread.h>
46
47#include "qdbusargument.h"
48#include "qdbuspendingcall.h"
49#include "qdbusmessage_p.h"
50#include "qdbusmetaobject_p.h"
51#include "qdbusmetatype_p.h"
52#include "qdbusutil_p.h"
53
54#include <qdebug.h>
55
56#ifndef QT_NO_DBUS
57
58QT_BEGIN_NAMESPACE
59
60static QDBusError checkIfValid(const QString &service, const QString &path,
61 const QString &interface, bool isDynamic)
62{
63 // We should be throwing exceptions here... oh well
64 QDBusError error;
65
66 // dynamic interfaces (QDBusInterface) can have empty interfaces, but not service and object paths
67 // non-dynamic is the opposite: service and object paths can be empty, but not the interface
68 if (!isDynamic) {
69 // use assertion here because this should never happen, at all
70 Q_ASSERT_X(!interface.isEmpty(), "QDBusAbstractInterface", "Interface name cannot be empty");
71 }
72 if (!QDBusUtil::checkBusName(service, isDynamic ? QDBusUtil::EmptyNotAllowed : QDBusUtil::EmptyAllowed, &error))
73 return error;
74 if (!QDBusUtil::checkObjectPath(path, isDynamic ? QDBusUtil::EmptyNotAllowed : QDBusUtil::EmptyAllowed, &error))
75 return error;
76 if (!QDBusUtil::checkInterfaceName(interface, QDBusUtil::EmptyAllowed, &error))
77 return error;
78
79 // no error
80 return QDBusError();
81}
82
83QDBusAbstractInterfacePrivate::QDBusAbstractInterfacePrivate(const QString &serv,
84 const QString &p,
85 const QString &iface,
86 const QDBusConnection& con,
87 bool isDynamic)
88 : connection(con), service(serv), path(p), interface(iface),
89 lastError(checkIfValid(serv, p, iface, isDynamic)),
90 isValid(!lastError.isValid())
91{
92 if (!isValid)
93 return;
94
95 if (!connection.isConnected()) {
96 lastError = QDBusError(QDBusError::Disconnected,
97 QLatin1String("Not connected to D-Bus server"));
98 } else if (!service.isEmpty()) {
99 currentOwner = connectionPrivate()->getNameOwner(service); // verify the name owner
100 if (currentOwner.isEmpty()) {
101 lastError = connectionPrivate()->lastError;
102 }
103 }
104}
105
106bool QDBusAbstractInterfacePrivate::canMakeCalls() const
107{
108 // recheck only if we have a wildcard (i.e. empty) service or path
109 // if any are empty, set the error message according to QDBusUtil
110 if (service.isEmpty())
111 return QDBusUtil::checkBusName(service, QDBusUtil::EmptyNotAllowed, &lastError);
112 if (path.isEmpty())
113 return QDBusUtil::checkObjectPath(path, QDBusUtil::EmptyNotAllowed, &lastError);
114 return true;
115}
116
117void QDBusAbstractInterfacePrivate::property(const QMetaProperty &mp, QVariant &where) const
118{
119 if (!isValid || !canMakeCalls()) { // can't make calls
120 where.clear();
121 return;
122 }
123
124 // is this metatype registered?
125 const char *expectedSignature = "";
126 if (mp.type() != 0xff) {
127 expectedSignature = QDBusMetaType::typeToSignature(where.userType());
128 if (expectedSignature == 0) {
129 qWarning("QDBusAbstractInterface: type %s must be registered with QtDBus before it can be "
130 "used to read property %s.%s",
131 mp.typeName(), qPrintable(interface), mp.name());
132 lastError = QDBusError(QDBusError::Failed,
133 QString::fromLatin1("Unregistered type %1 cannot be handled")
134 .arg(QLatin1String(mp.typeName())));
135 where.clear();
136 return;
137 }
138 }
139
140 // try to read this property
141 QDBusMessage msg = QDBusMessage::createMethodCall(service, path,
142 QLatin1String(DBUS_INTERFACE_PROPERTIES),
143 QLatin1String("Get"));
144 QDBusMessagePrivate::setParametersValidated(msg, true);
145 msg << interface << QString::fromUtf8(mp.name());
146 QDBusMessage reply = connection.call(msg, QDBus::Block);
147
148 if (reply.type() != QDBusMessage::ReplyMessage) {
149 lastError = reply;
150 where.clear();
151 return;
152 }
153 if (reply.signature() != QLatin1String("v")) {
154 QString errmsg = QLatin1String("Invalid signature `%1' in return from call to "
155 DBUS_INTERFACE_PROPERTIES);
156 lastError = QDBusError(QDBusError::InvalidSignature, errmsg.arg(reply.signature()));
157 where.clear();
158 return;
159 }
160
161 QByteArray foundSignature;
162 const char *foundType = 0;
163 QVariant value = qvariant_cast<QDBusVariant>(reply.arguments().at(0)).variant();
164
165 if (value.userType() == where.userType() || mp.type() == 0xff
166 || (expectedSignature[0] == 'v' && expectedSignature[1] == '\0')) {
167 // simple match
168 where = value;
169 return;
170 }
171
172 if (value.userType() == qMetaTypeId<QDBusArgument>()) {
173 QDBusArgument arg = qvariant_cast<QDBusArgument>(value);
174
175 foundType = "user type";
176 foundSignature = arg.currentSignature().toLatin1();
177 if (foundSignature == expectedSignature) {
178 // signatures match, we can demarshall
179 QDBusMetaType::demarshall(arg, where.userType(), where.data());
180 return;
181 }
182 } else {
183 foundType = value.typeName();
184 foundSignature = QDBusMetaType::typeToSignature(value.userType());
185 }
186
187 // there was an error...
188 QString errmsg = QLatin1String("Unexpected `%1' (%2) when retrieving property `%3.%4' "
189 "(expected type `%5' (%6))");
190 lastError = QDBusError(QDBusError::InvalidSignature,
191 errmsg.arg(QString::fromLatin1(foundType),
192 QString::fromLatin1(foundSignature),
193 interface,
194 QString::fromUtf8(mp.name()),
195 QString::fromLatin1(mp.typeName()),
196 QString::fromLatin1(expectedSignature)));
197 where.clear();
198 return;
199}
200
201bool QDBusAbstractInterfacePrivate::setProperty(const QMetaProperty &mp, const QVariant &value)
202{
203 if (!isValid || !canMakeCalls()) // can't make calls
204 return false;
205
206 // send the value
207 QDBusMessage msg = QDBusMessage::createMethodCall(service, path,
208 QLatin1String(DBUS_INTERFACE_PROPERTIES),
209 QLatin1String("Set"));
210 QDBusMessagePrivate::setParametersValidated(msg, true);
211 msg << interface << QString::fromUtf8(mp.name()) << qVariantFromValue(QDBusVariant(value));
212 QDBusMessage reply = connection.call(msg, QDBus::Block);
213
214 if (reply.type() != QDBusMessage::ReplyMessage) {
215 lastError = reply;
216 return false;
217 }
218 return true;
219}
220
221void QDBusAbstractInterfacePrivate::_q_serviceOwnerChanged(const QString &name,
222 const QString &oldOwner,
223 const QString &newOwner)
224{
225 Q_UNUSED(oldOwner);
226 //qDebug() << "QDBusAbstractInterfacePrivate serviceOwnerChanged" << name << oldOwner << newOwner;
227 if (name == service) {
228 currentOwner = newOwner;
229 }
230}
231
232QDBusAbstractInterfaceBase::QDBusAbstractInterfaceBase(QDBusAbstractInterfacePrivate &d, QObject *parent)
233 : QObject(d, parent)
234{
235}
236
237int QDBusAbstractInterfaceBase::qt_metacall(QMetaObject::Call _c, int _id, void **_a)
238{
239 int saved_id = _id;
240 _id = QObject::qt_metacall(_c, _id, _a);
241 if (_id < 0)
242 return _id;
243
244 if (_c == QMetaObject::ReadProperty || _c == QMetaObject::WriteProperty) {
245 QMetaProperty mp = metaObject()->property(saved_id);
246 int &status = *reinterpret_cast<int *>(_a[2]);
247 QVariant &variant = *reinterpret_cast<QVariant *>(_a[1]);
248
249 if (_c == QMetaObject::WriteProperty) {
250 status = d_func()->setProperty(mp, variant) ? 1 : 0;
251 } else {
252 d_func()->property(mp, variant);
253 status = variant.isValid() ? 1 : 0;
254 }
255 _id = -1;
256 }
257 return _id;
258}
259
260/*!
261 \class QDBusAbstractInterface
262 \inmodule QtDBus
263 \since 4.2
264
265 \brief The QDBusAbstractInterface class is the base class for all D-Bus interfaces in the QtDBus binding, allowing access to remote interfaces
266
267 Generated-code classes also derive from QDBusAbstractInterface,
268 all methods described here are also valid for generated-code
269 classes. In addition to those described here, generated-code
270 classes provide member functions for the remote methods, which
271 allow for compile-time checking of the correct parameters and
272 return values, as well as property type-matching and signal
273 parameter-matching.
274
275 \sa {qdbusxml2cpp.html}{The QDBus compiler}, QDBusInterface
276*/
277
278/*!
279 \internal
280 This is the constructor called from QDBusInterface::QDBusInterface.
281*/
282QDBusAbstractInterface::QDBusAbstractInterface(QDBusAbstractInterfacePrivate &d, QObject *parent)
283 : QDBusAbstractInterfaceBase(d, parent)
284{
285 // keep track of the service owner
286 if (d.isValid &&
287 d.connection.isConnected()
288 && !d.service.isEmpty()
289 && !d.service.startsWith(QLatin1Char(':')))
290 d_func()->connection.connect(QLatin1String(DBUS_SERVICE_DBUS), // service
291 QString(), // path
292 QLatin1String(DBUS_INTERFACE_DBUS), // interface
293 QLatin1String("NameOwnerChanged"),
294 QStringList() << d.service,
295 QString(), // signature
296 this, SLOT(_q_serviceOwnerChanged(QString,QString,QString)));
297}
298
299/*!
300 \internal
301 This is the constructor called from static classes derived from
302 QDBusAbstractInterface (i.e., those generated by dbusxml2cpp).
303*/
304QDBusAbstractInterface::QDBusAbstractInterface(const QString &service, const QString &path,
305 const char *interface, const QDBusConnection &con,
306 QObject *parent)
307 : QDBusAbstractInterfaceBase(*new QDBusAbstractInterfacePrivate(service, path, QString::fromLatin1(interface),
308 con, false), parent)
309{
310 // keep track of the service owner
311 if (d_func()->isValid &&
312 d_func()->connection.isConnected()
313 && !service.isEmpty()
314 && !service.startsWith(QLatin1Char(':')))
315 d_func()->connection.connect(QLatin1String(DBUS_SERVICE_DBUS), // service
316 QString(), // path
317 QLatin1String(DBUS_INTERFACE_DBUS), // interface
318 QLatin1String("NameOwnerChanged"),
319 QStringList() << service,
320 QString(), //signature
321 this, SLOT(_q_serviceOwnerChanged(QString,QString,QString)));
322}
323
324/*!
325 Releases this object's resources.
326*/
327QDBusAbstractInterface::~QDBusAbstractInterface()
328{
329}
330
331/*!
332 Returns true if this is a valid reference to a remote object. It returns false if
333 there was an error during the creation of this interface (for instance, if the remote
334 application does not exist).
335
336 Note: when dealing with remote objects, it is not always possible to determine if it
337 exists when creating a QDBusInterface.
338*/
339bool QDBusAbstractInterface::isValid() const
340{
341 return !d_func()->currentOwner.isEmpty();
342}
343
344/*!
345 Returns the connection this interface is assocated with.
346*/
347QDBusConnection QDBusAbstractInterface::connection() const
348{
349 return d_func()->connection;
350}
351
352/*!
353 Returns the name of the service this interface is associated with.
354*/
355QString QDBusAbstractInterface::service() const
356{
357 return d_func()->service;
358}
359
360/*!
361 Returns the object path that this interface is associated with.
362*/
363QString QDBusAbstractInterface::path() const
364{
365 return d_func()->path;
366}
367
368/*!
369 Returns the name of this interface.
370*/
371QString QDBusAbstractInterface::interface() const
372{
373 return d_func()->interface;
374}
375
376/*!
377 Returns the error the last operation produced, or an invalid error if the last operation did not
378 produce an error.
379*/
380QDBusError QDBusAbstractInterface::lastError() const
381{
382 return d_func()->lastError;
383}
384
385/*!
386 Places a call to the remote method specified by \a method on this interface, using \a args as
387 arguments. This function returns the message that was received as a reply, which can be a normal
388 QDBusMessage::ReplyMessage (indicating success) or QDBusMessage::ErrorMessage (if the call
389 failed). The \a mode parameter specifies how this call should be placed.
390
391 If the call succeeds, lastError() will be cleared; otherwise, it will contain the error this
392 call produced.
393
394 Normally, you should place calls using call().
395
396 \warning If you use \c UseEventLoop, your code must be prepared to deal with any reentrancy:
397 other method calls and signals may be delivered before this function returns, as well
398 as other Qt queued signals and events.
399
400 \threadsafe
401*/
402QDBusMessage QDBusAbstractInterface::callWithArgumentList(QDBus::CallMode mode,
403 const QString& method,
404 const QList<QVariant>& args)
405{
406 Q_D(QDBusAbstractInterface);
407
408 if (!d->isValid || !d->canMakeCalls())
409 return QDBusMessage::createError(d->lastError);
410
411 QString m = method;
412 // split out the signature from the method
413 int pos = method.indexOf(QLatin1Char('.'));
414 if (pos != -1)
415 m.truncate(pos);
416
417 if (mode == QDBus::AutoDetect) {
418 // determine if this a sync or async call
419 mode = QDBus::Block;
420 const QMetaObject *mo = metaObject();
421 QByteArray match = m.toLatin1() + '(';
422
423 for (int i = staticMetaObject.methodCount(); i < mo->methodCount(); ++i) {
424 QMetaMethod mm = mo->method(i);
425 if (QByteArray(mm.signature()).startsWith(match)) {
426 // found a method with the same name as what we're looking for
427 // hopefully, nobody is overloading asynchronous and synchronous methods with
428 // the same name
429
430 QList<QByteArray> tags = QByteArray(mm.tag()).split(' ');
431 if (tags.contains("Q_NOREPLY"))
432 mode = QDBus::NoBlock;
433
434 break;
435 }
436 }
437 }
438
439// qDebug() << "QDBusAbstractInterface" << "Service" << service() << "Path:" << path();
440 QDBusMessage msg = QDBusMessage::createMethodCall(service(), path(), interface(), m);
441 QDBusMessagePrivate::setParametersValidated(msg, true);
442 msg.setArguments(args);
443
444 QDBusMessage reply = d->connection.call(msg, mode);
445 if (thread() == QThread::currentThread())
446 d->lastError = reply; // will clear if reply isn't an error
447
448 // ensure that there is at least one element
449 if (reply.arguments().isEmpty())
450 reply << QVariant();
451
452 return reply;
453}
454
455/*!
456 \since 4.5
457 Places a call to the remote method specified by \a method on this
458 interface, using \a args as arguments. This function returns a
459 QDBusPendingCall object that can be used to track the status of the
460 reply and access its contents once it has arrived.
461
462 Normally, you should place calls using asyncCall().
463
464 \threadsafe
465*/
466QDBusPendingCall QDBusAbstractInterface::asyncCallWithArgumentList(const QString& method,
467 const QList<QVariant>& args)
468{
469 Q_D(QDBusAbstractInterface);
470
471 if (!d->isValid || !d->canMakeCalls())
472 return QDBusPendingCall::fromError(d->lastError);
473
474 QDBusMessage msg = QDBusMessage::createMethodCall(service(), path(), interface(), method);
475 QDBusMessagePrivate::setParametersValidated(msg, true);
476 msg.setArguments(args);
477 return d->connection.asyncCall(msg);
478}
479
480/*!
481 Places a call to the remote method specified by \a method
482 on this interface, using \a args as arguments. This function
483 returns immediately after queueing the call. The reply from
484 the remote function is delivered to the \a returnMethod on
485 object \a receiver. If an error occurs, the \a errorMethod
486 on object \a receiver is called instead.
487
488 This function returns true if the queueing succeeds. It does
489 not indicate that the executed call succeeded. If it fails,
490 the \a errorMethod is called. If the queueing failed, this
491 function returns false and no slot will be called.
492
493 The \a returnMethod must have as its parameters the types returned
494 by the function call. Optionally, it may have a QDBusMessage
495 parameter as its last or only parameter. The \a errorMethod must
496 have a QDBusError as its only parameter.
497
498 \since 4.3
499 \sa QDBusError, QDBusMessage
500 */
501bool QDBusAbstractInterface::callWithCallback(const QString &method,
502 const QList<QVariant> &args,
503 QObject *receiver,
504 const char *returnMethod,
505 const char *errorMethod)
506{
507 Q_D(QDBusAbstractInterface);
508
509 if (!d->isValid || !d->canMakeCalls())
510 return false;
511
512 QDBusMessage msg = QDBusMessage::createMethodCall(service(),
513 path(),
514 interface(),
515 method);
516 QDBusMessagePrivate::setParametersValidated(msg, true);
517 msg.setArguments(args);
518
519 d->lastError = 0;
520 return d->connection.callWithCallback(msg,
521 receiver,
522 returnMethod,
523 errorMethod);
524}
525
526/*!
527 \overload
528
529 This function is deprecated. Please use the overloaded version.
530
531 Places a call to the remote method specified by \a method
532 on this interface, using \a args as arguments. This function
533 returns immediately after queueing the call. The reply from
534 the remote function or any errors emitted by it are delivered
535 to the \a slot slot on object \a receiver.
536
537 This function returns true if the queueing succeeded: it does
538 not indicate that the call succeeded. If it failed, the slot
539 will be called with an error message. lastError() will not be
540 set under those circumstances.
541
542 \sa QDBusError, QDBusMessage
543*/
544bool QDBusAbstractInterface::callWithCallback(const QString &method,
545 const QList<QVariant> &args,
546 QObject *receiver,
547 const char *slot)
548{
549 return callWithCallback(method, args, receiver, slot, 0);
550}
551
552/*!
553 \internal
554 Catch signal connections.
555*/
556void QDBusAbstractInterface::connectNotify(const char *signal)
557{
558 // someone connecting to one of our signals
559 Q_D(QDBusAbstractInterface);
560 if (!d->isValid)
561 return;
562
563 // we end up recursing here, so optimize away
564 if (qstrcmp(signal + 1, "destroyed(QObject*)") == 0)
565 return;
566
567 QDBusConnectionPrivate *conn = d->connectionPrivate();
568 if (conn) {
569 conn->connectRelay(d->service, d->path, d->interface,
570 this, signal);
571 }
572}
573
574/*!
575 \internal
576 Catch signal disconnections.
577*/
578void QDBusAbstractInterface::disconnectNotify(const char *signal)
579{
580 // someone disconnecting from one of our signals
581 Q_D(QDBusAbstractInterface);
582 if (!d->isValid)
583 return;
584
585 QDBusConnectionPrivate *conn = d->connectionPrivate();
586 if (conn)
587 conn->disconnectRelay(d->service, d->path, d->interface,
588 this, signal);
589}
590
591/*!
592 \internal
593 Get the value of the property \a propname.
594*/
595QVariant QDBusAbstractInterface::internalPropGet(const char *propname) const
596{
597 // assume this property exists and is readable
598 // we're only called from generated code anyways
599
600 return property(propname);
601}
602
603/*!
604 \internal
605 Set the value of the property \a propname to \a value.
606*/
607void QDBusAbstractInterface::internalPropSet(const char *propname, const QVariant &value)
608{
609 setProperty(propname, value);
610}
611
612/*!
613 Calls the method \a method on this interface and passes the parameters to this function to the
614 method.
615
616 The parameters to \c call are passed on to the remote function via D-Bus as input
617 arguments. Output arguments are returned in the QDBusMessage reply. If the reply is an error
618 reply, lastError() will also be set to the contents of the error message.
619
620 This function can be used with up to 8 parameters, passed in arguments \a arg1, \a arg2,
621 \a arg3, \a arg4, \a arg5, \a arg6, \a arg7 and \a arg8. If you need more than 8
622 parameters or if you have a variable number of parameters to be passed, use
623 callWithArgumentList().
624
625 It can be used the following way:
626
627 \snippet doc/src/snippets/code/src_qdbus_qdbusabstractinterface.cpp 0
628
629 This example illustrates function calling with 0, 1 and 2 parameters and illustrates different
630 parameter types passed in each (the first call to \c "ProcessWorkUnicode" will contain one
631 Unicode string, the second call to \c "ProcessWork" will contain one string and one byte array).
632*/
633QDBusMessage QDBusAbstractInterface::call(const QString &method, const QVariant &arg1,
634 const QVariant &arg2,
635 const QVariant &arg3,
636 const QVariant &arg4,
637 const QVariant &arg5,
638 const QVariant &arg6,
639 const QVariant &arg7,
640 const QVariant &arg8)
641{
642 return call(QDBus::AutoDetect, method, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8);
643}
644
645/*!
646 \overload
647
648 Calls the method \a method on this interface and passes the
649 parameters to this function to the method. If \a mode is \c
650 NoWaitForReply, then this function will return immediately after
651 placing the call, without waiting for a reply from the remote
652 method. Otherwise, \a mode indicates whether this function should
653 activate the Qt Event Loop while waiting for the reply to arrive.
654
655 This function can be used with up to 8 parameters, passed in arguments \a arg1, \a arg2,
656 \a arg3, \a arg4, \a arg5, \a arg6, \a arg7 and \a arg8. If you need more than 8
657 parameters or if you have a variable number of parameters to be passed, use
658 callWithArgumentList().
659
660 If this function reenters the Qt event loop in order to wait for the
661 reply, it will exclude user input. During the wait, it may deliver
662 signals and other method calls to your application. Therefore, it
663 must be prepared to handle a reentrancy whenever a call is placed
664 with call().
665*/
666QDBusMessage QDBusAbstractInterface::call(QDBus::CallMode mode, const QString &method,
667 const QVariant &arg1,
668 const QVariant &arg2,
669 const QVariant &arg3,
670 const QVariant &arg4,
671 const QVariant &arg5,
672 const QVariant &arg6,
673 const QVariant &arg7,
674 const QVariant &arg8)
675{
676 QList<QVariant> argList;
677 int count = 0 + arg1.isValid() + arg2.isValid() + arg3.isValid() + arg4.isValid() +
678 arg5.isValid() + arg6.isValid() + arg7.isValid() + arg8.isValid();
679
680 switch (count) {
681 case 8:
682 argList.prepend(arg8);
683 case 7:
684 argList.prepend(arg7);
685 case 6:
686 argList.prepend(arg6);
687 case 5:
688 argList.prepend(arg5);
689 case 4:
690 argList.prepend(arg4);
691 case 3:
692 argList.prepend(arg3);
693 case 2:
694 argList.prepend(arg2);
695 case 1:
696 argList.prepend(arg1);
697 }
698
699 return callWithArgumentList(mode, method, argList);
700}
701
702
703/*!
704 \since 4.5
705 Calls the method \a method on this interface and passes the parameters to this function to the
706 method.
707
708 The parameters to \c call are passed on to the remote function via D-Bus as input
709 arguments. The returned QDBusPendingCall object can be used to find out information about
710 the reply.
711
712 This function can be used with up to 8 parameters, passed in arguments \a arg1, \a arg2,
713 \a arg3, \a arg4, \a arg5, \a arg6, \a arg7 and \a arg8. If you need more than 8
714 parameters or if you have a variable number of parameters to be passed, use
715 asyncCallWithArgumentList().
716
717 It can be used the following way:
718
719 \snippet doc/src/snippets/code/src_qdbus_qdbusabstractinterface.cpp 1
720
721 This example illustrates function calling with 0, 1 and 2 parameters and illustrates different
722 parameter types passed in each (the first call to \c "ProcessWorkUnicode" will contain one
723 Unicode string, the second call to \c "ProcessWork" will contain one string and one byte array).
724*/
725QDBusPendingCall QDBusAbstractInterface::asyncCall(const QString &method, const QVariant &arg1,
726 const QVariant &arg2,
727 const QVariant &arg3,
728 const QVariant &arg4,
729 const QVariant &arg5,
730 const QVariant &arg6,
731 const QVariant &arg7,
732 const QVariant &arg8)
733{
734 QList<QVariant> argList;
735 int count = 0 + arg1.isValid() + arg2.isValid() + arg3.isValid() + arg4.isValid() +
736 arg5.isValid() + arg6.isValid() + arg7.isValid() + arg8.isValid();
737
738 switch (count) {
739 case 8:
740 argList.prepend(arg8);
741 case 7:
742 argList.prepend(arg7);
743 case 6:
744 argList.prepend(arg6);
745 case 5:
746 argList.prepend(arg5);
747 case 4:
748 argList.prepend(arg4);
749 case 3:
750 argList.prepend(arg3);
751 case 2:
752 argList.prepend(arg2);
753 case 1:
754 argList.prepend(arg1);
755 }
756
757 return asyncCallWithArgumentList(method, argList);
758}
759
760/*!
761 \internal
762*/
763QDBusMessage QDBusAbstractInterface::internalConstCall(QDBus::CallMode mode,
764 const QString &method,
765 const QList<QVariant> &args) const
766{
767 // ### move the code here, and make the other functions call this
768 return const_cast<QDBusAbstractInterface*>(this)->callWithArgumentList(mode, method, args);
769}
770
771QT_END_NAMESPACE
772
773#endif // QT_NO_DBUS
774
775#include "moc_qdbusabstractinterface.cpp"
Note: See TracBrowser for help on using the repository browser.