summaryrefslogtreecommitdiffstats
path: root/src/location/landmarks/qlandmarkabstractrequest.cpp
blob: 7d3185a1b26a6583c9508457f7d6b06d1d08cba4 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
/****************************************************************************
**
** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
** All rights reserved.
** Contact: Nokia Corporation (qt-info@nokia.com)
**
** This file is part of the Qt Mobility Components.
**
** $QT_BEGIN_LICENSE:LGPL$
** No Commercial Usage
** This file contains pre-release code and may not be distributed.
** You may use this file in accordance with the terms and conditions
** contained in the Technology Preview License Agreement accompanying
** this package.
**
** GNU Lesser General Public License Usage
** Alternatively, this file may be used under the terms of the GNU Lesser
** General Public License version 2.1 as published by the Free Software
** Foundation and appearing in the file LICENSE.LGPL included in the
** packaging of this file.  Please review the following information to
** ensure the GNU Lesser General Public License version 2.1 requirements
** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
**
** In addition, as a special exception, Nokia gives you certain additional
** rights.  These rights are described in the Nokia Qt LGPL Exception
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
**
** If you have questions regarding the use of this file, please contact
** Nokia at qt-info@nokia.com.
**
**
**
**
**
**
**
**
** $QT_END_LICENSE$
**
****************************************************************************/
#include "qlandmarkabstractrequest.h"
#include "qlandmarkabstractrequest_p.h"
#include "qlandmarkmanagerengine.h"
#include "qlandmarkmanager_p.h"
#include <QDebug>
#include <QMutexLocker>

QTM_USE_NAMESPACE

QLandmarkAbstractRequestPrivate::QLandmarkAbstractRequestPrivate(QLandmarkManager *mgr)
    : type(QLandmarkAbstractRequest::InvalidRequest),
      state(QLandmarkAbstractRequest::InactiveState),
      error(QLandmarkManager::NoError),
      errorString(QString()),
      manager(mgr)
{
}

/*!
    \class QLandmarkAbstractRequest
    \brief The QLandmarkAbstractRequest class provides the interface
    from which all asynchronous request classes inherit.


    \inmodule QtLocation

    \ingroup landmarks-request

    It allows a client to asynchronously request some functionality of a
    particular QLandmarkManager. Instances of the class will emit signals when
    the state of the request changes, or when more results become available.

    Clients should not attempt to create instances of this class directly, but
    should instead use the use-case-specific classes derived from this class.

    All such request classes have a similar interface: clients set the
    parameters of the asynchronous call, then call the start() slot of the request. The manager
    will then enqueue or begin to process the request, at which point the
    request's state will transition from the \c InactiveState to \c ActiveState.
    After any state transition, the request will emit the stateChanged()
    signal. The manager may (if it supports it)
    periodically update the request with results, at
    which point the request will emit the resultsAvailable() signal. These
    results are not guaranteed to have a stable ordering. Error information is
    considered a result, so some requests will emit the resultsAvailable()
    signal even if no results are possible from the request (for example, a
    landmark remove request) when the manager updates the request with
    information about any errors which may have occurred.

    Clients can choose which signals they wish to handle from a request. If the
    client is not interested in interim results, they can choose to handle only
    the stateChanged() signal, and in the slot to which that signal is
    connected, check whether the state has changed to the \c FinishedState
    (which signifies that the manager has finished handling the request, and
    that the request will not be updated with any more results).  If the client
    is not interested in any results (including error information), they may
    choose to delete the request after calling \l start(), or simply may not
    connect the the request's signals to any slots.  (Please see the note
    below if you are working on Symbian with QtMobility 1.1.0)

    If the request is allocated via operator new, the client must delete the
    request when they are no longer using it in order to avoid leaking memory.
    That is, the client retains ownership of the request.

    The client may delete a heap-allocated request in various ways: by deleting
    it directly (but not within a slot connected to a signal emitted by the
    request), or by using the deleteLater() slot to schedule the request for
    deletion when control returns to the event loop (from within a slot
    connected to a signal emitted by the request, for example \l
    stateChanged()).

    An active request may be deleted by the client, but the client will
    not receive notifications about whether the request succeeded or not,
    nor the results of the request.

    Because clients retain ownership of any request object, and may delete a
    request object at any time, the manager engine,  implementers must be
    careful to ensue that they do not assume that a request has not been
    deleted at some time point during processing of a request, particularly
    if the engine has a multithreaded implementation.
*/

QLandmarkAbstractRequestPrivate::~QLandmarkAbstractRequestPrivate()
{
}

