| 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 | |