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

Last change on this file since 636 was 561, checked in by Dmitry A. Kuminov, 15 years ago

trunk: Merged in qt 4.6.1 sources.

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