void QLandmarkAbstractRequestPrivate::notifyEngine(QLandmarkAbstractRequest* request)
{
        Q_ASSERT(request);
        QLandmarkAbstractRequestPrivate* d = request->d_ptr;
        if (d) {
            QMutexLocker ml(&d->mutex);
            QLandmarkManagerEngine *engine = QLandmarkManagerPrivate::getEngine(d->manager);
            ml.unlock();
            if (engine) {
                engine->requestDestroyed(request);
            }
        }
}

/*!
    \enum QLandmarkAbstractRequest::RequestType
    Defines the possible types of asynchronous requests.
    \value  InvalidRequest An invalid request
    \value  LandmarkIdFetchRequest A request to fetch a list of landmark
            identifiers.
    \value  CategoryIdFetchRequest A request to fetch a list of catgory
            identifiers.

    \value  LandmarkFetchRequest A request to fetch a list of landmarks
    \value  LandmarkFetchByIdRequest A request to fetch a list of landmarks by id.
    \value  CategoryFetchRequest A request to fetch a list of categories
    \value  CategoryFetchByIdRequest A request to fetch a list of categories by id
    \value  LandmarkSaveRequest A request to save a list of landmarks.
    \value  LandmarkRemoveRequest A request to remove a list of landmarks.
    \value  CategorySaveRequest A request to save a list of categories.
    \value  CategoryRemoveRequest A request to remove a list of categories.
    \value  ImportRequest A request import landmarks.
    \value  ExportRequest A request export landmarks.
*/

/*!
    \enum QLandmarkAbstractRequest::State
    Defines the possible states of asynchronous requests.
    \value  InactiveState Operation not yet started.
    \value  ActiveState Operation started, not yet finished.
    \value  FinishedState Operation completed.  (Can be mean either successful or
            unsuccessful completion).
*/

/*!
    Constructs a new, invalid asynchronous request with the given \a manager and \a parent.
*/
QLandmarkAbstractRequest::QLandmarkAbstractRequest(QLandmarkManager *manager, QObject *parent)
    : QObject(parent),
      d_ptr(new QLandmarkAbstractRequestPrivate(manager))
{
}

/*!
    \internal
*/
QLandmarkAbstractRequest::QLandmarkAbstractRequest(QLandmarkAbstractRequestPrivate *dd, QObject *parent)
    : QObject(parent),
     d_ptr(dd)
{
}

/*!
    Destroys the asynchronous request.  Because the request object is effectiely a handle to a
    request operation, the operation may continue or it may just be canceled, depending upon
    the enine implementation, even though the request itself has been destroyed.
    The sqlite engine continues the operation behind the scenes if the
    request is destroyed whilst active.  For the symbian engine see the note below.
*/
QLandmarkAbstractRequest::~QLandmarkAbstractRequest()
{
    QLandmarkAbstractRequestPrivate::notifyEngine(this);
    delete d_ptr;
}

/*!
    Returns the type of this asynchronous request.
*/
QLandmarkAbstractRequest::RequestType QLandmarkAbstractRequest::type() const
{
    QMutexLocker ml(&d_ptr->mutex);
    return d_ptr->type;
}

/*!
    Returns the state of the request
*/
QLandmarkAbstractRequest::State QLandmarkAbstractRequest::state()
{
    QMutexLocker ml(&d_ptr->mutex);
    return d_ptr->state;
}

/*!
    Returns true if the request is in the \c QLandmarkAbstractRequest::Inactive state;
    otherwise, returns false.
    \sa state()
*/
bool QLandmarkAbstractRequest::isInactive() const
{
    QMutexLocker ml(&d_ptr->mutex);
    return d_ptr->state == QLandmarkAbstractRequest::InactiveState;
}

/*!
    Returns true if the request is in the \c QLandmarkAbstractRequest::Active state;
    otherwise, returns false.
    \sa state()
*/
bool QLandmarkAbstractRequest::isActive() const
{
    QMutexLocker ml(&d_ptr->mutex);
    return d_ptr->state == QLandmarkAbstractRequest::ActiveState;
}

/*!
    Returns true if the request is in the \c QLandmarkAbstractRequest::Finished state;
    otherwise, returns false.
    \sa state()
*/
bool QLandmarkAbstractRequest::isFinished() const
{
    QMutexLocker ml(&d_ptr->mutex);
    return d_ptr->state == QLandmarkAbstractRequest::FinishedState;
}

/*!
    Returns the overall error of the most recent asynchronous operation.
    \sa errorString()
*/
QLandmarkManager::Error QLandmarkAbstractRequest::error() const
{
    QMutexLocker ml(&d_ptr->mutex);
    return d_ptr->error;
}

/*!
    Returns a human readable string of the last error
    that occurred.  This error string is intended to be used
    by developers only and should not be seen by end users.
    \sa error()
*/
QString QLandmarkAbstractRequest::errorString() const
{
    QMutexLocker ml(&d_ptr->mutex);
    return d_ptr->errorString;
}

