Qt
Internal/Contributor docs for the Qt SDK. <b>Note:</b> These are NOT official API docs; those are found <a href='https://doc.qt.io/'>here</a>.
Loading...
Searching...
No Matches
qdeclarativesearchresultmodel.cpp
Go to the documentation of this file.
1// Copyright (C) 2022 The Qt Company Ltd.
2// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
3
6
7#include <QtQml/QQmlEngine>
8#include <QtQml/QQmlInfo>
9#include <QtLocation/QGeoServiceProvider>
10#include <QtLocation/QPlaceSearchReply>
11#include <QtLocation/QPlaceManager>
12#include <QtLocation/QPlaceMatchRequest>
13#include <QtLocation/QPlaceMatchReply>
14#include <QtLocation/QPlaceResult>
15#include <QtLocation/QPlaceProposedSearchResult>
16#include <QtLocation/private/qplacesearchrequest_p.h>
17
19
325
329
339
350
357QQmlListProperty<QDeclarativeCategory> QDeclarativeSearchResultModel::categories()
358{
359 return QQmlListProperty<QDeclarativeCategory>(this,
360 0, // opaque data parameter
365}
366
367void QDeclarativeSearchResultModel::categories_append(QQmlListProperty<QDeclarativeCategory> *list,
368 QDeclarativeCategory *declCategory)
369{
370 QDeclarativeSearchResultModel *searchModel = qobject_cast<QDeclarativeSearchResultModel *>(list->object);
371 if (searchModel && declCategory) {
372 searchModel->m_request.setSearchContext(QVariant());
373 searchModel->m_categories.append(declCategory);
374 QList<QPlaceCategory> categories = searchModel->m_request.categories();
375 categories.append(declCategory->category());
376 searchModel->m_request.setCategories(categories);
377 emit searchModel->categoriesChanged();
378 }
379}
380
381qsizetype QDeclarativeSearchResultModel::categories_count(QQmlListProperty<QDeclarativeCategory> *list)
382{
383 QDeclarativeSearchResultModel *searchModel = qobject_cast<QDeclarativeSearchResultModel *>(list->object);
384 if (searchModel)
385 return searchModel->m_categories.count();
386 else
387 return -1;
388}
389
392{
393 QDeclarativeSearchResultModel *searchModel = qobject_cast<QDeclarativeSearchResultModel *>(list->object);
394 if (searchModel && (searchModel->m_categories.count() > index) && (index > -1))
395 return searchModel->m_categories.at(index);
396 return nullptr;
397}
398
399void QDeclarativeSearchResultModel::categories_clear(QQmlListProperty<QDeclarativeCategory> *list)
400{
401 QDeclarativeSearchResultModel *searchModel = qobject_cast<QDeclarativeSearchResultModel *>(list->object);
402 if (searchModel) {
403 //note: we do not need to delete each of the objects in m_categories since the search model
404 //should never be the parent of the categories anyway.
405 searchModel->m_request.setSearchContext(QVariant());
406 searchModel->m_categories.clear();
407 searchModel->m_request.setCategories(QList<QPlaceCategory>());
408 emit searchModel->categoriesChanged();
409 }
410}
411
422
424{
425 if (m_request.recommendationId() == placeId)
426 return;
427
430}
431
458
466
495
497{
498 QLocation::VisibilityScope scope = QLocation::VisibilityScope(visibilityScope);
499
500 if (m_visibilityScope == scope)
501 return;
502
503 m_visibilityScope = scope;
505}
506
514
519{
520
521 if (m_favoritesPlugin == plugin)
522 return;
523
524 m_favoritesPlugin = plugin;
525
526 if (m_favoritesPlugin) {
527 QGeoServiceProvider *serviceProvider = m_favoritesPlugin->sharedGeoServiceProvider();
528 if (serviceProvider) {
529 QPlaceManager *placeManager = serviceProvider->placeManager();
530 if (placeManager) {
531 if (placeManager->childCategoryIds().isEmpty()) {
532 QPlaceReply *reply = placeManager->initializeCategories();
534 }
535 }
536 }
537 }
538
540}
541
546{
547 return m_matchParameters;
548}
549
554{
555 if (m_matchParameters == parameters)
556 return;
557
558 m_matchParameters = parameters;
560}
561
566{
568
569 return m_results.count();
570}
571
573{
575
576 qDeleteAll(m_places);
577 m_places.clear();
578 m_icons.clear();
579 if (!m_results.isEmpty()) {
580 m_results.clear();
581
582 if (!suppressSignal)
584 }
585}
586
588{
589 if (index.row() > m_results.count())
590 return QVariant();
591
592 const QPlaceSearchResult &result = m_results.at(index.row());
593
594 switch (role) {
595 case SearchResultTypeRole:
596 return result.type();
597 case Qt::DisplayRole:
598 case TitleRole:
599 return result.title();
600 case IconRole:
601 return QVariant::fromValue(m_icons.at(index.row()));
602 case DistanceRole:
604 QPlaceResult placeResult = result;
605 return placeResult.distance();
606 }
607 break;
608 case PlaceRole:
610 return QVariant::fromValue(static_cast<QObject *>(m_places.at(index.row())));
611 break;
612 case SponsoredRole:
614 QPlaceResult placeResult = result;
615 return placeResult.isSponsored();
616 }
617 break;
618 }
619 return QVariant();
620}
621
626{
627 QModelIndex modelIndex = createIndex(index, 0);
628 return data(modelIndex, roleNames().key(role.toLatin1()));
629}
630
631QHash<int, QByteArray> QDeclarativeSearchResultModel::roleNames() const
632{
633 QHash<int, QByteArray> roles = QDeclarativeSearchModelBase::roleNames();
634 roles.insert(SearchResultTypeRole, "type");
635 roles.insert(TitleRole, "title");
636 roles.insert(IconRole, "icon");
637 roles.insert(DistanceRole, "distance");
638 roles.insert(PlaceRole, "place");
639 roles.insert(SponsoredRole, "sponsored");
640
641 return roles;
642}
643
655void QDeclarativeSearchResultModel::updateWith(int proposedSearchIndex)
656{
657 if (m_results.at(proposedSearchIndex).type() != QPlaceSearchResult::ProposedSearchResult)
658 return;
659
660 m_request = QPlaceProposedSearchResult(m_results.at(proposedSearchIndex)).searchRequest();
661 update();
662}
663
670
675{
676 //disconnect the manager of the old plugin if we have one
677 if (m_plugin) {
679 if (serviceProvider) {
680 QPlaceManager *placeManager = serviceProvider->placeManager();
681 if (placeManager) {
683 this, &QDeclarativeSearchResultModel::placeUpdated);
685 this, &QDeclarativeSearchResultModel::placeRemoved);
686 connect(placeManager, &QPlaceManager::dataChanged,
688 }
689 }
690 }
691
692 //connect to the manager of the new plugin.
693 if (plugin) {
695 if (serviceProvider) {
696 QPlaceManager *placeManager = serviceProvider->placeManager();
697 if (placeManager) {
699 this, &QDeclarativeSearchResultModel::placeUpdated);
701 this, &QDeclarativeSearchResultModel::placeRemoved);
704 }
705 }
706 }
708}
709
714{
715 if (!m_reply)
716 return;
718 m_reply = nullptr;
720
721 if (!m_incremental)
722 m_pages.clear();
723
724 if (reply->error() != QPlaceReply::NoError) {
725 m_resultsBuffer.clear();
726 updateLayout();
728 return;
729 }
730
731 if (reply->type() == QPlaceReply::SearchReply) {
732 QPlaceSearchReply *searchReply = qobject_cast<QPlaceSearchReply *>(reply);
733 Q_ASSERT(searchReply);
734
736 if (!rpimpl->related || !m_incremental)
737 m_pages.clear();
738 m_resultsBuffer = searchReply->results();
739 bool alreadyLoaded = false;
740 if (m_pages.contains(rpimpl->page) && m_resultsBuffer == m_pages.value(rpimpl->page))
741 alreadyLoaded = true;
742 m_pages.insert(rpimpl->page, m_resultsBuffer);
744 setNextPageRequest(searchReply->nextPageRequest());
745
746 // Performing favorite matching only upon finished()
747 if (!m_favoritesPlugin) {
748 updateLayout();
750 } else {
751 QGeoServiceProvider *serviceProvider = m_favoritesPlugin->sharedGeoServiceProvider();
752 if (!serviceProvider) {
753 updateLayout();
754 setStatus(Error, QStringLiteral("Favorites plugin returns a null QGeoServiceProvider instance"));
755 return;
756 }
757
758 QPlaceManager *favoritesManager = serviceProvider->placeManager();
759 if (!favoritesManager) {
760 updateLayout();
761 setStatus(Error, QStringLiteral("Favorites plugin returns a null QPlaceManager"));
762 return;
763 }
764
766 if (m_matchParameters.isEmpty()) {
767 if (!m_plugin) {
768 setStatus(Error, QStringLiteral("Plugin not assigned"));
769 return;
770 }
771
774 request.setParameters(params);
775 } else {
776 request.setParameters(m_matchParameters);
777 }
778
779 request.setResults(m_resultsBuffer);
780 if (alreadyLoaded)
781 m_resultsBuffer.clear();
782 m_reply = favoritesManager->matchingPlaces(request);
787 }
788 } else if (reply->type() == QPlaceReply::MatchReply) {
789 QPlaceMatchReply *matchReply = qobject_cast<QPlaceMatchReply *>(reply);
790 Q_ASSERT(matchReply);
791 updateLayout(matchReply->places());
793 } else {
794 setStatus(Error, QStringLiteral("Unknown reply type"));
795 }
796}
797
799{
800 if (!m_reply)
801 return;
802
803 QPlaceReply *reply = m_reply; // not finished, don't delete.
804
805 if (!m_incremental)
806 m_pages.clear();
807
808 if (reply->error() != QPlaceReply::NoError) {
809 m_resultsBuffer.clear();
810 updateLayout();
812 return;
813 }
814
815 if (reply->type() == QPlaceReply::SearchReply) {
816 QPlaceSearchReply *searchReply = qobject_cast<QPlaceSearchReply *>(reply);
817 Q_ASSERT(searchReply);
818
820 if (!rpimpl->related || !m_incremental)
821 m_pages.clear();
822 m_resultsBuffer = searchReply->results();
823 if (!(m_pages.contains(rpimpl->page) && m_resultsBuffer == m_pages.value(rpimpl->page))) {
824 m_pages.insert(rpimpl->page, m_resultsBuffer);
825 updateLayout();
826 }
827 } else if (reply->type() == QPlaceReply::MatchReply) {
828 // ToDo: handle incremental match replies
829 } else {
830 setStatus(Error, QStringLiteral("Unknown reply type"));
831 }
832}
833
855void QDeclarativeSearchResultModel::updateLayout(const QList<QPlace> &favoritePlaces)
856{
857 const int oldRowCount = rowCount();
858 int start = 0;
859
860 if (m_incremental) {
861 if (!m_resultsBuffer.size())
862 return;
863
864 beginInsertRows(QModelIndex(), oldRowCount , oldRowCount + m_resultsBuffer.size() - 1);
865 m_results = resultsFromPages();
866 start = oldRowCount;
867 } else {
869 clearData(true);
870 m_results = m_resultsBuffer;
871 }
872
873 m_resultsBuffer.clear();
874 for (qsizetype i = start; i < m_results.count(); ++i) {
875 const QPlaceSearchResult &result = m_results.at(i);
876
878 QPlaceResult placeResult = result;
879 QDeclarativePlace *place = new QDeclarativePlace(placeResult.place(), plugin(), this);
880 m_places.append(place);
881
882 if ((favoritePlaces.count() == m_results.count()) && favoritePlaces.at(i) != QPlace())
883 m_places[i]->setFavorite(new QDeclarativePlace(favoritePlaces.at(i),
884 m_favoritesPlugin, m_places[i]));
886 m_places.append(0);
887 }
888
889 if (!result.icon().isEmpty())
890 m_icons.append(result.icon());
891 }
892
893 if (m_incremental)
895 else
897 if (m_results.count() != oldRowCount)
899}
900
904void QDeclarativeSearchResultModel::placeUpdated(const QString &placeId)
905{
906 int row = getRow(placeId);
907 if (row < 0 || row > m_places.count())
908 return;
909
910 if (m_places.at(row))
911 m_places.at(row)->getDetails();
912}
913
917void QDeclarativeSearchResultModel::placeRemoved(const QString &placeId)
918{
919 int row = getRow(placeId);
920 if (row < 0 || row > m_places.count())
921 return;
922
924 delete m_places.at(row);
925 m_places.removeAt(row);
926 m_results.removeAt(row);
927 removePageRow(row);
929
931}
932
933QList<QPlaceSearchResult> QDeclarativeSearchResultModel::resultsFromPages() const
934{
935 QList<QPlaceSearchResult> res;
936 for (const auto &e : m_pages)
937 res.append(e);
938 return res;
939}
940
941void QDeclarativeSearchResultModel::removePageRow(int row)
942{
943 int scanned = 0;
944 for (auto i = m_pages.begin(), end = m_pages.end(); i != end; ++i) {
945 QList<QPlaceSearchResult> &page = i.value();
946 scanned += page.size();
947 if (row >= scanned)
948 continue;
949 page.removeAt(row - scanned + page.size());
950 return;
951 }
952}
953
957int QDeclarativeSearchResultModel::getRow(const QString &placeId) const
958{
959 for (qsizetype i = 0; i < m_places.count(); ++i) {
960 if (!m_places.at(i))
961 continue;
962 else if (m_places.at(i)->placeId() == placeId)
963 return i;
964 }
965
966 return -1;
967}
968
void endResetModel()
Completes a model reset operation.
void endRemoveRows()
Ends a row removal operation.
virtual QHash< int, QByteArray > roleNames() const
void endInsertRows()
Ends a row insertion operation.
void beginResetModel()
Begins a model reset operation.
QModelIndex createIndex(int row, int column, const void *data=nullptr) const
Creates a model index for the given row and column with the internal pointer ptr.
void beginRemoveRows(const QModelIndex &parent, int first, int last)
Begins a row removal operation.
void beginInsertRows(const QModelIndex &parent, int first, int last)
Begins a row insertion operation.
QObject * parent() const
Returns a pointer to the parent object.
Definition qobject.h:346
qsizetype size() const noexcept
Returns the number of bytes in this byte array.
Definition qbytearray.h:494
QByteArray & removeAt(qsizetype pos)
Definition qbytearray.h:327
QGeoServiceProvider * sharedGeoServiceProvider() const
Q_INVOKABLE void getDetails()
\qmlmethod void Place::getDetails()
virtual void clearData(bool suppressSignal=false)
QDeclarativeGeoServiceProvider * plugin
virtual void initializePlugin(QDeclarativeGeoServiceProvider *plugin)
QDeclarativeGeoServiceProvider * m_plugin
void setPreviousPageRequest(const QPlaceSearchRequest &previous)
void setNextPageRequest(const QPlaceSearchRequest &next)
void setStatus(Status status, const QString &errorString=QString())
QVariant data(const QModelIndex &index, int role=Qt::DisplayRole) const override
Returns the data stored under the given role for the item referred to by the index.
QDeclarativeSearchResultModel(QObject *parent=nullptr)
\qmltype PlaceSearchModel \instantiates QDeclarativeSearchResultModel \inqmlmodule QtLocation
Q_INVOKABLE void updateWith(int proposedSearchIndex)
\qmlmethod void PlaceSearchModel::updateWith(int proposedSearchIndex)
void setRelevanceHint(QDeclarativeSearchResultModel::RelevanceHint hint)
void setVisibilityScope(QDeclarativePlace::Visibility visibilityScope)
QDeclarativeGeoServiceProvider * favoritesPlugin
void clearData(bool suppressSignal=false) override
QQmlListProperty< QDeclarativeCategory > categories
\qmlproperty list<Category> PlaceSearchModel::categories
static void categories_clear(QQmlListProperty< QDeclarativeCategory > *list)
void setSearchTerm(const QString &searchTerm)
static qsizetype categories_count(QQmlListProperty< QDeclarativeCategory > *list)
QPlaceReply * sendQuery(QPlaceManager *manager, const QPlaceSearchRequest &request) override
int rowCount(const QModelIndex &parent=QModelIndex()) const override
void setFavoritesMatchParameters(const QVariantMap &parameters)
void setFavoritesPlugin(QDeclarativeGeoServiceProvider *plugin)
static QDeclarativeCategory * category_at(QQmlListProperty< QDeclarativeCategory > *list, qsizetype index)
static void categories_append(QQmlListProperty< QDeclarativeCategory > *list, QDeclarativeCategory *category)
void setRecommendationId(const QString &recommendationId)
void initializePlugin(QDeclarativeGeoServiceProvider *plugin) override
QHash< int, QByteArray > roleNames() const override
QDeclarativePlace::Visibility visibilityScope
\inmodule QtLocation
QPlaceManager * placeManager() const
Returns the QPlaceManager made available by the service provider.
QString errorString() const
Returns a human-readable description of the last device error that occurred.
qsizetype size() const noexcept
Definition qlist.h:397
bool isEmpty() const noexcept
Definition qlist.h:401
void removeAt(qsizetype i)
Definition qlist.h:590
const_reference at(qsizetype i) const noexcept
Definition qlist.h:446
qsizetype count() const noexcept
Definition qlist.h:398
void append(parameter_type t)
Definition qlist.h:458
void clear()
Definition qlist.h:434
iterator insert(const Key &key, const T &value)
Definition qmap.h:688
T value(const Key &key, const T &defaultValue=T()) const
Definition qmap.h:357
bool contains(const Key &key) const
Definition qmap.h:341
void clear()
Definition qmap.h:289
bool isEmpty() const
Definition qmap.h:269
iterator begin()
Definition qmap.h:598
iterator end()
Definition qmap.h:602
\inmodule QtCore
NetworkError error() const
Returns the error that was found during the processing of this request.
\inmodule QtCore
Definition qobject.h:103
void deleteLater()
\threadsafe
Definition qobject.cpp:2435
\inmodule QtLocation
QStringList childCategoryIds(const QString &parentId=QString()) const
Returns the child category identifiers of the category corresponding to parentId.
void placeUpdated(const QString &placeId)
This signal is emitted if a place has been modified in the manager's datastore.
QPlaceReply * initializeCategories()
Initializes the categories of the manager.
void dataChanged()
This signal is emitted by the manager if there are large scale changes to its underlying datastore an...
void placeRemoved(const QString &placeId)
This signal is emitted if a place has been removed from the manager's datastore.
\inmodule QtLocation
QList< QPlace > places() const
Returns a list of matching places;.
\inmodule QtLocation
static const QString AlternativeId
\variable QPlaceMatchRequest::AlternativeId The key to specify that matching is to be accomplished vi...
QPlaceSearchRequest searchRequest() const
Returns a place search request that can be used to perform an additional proposed search.
\inmodule QtLocation
Definition qplacereply.h:15
void finished()
This signal is emitted when this reply has finished processing.
void contentUpdated()
This signal is emitted when this reply has updated content available.
\inmodule QtLocation
bool isSponsored() const
Returns true if the result is a sponsored result.
qreal distance() const
Returns the distance of the place to the search center.
\inmodule QtLocation
QPlaceSearchRequest request() const
Returns the search request that was used to generate this reply.
QList< QPlaceSearchResult > results() const
Returns a list of search results;.
QPlaceSearchRequest previousPageRequest() const
Returns a place search request which can be used to request the previous page of search results.
QPlaceSearchRequest nextPageRequest() const
Returns a place search request which can be used to request the next page of search results.
static const QPlaceSearchRequestPrivate * get(const QPlaceSearchRequest &request)
\inmodule QtLocation
void setSearchTerm(const QString &term)
Sets the search term.
RelevanceHint
Defines hints to help rank place results.
QString searchTerm() const
Returns the search term.
void setRecommendationId(const QString &recommendationId)
Sets the placeId which will be used to search for recommendations.
QList< QPlaceCategory > categories() const
Return the categories to be used in the search request.
void setRelevanceHint(RelevanceHint hint)
Sets the relevance hint to be used when searching for a place.
QString recommendationId() const
Returns the place id which will be used to search for recommendations for similar places.
void setSearchContext(const QVariant &context)
Sets the search context to context.
void setCategories(const QList< QPlaceCategory > &categories)
Sets the search request to search from the list of given categories.
RelevanceHint relevanceHint() const
Returns the relevance hint of the request.
\inmodule QtLocation
SearchResultType type() const
Returns the result type.
\inmodule QtLocation
Definition qplace.h:25
\macro QT_RESTRICTED_CAST_FROM_ASCII
Definition qstring.h:129
QByteArray toLatin1() const &
Definition qstring.h:630
static QString fromLatin1(QByteArrayView ba)
This is an overloaded member function, provided for convenience. It differs from the above function o...
Definition qstring.cpp:5871
\inmodule QtCore
Definition qvariant.h:65
static auto fromValue(T &&value) noexcept(std::is_nothrow_copy_constructible_v< T > &&Private::CanUseInternalSpace< T >) -> std::enable_if_t< std::conjunction_v< std::is_copy_constructible< T >, std::is_destructible< T > >, QVariant >
Definition qvariant.h:536
list append(new Employee("Blackpool", "Stephen"))
qDeleteAll(list.begin(), list.end())
Combined button and popup list for selecting options.
@ DisplayRole
GLuint64 key
GLuint index
[2]
GLuint GLuint end
GLint GLsizei GLsizei GLenum GLenum GLsizei void * data
GLuint start
void ** params
GLsizei GLenum * categories
GLuint res
GLenum GLenum GLsizei void * row
GLuint64EXT * result
[6]
#define Q_ASSERT(cond)
Definition qrandom.cpp:47
#define QStringLiteral(str)
static QT_BEGIN_NAMESPACE QVariant hint(QPlatformIntegration::StyleHint h)
#define emit
#define Q_UNUSED(x)
ptrdiff_t qsizetype
Definition qtypes.h:165
QList< int > list
[14]
connect(quitButton, &QPushButton::clicked, &app, &QCoreApplication::quit, Qt::QueuedConnection)
myObject disconnect()
[26]
QByteArray page
[45]
QNetworkAccessManager manager
QNetworkRequest request(url)
QNetworkReply * reply