/** -*- mode: C++ -*-
** Copyright (C) 1992-2007 Trolltech ASA. All rights reserved.
**
** This file is part of the documentation 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.
**
****************************************************************************/

/*!
    \page usingadaptors.html
    \title Using QtDBus Adaptors

    Adaptors are special classes that are attached to any QObject-derived class
    and provide the interface to the external world using D-Bus. Adaptors are
    intended to be lightweight classes whose main purpose is to relay calls to
    and from the real object, possibly validating or converting the input from
    the external world and, thus, protecting the real object.

    Unlike multiple inheritance, adaptors can be added at any time to any object
    (but not removed), which allows for greater flexibility when exporting
    existing classes. Another advantage of adaptors is to provide similar but not
    identical functionality in methods of the same name in different interfaces,
    a case which can be quite common when adding a new version of a standard
    interface to an object.

    In order to use an adaptor, one must create a class which inherits
    QDBusAbstractAdaptor. Since that is a standard QObject-derived class, the
    Q_OBJECT macro must appear in the declaration and the source file must be
    processed with the \l {moc} tool. The class must also contain one or more
    Q_CLASSINFO entries with the \c {"D-Bus Interface"} name, declaring which
    interfaces it is exporting.

    Any public slot in the class will be accessible through the bus over messages
    of the MethodCall type. (See \l {Declaring Slots in D-Bus Adaptors} for more
    information). Signals in the class will be automatically relayed over D-Bus.
    However, not all types are allowed signals or slots' parameter lists: see
    \l {The QtDBus Type System} for more information.

    Also, any property declared with Q_PROPERTY will be automatically exposed
    over the Properties interface on D-Bus. Since the QObject property system
    does not allow for non-readable properties, it is not possible to declare
    write-only properties using adaptors.

    More information:
    \list
      \o \l{Declaring Slots in D-Bus Adaptors}
      \o \l{Declaring Signals in D-Bus Adaptors}
      \o \l{The QtDBus Type System}
      \o \l{D-Bus Adaptor Example}
    \endlist

    \sa QDBusAbstractAdaptor
*/

