~ubuntu-branches/ubuntu/trusty/tomahawk/trusty-proposed

« back to all changes in this revision

Viewing changes to thirdparty/qxt/qxtweb-standalone/qxtweb/qxtboundfunction.h

  • Committer: Package Import Robot
  • Author(s): Harald Sitter
  • Date: 2013-03-07 21:50:13 UTC
  • Revision ID: package-import@ubuntu.com-20130307215013-6gdjkdds7i9uenvs
Tags: upstream-0.6.0+dfsg
ImportĀ upstreamĀ versionĀ 0.6.0+dfsg

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/****************************************************************************
 
2
 **
 
3
 ** Copyright (C) Qxt Foundation. Some rights reserved.
 
4
 **
 
5
 ** This file is part of the QxtCore module of the Qxt library.
 
6
 **
 
7
 ** This library is free software; you can redistribute it and/or modify it
 
8
 ** under the terms of the Common Public License, version 1.0, as published
 
9
 ** by IBM, and/or under the terms of the GNU Lesser General Public License,
 
10
 ** version 2.1, as published by the Free Software Foundation.
 
11
 **
 
12
 ** This file is provided "AS IS", without WARRANTIES OR CONDITIONS OF ANY
 
13
 ** KIND, EITHER EXPRESS OR IMPLIED INCLUDING, WITHOUT LIMITATION, ANY
 
14
 ** WARRANTIES OR CONDITIONS OF TITLE, NON-INFRINGEMENT, MERCHANTABILITY OR
 
15
 ** FITNESS FOR A PARTICULAR PURPOSE.
 
16
 **
 
17
 ** You should have received a copy of the CPL and the LGPL along with this
 
18
 ** file. See the LICENSE file and the cpl1.0.txt/lgpl-2.1.txt files
 
19
 ** included with the source distribution for more information.
 
20
 ** If you did not receive a copy of the licenses, contact the Qxt Foundation.
 
21
 **
 
22
 ** <http://libqxt.org>  <foundation@libqxt.org>
 
23
 **
 
24
 ****************************************************************************/
 
25
 
 
26
#ifndef QXTBOUNDFUNCTION_H
 
27
#define QXTBOUNDFUNCTION_H
 
28
 
 
29
#include <QObject>
 
30
#include <QMetaObject>
 
31
#include <QGenericArgument>
 
32
#include <qxtmetaobject.h>
 
33
#include <qxtnull.h>
 
34
#include <QThread>
 
35
#include <QtDebug>
 
36
 
 
37
/*!
 
38
\class QxtBoundFunction
 
39
 
 
40
\inmodule QxtCore
 
41
 
 
42
\brief Binds parameters to a function call
 
43
 
 
44
 * A bound function is very similar to what the C++ FAQ Lite refers to as "functionoids."
 
45
 * (http://www.parashift.com/c++-faq-lite/pointers-to-members.html#faq-33.10)
 
46
 * It is similar in use to a function pointer, but allows any or all parameters to be
 
47
 * pre-filled with constant values. The remaining parameters are specified when the
 
48
 * function is invoked, for instance, by a Qt signal connection.
 
49
 *
 
50
 * By far, the most common expected use is to provide a parameter to a slot when the
 
51
 * signal doesn't have offer one. Many developers new to Qt try to write code like this:
 
52
 * \code
 
53
 *     connect(button, SIGNAL(clicked()), lineEdit, SLOT(setText("Hello, world")));
 
54
 * \endcode
 
55
 * Experienced Qt developers will immediately spot the flaw here. The typical solution
 
56
 * is to create a short, one-line wrapper slot that invokes the desired function. Some
 
57
 * clever developers may even use QSignalMapper to handle slots that only need one
 
58
 * int or QString parameter.
 
59
 *
 
60
 * QxtBoundFunction enables the previous connect statement to be written like this:
 
61
 * \code
 
62
 *     connect(button, SIGNAL(clicked()), QxtMetaObject::bind(lineEdit, SLOT(setText(QString)), Q_ARG(QString, "Hello, world!")));
 
63
 * \code
 
64
 * This accomplishes the same result without having to create a new slot, or worse,
 
65
 * an entire object, just to pass a constant value.
 
66
 *
 
67
 * Additionally, through the use of the QXT_BIND macro, parameters from the signal
 
68
 * can be rearranged, skipped, or passed alongside constant arguments provided
 
69
 * with the Q_ARG macro. This can be used to provide stateful callbacks to a
 
70
 * generic function, for example.
 
71
 *
 
72
 * Many kinds of functions can be bound. The most common binding applies to
 
73
 * Qt signals and slots, but standard C/C++ functions can be bound as well.
 
74
 * Future development may add the ability to bind to C++ member functions,
 
75
 * and developers can make custom QxtBoundFunction subclasses for even more
 
76
 * flexibility if necessary.
 
77
 *
 
78
 *
 
79
 */
 
