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
52 QT_BEGIN_NAMESPACE
53
QDeclarativeSearchModelBase(QObject * parent)54 QDeclarativeSearchModelBase::QDeclarativeSearchModelBase(QObject *parent)
55 : QAbstractListModel(parent), m_plugin(0), m_reply(0), m_complete(false), m_status(Null)
56 {
57 }
58
~QDeclarativeSearchModelBase()59 QDeclarativeSearchModelBase::~QDeclarativeSearchModelBase()
60 {
61 }
62
63 /*!
64 \internal
65 */
plugin() const66 QDeclarativeGeoServiceProvider *QDeclarativeSearchModelBase::plugin() const
67 {
68 return m_plugin;
69 }
70
71 /*!
72 \internal
73 */
setPlugin(QDeclarativeGeoServiceProvider * plugin)74 void 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 */
searchArea() const88 QVariant QDeclarativeSearchModelBase::searchArea() const
89 {
90 QGeoShape s = m_request.searchArea();
91 if (s.type() == QGeoShape::RectangleType)
92 return QVariant::fromValue(QGeoRectangle(s));
93 else if (s.type() == QGeoShape::CircleType)
94 return QVariant::fromValue(QGeoCircle(s));
95 else if (s.type() == QGeoShape::PolygonType)
96 return QVariant::fromValue(QGeoPolygon(s));
97 else
98 return QVariant::fromValue(s);
99 }
100
101 /*!
102 \internal
103 */
setSearchArea(const QVariant & searchArea)104 void 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(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 */
limit() const143 int QDeclarativeSearchModelBase::limit() const
144 {
145 return m_request.limit();
146 }
147
148 /*!
149 \internal
150 */
setLimit(int limit)151 void 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 */
previousPagesAvailable() const163 bool QDeclarativeSearchModelBase::previousPagesAvailable() const
164 {
165 return m_previousPageRequest != QPlaceSearchRequest();
166 }
167
168 /*!
169 \internal
170 */
nextPagesAvailable() const171 bool QDeclarativeSearchModelBase::nextPagesAvailable() const
172 {
173 return m_nextPageRequest != QPlaceSearchRequest();
174 }
175
176 /*!
177 \internal
178 */
status() const179 QDeclarativeSearchModelBase::Status QDeclarativeSearchModelBase::status() const
180 {
181 return m_status;
182 }
183
184 /*!
185 \internal
186 */
setStatus(Status status,const QString & errorString)187 void 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 */
update()201 void QDeclarativeSearchModelBase::update()
202 {
203 if (m_reply)
204 return;
205
206 setStatus(Loading);
207
208 if (!m_plugin) {
209 clearData();
210 setStatus(Error, QCoreApplication::translate(CONTEXT_NAME, PLUGIN_PROPERTY_NOT_SET));
211 return;
212 }
213
214 QGeoServiceProvider *serviceProvider = m_plugin->sharedGeoServiceProvider();
215 if (!serviceProvider) {
216 clearData();
217 setStatus(Error, QCoreApplication::translate(CONTEXT_NAME, PLUGIN_PROVIDER_ERROR)
218 .arg(m_plugin->name()));
219 return;
220 }
221
222 QPlaceManager *placeManager = serviceProvider->placeManager();
223 if (!placeManager) {
224 clearData();
225 setStatus(Error, QCoreApplication::translate(CONTEXT_NAME, PLUGIN_ERROR)
226 .arg(m_plugin->name()).arg(serviceProvider->errorString()));
227 return;
228 }
229
230 m_reply = sendQuery(placeManager, m_request);
231 if (!m_reply) {
232 clearData();
233 setStatus(Error, QCoreApplication::translate(CONTEXT_NAME, UNABLE_TO_MAKE_REQUEST));
234 return;
235 }
236
237 m_reply->setParent(this);
238 connect(m_reply, SIGNAL(finished()), this, SLOT(queryFinished()));
239 connect(m_reply, SIGNAL(contentUpdated()), this, SLOT(onContentUpdated()));
240 }
241
242 /*!
243 \internal
244 */
cancel()245 void 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(Ready);
259 }
260
261 /*!
262 \internal
263 */
reset()264 void QDeclarativeSearchModelBase::reset()
265 {
266 beginResetModel();
267 clearData();
268 setStatus(Null);
269 endResetModel();
270 }
271
272 /*!
273 \internal
274 */
errorString() const275 QString QDeclarativeSearchModelBase::errorString() const
276 {
277 return m_errorString;
278 }
279
280 /*!
281 \internal
282 */
previousPage()283 void QDeclarativeSearchModelBase::previousPage()
284 {
285 if (m_previousPageRequest == QPlaceSearchRequest())
286 return;
287
288 m_request = m_previousPageRequest;
289 update();
290 }
291
292 /*!
293 \internal
294 */
nextPage()295 void QDeclarativeSearchModelBase::nextPage()
296 {
297 if (m_nextPageRequest == QPlaceSearchRequest())
298 return;
299
300 m_request = m_nextPageRequest;
301 update();
302 }
303
304 /*!
305 \internal
306 */
clearData(bool suppressSignal)307 void QDeclarativeSearchModelBase::clearData(bool suppressSignal)
308 {
309 Q_UNUSED(suppressSignal);
310 }
311
312 /*!
313 \internal
314 */
classBegin()315 void QDeclarativeSearchModelBase::classBegin()
316 {
317 }
318
319 /*!
320 \internal
321 */
componentComplete()322 void QDeclarativeSearchModelBase::componentComplete()
323 {
324 m_complete = true;
325 }
326
327 /*!
328 \internal
329 */
initializePlugin(QDeclarativeGeoServiceProvider * plugin)330 void QDeclarativeSearchModelBase::initializePlugin(QDeclarativeGeoServiceProvider *plugin)
331 {
332 beginResetModel();
333 if (plugin != m_plugin) {
334 if (m_plugin)
335 disconnect(m_plugin, SIGNAL(nameChanged(QString)), this, SLOT(pluginNameChanged()));
336 if (plugin)
337 connect(plugin, SIGNAL(nameChanged(QString)), 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(reply, SIGNAL(finished()), reply, SLOT(deleteLater()));
349 }
350 }
351 }
352 }
353
354 endResetModel();
355 }
356
onContentUpdated()357 void QDeclarativeSearchModelBase::onContentUpdated()
358 {
359
360 }
361
362 /*!
363 \internal
364 */
pluginNameChanged()365 void QDeclarativeSearchModelBase::pluginNameChanged()
366 {
367 initializePlugin(m_plugin);
368 }
369
370 /*!
371 \internal
372 */
setPreviousPageRequest(const QPlaceSearchRequest & previous)373 void QDeclarativeSearchModelBase::setPreviousPageRequest(const QPlaceSearchRequest &previous)
374 {
375 if (m_previousPageRequest == previous)
376 return;
377
378 m_previousPageRequest = previous;
379 emit previousPagesAvailableChanged();
380 }
381
setNextPageRequest(const QPlaceSearchRequest & next)382 void QDeclarativeSearchModelBase::setNextPageRequest(const QPlaceSearchRequest &next)
383 {
384 if (m_nextPageRequest == next)
385 return;
386
387 m_nextPageRequest = next;
388 emit nextPagesAvailableChanged();
389 }
390
391 QT_END_NAMESPACE
392