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 <qgalleryabstractrequest.h>
43#include "qgalleryabstractrequest_p.h"
44#include <qabstractgallery.h>
45
46QT_BEGIN_NAMESPACE_DOCGALLERY
47
48void QGalleryAbstractRequestPrivate::_q_finished()
49{
50 if (state == QGalleryAbstractRequest::Active
51 || state == QGalleryAbstractRequest::Canceling
52 || state == QGalleryAbstractRequest::Idle) {
53 if (response->error() != QGalleryAbstractRequest::NoError) {
54 error = response->error();
55 errorString = response->errorString();
56
57 state = QGalleryAbstractRequest::Error;
58
59 emit q_func()->error(error, errorString);
60 emit q_func()->errorChanged();
61 emit q_func()->stateChanged(state);
62 } else if (state == QGalleryAbstractRequest::Idle) {
63 if (!response->isIdle()) {
64 state = QGalleryAbstractRequest::Finished;
65
66 emit q_func()->stateChanged(state);
67 }
68 } else if (response->isIdle()) {
69 state = QGalleryAbstractRequest::Idle;
70
71 if (!wasIdle) {
72 wasIdle = true;
73
74 emit q_func()->finished();
75 }
76
77 emit q_func()->stateChanged(state);
78 } else if (!response->isActive()) {
79 state = QGalleryAbstractRequest::Finished;
80
81 if (!wasIdle)
82 emit q_func()->finished();
83
84 emit q_func()->stateChanged(state);
85 }
86 }
87}
88
89void QGalleryAbstractRequestPrivate::_q_canceled()
90{
91 if (state == QGalleryAbstractRequest::Canceling) {
92 if (!wasIdle) {
93 state = QGalleryAbstractRequest::Canceled;
94
95 emit q_func()->canceled();
96 } else {
97 state = QGalleryAbstractRequest::Finished;
98 }
99 emit q_func()->stateChanged(state);
100 }
101}
102
103void QGalleryAbstractRequestPrivate::_q_resumed()
104{
105 if (state == QGalleryAbstractRequest::Idle && !response->isIdle()) {
106 state = QGalleryAbstractRequest::Active;
107
108 emit q_func()->stateChanged(state);
109 }
110}
111
112void QGalleryAbstractRequestPrivate::_q_progressChanged(int current, int maximum)
113{
114 currentProgress = current;
115 maximumProgress = maximum;
116
117 emit q_func()->progressChanged(current, maximum);
118}
119
120/*!
121 \class QGalleryAbstractRequest
122
123 \ingroup gallery
124 \ingroup gallery-requests
125
126 \inmodule QtDocGallery
127
128 \brief The QGalleryAbstractRequest class provides a base class for gallery
129 requests.
130
131 Gallery requests are the interface through which clients can interact with
132 a gallery to execute queries or perform actions. QAbstractGalleryRequest
133 manages executing requests against a gallery and reporting the state of
134 responses.
135
136 In order to execute a request it is first necessary to assign the \l gallery
137 to the request. If the request is supported by the gallery the \l supported
138 property will be true, otherwise if the request is not supported or no
139 gallery is assigned to the request \l supported will be false.
140
141 Once a request has been assigned a gallery and its own arguments it can be
142 \l {execute()}{executed}. As requests are asynchronous results will not
143 be available immediately, instead the request will go into an \l Active
144 \l state until it is finished. If the request is successful the finished()
145 signal will be emitted and if not the error() signal will be emitted, in
146 both cases the stateChanged() signal will be emitted with the new state of
147 the request.
148
149 Active requests can be canceled by calling the cancel() function.
150 Canceling a request can also be an asynchronous action and does not always
151 prevent a request from finishing successfully such as when the earliest
152 possible point to interrupt a request is on completion. If a canceled
153 request isn't aborted immediately it will go into the \l Canceling state
154 until it is aborted and enters the \l Canceled state or succeeds and enters
155 the \l Finished state.
156
157 Some requests support automatically updating their results in response to
158 changes in their source data or some other event. A request that will
159 provide these sort of updates will enter the Idle state upon finishing
160 its initial request. From the \l Idle state a request may return to the
161 \l Active state itself to refresh its results or update it results
162 immeditately if a a new query is not required. Cancelling an idle request
163 will put it into the \l Finished state and prevent future updates.
164
165 While requests are asynchronous it is possible to use them in a synchronous
166 manner by using the waitForFinished() function to block until the request
167 has finished.
168*/
169
170/*!
171 \enum QGalleryAbstractRequest::State
172
173 Identifies the state of a gallery request.
174
175 \value Inactive The request has not been executed.
176 \value Active The request is currently executing.
177 \value Canceling The request was canceled, but hasn't yet reached the
178 Canceled state.
179 \value Canceled The request was canceled.
180 \value Idle The request has finished, but may return to the active state
181 in response to an internal event.
182 \value Finished The request is finished.
183 \value Error The request runs into an error.
184*/
185
186/*!
187 \enum QGalleryAbstractRequest::RequestError
188
189 \value NoError No error.
190 \value NoGallery No gallery found.
191 \value NotSupported Request is not supported.
192 \value GalleryError The gallery is wrong or corrupt.
193*/
194
195/*!
196 \enum QGalleryAbstractRequest::RequestType
197
198 Identifies the type of a request.
199
200 \value QueryRequest The request is a QGalleryQueryRequest.
201 \value ItemRequest The request is a QGalleryItemRequest.
202 \value TypeRequest The request is a QGalleryTypeRequest
203*/
204
205/*!
206 Constructs a new gallery \a type request.
207
208 The \a parent is passed to QObject.
209*/
210
211QGalleryAbstractRequest::QGalleryAbstractRequest(RequestType type, QObject *parent)
212 : QObject(parent)
213 , d_ptr(new QGalleryAbstractRequestPrivate(0, type))
214{
215 d_ptr->q_ptr = this;
216}
217
218/*!
219 Constructs a new \a type request for the given \a gallery.
220
221 The \a parent is passed to QObject.
222*/
223
224QGalleryAbstractRequest::QGalleryAbstractRequest(
225 QAbstractGallery *gallery, RequestType type, QObject *parent)
226 : QObject(parent)
227 , d_ptr(new QGalleryAbstractRequestPrivate(gallery, type))
228{
229 d_ptr->q_ptr = this;
230}
231
232/*!
233 \internal
234*/
235
236QGalleryAbstractRequest::QGalleryAbstractRequest(QGalleryAbstractRequestPrivate &dd, QObject *parent)
237 : QObject(parent)
238 , d_ptr(&(dd))
239{
240 d_ptr->q_ptr = this;
241}
242
243/*!
244 Destroys a gallery request.
245*/
246
247QGalleryAbstractRequest::~QGalleryAbstractRequest()
248{
249}
250
251/*!
252 \property QGalleryAbstractRequest::gallery
253
254 \brief The gallery service a request acts on.
255*/
256
257QAbstractGallery *QGalleryAbstractRequest::gallery() const
258{
259 return d_ptr->gallery.data();
260}
261
262void QGalleryAbstractRequest::setGallery(QAbstractGallery *gallery)
263{
264 if (d_ptr->gallery.data() != gallery) {
265 d_ptr->gallery = gallery;
266
267 emit galleryChanged();
268 emit supportedChanged();
269 }
270}
271
272/*!
273 \fn QGalleryAbstractRequest::galleryChanged()
274
275 Signals that the value of \l gallery has changed.
276*/
277
278/*!
279 \property QGalleryAbstractRequest::supported
280
281 \brief Whether a request is supported by its current \a gallery.
282*/
283
284bool QGalleryAbstractRequest::isSupported() const
285{
286 return d_ptr->gallery && d_ptr->gallery.data()->isRequestSupported(type: d_ptr->type);
287}
288
289/*!
290 \fn QGalleryAbstractRequest::supportedChanged()
291
292 Signals the \l supported property has changed.
293*/
294
295
296/*!
297 Returns the type of a request.
298*/
299QGalleryAbstractRequest::RequestType QGalleryAbstractRequest::type() const
300{
301 return d_ptr->type;
302}
303
304/*!
305 \property QGalleryAbstractRequest::state
306
307 \brief The state of a request.
308*/
309
310QGalleryAbstractRequest::State QGalleryAbstractRequest::state() const
311{
312 return d_ptr->state;
313}
314
315/*!
316 \property QGalleryAbstractRequest::error
317
318 \brief The error encountered by an unsuccessful request.
319
320 Common errors are defined in \l Error, more specific errors are defined by
321 the gallery implementations such as in QDocumentGallery::Error.
322*/
323
324int QGalleryAbstractRequest::error() const
325{
326 return d_ptr->error;
327}
328
329/*!
330 \property QGalleryAbstractRequest::errorString
331
332 \brief A string describing the cause of an \l error in more detail.
333
334 This may be an empty string if more information is not known.
335*/
336
337QString QGalleryAbstractRequest::errorString() const
338{
339 return d_ptr->errorString;
340}
341
342/*!
343 \fn QGalleryAbstractRequest::errorChanged()
344
345 Signals that the \l error and \l errorString properties have changed.
346*/
347
348/*!
349 \property QGalleryAbstractRequest::currentProgress
350
351 \brief the current progress of a request.
352*/
353
354int QGalleryAbstractRequest::currentProgress() const
355{
356 return d_func()->currentProgress;
357}
358
359/*!
360 \property QGalleryAbstractRequest::maximumProgress
361
362 \brief the maximum value of \l currentProgress
363*/
364
365int QGalleryAbstractRequest::maximumProgress() const
366{
367 return d_func()->maximumProgress;
368}
369
370/*!
371 \fn QGalleryAbstractRequest::progressChanged(int current, int maximum)
372
373 Signals that the \a current or \a maximum progress value has changed.
374*/
375
376/*!
377 Waits for \a msecs for the a request to finish.
378
379 Returns true if the request has finished on return, and returns false if the
380 wait time expires or the request is inactive or idle.
381*/
382bool QGalleryAbstractRequest::waitForFinished(int msecs)
383{
384 return d_ptr->response && d_ptr->state == Active
385 ? d_ptr->response->waitForFinished(msecs)
386 : true;
387}
388
389/*!
390 Executes a request.
391
392 \b {Note}: A valid \l gallery must be set before a request can be
393 executed.
394*/
395
396void QGalleryAbstractRequest::execute()
397{
398 const int oldError = d_ptr->error;
399
400 d_ptr->error = NoError;
401 d_ptr->errorString = QString();
402
403 if (!d_ptr->gallery) {
404 d_ptr->state = Error;
405 d_ptr->error = NoGallery;
406 d_ptr->errorString = tr(s: "No gallery has been set on the %1.", c: "%1 = class name")
407 .arg(a: QString::fromLatin1(str: metaObject()->className()));
408
409 if (d_ptr->response) {
410 QScopedPointer<QGalleryAbstractResponse> oldResponse(d_ptr->response.take());
411
412 Q_UNUSED(oldResponse);
413
414 setResponse(0);
415 }
416
417 emit error(error: d_ptr->error, errorString: d_ptr->errorString);
418 emit errorChanged();
419 } else {
420 QScopedPointer<QGalleryAbstractResponse> oldResponse(
421 d_ptr->gallery.data()->createResponse(request: this));
422 d_ptr->response.swap(other&: oldResponse);
423
424 if (d_ptr->response) {
425 d_ptr->error = d_ptr->response->error();
426
427 if (d_ptr->error != NoError) {
428 d_ptr->errorString = d_ptr->response->errorString();
429 d_ptr->state = Error;
430
431 d_ptr->response.reset();
432
433 if (oldResponse)
434 setResponse(0);
435
436 emit error(error: d_ptr->error, errorString: d_ptr->errorString);
437 emit errorChanged();
438 } else {
439 if (d_ptr->response->isActive()) {
440 d_ptr->state = Active;
441 d_ptr->wasIdle = false;
442 } else if (d_ptr->response->isIdle()) {
443 d_ptr->state = Idle;
444 d_ptr->wasIdle = true;
445 } else {
446 d_ptr->state = Finished;
447 }
448
449 connect(sender: d_ptr->response.data(), SIGNAL(finished()), receiver: this, SLOT(_q_finished()));
450 connect(sender: d_ptr->response.data(), SIGNAL(resumed()), receiver: this, SLOT(_q_resumed()));
451 connect(sender: d_ptr->response.data(), SIGNAL(canceled()), receiver: this, SLOT(_q_canceled()));
452 connect(sender: d_ptr->response.data(), SIGNAL(progressChanged(int,int)),
453 receiver: this, SLOT(_q_progressChanged(int,int)));
454
455 setResponse(d_ptr->response.data());
456 }
457
458 oldResponse.reset();
459 } else {
460 d_ptr->state = Error;
461 d_ptr->error = NotSupported;
462 d_ptr->errorString = tr(
463 s: "%1 is not supported by %2.", c: "%1 = interface, %2 = gallery implementation")
464 .arg(a: QString::fromLatin1(str: metaObject()->className()))
465 .arg(a: QString::fromLatin1(str: d_ptr->gallery.data()->metaObject()->className()));
466
467 if (oldResponse)
468 setResponse(0);
469
470 oldResponse.reset();
471
472 emit error(error: d_ptr->error, errorString: d_ptr->errorString);
473 emit errorChanged();
474 }
475
476 if (d_ptr->currentProgress != 0 || d_ptr->maximumProgress != 0) {
477 d_ptr->currentProgress = 0;
478 d_ptr->maximumProgress = 0;
479
480 emit progressChanged(current: 0, maximum: 0);
481 }
482
483 if (d_ptr->state == Finished || d_ptr->state == Idle)
484 emit finished();
485 }
486
487 if (oldError != NoError && d_ptr->error == NoError)
488 emit errorChanged();
489
490 emit stateChanged(state: d_ptr->state);
491}
492
493/*!
494 Cancels the execution of a request. If the request is idle this will stop
495 any future updates.
496*/
497
498void QGalleryAbstractRequest::cancel()
499{
500 if (d_ptr->state == Active || d_ptr->state == Idle) {
501 d_ptr->state = Canceling;
502 d_ptr->response->cancel();
503
504 if (d_ptr->state == Canceling)
505 emit stateChanged(state: d_ptr->state);
506 }
507}
508
509/*!
510 Clears the results of a request.
511
512 If the request is active or idle it will be canceled.
513*/
514
515void QGalleryAbstractRequest::clear()
516{
517 const int oldError = d_ptr->error;
518
519 d_ptr->error = NoError;
520 d_ptr->errorString = QString();
521
522 if (d_ptr->response) {
523 QScopedPointer<QGalleryAbstractResponse> oldResponse(d_ptr->response.take());
524
525 d_ptr->state = Inactive;
526
527 setResponse(0);
528
529 oldResponse.reset();
530
531 if (d_ptr->currentProgress != 0 || d_ptr->maximumProgress != 0) {
532 d_ptr->currentProgress = 0;
533 d_ptr->maximumProgress = 0;
534
535 emit progressChanged(current: 0, maximum: 0);
536 }
537
538 emit stateChanged(state: d_ptr->state);
539 } else if (d_ptr->state == Error) {
540 d_ptr->state = Inactive;
541
542 emit stateChanged(state: d_ptr->state);
543 }
544
545 if (oldError != NoError)
546 emit errorChanged();
547}
548
549/*!
550 \fn QGalleryAbstractRequest::finished()
551
552 Signals that a request has finished.
553*/
554
555/*!
556 \fn QGalleryAbstractRequest::canceled()
557
558 Signals that a request was canceled before it could finish.
559*/
560
561/*!
562 \fn QGalleryAbstractRequest::stateChanged(QGalleryAbstractRequest::State state)
563
564 Signals that the \a state of a request has changed.
565*/
566
567/*!
568 \fn QGalleryAbstractRequest::error(int error, const QString &errorString)
569
570 Signals that a request failed with the given \a error. The \a errorString
571 may provide more detail.
572*/
573
574/*!
575 \fn QGalleryAbstractRequest::setResponse(QGalleryAbstractResponse *response)
576
577 Sets the \a response to an executed request.
578*/
579
580#include "moc_qgalleryabstractrequest.cpp"
581
582QT_END_NAMESPACE_DOCGALLERY
583

source code of qtdocgallery/src/gallery/qgalleryabstractrequest.cpp