summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPaolo Angelelli <paolo.angelelli@qt.io>2018-06-29 14:29:06 +0200
committerPaolo Angelelli <paolo.angelelli@qt.io>2018-07-27 09:23:46 +0000
commitd70ec0045af17458fe29a8ced6aec14820ac8148 (patch)
tree0cc41277fa5d0811ad63c93a37f0f29f03ddfc9f
parent850c0bbba4c4c65df90f26e1e6174ce68b61d73c (diff)
Enable asynchronous incremental updates of QPlaceReply
This patch adds a new signal to QPlaceReply, contentUpdated. This signal can be emitted in subclasses when the provider is capable of notifying partial updates of the content. The typical use case if fetching the data from multiple databases, also locally instead of over network, and incrementally populating the results, as opposed to the current way of operating, that is via previous page / next page, in which case it's the backend who provides the proper query parameters to obtain the previous or the next page. This signal is currently handled only for QPlaceSearchReplies in QDeclarativeSearchResultModel, where such a signal would trigger a layout update. Change-Id: I0aaba5aa9249b61c970d3a309d93fab7fc39d667 Reviewed-by: Alex Blasche <alexander.blasche@qt.io>
-rw-r--r--src/location/declarativeplaces/qdeclarativesearchmodelbase.cpp6
-rw-r--r--src/location/declarativeplaces/qdeclarativesearchmodelbase_p.h1
-rw-r--r--src/location/declarativeplaces/qdeclarativesearchresultmodel.cpp46
-rw-r--r--src/location/declarativeplaces/qdeclarativesearchresultmodel_p.h1
-rw-r--r--src/location/places/qplacereply.cpp13
-rw-r--r--src/location/places/qplacereply.h1
6 files changed, 62 insertions, 6 deletions
diff --git a/src/location/declarativeplaces/qdeclarativesearchmodelbase.cpp b/src/location/declarativeplaces/qdeclarativesearchmodelbase.cpp
index 92e298d3..b9f782cf 100644
--- a/src/location/declarativeplaces/qdeclarativesearchmodelbase.cpp
+++ b/src/location/declarativeplaces/qdeclarativesearchmodelbase.cpp
@@ -216,6 +216,7 @@ void QDeclarativeSearchModelBase::update()
m_reply->setParent(this);
connect(m_reply, SIGNAL(finished()), this, SLOT(queryFinished()));
+ connect(m_reply, SIGNAL(contentUpdated()), this, SLOT(onContentUpdated()));
}
/*!
@@ -333,6 +334,11 @@ void QDeclarativeSearchModelBase::initializePlugin(QDeclarativeGeoServiceProvide
endResetModel();
}
+void QDeclarativeSearchModelBase::onContentUpdated()
+{
+
+}
+
/*!
\internal
*/
diff --git a/src/location/declarativeplaces/qdeclarativesearchmodelbase_p.h b/src/location/declarativeplaces/qdeclarativesearchmodelbase_p.h
index 2bf1aab5..b85137a6 100644
--- a/src/location/declarativeplaces/qdeclarativesearchmodelbase_p.h
+++ b/src/location/declarativeplaces/qdeclarativesearchmodelbase_p.h
@@ -133,6 +133,7 @@ protected:
protected Q_SLOTS:
virtual void queryFinished() = 0;
+ virtual void onContentUpdated();
private Q_SLOTS:
void pluginNameChanged();
diff --git a/src/location/declarativeplaces/qdeclarativesearchresultmodel.cpp b/src/location/declarativeplaces/qdeclarativesearchresultmodel.cpp
index 73e43240..4cfd26dd 100644
--- a/src/location/declarativeplaces/qdeclarativesearchresultmodel.cpp
+++ b/src/location/declarativeplaces/qdeclarativesearchresultmodel.cpp
@@ -746,6 +746,8 @@ void QDeclarativeSearchResultModel::queryFinished()
return;
QPlaceReply *reply = m_reply;
m_reply = 0;
+ reply->deleteLater();
+
if (!m_incremental)
m_pages.clear();
@@ -753,7 +755,6 @@ void QDeclarativeSearchResultModel::queryFinished()
m_resultsBuffer.clear();
updateLayout();
setStatus(Error, reply->errorString());
- reply->deleteLater();
return;
}
@@ -772,8 +773,7 @@ void QDeclarativeSearchResultModel::queryFinished()
setPreviousPageRequest(searchReply->previousPageRequest());
setNextPageRequest(searchReply->nextPageRequest());
- reply->deleteLater();
-
+ // Performing favorite matching only upon finished()
if (!m_favoritesPlugin) {
updateLayout();
setStatus(Ready);
@@ -795,7 +795,6 @@ void QDeclarativeSearchResultModel::queryFinished()
QPlaceMatchRequest request;
if (m_matchParameters.isEmpty()) {
if (!m_plugin) {
- reply->deleteLater();
setStatus(Error, QStringLiteral("Plugin not assigned"));
return;
}
@@ -812,16 +811,51 @@ void QDeclarativeSearchResultModel::queryFinished()
m_resultsBuffer.clear();
m_reply = favoritesManager->matchingPlaces(request);
connect(m_reply, SIGNAL(finished()), this, SLOT(queryFinished()));
+ connect(m_reply, SIGNAL(contentUpdated()), this, SLOT(onContentUpdated()));
}
} else if (reply->type() == QPlaceReply::MatchReply) {
QPlaceMatchReply *matchReply = qobject_cast<QPlaceMatchReply *>(reply);
Q_ASSERT(matchReply);
updateLayout(matchReply->places());
setStatus(Ready);
- reply->deleteLater();
} else {
setStatus(Error, QStringLiteral("Unknown reply type"));
- reply->deleteLater();
+ }
+}
+
+void QDeclarativeSearchResultModel::onContentUpdated()
+{
+ if (!m_reply)
+ return;
+
+ QPlaceReply *reply = m_reply; // not finished, don't delete.
+
+ if (!m_incremental)
+ m_pages.clear();
+
+ if (reply->error() != QPlaceReply::NoError) {
+ m_resultsBuffer.clear();
+ updateLayout();
+ setStatus(Error, reply->errorString());
+ return;
+ }
+
+ if (reply->type() == QPlaceReply::SearchReply) {
+ QPlaceSearchReply *searchReply = qobject_cast<QPlaceSearchReply *>(reply);
+ Q_ASSERT(searchReply);
+
+ const QPlaceSearchRequestPrivate *rpimpl = QPlaceSearchRequestPrivate::get(searchReply->request());
+ if (!rpimpl->related || !m_incremental)
+ m_pages.clear();
+ m_resultsBuffer = searchReply->results();
+ if (!(m_pages.contains(rpimpl->page) && m_resultsBuffer == m_pages.value(rpimpl->page))) {
+ m_pages.insert(rpimpl->page, m_resultsBuffer);
+ updateLayout();
+ }
+ } else if (reply->type() == QPlaceReply::MatchReply) {
+ // ToDo: handle incremental match replies
+ } else {
+ setStatus(Error, QStringLiteral("Unknown reply type"));
}
}
diff --git a/src/location/declarativeplaces/qdeclarativesearchresultmodel_p.h b/src/location/declarativeplaces/qdeclarativesearchresultmodel_p.h
index 5892753f..40c2e47c 100644
--- a/src/location/declarativeplaces/qdeclarativesearchresultmodel_p.h
+++ b/src/location/declarativeplaces/qdeclarativesearchresultmodel_p.h
@@ -147,6 +147,7 @@ protected:
protected Q_SLOTS:
virtual void queryFinished() override;
+ virtual void onContentUpdated() override;
private Q_SLOTS:
void updateLayout(const QList<QPlace> &favoritePlaces = QList<QPlace>());
diff --git a/src/location/places/qplacereply.cpp b/src/location/places/qplacereply.cpp
index 55e67e43..29f1fb84 100644
--- a/src/location/places/qplacereply.cpp
+++ b/src/location/places/qplacereply.cpp
@@ -229,6 +229,19 @@ void QPlaceReply::abort()
*/
/*!
+ \fn void QPlaceReply::contentUpdated()
+
+ This signal is emitted when this reply has updated content available.
+ Depending on the plugin, this signal may never be emitted or emitted
+ multiple times before \l QPlaceReply::finished() is emitted, as some
+ backends are able to return the requested content asynchronously and
+ incrementally.
+
+ \note Do not delete or deleteLater this reply object in the slot
+ connected to this signal. Do it only upon \l QPlaceReply::finished.
+*/
+
+/*!
\fn void QPlaceReply::error(QPlaceReply::Error error, const QString &errorString)
This signal is emitted when an error has been detected in the processing of
diff --git a/src/location/places/qplacereply.h b/src/location/places/qplacereply.h
index 8fd34643..8e84f113 100644
--- a/src/location/places/qplacereply.h
+++ b/src/location/places/qplacereply.h
@@ -86,6 +86,7 @@ public Q_SLOTS:
Q_SIGNALS:
void finished();
+ void contentUpdated();
void aborted();
void error(QPlaceReply::Error error, const QString &errorString = QString());