/*!
    Returns a pointer to the landmark manager which
    this request operates on.
*/
QLandmarkManager *QLandmarkAbstractRequest::manager() const
{
    QMutexLocker ml(&d_ptr->mutex);
    return d_ptr->manager;
}

/*!
    Sets the \a manager which this request operates on.

    Note that if a NULL manager is set, the functions
    start(), cancel() and waitForFinished() will return false and
    error will be set to QLandmarkManager::InvalidManagerError.

    A manager cannot be assigned while the request is in the
    QLandmarkAbstractRequest::ActiveState.
*/
void QLandmarkAbstractRequest::setManager(QLandmarkManager *manager)
{
    QMutexLocker ml(&d_ptr->mutex);
    if (d_ptr->state == QLandmarkAbstractRequest::ActiveState && d_ptr->manager)
        return;
    d_ptr->manager = manager;
}

/*!
    Attempts to start the request.

    Returns true if the request was started, otherwise false. Trying to start a
    request that is already active returns false.
    \sa cancel().
*/
bool QLandmarkAbstractRequest::start()
{
    QMutexLocker ml(&d_ptr->mutex);
    if (!d_ptr->manager) {
        d_ptr->error = QLandmarkManager::BadArgumentError;
        d_ptr->errorString = "No manager assigned to landmark request object";
        qWarning() << d_ptr->errorString;
        return false;
    }
    QLandmarkManagerEngine *engine = d_ptr->manager->engine();
    if (!engine) {
        d_ptr->error = QLandmarkManager::InvalidManagerError;
        d_ptr->errorString = "The manager is invalid";
        return false;
    }

    if (d_ptr->state != QLandmarkAbstractRequest::ActiveState) {
        ml.unlock();
        return engine->startRequest(this);
    }
     else {
        return false;
     }
}

/*!
    Notifies the request that it should be canceled.

    Returns true if the request was successfully notified
    that it should be canceled.  The request may or may not honor
    the cancel notification.  Returns false if the notification
    could not be made or the request is not in the
    QLandmarkManager::Active state.

    \sa start()
*/
bool QLandmarkAbstractRequest::cancel()
{
    QMutexLocker ml(&d_ptr->mutex);
    if (!d_ptr->manager) {
        d_ptr->error = QLandmarkManager::BadArgumentError;
        d_ptr->errorString = "No manager assigned to landmark request object";
        qWarning() << d_ptr->errorString;
        return false;
    }
    QLandmarkManagerEngine *engine = d_ptr->manager->engine();

    if(d_ptr->state == QLandmarkAbstractRequest::ActiveState) {
        ml.unlock();
        return engine->cancelRequest(this);
    }
    else
        return false;
}

/*!
    Blocks until the request has been completed or until \a msecs milliseconds
    has elapsed.  If \a msecs is zero or negative, this function will block indefinitely.

    Returns true if the request was canceled or completed
    within the given period, otherwise returns false.  Some backends may be unable
    to support this  operation safely and will return false immediately.

    (Note: This function is not supported for an import request
    with the symbian manager which always returns false.  As of
    Qt Mobility 1.1.1 waitForFinished() is supported using the sqlite manager).

    Note that any signals generated while waiting for the request to be complete
    may be queued and delivered sometime after this function has returned, when
    the calling thread's event loop is dispatched.  If your code depends on
    your slots being invoked, you may need to process events after calling
    this function.
*/
bool QLandmarkAbstractRequest::waitForFinished(int msecs)
{

    QMutexLocker ml(&d_ptr->mutex);
    if (!d_ptr->manager) {
        d_ptr->error = QLandmarkManager::BadArgumentError;
        d_ptr->errorString = "No manager assigned to landmark request object";
        qWarning() << d_ptr->errorString;
        return false;
    }
    QLandmarkManagerEngine *engine = d_ptr->manager->engine();

    switch(d_ptr->state) {
        case QLandmarkAbstractRequest::ActiveState:
            ml.unlock();
            return engine->waitForRequestFinished(this, msecs);
        case QLandmarkAbstractRequest::FinishedState:
            return true;
        default:
            return false;
    }
}

/*!
  \fn void QLandmarkAbstractRequest::resultsAvailable()
  This signal is emitted when new results are available.  Results
  can include the operation error which may be accessed via error(),
  or derived-class specific results which are accessible through
  the derived class API.

  \sa error()
*/

/*!
    \fn void QLandmarkAbstractRequest::stateChanged(QLandmarkAbstractRequest::State newState)
    This signal is emitted when the state of the request is changed.  The new state of
    the request will be contained in \a newState.
*/

#include "moc_qlandmarkabstractrequest.cpp"