/*!
    \page qdbusadaptorexample.html
    \title D-Bus Adaptor Example

    The following example code shows how a D-Bus interface can be implemented
    using an adaptor.

    A sample usage of QDBusAbstractAdaptor is as follows:
    \code
        class MainApplicationAdaptor: public QDBusAbstractAdaptor
        {
            Q_OBJECT
            Q_CLASSINFO("D-Bus Interface", "com.example.DBus.MainApplication")
            Q_CLASSINFO("D-Bus Interface", "org.kde.DBus.MainApplication")
            Q_PROPERTY(QString caption READ caption WRITE setCaption)
            Q_PROPERTY(QString organizationName READ organizationName)
            Q_PROPERTY(QString organizationDomain READ organizationDomain)

        private:
            QApplication *app;

        public:
            MainApplicationAdaptor(QApplication *application)
                : QDBusAbstractAdaptor(application), app(application)
            {
                connect(application, SIGNAL(aboutToQuit()), SIGNAL(aboutToQuit());
                connect(application, SIGNAL(focusChanged(QWidget*, QWidget*)),
                        SLOT(focusChangedSlot(QWidget*, QWidget*)));
            }

            QString caption()
            {
                if (app->hasMainWindow())
                    return app->mainWindow()->caption();
                return QString(""); // must not return a null QString
            }

            void setCaption(const QString &newCaption)
            {
                if (app->hasMainWindow())
                    app->mainWindow()->setCaption(newCaption);
            }

            QString organizationName()
            {
                return app->organizationName();
            }

            QString organizationDomain()
            {
                return app->organizationDomain();
            }

        public slots:
            Q_NOREPLY void quit()
            { app->quit(); }

            void reparseConfiguration()
            { app->reparseConfiguration(); }

            QString mainWindowObject()
            {
                if (app->hasMainWindow())
                    return QString("/%1/mainwindow").arg(app->applicationName());
                return QString();
            }

            void setSessionManagement(bool enable)
            {
                if (enable)
                   app->enableSessionManagement();
                else
                   app->disableSessionManagement();
            }

        private slots:
            void focusChangedSlot(QWidget *, QWidget *now)
            {
                if (now == app->mainWindow())
                    emit mainWindowHasFocus();
            }

        signals:
            void aboutToQuit();
            void mainWindowHasFocus();
        };
    \endcode

    The code above would create an interface that could be represented more or less in the following
    canonical representation:
    \code
        interface com.example.DBus.MainApplication
        {
            property readwrite STRING caption
            property read STRING organizationName
            property read STRING organizationDomain

            method quit() annotation("org.freedesktop.DBus.Method.NoReply", "true")
            method reparseConfiguration()
            method mainWindowObject(out STRING)
            method disableSessionManagement(in BOOLEAN enable)

            signal aboutToQuit()
            signal mainWindowHasFocus()
        }

        interface org.kde.DBus.MainApplication
        {
            ....
        }
    \endcode

    This adaptor could be used in the application's main function as follows
    \code
        int main(int argc, char **argv)
        {
            // create the QApplication object
            QApplication app(argc, argv);

            // create the MainApplication adaptor:
            new MainApplicationAdaptor(app);

            // connect to D-Bus and register as an object:
            QDBus::sessionBus().registerObject("/MainApplication", app);

            // add main window, etc.
            [...]

            app.exec();
        }
    \endcode

    Break-down analysis:
    \tableofcontents

    \section1 The header

    The header of the example is:
    \code
        class MainApplicationAdaptor: public QDBusAbstractAdaptor
        {
            Q_OBJECT
            Q_CLASSINFO("D-Bus Interface", "com.example.DBus.MainApplication")
            Q_CLASSINFO("D-Bus Interface", "org.kde.DBus.MainApplication")
    \endcode

    The code does the following:
    \list
      \o it declares the adaptor MainApplicationAdaptor, which descends from QDBusAbstractAdaptor
      \o it declares the Qt Meta Object data using the Q_OBJECT macro
      \o it declares the names of two D-Bus interfaces it implements. Those interfaces are equal in
         all aspects.
    \endlist

    \section1 The properties

    The properties are declared as follows:
    \code
            Q_PROPERTY(QString caption READ caption WRITE setCaption)
            Q_PROPERTY(QString organizationName READ organizationName)
            Q_PROPERTY(QString organizationDomain READ organizationDomain)
    \endcode

    And are implemented as follows:
    \code
            QString caption()
            {
                if (app->hasMainWindow())
                    return app->mainWindow()->caption();
                return QString();
            }

            void setCaption(const QString &newCaption)
            {
                if (app->hasMainWindow())
                    app->mainWindow()->setCaption(newCaption);
            }

            QString organizationName()
            {
                return app->organizationName();
            }

            QString organizationDomain()
            {
                return app->organizationDomain();
            }
    \endcode

    The code declares three properties: one of them is a read-write property called "caption" of
    string type. The other two are read-only, also of the string type.

    The properties organizationName and organizationDomain are simple relays of the app object's
    organizationName and organizationDomain properties. However, the caption property requires
    verifying if the application has a main window associated with it: if there isn't any, the
    caption property is empty. Note how it is possible to access data defined in other objects
    through the getter/setter functions.

    \section1 The constructor

    The constructor:
    \code
            MyInterfaceAdaptor(QApplication *application)
                : QDBusAbstractAdaptor(application), app(application)
            {
                connect(application, SIGNAL(aboutToQuit()), SIGNAL(aboutToQuit());
                connect(application, SIGNAL(focusChanged(QWidget*, QWidget*)),
                        SLOT(focusChangedSlot(QWidget*, QWidget*)));
            }
    \endcode

    The constructor does the following:
    \list
    \o it initialises its base class (QDBusAbstractAdaptor) with the parent object it is related to.
    \o it stores the app pointer in a member variable. Note that it would be possible to access the
       same object using the QDBusAbstractAdaptor::object() function, but it would be necessary to
       use \a static_cast<> to properly access the methods in QApplication that are not part of
       QObject.
    \o it connects the application's signal \a aboutToQuit to its own signal \a aboutToQuit.
    \o it connects the application's signal \a focusChanged to a private slot to do some further
       processing before emitting a D-Bus signal.
    \endlist

    Note that there is no destructor in the example. An eventual destructor could be used to emit
    one last signal before the object is destroyed, for instance.

    \section1 Slots/methods

    The public slots in the example (which will be exported as D-Bus methods) are the following:
    \code
        public slots:
            Q_NOREPLY void quit()
            { app->quit(); }

            void reparseConfiguration()
            { app->reparseConfiguration(); }

            QString mainWindowObject()
            {
                if (app->hasMainWindow())
                    return QString("/%1/mainwindow").arg(app->applicationName());
                return QString();
            }

            void setSessionManagement(bool enable)
            {
                if (enable)
                   app->enableSessionManagement();
                else
                   app->disableSessionManagement();
            }
    \endcode

    This snippet of code defines 4 methods with different properties each:
    \list 1
    \o \c quit: this method takes no parameters and is defined to be asynchronous. That is, callers
      are expected to use "fire-and-forget" mechanism when calling this method, since it provides no
      useful reply. This is represented in D-Bus by the use of the
      org.freedesktop.DBus.Method.NoReply annotation. See \l Q_NOREPLY for more information on
      asynchronous methods

    \o \c reparseConfiguration: this simple method, with no input or output arguments simply relays
      the call to the application's reparseConfiguration member function.

    \o \c mainWindowObject: this method takes no input parameter, but returns one string output
      argument, containing the path to the main window object (if the application has a main
      window), or an empty string if it has no main window. Note that this method could have also
      been written: void mainWindowObject(QString &path).

    \o \c setSessionManagement: this method takes one input argument (a boolean) and, depending on
      its value, it calls one function or another in the application.
    \endlist

    See also: \l Q_NOREPLY.

    \section1 Signals

    The signals in this example are defined as follows:
    \code
        signals:
            void aboutToQuit();
            void mainWindowHasFocus();
    \endcode

    However, signal definition isn't enough: signals have to be emitted. One simple way of emitting
    signals is to connect another signal to them, so that Qt's signal handling system chains them
    automatically. This is what is done for the \a aboutToQuit signal.

    When this is the case, one can use the QDBusAbstractAdaptor::setAutoRelaySignals to
    automatically connect every signal from the real object to the adaptor.

    When simple signal-to-signal connection isn't enough, one can use a private slot do do some
    work. This is what was done for the mainWindowHasFocus signal:
    \code
        private slots:
            void focusChangedSlot(QWidget *, QWidget *now)
            {
                if (now == app->mainWindow())
                    emit mainWindowHasFocus();
            }
    \endcode

    This private slot (which will not be exported as a method via D-Bus) was connected to the
    \c focusChanged signal in the adaptor's constructor. It is therefore able to shape the
    application's signal into what the interface expects it to be.
*/

