summaryrefslogtreecommitdiffstats
path: root/src/imports/location/declarativeplaces/qdeclarativereviewmodel.cpp
diff options
context:
space:
mode:
authorAaron McCarthy <aaron.mccarthy@nokia.com>2011-07-04 12:48:39 +1000
committerAaron McCarthy <aaron.mccarthy@nokia.com>2011-07-26 08:16:45 +0200
commit649b10751ec752725ca7c1d4ca9979fcf9a233c1 (patch)
tree3acfdd8228779109d1c2195a9e1e7ccce5b75599 /src/imports/location/declarativeplaces/qdeclarativereviewmodel.cpp
parentfc891cec2a8d3c7ffcbe7ee5b8dfaa0908121cd9 (diff)
Add ReviewModel element.
Use a data model for fetching and handling place reviews. Change-Id: I066d97bd8c4b7897c2a471da346f135ea69524c3 Reviewed-on: http://codereview.qt.nokia.com/2012 Reviewed-by: Qt Sanity Bot <qt_sanity_bot@ovi.com> Reviewed-by: Aaron McCarthy <aaron.mccarthy@nokia.com>
Diffstat (limited to 'src/imports/location/declarativeplaces/qdeclarativereviewmodel.cpp')
-rw-r--r--src/imports/location/declarativeplaces/qdeclarativereviewmodel.cpp219
1 files changed, 219 insertions, 0 deletions
diff --git a/src/imports/location/declarativeplaces/qdeclarativereviewmodel.cpp b/src/imports/location/declarativeplaces/qdeclarativereviewmodel.cpp
new file mode 100644
index 00000000..6364a4c6
--- /dev/null
+++ b/src/imports/location/declarativeplaces/qdeclarativereviewmodel.cpp
@@ -0,0 +1,219 @@
+#include "qdeclarativereviewmodel_p.h"
+#include <qdeclarativeplace_p.h>
+
+QT_USE_NAMESPACE
+
+/*!
+ \qmlclass ReviewModel QDeclarativeReviewModel
+
+ \brief The ReviewModel element provides access to reviews of a Place.
+ \ingroup qml-places
+ \since 5.0
+
+ The ReviewModel is a read-only model used to fetch reviews about a Place. The model
+ incrementally fetches reviews. The number of reviews which are fetched at a time is specified
+ by the batchSize property. The total number of reviews available can be accessed via the
+ totalCount property and the number of fetched reviews via the count property.
+
+ The model provides a single data role, the "review" role, which returns a Review object.
+*/
+
+QDeclarativeReviewModel::QDeclarativeReviewModel(QObject* parent)
+: QAbstractListModel(parent), m_place(0), m_batchSize(1), m_reviewCount(-1),
+ m_manager(new QPlaceManager(this)), m_reply(0)
+{
+ QHash<int, QByteArray> roleNames;
+ roleNames.insert(ReviewRole, "review");
+ setRoleNames(roleNames);
+}
+
+QDeclarativeReviewModel::~QDeclarativeReviewModel()
+{
+ qDeleteAll(m_reviews);
+}
+
+/*!
+ \qmlproperty Place ReviewModel::place
+
+ This property holds the Place that the reviews are for.
+*/
+QDeclarativePlace *QDeclarativeReviewModel::place() const
+{
+ return m_place;
+}
+
+void QDeclarativeReviewModel::setPlace(QDeclarativePlace *place)
+{
+ if (m_place != place) {
+ beginResetModel();
+ if (m_reply) {
+ m_reply->abort();
+ m_reply->deleteLater();
+ m_reply = 0;
+ }
+ qDeleteAll(m_reviews);
+ endResetModel();
+
+ m_reviewCount = -1;
+ emit totalCountChanged();
+
+ m_place = place;
+ emit placeChanged();
+
+ fetchMore(QModelIndex());
+ }
+}
+
+/*!
+ \qmlproperty int ReviewModel::batchSize
+
+ This property holds the batch size to use when fetching more reviews.
+*/
+int QDeclarativeReviewModel::batchSize() const
+{
+ return m_batchSize;
+}
+
+void QDeclarativeReviewModel::setBatchSize(int batchSize)
+{
+ if (m_batchSize != batchSize) {
+ m_batchSize = batchSize;
+ emit batchSizeChanged();
+ }
+}
+
+/*!
+ \qmlproperty int ReviewModel::totalCount
+
+ This property holds the total number of reviews for the place.
+*/
+int QDeclarativeReviewModel::totalCount() const
+{
+ return m_reviewCount;
+}
+
+static QPair<int, int> findMissingKey(const QMap<int, QDeclarativeReview *> &map)
+{
+ int start = 0;
+ while (map.value(start, 0) != 0)
+ ++start;
+
+ QMap<int, QDeclarativeReview *>::const_iterator it = map.lowerBound(start);
+ if (it == map.end())
+ return qMakePair(start, -1);
+
+ int end = start;
+ while (map.value(end, 0) == 0)
+ ++end;
+
+ return qMakePair(start, end - 1);
+}
+
+bool QDeclarativeReviewModel::canFetchMore(const QModelIndex &parent) const
+{
+ if (parent.isValid())
+ return false;
+
+ if (!m_place)
+ return false;
+
+ if (m_reviewCount == -1)
+ return true;
+
+ return m_reviews.count() != m_reviewCount;
+}
+
+void QDeclarativeReviewModel::fetchMore(const QModelIndex &parent)
+{
+ if (parent.isValid())
+ return;
+
+ if (!m_place)
+ return;
+
+ if (m_reply)
+ return;
+
+ QPlaceQuery query;
+
+ if (m_reviewCount == -1) {
+ query.setOffset(0);
+ query.setLimit(m_batchSize);
+ } else {
+ QPair<int, int> missing = findMissingKey(m_reviews);
+ query.setOffset(missing.first);
+ if (missing.second == -1)
+ query.setLimit(m_batchSize);
+ else
+ query.setLimit(qMin(m_batchSize, missing.second - missing.first + 1));
+ }
+
+ m_reply = m_manager->getReviews(m_place->place(), query);
+ connect(m_reply, SIGNAL(finished()), this, SLOT(fetchFinished()), Qt::QueuedConnection);
+}
+
+void QDeclarativeReviewModel::clear()
+{
+ beginResetModel();
+ m_reviewCount = -1;
+ qDeleteAll(m_reviews);
+ m_reviews.clear();
+ delete m_reply;
+ m_reply = 0;
+ endResetModel();
+}
+
+void QDeclarativeReviewModel::classBegin()
+{
+}
+
+void QDeclarativeReviewModel::componentComplete()
+{
+ fetchMore(QModelIndex());
+}
+
+void QDeclarativeReviewModel::fetchFinished()
+{
+ QPlaceReviewReply *reply = m_reply;
+ m_reply = 0;
+
+ if (m_reviewCount != reply->totalCount()) {
+ m_reviewCount = reply->totalCount();
+ emit totalCountChanged();
+ }
+
+ if (reply->reviews().items() > 0) {
+ int startIndex = reply->reviews().start();
+
+ QList<QPlaceReview> reviews = reply->reviews().data();
+
+ beginInsertRows(QModelIndex(), startIndex, startIndex + reviews.length() - 1);
+ for (int i = 0; i < reviews.length(); ++i)
+ m_reviews.insert(startIndex + i, new QDeclarativeReview(reviews.at(i), this));
+ endInsertRows();
+ }
+
+ reply->deleteLater();
+}
+
+int QDeclarativeReviewModel::rowCount(const QModelIndex &parent) const
+{
+ if (parent.isValid())
+ return 0;
+
+ return m_reviews.count();
+}
+
+QVariant QDeclarativeReviewModel::data(const QModelIndex &index, int role) const
+{
+ if (!index.isValid())
+ return QVariant();
+
+ if (index.row() >= rowCount(index.parent()) || index.row() < 0)
+ return QVariant();
+
+ if (role == ReviewRole)
+ return QVariant::fromValue(static_cast<QObject *>(m_reviews.value(index.row())));
+
+ return QVariant();
+}