80
class QXT_CORE_EXPORT QxtBoundFunction : public QObject
 
81
{
 
82
    Q_OBJECT
 
83
public:
 
84
    /*!
 
85
     * Invokes the bound function and returns a value.
 
86
     *
 
87
     * The template parameter should be the return type of the invoked function. This overload accepts
 
88
     * QVariant parameters and will guess the data type of each parameter based on the type of the QVariant.
 
89
     */
 
90
    template <class T>
 
91
    inline QxtNullable<T> invoke(QXT_PROTO_10ARGS(QVariant))
 
92
    {
 
93
        if (!parent() || QThread::currentThread() == parent()->thread())
 
94
            return invoke<T>(Qt::DirectConnection, p1, p2, p3, p4, p5, p6, p7, p8, p9, p10);
 
95
#if QT_VERSION >= 0x040300
 
96
        return invoke<T>(Qt::BlockingQueuedConnection, p1, p2, p3, p4, p5, p6, p7, p8, p9, p10);
 
97
#else
 
98
        qWarning() << "QxtBoundFunction::invoke: Cannot return a value using a queued connection";
 
99
        return QxtNull();
 
100
#endif
 
101
    }
 
102
 
 
103
    /*!
 
104
     * Invokes the bound function and returns a value.
 
105
     *
 
106
     * The template parameter should be the return type of the invoked function. This overload accepts
 
107
     * QGenericArgument parameters, expressed using the Q_ARG() macro.
 
108
     */
 
109
    template <class T>
 
110
    QxtNullable<T> invoke(Qt::ConnectionType type, QVariant p1, QXT_PROTO_9ARGS(QVariant))
 
111
    {
 
112
        if (type == Qt::QueuedConnection)
 
113
        {
 
114
            qWarning() << "QxtBoundFunction::invoke: Cannot return a value using a queued connection";
 
115
            return QxtNull();
 
116
        }
 
117
        T retval;
 
118
        // I know this is a totally ugly function call
 
119
        if (invoke(type, QGenericReturnArgument(qVariantFromValue<T>(*reinterpret_cast<T*>(0)).typeName(), reinterpret_cast<void*>(&retval)),
 
120
                   p1, p2, p3, p4, p5, p6, p7, p8, p9, p10))
 
121
        {
 
122
            return retval;
 
123
        }
 
124
        else
 
125
        {
 
126
            return QxtNull();
 
127
        }
 
128
    }
 
129
 
 
130
    /*!
 
131
     * Invokes the bound function, discarding the return value.
 
132
     *
 
133
     * This overload accepts QVariant parameters and will guess the data type of each
 
134
     * parameter based on the type of the QVariant.
 
135
     *
 
136
     * This function returns true if the invocation was successful, otherwise it
 
137
     * returns false.
 
138
     */
 
139
    inline bool invoke(QVariant p1, QXT_PROTO_9ARGS(QVariant))
 
140
    {
 
141
        return invoke(Qt::AutoConnection, p1, p2, p3, p4, p5, p6, p7, p8, p9, p10);
 
142
    }
 
143
    /*!
 
144
     * Invokes the bound function, discarding the return value.
 
145
     *
 
146
     * This overload accepts QVariant parameters and will guess the data type of each
 
147
     * parameter based on the type of the QVariant. It also allows you to specify the
 
148
     * connection type, allowing the bound function to be invoked across threads using
 
149
     * the Qt event loop.
 
150
     *
 
151
     * This function returns true if the invocation was successful, otherwise it
 
152
     * returns false.
 
153
     */
 
154
    bool invoke(Qt::ConnectionType, QVariant p1, QXT_PROTO_9ARGS(QVariant));
 
155
 
 
156
    /*!
 
157
     * Invokes the bound function, discarding the return value.
 
158
     *
 
159
     * This overload accepts QGenericArgument parameters, expressed using the Q_ARG()
 
160
     * macro.
 
161
     *
 
162
     * This function returns true if the invocation was successful, otherwise it
 
163
     * returns false.
 
164
     */
 
165
    inline bool invoke(QXT_PROTO_10ARGS(QGenericArgument))
 
166
    {
 
167
        return invoke(Qt::AutoConnection, p1, p2, p3, p4, p5, p6, p7, p8, p9, p10);
 
168
    }
 
169
    /*!
 
170
     * Invokes the bound function, discarding the return value.
 
171
     *
 
172
     * This overload accepts QGenericArgument parameters, expressed using the Q_ARG()
 
173
     * macro. It also allows you to specify the connection type, allowing the bound
 
174
     * function to be invoked across threads using the Qt event loop.
 
175
     *
 
176
     * This function returns true if the invocation was successful, otherwise it
 
177
     * returns false.
 
178
     */
 
179
    inline bool invoke(Qt::ConnectionType type, QXT_PROTO_10ARGS(QGenericArgument))
 
180
    {
 
181
        return invoke(type, QGenericReturnArgument(), p1, p2, p3, p4, p5, p6, p7, p8, p9, p10);
 
182
    }
 
183
 
 
184
    /*!
 
185
     * Invokes the bound function and assigns the return value to a parameter passed by reference.
 
186
     *
 
187
     * Use the Q_RETURN_ARG() macro to pass a reference to an assignable object of the function's
 
188
     * return type. When the function completes, its return value will be stored in that object.
 
189
     *
 
190
     * This overload accepts QVariant parameters and will guess the data type of each
 
191
     * parameter based on the type of the QVariant.
 
192
     *
 
193
     * This function returns true if the invocation was successful, otherwise it
 
194
     * returns false.
 
195
     */
 
196
    inline bool invoke(QGenericReturnArgument returnValue, QVariant p1, QXT_PROTO_9ARGS(QVariant))
 
197
    {
 
198
        return invoke(Qt::AutoConnection, returnValue, p1, p2, p3, p4, p5, p6, p7, p8, p9, p10);
 
199
    }
 
200
    /*!
 
201
     * Invokes the bound function and assigns the return value to a parameter passed by reference.
 
202
     *
 
203
     * Use the Q_RETURN_ARG() macro to pass a reference to an assignable object of the function's
 
204
     * return type. When the function completes, its return value will be stored in that object.
 
205
     *
 
206
     * This overload accepts QVariant parameters and will guess the data type of each
 
207
     * parameter based on the type of the QVariant. It also allows you to specify the
 
208
     * connection type, allowing the bound function to be invoked across threads using
 
209
     * the Qt event loop.
 
210
     *
 
211
     * This function returns true if the invocation was successful, otherwise it
 
212
     * returns false.
 
213
     */
 
214
    bool invoke(Qt::ConnectionType type, QGenericReturnArgument returnValue, QVariant p1, QXT_PROTO_9ARGS(QVariant));
 
215
 
 
216
    /*!
 
217
     * Invokes the bound function and assigns the return value to a parameter passed by reference.
 
218
     *
 
219
     * Use the Q_RETURN_ARG() macro to pass a reference to an assignable object of the function's
 
220
     * return type. When the function completes, its return value will be stored in that object.
 
221
     *
 
222
     * This overload accepts QGenericArgument parameters, expressed using the Q_ARG()
 
223
     * macro.
 
224
     *
 
225
     * This function returns true if the invocation was successful, otherwise it
 
226
     * returns false.
 
227
     */
 
228
    inline bool invoke(QGenericReturnArgument returnValue, QXT_PROTO_10ARGS(QGenericArgument))
 
229
    {
 
230
        return invoke(Qt::AutoConnection, returnValue, p1, p2, p3, p4, p5, p6, p7, p8, p9, p10);
 
231
    }
 
232
    /*!
 
233
     * Invokes the bound function and assigns the return value to a parameter passed by reference.
 
234
     *
 
235
     * Use the Q_RETURN_ARG() macro to pass a reference to an assignable object of the function's
 
236
     * return type. When the function completes, its return value will be stored in that object.
 
237
     *
 
238
     * This overload accepts QGenericArgument parameters, expressed using the Q_ARG()
 
239
     * macro. It also allows you to specify the connection type, allowing the bound
 
240
     * function to be invoked across threads using the Qt event loop.
 
241
     *
 
242
     * This function returns true if the invocation was successful, otherwise it
 
243
     * returns false.
 
244
     */
 
245
    bool invoke(Qt::ConnectionType type, QGenericReturnArgument returnValue, QXT_PROTO_10ARGS(QGenericArgument));
 
246
 
 
247
protected:
 
248
#ifndef QXT_DOXYGEN_RUN
 
249
    QxtBoundFunction(QObject* parent = 0);
 
250
#endif
 
251
 
 
252
    /*!
 
253
     * Performs the work of invoking the bound function.
 
254
     *
 
255
     * This function is pure virtual. The various QxtMetaObject::bind() functions return opaque subclasses
 
256
     * of QxtBoundFunction. If you wish to create a new kind of bound function, reimplement this function to
 
257
     * perform the invocation and assign the function's return value, if any, to the returnValue parameter.
 
258
     *
 
259
     * This function should return true if the invocation is successful and false if an error occurs.
 
260
     */
 
261
    virtual bool invokeImpl(Qt::ConnectionType type, QGenericReturnArgument returnValue, QXT_PROTO_10ARGS(QGenericArgument)) = 0;
 
262
};
 
263
 
 
264
#endif