/*!
    \page qdbusdeclaringslots.html
    \title Declaring Slots in D-Bus Adaptors

    Slots in D-Bus adaptors are declared just like normal, public slots, but their
    parameters must follow certain rules (see \l{The QtDBus Type System} for more
    information). Slots whose parameters do not follow those rules or that are not
    public will not be accessible via D-Bus.

    Slots can have one parameter of type \c{const QDBusMessage &}, which must
    appear at the end of the input parameter list, before any output parameters.
    This parameter, if present, will be initialized with a copy of the
    current message being processed, which allows the callee to obtain
    information about the caller, such as its connection name.

    Slots can be of three kinds:
    \list 1
      \o Asynchronous
      \o Input-only
      \o Input-and-output
    \endlist

    \section1 Asynchronous Slots
    Asynchronous slots are those that do not normally return any reply to the
    caller. For that reason, they cannot take any output parameters. In most
    cases, by the time the first line of the slot is run, the caller function
    has already resumed working.

    However, slots must rely on that behavior. Scheduling and message-dispatching
    issues could change the order in which the slot is run. Code intending to
    synchronize with the caller should provide its own method of synchronization.

    Asynchronous slots are marked by the keyword \l Q_NOREPLY in the method
    signature, before the \c void return type and the slot name. (See the
    \c quit() slot in the \l{D-Bus Adaptor Example}).

    \section1 Input-Only Slots

    Input-only slots are normal slots that take parameters passed by value or
    by constant reference. However, unlike asynchronous slots, the caller is
    usually waiting for completion of the callee before resuming operation.
    Therefore, non-asynchronous slots should not block or should state it its
    documentation that they may do so.

    Input-only slots have no special marking in their signature, except that
    they take only parameters passed by value or by constant reference.
    Optionally, slots can take a QDBusMessage parameter as a last parameter,
    which can be used to perform additional analysis of the method call message.

    \section1 Input and Output Slots

    Like input-only slots, input-and-output slots are those that the caller is
    waiting for a reply. Unlike input-only ones, though, this reply will contain
    data. Slots that output data may contain non-constant references and may
    return a value as well. However, the output parameters must all appear at
    the end of the argument list and may not have input arguments interleaved.
    Optionally, a QDBusMessage argument may appear between the input and the
    output arguments.

    \section1 Automatic Replies

    Method replies are generated automatically with the contents of the output
    parameters (if there were any) by the QtDBus implementation. Slots need not
    worry about constructing proper QDBusMessage objects and sending them over
    the connection.

    However, the possibility of doing so remains there. Should the slot find out
    it needs to send a special reply or even an error, it can do so by using
    QDBusMessage::createReply() or QDBusMessage::createErrorReply() on the
    QDBusMessage parameter and send it with QDBusConnection::send(). The
    QtDBus implementation will not generate any reply if the slot did so.

    \warning When a caller places a method call and waits for a reply, it will
    only wait for a limited amount of time. Slots intending to take a long time
    to complete should make that fact clear in documentation so that callers
    properly set higher timeouts.

    \section1 Delayed Replies

    In some circumstances, the called slot may not be able to process
    the request immediately. This is frequently the case when the
    request involves an I/O or networking operation which may block.

    If this is the case, the slot should return control to the
    application's main loop to avoid freezing the user interface, and
    resume the process later. To accomplish this, it should make use
    of the extra \c QDBusMessage parameter at the end of the input
    parameter list and request a delayed reply.

    We do this by writing a slot that stores the request data in a
    persistent structure, indicating to the caller using
    \l{QDBusMessage::setDelayedReply()}{QDBusMessage::setDelayedReply(true)}
    that the response will be sent later.

    \code
    struct RequestData
    {
        QString request;
        QString processedData;
        QDBusMessage reply;
    };

    QString processRequest(const QString &request, const QDBusMessage &message)
    {
        RequestData *data = new RequestData;
        data->request = request;
        message.setDelayedReply(true);
        data->reply = message.createReply();
        QDBusConnection::sessionBus().send(data->reply);

        appendRequest(data);
        return QString();
    }
    \endcode

    The use of
    \l{QDBusConnection::send()}{QDBusConnection::sessionBus().send(data->reply)}
    is needed to explicitly inform the caller that the response will be delayed.
    In this case, the return value is unimportant; we return an arbitrary value
    to satisfy the compiler.

    When the request is processed and a reply is available, it should be sent
    using the \c QDBusMessage object that was obtained. In our example, the
    reply code could be something as follows:

    \code
    void sendReply(RequestData *data)
    {
        // data->processedData has been initialized with the request's reply
        QDBusMessage &reply = &data->reply;

        // send the reply over D-Bus:
        reply << data->processedData;
        QDBusConnection::sessionBus().send(reply);

        // dispose of the transaction data
        delete data;
    }
    \endcode

    As can be seen in the example, when a delayed reply is in place,
    the return value(s) from the slot will be ignored by QtDBus. They
    are used only to determine the slot's signature when communicating
    the adaptor's description to remote applications, or in case the
    code in the slot decides not to use a delayed reply.

    The delayed reply itself is requested from QtDBus by calling
    QDBusMessage::reply() on the original message. It then becomes the
    resposibility of the called code to eventually send a reply to the
    caller.

    \warning When a caller places a method call and waits for a reply, it will
    only wait for a limited amount of time. Slots intending to take a long time
    to complete should make that fact clear in documentation so that callers
    properly set higher timeouts.

    \sa {Using QtDBus Adaptors}, {Declaring Signals in D-Bus Adaptors},
        {The QtDBus Type System}, QDBusConnection, QDBusMessage
*/

