1/****************************************************************************
2**
3** Copyright (C) 2015 The Qt Company Ltd.
4** Contact: http://www.qt.io/licensing/
5**
6** This file is part of the QtLocation module of the Qt Toolkit.
7**
8** $QT_BEGIN_LICENSE:LGPL3$
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 The Qt Company. For licensing terms
14** and conditions see http://www.qt.io/terms-conditions. For further
15** information use the contact form at http://www.qt.io/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 3 as published by the Free Software
20** Foundation and appearing in the file LICENSE.LGPLv3 included in the
21** packaging of this file. Please review the following information to
22** ensure the GNU Lesser General Public License version 3 requirements
23** will be met: https://www.gnu.org/licenses/lgpl.html.
24**
25** GNU General Public License Usage
26** Alternatively, this file may be used under the terms of the GNU
27** General Public License version 2.0 or later as published by the Free
28** Software Foundation and appearing in the file LICENSE.GPL included in
29** the packaging of this file. Please review the following information to
30** ensure the GNU General Public License version 2.0 requirements will be
31** met: http://www.gnu.org/licenses/gpl-2.0.html.
32**
33** $QT_END_LICENSE$
34**
35****************************************************************************/
36
37#include "qdeclarativesearchmodelbase_p.h"
38#include "qdeclarativeplace_p.h"
39#include "error_messages_p.h"
40
41#include <QtCore/QCoreApplication>
42#include <QtQml/QQmlInfo>
43#include <QtLocation/QGeoServiceProvider>
44#include <QtLocation/QPlaceManager>
45#include <QtLocation/QPlaceSearchRequest>
46#include <QtLocation/QPlaceSearchReply>
47#include <QtPositioning/QGeoCircle>
48#include <QtPositioning/QGeoPolygon>
49#include <QtLocation/private/qdeclarativegeoroute_p.h>
50#include <QtLocation/private/qplacesearchrequest_p.h>
51
52QT_BEGIN_NAMESPACE
53
54QDeclarativeSearchModelBase::QDeclarativeSearchModelBase(QObject *parent)
55: QAbstractListModel(parent), m_plugin(0), m_reply(0), m_complete(false), m_status(Null)
56{
57}
58
59QDeclarativeSearchModelBase::~QDeclarativeSearchModelBase()
60{
61}
62
63/*!
64 \internal
65*/
66QDeclarativeGeoServiceProvider *QDeclarativeSearchModelBase::plugin() const
67{
68 return m_plugin;
69}
70
71/*!
72 \internal
73*/
74void QDeclarativeSearchModelBase::setPlugin(QDeclarativeGeoServiceProvider *plugin)
75{
76 if (m_plugin == plugin)
77 return;
78
79 initializePlugin(plugin);
80
81 if (m_complete)
82 emit pluginChanged();
83}
84
85/*!
86 \internal
87*/
88QVariant QDeclarativeSearchModelBase::searchArea() const
89{
90 QGeoShape s = m_request.searchArea();
91 if (s.type() == QGeoShape::RectangleType)
92 return QVariant::fromValue(value: QGeoRectangle(s));
93 else if (s.type() == QGeoShape::CircleType)
94 return QVariant::fromValue(value: QGeoCircle(s));
95 else if (s.type() == QGeoShape::PolygonType)
96 return QVariant::fromValue(value: QGeoPolygon(s));
97 else
98 return QVariant::fromValue(value: s);
99}
100
101/*!
102 \internal
103*/
104void QDeclarativeSearchModelBase::setSearchArea(const QVariant &searchArea)
105{
106 QGeoShape s;
107 QDeclarativeGeoRoute *route = nullptr;
108 bool routeSearchArea = false;
109 if (searchArea.userType() == qMetaTypeId<QGeoRectangle>())
110 s = searchArea.value<QGeoRectangle>();
111 else if (searchArea.userType() == qMetaTypeId<QGeoCircle>())
112 s = searchArea.value<QGeoCircle>();
113 else if (searchArea.userType() == qMetaTypeId<QGeoShape>())
114 s = searchArea.value<QGeoShape>();
115 else if (int(searchArea.type()) == qMetaTypeId<QObject *>()) {
116 route = searchArea.value<QDeclarativeGeoRoute *>();
117 if (!route)
118 return;
119 routeSearchArea = true;
120 }
121
122 QPlaceSearchRequestPrivate *rp = QPlaceSearchRequestPrivate::get(request&: m_request);
123 // Invalidating the other thing
124 if (routeSearchArea)
125 m_request.setSearchArea(QGeoShape());
126 else
127 rp->routeSearchArea = QGeoRoute();
128
129 if (m_request.searchArea() == s
130 && (!route || rp->routeSearchArea == route->route()))
131 return;
132
133 if (routeSearchArea)
134 rp->routeSearchArea = route->route();
135 else
136 m_request.setSearchArea(s);
137 emit searchAreaChanged();
138}
139
140/*!
141 \internal
142*/
143int QDeclarativeSearchModelBase::limit() const
144{
145 return m_request.limit();
146}
147
148/*!
149 \internal
150*/
151void QDeclarativeSearchModelBase::setLimit(int limit)
152{
153 if (m_request.limit() == limit)
154 return;
155
156 m_request.setLimit(limit);
157 emit limitChanged();
158}
159
160/*!
161 \internal
162*/
163bool QDeclarativeSearchModelBase::previousPagesAvailable() const
164{
165 return m_previousPageRequest != QPlaceSearchRequest();
166}
167
168/*!
169 \internal
170*/
171bool QDeclarativeSearchModelBase::nextPagesAvailable() const
172{
173 return m_nextPageRequest != QPlaceSearchRequest();
174}
175
176/*!
177 \internal
178*/
179QDeclarativeSearchModelBase::Status QDeclarativeSearchModelBase::status() const
180{
181 return m_status;
182}
183
184/*!
185 \internal
186*/
187void QDeclarativeSearchModelBase::setStatus(Status status, const QString &errorString)
188{
189 Status prevStatus = m_status;
190
191 m_status = status;
192 m_errorString = errorString;
193
194 if (prevStatus != m_status)
195 emit statusChanged();
196}
197
198/*!
199 \internal
200*/
201void QDeclarativeSearchModelBase::update()
202{
203 if (m_reply)
204 return;
205
206 setStatus(status: Loading);
207
208 if (!m_plugin) {
209 clearData();
210 setStatus(status: Error, errorString: QCoreApplication::translate(context: CONTEXT_NAME, key: PLUGIN_PROPERTY_NOT_SET));
211 return;
212 }
213
214 QGeoServiceProvider *serviceProvider = m_plugin->sharedGeoServiceProvider();
215 if (!serviceProvider) {
216 clearData();
217 setStatus(status: Error, errorString: QCoreApplication::translate(context: CONTEXT_NAME, key: PLUGIN_PROVIDER_ERROR)
218 .arg(a: m_plugin->name()));
219 return;
220 }
221
222 QPlaceManager *placeManager = serviceProvider->placeManager();
223 if (!placeManager) {
224 clearData();
225 setStatus(status: Error, errorString: QCoreApplication::translate(context: CONTEXT_NAME, key: PLUGIN_ERROR)
226 .arg(a: m_plugin->name()).arg(a: serviceProvider->errorString()));
227 return;
228 }
229
230 m_reply = sendQuery(manager: placeManager, request: m_request);
231 if (!m_reply) {
232 clearData();
233 setStatus(status: Error, errorString: QCoreApplication::translate(context: CONTEXT_NAME, key: UNABLE_TO_MAKE_REQUEST));
234 return;
235 }
236
237 m_reply->setParent(this);
238 connect(sender: m_reply, SIGNAL(finished()), receiver: this, SLOT(queryFinished()));
239 connect(sender: m_reply, SIGNAL(contentUpdated()), receiver: this, SLOT(onContentUpdated()));
240}
241
242/*!
243 \internal
244*/
245void QDeclarativeSearchModelBase::cancel()
246{
247 if (!m_reply)
248 return;
249
250 if (!m_reply->isFinished())
251 m_reply->abort();
252
253 if (m_reply) {
254 m_reply->deleteLater();
255 m_reply = 0;
256 }
257
258 setStatus(status: Ready);
259}
260
261/*!
262 \internal
263*/
264void QDeclarativeSearchModelBase::reset()
265{
266 beginResetModel();
267 clearData();
268 setStatus(status: Null);
269 endResetModel();
270}
271
272/*!
273 \internal
274*/
275QString QDeclarativeSearchModelBase::errorString() const
276{
277 return m_errorString;
278}
279
280/*!
281 \internal
282*/
283void QDeclarativeSearchModelBase::previousPage()
284{
285 if (m_previousPageRequest == QPlaceSearchRequest())
286 return;
287
288 m_request = m_previousPageRequest;
289 update();
290}
291
292/*!
293 \internal
294*/
295void QDeclarativeSearchModelBase::nextPage()
296{
297 if (m_nextPageRequest == QPlaceSearchRequest())
298 return;
299
300 m_request = m_nextPageRequest;
301 update();
302}
303
304/*!
305 \internal
306*/
307void QDeclarativeSearchModelBase::clearData(bool suppressSignal)
308{
309 Q_UNUSED(suppressSignal);
310}
311
312/*!
313 \internal
314*/
315void QDeclarativeSearchModelBase::classBegin()
316{
317}
318
319/*!
320 \internal
321*/
322void QDeclarativeSearchModelBase::componentComplete()
323{
324 m_complete = true;
325}
326
327/*!
328 \internal
329*/
330void QDeclarativeSearchModelBase::initializePlugin(QDeclarativeGeoServiceProvider *plugin)
331{
332 beginResetModel();
333 if (plugin != m_plugin) {
334 if (m_plugin)
335 disconnect(sender: m_plugin, SIGNAL(nameChanged(QString)), receiver: this, SLOT(pluginNameChanged()));
336 if (plugin)
337 connect(sender: plugin, SIGNAL(nameChanged(QString)), receiver: this, SLOT(pluginNameChanged()));
338 m_plugin = plugin;
339 }
340
341 if (m_plugin) {
342 QGeoServiceProvider *serviceProvider = m_plugin->sharedGeoServiceProvider();
343 if (serviceProvider) {
344 QPlaceManager *placeManager = serviceProvider->placeManager();
345 if (placeManager) {
346 if (placeManager->childCategoryIds().isEmpty()) {
347 QPlaceReply *reply = placeManager->initializeCategories();
348 connect(sender: reply, SIGNAL(finished()), receiver: reply, SLOT(deleteLater()));
349 }
350 }
351 }
352 }
353
354 endResetModel();
355}
356
357void QDeclarativeSearchModelBase::onContentUpdated()
358{
359
360}
361
362/*!
363 \internal
364*/
365void QDeclarativeSearchModelBase::pluginNameChanged()
366{
367 initializePlugin(plugin: m_plugin);
368}
369
370/*!
371 \internal
372*/
373void QDeclarativeSearchModelBase::setPreviousPageRequest(const QPlaceSearchRequest &previous)
374{
375 if (m_previousPageRequest == previous)
376 return;
377
378 m_previousPageRequest = previous;
379 emit previousPagesAvailableChanged();
380}
381
382void QDeclarativeSearchModelBase::setNextPageRequest(const QPlaceSearchRequest &next)
383{
384 if (m_nextPageRequest == next)
385 return;
386
387 m_nextPageRequest = next;
388 emit nextPagesAvailableChanged();
389}
390
391QT_END_NAMESPACE
392

source code of qtlocation/src/location/declarativeplaces/qdeclarativesearchmodelbase.cpp