9#include <QtQml/QQmlInfo>
10#include <QtLocation/QGeoServiceProvider>
11#include <QtLocation/QPlaceManager>
12#include <QtLocation/QPlaceContentRequest>
13#include <QtLocation/QPlaceUser>
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
119
120
121
122
125
126
127
128
131
132
133
134
137
138
139
140
141
142
143
144
145
146
149
150
151
152
153
154
155
156
157
158
160QDeclarativePlaceContentModel::QDeclarativePlaceContentModel(QPlaceContent::Type type,
162 : QAbstractListModel(parent), m_type(type)
166QDeclarativePlaceContentModel::~QDeclarativePlaceContentModel()
171
172
173QDeclarativePlace *QDeclarativePlaceContentModel::place()
const
179
180
181void QDeclarativePlaceContentModel::setPlace(QDeclarativePlace *place)
183 if (m_place != place) {
186 int initialCount = m_contentCount;
192 if (initialCount != -1)
193 emit totalCountChanged();
195 fetchMore(QModelIndex());
200
201
202int QDeclarativePlaceContentModel::batchSize()
const
208
209
210void QDeclarativePlaceContentModel::setBatchSize(
int batchSize)
212 if (m_batchSize != batchSize) {
213 m_batchSize = batchSize;
214 emit batchSizeChanged();
219
220
221int QDeclarativePlaceContentModel::totalCount()
const
223 return m_contentCount;
227
228
229
230void QDeclarativePlaceContentModel::clearData()
240 m_reply->deleteLater();
244 m_nextRequest.clear();
248
249
250void QDeclarativePlaceContentModel::initializeCollection(
int totalCount,
const QPlaceContent::Collection &collection)
254 int initialCount = m_contentCount;
257 for (
auto i = collection.cbegin(), end = collection.cend(); i != end; ++i) {
258 const QPlaceContent &content = i.value();
259 if (content.type() != m_type)
262 m_content.insert(i.key(), content);
263 const auto supplier = content.value(QPlaceContent::ContentSupplier)
264 .value<QPlaceSupplier>();
265 if (!m_suppliers.contains(supplier.supplierId()))
266 m_suppliers.insert(supplier.supplierId(), supplier);
267 const auto user = content.value(QPlaceContent::ContentUser)
268 .value<QPlaceUser>();
269 if (!m_users.contains(user.userId()))
270 m_users.insert(user.userId(), user);
273 m_contentCount = totalCount;
275 if (initialCount != totalCount)
276 emit totalCountChanged();
282
283
284int QDeclarativePlaceContentModel::rowCount(
const QModelIndex &parent)
const
286 if (parent.isValid())
289 return m_content.count();
293
294
295QVariant QDeclarativePlaceContentModel::data(
const QModelIndex &index,
int role)
const
297 if (!index.isValid())
300 if (index.row() >= rowCount(index.parent()) || index.row() < 0)
303 const QPlaceContent &content = m_content.value(index.row());
304 if (content.type() != m_type)
308 case ContentSupplierRole:
309 return QVariant::fromValue(m_suppliers.value(content.value(QPlaceContent::ContentSupplier)
310 .value<QPlaceSupplier>().supplierId()));
311 case ContentUserRole:
312 return QVariant::fromValue(m_users.value(content.value(QPlaceContent::ContentUser)
313 .value<QPlaceUser>().userId()));
314 case ContentAttributionRole:
315 return content.value(QPlaceContent::ContentAttribution);
317 return content.value(QPlaceContent::ImageUrl);
319 return content.value(QPlaceContent::ImageId);
320 case ImageMimeTypeRole:
321 return content.value(QPlaceContent::ImageMimeType);
323 case EditorialTextRole:
324 return content.value(QPlaceContent::EditorialText);
325 case EditorialTitleRole:
326 return content.value(QPlaceContent::EditorialTitle);
327 case EditorialLanguageRole:
328 return content.value(QPlaceContent::EditorialLanguage);
330 case ReviewDateTimeRole:
331 return content.value(QPlaceContent::ReviewDateTime);
333 return content.value(QPlaceContent::ReviewText);
334 case ReviewLanguageRole:
335 return content.value(QPlaceContent::ReviewLanguage);
336 case ReviewRatingRole:
337 return content.value(QPlaceContent::ReviewRating);
339 return content.value(QPlaceContent::ReviewId);
340 case ReviewTitleRole:
341 return content.value(QPlaceContent::ReviewTitle);
347QHash<
int, QByteArray> QDeclarativePlaceContentModel::roleNames()
const
349 QHash<
int, QByteArray> roles = QAbstractListModel::roleNames();
350 roles.insert(ContentSupplierRole,
"supplier");
351 roles.insert(ContentUserRole,
"user");
352 roles.insert(ContentAttributionRole,
"attribution");
355 case QPlaceContent::EditorialType:
356 roles.insert(EditorialTextRole,
"text");
357 roles.insert(EditorialTitleRole,
"title");
358 roles.insert(EditorialLanguageRole,
"language");
360 case QPlaceContent::ImageType:
361 roles.insert(ImageUrlRole,
"url");
362 roles.insert(ImageIdRole,
"imageId");
363 roles.insert(ImageMimeTypeRole,
"mimeType");
365 case QPlaceContent::ReviewType:
366 roles.insert(ReviewDateTimeRole,
"dateTime");
367 roles.insert(ReviewTextRole,
"text");
368 roles.insert(ReviewLanguageRole,
"language");
369 roles.insert(ReviewRatingRole,
"rating");
370 roles.insert(ReviewIdRole,
"reviewId");
371 roles.insert(ReviewTitleRole,
"title");
380
381
382bool QDeclarativePlaceContentModel::canFetchMore(
const QModelIndex &parent)
const
384 if (parent.isValid())
390 if (m_contentCount == -1)
393 return m_content.count() != m_contentCount;
397
398
399void QDeclarativePlaceContentModel::fetchMore(
const QModelIndex &parent)
401 if (parent.isValid())
410 if (!m_place->plugin())
413 QDeclarativeGeoServiceProvider *plugin = m_place->plugin();
415 QGeoServiceProvider *serviceProvider = plugin->sharedGeoServiceProvider();
416 if (!serviceProvider)
419 QPlaceManager *placeManager = serviceProvider->placeManager();
423 if (m_nextRequest == QPlaceContentRequest()) {
424 QPlaceContentRequest request;
425 request.setContentType(m_type);
426 request.setPlaceId(m_place->place().placeId());
427 request.setLimit(m_batchSize);
429 m_reply = placeManager->getPlaceContent(request);
431 m_reply = placeManager->getPlaceContent(m_nextRequest);
434 connect(m_reply, &QPlaceReply::finished,
435 this, &QDeclarativePlaceContentModel::fetchFinished, Qt::QueuedConnection);
439
440
441void QDeclarativePlaceContentModel::classBegin()
446
447
448void QDeclarativePlaceContentModel::componentComplete()
451 fetchMore(QModelIndex());
455
456
457void QDeclarativePlaceContentModel::fetchFinished()
462 QPlaceContentReply *reply = m_reply;
465 m_nextRequest = reply->nextPageRequest();
467 if (m_contentCount != reply->totalCount()) {
468 m_contentCount = reply->totalCount();
469 emit totalCountChanged();
472 if (!reply->content().isEmpty()) {
473 QPlaceContent::Collection contents = reply->content();
476 QList<
int> changedIndexes;
477 QList<
int> newIndexes;
478 for (
auto it = contents.cbegin(), end = contents.cend(); it != end; ++it) {
479 if (!m_content.contains(it.key()))
480 newIndexes.append(it.key());
481 else if (it.value() != m_content.value(it.key()))
482 changedIndexes.append(it.key());
488 for (
auto it = newIndexes.cbegin(), end = newIndexes.cend(); it != end; ++it) {
489 int currentIndex = *it;
490 if (startIndex == -1)
491 startIndex = currentIndex;
493 auto next = std::next(it);
494 if (next == end || *next > (currentIndex + 1)) {
495 beginInsertRows(QModelIndex(),startIndex,currentIndex);
496 for (
int i = startIndex; i <= currentIndex; ++i) {
497 const QPlaceContent &content = contents.value(i);
499 m_content.insert(i, content);
500 const auto supplier = content.value(QPlaceContent::ContentSupplier)
501 .value<QPlaceSupplier>();
502 if (!m_suppliers.contains(supplier.supplierId()))
503 m_suppliers.insert(supplier.supplierId(), supplier);
504 const auto user = content.value(QPlaceContent::ContentUser)
505 .value<QPlaceUser>();
506 if (!m_users.contains(user.userId()))
507 m_users.insert(user.userId(), user);
517 for (
auto it = changedIndexes.cbegin(), end = changedIndexes.cend(); it != end; ++it) {
518 int currentIndex = *it;
519 if (startIndex == -1)
520 startIndex = currentIndex;
522 auto next = std::next(it);
523 if (next == end || *next > (currentIndex + 1)) {
524 for (
int i = startIndex; i <= currentIndex; ++i) {
525 const QPlaceContent &content = contents.value(i);
526 m_content.insert(i, content);
527 const auto supplier = content.value(QPlaceContent::ContentSupplier)
528 .value<QPlaceSupplier>();
529 if (!m_suppliers.contains(supplier.supplierId()))
530 m_suppliers.insert(supplier.supplierId(), supplier);
531 const auto user = content.value(QPlaceContent::ContentUser)
532 .value<QPlaceUser>();
533 if (!m_users.contains(user.userId()))
534 m_users.insert(user.userId(), user);
536 emit dataChanged(index(startIndex),index(currentIndex));
544 if (newIndexes.isEmpty() && m_content.count() != m_contentCount)
545 fetchMore(QModelIndex());
548 reply->deleteLater();