10#include <QtQml/QQmlInfo>
11#include <QtLocation/QGeoServiceProvider>
12#include <QtLocation/QPlaceManager>
13#include <QtLocation/QPlaceContentRequest>
14#include <QtLocation/QPlaceUser>
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
120
121
122
123
126
127
128
129
132
133
134
135
138
139
140
141
142
143
144
145
146
147
150
151
152
153
154
155
156
157
158
159
161QDeclarativePlaceContentModel::QDeclarativePlaceContentModel(QPlaceContent::Type type,
163 : QAbstractListModel(parent), m_type(type)
167QDeclarativePlaceContentModel::~QDeclarativePlaceContentModel()
172
173
174QDeclarativePlace *QDeclarativePlaceContentModel::place()
const
180
181
182void QDeclarativePlaceContentModel::setPlace(QDeclarativePlace *place)
184 if (m_place != place) {
187 int initialCount = m_contentCount;
193 if (initialCount != -1)
194 emit totalCountChanged();
196 fetchMore(QModelIndex());
201
202
203int QDeclarativePlaceContentModel::batchSize()
const
209
210
211void QDeclarativePlaceContentModel::setBatchSize(
int batchSize)
213 if (m_batchSize != batchSize) {
214 m_batchSize = batchSize;
215 emit batchSizeChanged();
220
221
222int QDeclarativePlaceContentModel::totalCount()
const
224 return m_contentCount;
228
229
230
231void QDeclarativePlaceContentModel::clearData()
241 m_reply->deleteLater();
245 m_nextRequest.clear();
249
250
251void QDeclarativePlaceContentModel::initializeCollection(
int totalCount,
const QPlaceContent::Collection &collection)
255 int initialCount = m_contentCount;
258 for (
auto i = collection.cbegin(), end = collection.cend(); i != end; ++i) {
259 const QPlaceContent &content = i.value();
260 if (content.type() != m_type)
263 m_content.insert(i.key(), content);
264 const auto supplier = content.value(QPlaceContent::ContentSupplier)
265 .value<QPlaceSupplier>();
266 if (!m_suppliers.contains(supplier.supplierId()))
267 m_suppliers.insert(supplier.supplierId(), supplier);
268 const auto user = content.value(QPlaceContent::ContentUser)
269 .value<QPlaceUser>();
270 if (!m_users.contains(user.userId()))
271 m_users.insert(user.userId(), user);
274 m_contentCount = totalCount;
276 if (initialCount != totalCount)
277 emit totalCountChanged();
283
284
285int QDeclarativePlaceContentModel::rowCount(
const QModelIndex &parent)
const
287 if (parent.isValid())
290 return m_content.count();
294
295
296QVariant QDeclarativePlaceContentModel::data(
const QModelIndex &index,
int role)
const
298 if (!index.isValid())
301 if (index.row() >= rowCount(index.parent()) || index.row() < 0)
304 const QPlaceContent &content = m_content.value(index.row());
305 if (content.type() != m_type)
309 case ContentSupplierRole:
310 return QVariant::fromValue(m_suppliers.value(content.value(QPlaceContent::ContentSupplier)
311 .value<QPlaceSupplier>().supplierId()));
312 case ContentUserRole:
313 return QVariant::fromValue(m_users.value(content.value(QPlaceContent::ContentUser)
314 .value<QPlaceUser>().userId()));
315 case ContentAttributionRole:
316 return content.value(QPlaceContent::ContentAttribution);
318 return content.value(QPlaceContent::ImageUrl);
320 return content.value(QPlaceContent::ImageId);
321 case ImageMimeTypeRole:
322 return content.value(QPlaceContent::ImageMimeType);
324 case EditorialTextRole:
325 return content.value(QPlaceContent::EditorialText);
326 case EditorialTitleRole:
327 return content.value(QPlaceContent::EditorialTitle);
328 case EditorialLanguageRole:
329 return content.value(QPlaceContent::EditorialLanguage);
331 case ReviewDateTimeRole:
332 return content.value(QPlaceContent::ReviewDateTime);
334 return content.value(QPlaceContent::ReviewText);
335 case ReviewLanguageRole:
336 return content.value(QPlaceContent::ReviewLanguage);
337 case ReviewRatingRole:
338 return content.value(QPlaceContent::ReviewRating);
340 return content.value(QPlaceContent::ReviewId);
341 case ReviewTitleRole:
342 return content.value(QPlaceContent::ReviewTitle);
348QHash<
int, QByteArray> QDeclarativePlaceContentModel::roleNames()
const
350 QHash<
int, QByteArray> roles = QAbstractListModel::roleNames();
351 roles.insert(ContentSupplierRole,
"supplier");
352 roles.insert(ContentUserRole,
"user");
353 roles.insert(ContentAttributionRole,
"attribution");
356 case QPlaceContent::EditorialType:
357 roles.insert(EditorialTextRole,
"text");
358 roles.insert(EditorialTitleRole,
"title");
359 roles.insert(EditorialLanguageRole,
"language");
361 case QPlaceContent::ImageType:
362 roles.insert(ImageUrlRole,
"url");
363 roles.insert(ImageIdRole,
"imageId");
364 roles.insert(ImageMimeTypeRole,
"mimeType");
366 case QPlaceContent::ReviewType:
367 roles.insert(ReviewDateTimeRole,
"dateTime");
368 roles.insert(ReviewTextRole,
"text");
369 roles.insert(ReviewLanguageRole,
"language");
370 roles.insert(ReviewRatingRole,
"rating");
371 roles.insert(ReviewIdRole,
"reviewId");
372 roles.insert(ReviewTitleRole,
"title");
381
382
383bool QDeclarativePlaceContentModel::canFetchMore(
const QModelIndex &parent)
const
385 if (parent.isValid())
391 if (m_contentCount == -1)
394 return m_content.count() != m_contentCount;
398
399
400void QDeclarativePlaceContentModel::fetchMore(
const QModelIndex &parent)
402 if (parent.isValid())
411 if (!m_place->plugin())
414 QDeclarativeGeoServiceProvider *plugin = m_place->plugin();
416 QGeoServiceProvider *serviceProvider = plugin->sharedGeoServiceProvider();
417 if (!serviceProvider)
420 QPlaceManager *placeManager = serviceProvider->placeManager();
424 if (m_nextRequest == QPlaceContentRequest()) {
425 QPlaceContentRequest request;
426 request.setContentType(m_type);
427 request.setPlaceId(m_place->place().placeId());
428 request.setLimit(m_batchSize);
430 m_reply = placeManager->getPlaceContent(request);
432 m_reply = placeManager->getPlaceContent(m_nextRequest);
435 connect(m_reply, &QPlaceReply::finished,
436 this, &QDeclarativePlaceContentModel::fetchFinished, Qt::QueuedConnection);
440
441
442void QDeclarativePlaceContentModel::classBegin()
447
448
449void QDeclarativePlaceContentModel::componentComplete()
452 fetchMore(QModelIndex());
456
457
458void QDeclarativePlaceContentModel::fetchFinished()
463 QPlaceContentReply *reply = m_reply;
466 m_nextRequest = reply->nextPageRequest();
468 if (m_contentCount != reply->totalCount()) {
469 m_contentCount = reply->totalCount();
470 emit totalCountChanged();
473 if (!reply->content().isEmpty()) {
474 QPlaceContent::Collection contents = reply->content();
477 QList<
int> changedIndexes;
478 QList<
int> newIndexes;
479 for (
auto it = contents.cbegin(), end = contents.cend(); it != end; ++it) {
480 if (!m_content.contains(it.key()))
481 newIndexes.append(it.key());
482 else if (it.value() != m_content.value(it.key()))
483 changedIndexes.append(it.key());
489 for (
auto it = newIndexes.cbegin(), end = newIndexes.cend(); it != end; ++it) {
490 int currentIndex = *it;
491 if (startIndex == -1)
492 startIndex = currentIndex;
494 auto next = std::next(it);
495 if (next == end || *next > (currentIndex + 1)) {
496 beginInsertRows(QModelIndex(),startIndex,currentIndex);
497 for (
int i = startIndex; i <= currentIndex; ++i) {
498 const QPlaceContent &content = contents.value(i);
500 m_content.insert(i, content);
501 const auto supplier = content.value(QPlaceContent::ContentSupplier)
502 .value<QPlaceSupplier>();
503 if (!m_suppliers.contains(supplier.supplierId()))
504 m_suppliers.insert(supplier.supplierId(), supplier);
505 const auto user = content.value(QPlaceContent::ContentUser)
506 .value<QPlaceUser>();
507 if (!m_users.contains(user.userId()))
508 m_users.insert(user.userId(), user);
518 for (
auto it = changedIndexes.cbegin(), end = changedIndexes.cend(); it != end; ++it) {
519 int currentIndex = *it;
520 if (startIndex == -1)
521 startIndex = currentIndex;
523 auto next = std::next(it);
524 if (next == end || *next > (currentIndex + 1)) {
525 for (
int i = startIndex; i <= currentIndex; ++i) {
526 const QPlaceContent &content = contents.value(i);
527 m_content.insert(i, content);
528 const auto supplier = content.value(QPlaceContent::ContentSupplier)
529 .value<QPlaceSupplier>();
530 if (!m_suppliers.contains(supplier.supplierId()))
531 m_suppliers.insert(supplier.supplierId(), supplier);
532 const auto user = content.value(QPlaceContent::ContentUser)
533 .value<QPlaceUser>();
534 if (!m_users.contains(user.userId()))
535 m_users.insert(user.userId(), user);
537 emit dataChanged(index(startIndex),index(currentIndex));
545 if (newIndexes.isEmpty() && m_content.count() != m_contentCount)
546 fetchMore(QModelIndex());
549 reply->deleteLater();
Combined button and popup list for selecting options.