1 | /**************************************************************************** |
2 | ** |
3 | ** Copyright (C) 2012 Digia Plc and/or its subsidiary(-ies). |
4 | ** Contact: http://www.qt-project.org/legal |
5 | ** |
6 | ** This file is part of the QtDocGallery module of the Qt Toolkit. |
7 | ** |
8 | ** $QT_BEGIN_LICENSE:LGPL$ |
9 | ** Commercial License Usage |
10 | ** Licensees holding valid commercial Qt licenses may use this file in |
11 | ** accordance with the commercial license agreement provided with the |
12 | ** Software or, alternatively, in accordance with the terms contained in |
13 | ** a written agreement between you and Digia. For licensing terms and |
14 | ** conditions see http://qt.digia.com/licensing. For further information |
15 | ** use the contact form at http://qt.digia.com/contact-us. |
16 | ** |
17 | ** GNU Lesser General Public License Usage |
18 | ** Alternatively, this file may be used under the terms of the GNU Lesser |
19 | ** General Public License version 2.1 as published by the Free Software |
20 | ** Foundation and appearing in the file LICENSE.LGPL included in the |
21 | ** packaging of this file. Please review the following information to |
22 | ** ensure the GNU Lesser General Public License version 2.1 requirements |
23 | ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. |
24 | ** |
25 | ** In addition, as a special exception, Digia gives you certain additional |
26 | ** rights. These rights are described in the Digia Qt LGPL Exception |
27 | ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. |
28 | ** |
29 | ** GNU General Public License Usage |
30 | ** Alternatively, this file may be used under the terms of the GNU |
31 | ** General Public License version 3.0 as published by the Free Software |
32 | ** Foundation and appearing in the file LICENSE.GPL included in the |
33 | ** packaging of this file. Please review the following information to |
34 | ** ensure the GNU General Public License version 3.0 requirements will be |
35 | ** met: http://www.gnu.org/copyleft/gpl.html. |
36 | ** |
37 | ** |
38 | ** $QT_END_LICENSE$ |
39 | ** |
40 | ****************************************************************************/ |
41 | |
42 | #include "qgalleryabstractresponse_p.h" |
43 | |
44 | #include <QtCore/qcoreapplication.h> |
45 | #include <QtCore/qtimer.h> |
46 | |
47 | QT_BEGIN_NAMESPACE_DOCGALLERY |
48 | |
49 | /*! |
50 | \class QGalleryAbstractResponse |
51 | |
52 | \ingroup gallery |
53 | |
54 | \inmodule QtDocGallery |
55 | |
56 | \brief The QGalleryAbstractResponse class provides a base class for |
57 | responses to gallery requests. |
58 | |
59 | QGalleryAbstractResponse is the interface through which a QAbstractGallery |
60 | returns a response to a QGalleryAbstractRequest. The interface provides |
61 | functions to communicate the state of a response to a request, additional |
62 | classes derived from QGalleryAbstractRequest such as QGalleryResultSet are |
63 | used to communicate actual results. |
64 | |
65 | New responses start in an active state indicating they have not yet |
66 | finished. When a response has finished; implementers should call the |
67 | finish function which will put the response into an inactive state and |
68 | emit the finished signal. If the idle argument of finish is true then |
69 | isIdle() will be true on return indicating that the response may return to |
70 | an active state in order to refresh its results in the future. The resume |
71 | function will return the response to an active state and emit the resumed |
72 | signal. |
73 | |
74 | If a response cannot finish successfully then implementers should call the |
75 | error() function and supply an error code and description. This will finish |
76 | the request and set values for error() and errorString(). |
77 | |
78 | If a request is cancelled it will call cancel() on its response. The |
79 | base implementation wsets isActive() and isIdle() to false and emits |
80 | the canceled signal, so implementers will need to override the default |
81 | implementation to actually cancel any ongoing task or suspend updates before |
82 | calling the base implementation. If the response can't be canceled |
83 | synchronously then calling the base implementation should be deferred until |
84 | the cancelation has completed. Canceling a response should not discard any |
85 | intermediate results already made available by the response. |
86 | |
87 | Unless a response finishes synchronously and calls finish() or error() |
88 | from its constructor it must implement the waitForFinished() function |
89 | to allow clients to block while waiting for the response to finish. |
90 | */ |
91 | |
92 | /*! |
93 | Constructs a new gallery response. |
94 | |
95 | The \a parent is passed to QObject. |
96 | */ |
97 | |
98 | QGalleryAbstractResponse::QGalleryAbstractResponse(QObject *parent) |
99 | : QObject(parent) |
100 | , d_ptr(new QGalleryAbstractResponsePrivate) |
101 | { |
102 | d_ptr->q_ptr = this; |
103 | } |
104 | |
105 | /*! |
106 | Constructs a new gallery response, for a request that has finished with an |
107 | \a error. The optional \a errorString will describe the error in greater |
108 | detail. |
109 | |
110 | The \a parent is passed to QObject. |
111 | */ |
112 | |
113 | QGalleryAbstractResponse::QGalleryAbstractResponse( |
114 | int error, const QString &errorString, QObject *parent) |
115 | : QObject(parent) |
116 | , d_ptr(new QGalleryAbstractResponsePrivate) |
117 | { |
118 | d_ptr->q_ptr = this; |
119 | |
120 | QGalleryAbstractResponse::error(error, errorString); |
121 | } |
122 | |
123 | /*! |
124 | \internal |
125 | */ |
126 | |
127 | QGalleryAbstractResponse::QGalleryAbstractResponse( |
128 | QGalleryAbstractResponsePrivate &dd, QObject *parent) |
129 | : QObject(parent) |
130 | , d_ptr(&dd) |
131 | { |
132 | d_ptr->q_ptr = this; |
133 | } |
134 | |
135 | /*! |
136 | Destroys a gallery response. |
137 | */ |
138 | |
139 | QGalleryAbstractResponse::~QGalleryAbstractResponse() |
140 | { |
141 | } |
142 | |
143 | /*! |
144 | Identifies if a response is in an active state. |
145 | |
146 | Returns true if a response is active, and false otherwise. |
147 | */ |
148 | |
149 | bool QGalleryAbstractResponse::isActive() const |
150 | { |
151 | return d_func()->state == QGalleryAbstractRequest::Active; |
152 | } |
153 | |
154 | /*! |
155 | Identifies if the items returned by a response are being monitored for |
156 | changes. |
157 | |
158 | Returns true if a response is in an idle state, and false otherwise. |
159 | */ |
160 | |
161 | bool QGalleryAbstractResponse::isIdle() const |
162 | { |
163 | return d_func()->state == QGalleryAbstractRequest::Idle; |
164 | } |
165 | |
166 | /*! |
167 | Returns an identifier describing an error condition encountered by a |
168 | response. |
169 | |
170 | In the case of no error this will return QGalleryAbstractRequest::NoError. |
171 | |
172 | \sa QGalleryAbstractRequest::Error, QDocumentGallery::Error |
173 | */ |
174 | |
175 | int QGalleryAbstractResponse::error() const |
176 | { |
177 | return d_func()->error; |
178 | } |
179 | |
180 | /*! |
181 | Returns a string describing the cause of an \l error() in more detail. |
182 | */ |
183 | |
184 | QString QGalleryAbstractResponse::errorString() const |
185 | { |
186 | return d_func()->errorString; |
187 | } |
188 | |
189 | /*! |
190 | Waits for \a msecs for the a response to finish. |
191 | |
192 | Returns true if the response has finished on return, and returns false if |
193 | the wait time expires or the request is inactive or idle. |
194 | */ |
195 | |
196 | bool QGalleryAbstractResponse::waitForFinished(int msecs) |
197 | { |
198 | Q_D(QGalleryAbstractResponse); |
199 | |
200 | if (d->state != QGalleryAbstractRequest::Active) { |
201 | return true; |
202 | } else if (d->waitLoop || msecs == 0) { |
203 | QCoreApplication::processEvents(flags: QEventLoop::ExcludeUserInputEvents, maxtime: qMax(a: 0, b: msecs)); |
204 | } else { |
205 | QEventLoop waitLoop; |
206 | |
207 | if (msecs > 0) |
208 | QTimer::singleShot(msec: msecs, receiver: &waitLoop, SLOT(quit())); |
209 | |
210 | d->waitLoop = &waitLoop; |
211 | waitLoop.exec(flags: QEventLoop::ExcludeUserInputEvents); |
212 | d->waitLoop = 0; |
213 | } |
214 | return d->state != QGalleryAbstractRequest::Active; |
215 | } |
216 | |
217 | /*! |
218 | Cancels an active or idle gallery response. |
219 | |
220 | The default implementation finishes the an active response with the |
221 | \l QGalleryAbstractRequest::Canceled result. If the reponse is idle the |
222 | \l finished() signal will be re-emitted with idle. |
223 | */ |
224 | |
225 | void QGalleryAbstractResponse::cancel() |
226 | { |
227 | Q_D(QGalleryAbstractResponse); |
228 | |
229 | if (d->state == QGalleryAbstractRequest::Active |
230 | || d->state == QGalleryAbstractRequest::Idle) { |
231 | d->state = QGalleryAbstractRequest::Canceled; |
232 | |
233 | if (d->waitLoop) |
234 | d->waitLoop->exit(); |
235 | |
236 | emit canceled(); |
237 | } |
238 | } |
239 | |
240 | /*! |
241 | \fn QGalleryAbstractResponse::progressChanged(int current, int maximum) |
242 | |
243 | Signals that the \a current or \a maximum progress of a request has |
244 | changed. |
245 | */ |
246 | |
247 | /*! |
248 | Finalizes a gallery response. |
249 | |
250 | If \a idle is true the items returned by a response will be monitored |
251 | for changes and updated as appropriate. |
252 | */ |
253 | |
254 | void QGalleryAbstractResponse::finish(bool idle) |
255 | { |
256 | Q_D(QGalleryAbstractResponse); |
257 | |
258 | if (d->state == QGalleryAbstractRequest::Active |
259 | || (d->state == QGalleryAbstractRequest::Idle && !idle)) { |
260 | d->state = idle |
261 | ? QGalleryAbstractRequest::Idle |
262 | : QGalleryAbstractRequest::Finished; |
263 | |
264 | if (d->waitLoop) |
265 | d->waitLoop->exit(); |
266 | |
267 | emit finished(); |
268 | } |
269 | } |
270 | |
271 | /*! |
272 | Returns a response to an active state. |
273 | |
274 | An idle response can call this to indicate it has begun refreshing its |
275 | contents. |
276 | */ |
277 | |
278 | void QGalleryAbstractResponse::resume() |
279 | { |
280 | Q_D(QGalleryAbstractResponse); |
281 | |
282 | if (d->state == QGalleryAbstractRequest::Idle) { |
283 | d->state = QGalleryAbstractRequest::Active; |
284 | |
285 | emit resumed(); |
286 | } |
287 | } |
288 | |
289 | /*! |
290 | Finalizes a response in response to an error condition. |
291 | |
292 | The \a error, and \a errorString are communicated to issuing request. |
293 | */ |
294 | |
295 | void QGalleryAbstractResponse::error(int error, const QString &errorString) |
296 | { |
297 | Q_D(QGalleryAbstractResponse); |
298 | |
299 | if (d->state == QGalleryAbstractRequest::Active |
300 | || d->state == QGalleryAbstractRequest::Idle) { |
301 | d->state = QGalleryAbstractRequest::Finished; |
302 | |
303 | d->error = error; |
304 | d->errorString = errorString; |
305 | |
306 | if (d->waitLoop) |
307 | d->waitLoop->exit(); |
308 | |
309 | emit finished(); |
310 | } |
311 | } |
312 | |
313 | /*! |
314 | \fn QGalleryAbstractResponse::finished() |
315 | |
316 | Signals that a response has finished. |
317 | */ |
318 | |
319 | /*! |
320 | \fn QGalleryAbstractResponse::resumed() |
321 | |
322 | Signals that an idle response has resumed communications. |
323 | */ |
324 | |
325 | /*! |
326 | \fn QGalleryAbstractResponse::canceled() |
327 | |
328 | Signals that a response was canceled. |
329 | */ |
330 | |
331 | #include "moc_qgalleryabstractresponse.cpp" |
332 | |
333 | QT_END_NAMESPACE_DOCGALLERY |
334 | |