/*!
    \page qdbusdeclaringsignals.html
    \title Declaring Signals in D-Bus Adaptors

    Any signal in a class derived from QDBusAbstractAdaptor will be automatically
    relayed into D-Bus, provided that the signal's parameters conform to certain
    rules (see \l{The QtDBus Type System} for more information). No special code
    is necessary to make this relay.

    However, signals must still be emitted. The easiest way to emit an adaptor
    signal is to connect another signal to it, so that Qt's signals and slots
    mechanism automatically emits the adaptor signal, too. This can be done in
    the adaptor's constructor, as has been done in the
    \l{D-Bus Adaptor Example}{D-Bus Adaptor example}.

    The QDBusAbstractAdaptor::setAutoRelaySignals() convenience function can also
    be used to make and break connections between signals in the real object and
    the corresponding signals in the adaptor. It will inspect the list of signals
    in both classes and connect those whose parameters match exactly.

    \sa {Using QtDBus Adaptors},
        {Declaring Slots in D-Bus Adaptors},
        {The QtDBus Type System}, QDBusAbstractAdaptor
*/

/*!
    \page qdbustypesystem.html
    \title The QtDBus Type System

    D-Bus has an extensible type system based on a few primitives and
    composition of the primitives in arrays and structures. QtDBus
    implements the interface to that type system through the
    QDBusArgument class, allowing user programs to send and receive
    practically every C++ type over the bus.

    \section1 Primitive Types

    The primitive types are supported natively by QDBusArgument and
    need no special customization to be sent or received. They are
    listed below, along with the C++ class they relate to:

    \table
      \header
        \o Qt type
        \o D-Bus equivalent type
      \row
        \o uchar
        \o BYTE
      \row
        \o bool
        \o BOOLEAN
      \row
        \o short
        \o INT16
      \row
        \o ushort
        \o UINT16
      \row
        \o int
        \o INT32
      \row
        \o uint
        \o UINT32
      \row
        \o qlonglong
        \o INT64
      \row
        \o qulonglong
        \o UINT64
      \row
        \o double
        \o DOUBLE
      \row
        \o QString
        \o STRING
      \row
        \o QDBusVariant
        \o VARIANT
      \row
        \o QDBusObjectPath
        \o OBJECT_PATH
      \row
        \o QDBusSignature
        \o SIGNATURE
    \endtable

    Aside from the primitive types, QDBusArgument also supports two
    non-primitive types natively, due to their widespread use in Qt
    applications: QStringList and QByteArray.

    \section1 Compound Types

    D-Bus specifies three types of aggregations of primitive types
    that allow one to create compound types. They are \c ARRAY, \c
    STRUCT and maps/dictionaries.

    Arrays are sets of zero or more elements of the same type, while
    structures are a set of a fixed number of elements, each of any
    type. Maps or dictionaries are implemented as arrays of a pair of
    elements, so there can be zero or more elements in one map.

    \section1 Extending the Type System

    In order to use one's own type with QtDBus, the type has to be
    declared as a Qt meta-type with the Q_DECLARE_METATYPE() macro and
    registered with the qDBusRegisterMetaType() function. The
    streaming operators \c{operator>>} and \c{operator<<} will be
    automatically found by the registration system.

    QtDBus provides template specializations for arrays and maps for
    use with Qt's \l{Container classes}{container classes}, such as
    QMap and QList, so it is not necessary to write the streaming
    operator functions for those. For other types, and specially for
    types implementing structures, the operators have to be explicitly
    implemented.

    See the documentation for QDBusArgument for examples for
    structures, arrays and maps.

    \section1 The Type System in Use

    All of the QtDBus types (primitives and user-defined alike) can be
    used to send and receive messages of all types over the bus.

    \warning You may not use any type that is not on the list above,
    including \a typedefs to the types listed. This also includes
    QList<QVariant> and QMap<QString,QVariant>.
*/

/*!
    \macro Q_NOREPLY
    \relates QDBusAbstractAdaptor
    \since 4.2

    The Q_NOREPLY macro can be used to mark a method to be called and not wait for it to finish
    processing before returning from QDBusInterface::call(). The called method cannot return any
    output arguments and, if it does, any such arguments will be discarded.

    You can use this macro in your own adaptors by placing it before your method's return value
    (which must be "void") in the class declaration, as shown in the example:
    \code
        Q_NOREPLY void myMethod();
    \endcode

    Its presence in the method implementation (outside the class declaration) is optional.

    \sa {Using QtDBus Adaptors}
*/
