Marble

SearchBackend.cpp
1// SPDX-License-Identifier: LGPL-2.1-or-later
2//
3// SPDX-FileCopyrightText: 2015 Gábor Péterffy <peterffy95@gmail.com>
4//
5
6#include "SearchBackend.h"
7
8#include "MarbleModel.h"
9#include "SearchRunnerManager.h"
10
11#include <QCompleter>
12
13using namespace Marble;
14
15SearchBackend::SearchBackend(QObject *parent)
16 : QObject(parent)
17 , m_completionModel(new MarblePlacemarkModel)
18 , m_completionContainer(new QList<GeoDataPlacemark *>())
19 , m_selectedPlacemark()
20{
22 m_model.sort(0);
23 m_model.setDynamicSortFilter(true);
24 m_completionModel->setPlacemarkContainer(m_completionContainer);
25}
26
27void SearchBackend::search(const QString &place)
28{
29 if (m_marbleQuickItem) {
30 m_searchManager->searchPlacemarks(place);
31 }
32}
33
34void SearchBackend::setCompletionPrefix(const QString &prefix)
35{
36 if (m_completer != nullptr && m_completer->completionPrefix() != prefix) {
37 if (!m_lastSuccessfulCompletion.isEmpty() && prefix.startsWith(m_lastSuccessfulCompletion) && prefix.size() > m_lastSuccessfulCompletion.size()) {
38 return;
39 }
40
41 m_completionModel->removePlacemarks(QStringLiteral("Completion model"), 0, m_completionModel->rowCount());
42 m_completionContainer->clear();
43 QString const lastPrefix = m_completer->completionPrefix();
44 m_completer->setCompletionPrefix(prefix);
45 if (prefix.isEmpty()) {
46 Q_EMIT completionModelChanged(m_completionModel);
47 return;
48 }
49 auto container = new QList<GeoDataPlacemark *>();
50 auto model = qobject_cast<QAbstractProxyModel *>(m_completer->completionModel());
51 for (int i = 0; i < m_completer->completionModel()->rowCount(); ++i) {
52 QModelIndex index = model->mapToSource(model->index(i, 0));
53 QVariant data = m_marbleQuickItem->model()->placemarkModel()->data(index, MarblePlacemarkModel::ObjectPointerRole);
54 GeoDataPlacemark *placemark = placemarkFromQVariant(data);
55 if (placemark != nullptr) {
56 container->append(placemark);
57 }
58 }
59 if (container->isEmpty() && prefix.startsWith(lastPrefix)) {
60 m_lastSuccessfulCompletion = lastPrefix;
61 } else if (!container->isEmpty()) {
62 m_lastSuccessfulCompletion.clear();
63 }
64 m_completionModel->setPlacemarkContainer(container);
65 m_completionModel->addPlacemarks(0, container->size());
66 delete m_completionContainer;
67 m_completionContainer = container;
68 Q_EMIT completionModelChanged(m_completionModel);
69 }
70}
71
72QObject *SearchBackend::marbleQuickItem()
73{
74 return m_marbleQuickItem;
75}
76
77MarblePlacemarkModel *SearchBackend::completionModel()
78{
79 return m_completionModel;
80}
81
82const QObject *SearchBackend::marbleQuickItem() const
83{
84 return m_marbleQuickItem;
85}
86
87Placemark *SearchBackend::selectedPlacemark()
88{
89 return &m_selectedPlacemark;
90}
91
92void SearchBackend::setSelectedPlacemark(int placemarkIndex)
93{
94 QVariant data = m_placemarkModel->data(m_placemarkModel->index(placemarkIndex), MarblePlacemarkModel::ObjectPointerRole);
95 GeoDataPlacemark *placemark = placemarkFromQVariant(data);
96 if (placemark == nullptr) {
97 return;
98 }
99
100 m_selectedPlacemark.setGeoDataPlacemark(*placemark);
101 m_marbleQuickItem->centerOn(*placemark, true);
102 Q_EMIT selectedPlacemarkChanged(&m_selectedPlacemark);
103}
104
105void SearchBackend::setMarbleQuickItem(QObject *marbleQuickItem)
106{
107 auto item = qobject_cast<MarbleQuickItem *>(marbleQuickItem);
108 if (m_marbleQuickItem == item) {
109 return;
110 }
111
112 if (item) {
113 delete m_searchManager;
114 delete m_completer;
115 m_marbleQuickItem = item;
116 m_searchManager = new SearchRunnerManager(m_marbleQuickItem->model(), this);
117
118 connect(m_searchManager, SIGNAL(searchResultChanged(QAbstractItemModel *)), this, SLOT(updateSearchResult(QAbstractItemModel *)));
119 connect(m_searchManager, SIGNAL(searchFinished(QString)), this, SIGNAL(searchFinished(QString)));
120
121 m_completer = new QCompleter();
122 m_completer->setModel(m_marbleQuickItem->model()->placemarkModel());
125
126 Q_EMIT marbleQuickItemChanged(marbleQuickItem);
127 }
128}
129
130void SearchBackend::updateSearchResult(QAbstractItemModel *result)
131{
132 m_placemarkModel = qobject_cast<MarblePlacemarkModel *>(result);
133 Q_EMIT searchResultChanged(m_placemarkModel);
134}
135
136GeoDataPlacemark *SearchBackend::placemarkFromQVariant(const QVariant &data)
137{
138 if (!data.isValid()) {
139 return nullptr;
140 }
141 auto object = qvariant_cast<GeoDataObject *>(data);
142 if (object == nullptr) {
143 return nullptr;
144 }
145 auto placemark = dynamic_cast<GeoDataPlacemark *>(object);
146 if (placemark == nullptr) {
147 return nullptr;
148 }
149 return placemark;
150}
151
152#include "moc_SearchBackend.cpp"
This file contains the headers for MarbleModel.
a class representing a point of interest on the map
This class represents a model of all place marks which are currently available through a given Placem...
void addPlacemarks(int start, int length)
This method is used by the PlacemarkManager to add new place marks to the model.
int rowCount(const QModelIndex &parent=QModelIndex()) const override
Return the number of Placemarks in the Model.
@ PopularityIndexRole
The popularity index.
@ ObjectPointerRole
The pointer to a specific object.
void removePlacemarks(const QString &containerName, int start, int length)
This method is used by the PlacemarkManager to remove place marks from the model.
QVariant data(const QModelIndex &index, int role) const override
Return the data according to the index.
Wraps a GeoDataPlacemark for QML access.
Definition Placemark.h:24
Binds a QML item to a specific geodetic location in screen coordinates.
virtual QVariant data(const QModelIndex &index, int role) const const=0
virtual QModelIndex index(int row, int column, const QModelIndex &parent) const const override
void setCaseSensitivity(Qt::CaseSensitivity caseSensitivity)
QAbstractItemModel * completionModel() const const
void setCompletionRole(int role)
void setModel(QAbstractItemModel *model)
Q_EMITQ_EMIT
QMetaObject::Connection connect(const QObject *sender, PointerToMemberFunction signal, Functor functor)
T qobject_cast(QObject *object)
void clear()
bool isEmpty() const const
qsizetype size() const const
bool startsWith(QChar c, Qt::CaseSensitivity cs) const const
CaseInsensitive
DisplayRole
bool isValid() const const
This file is part of the KDE documentation.
Documentation copyright © 1996-2024 The KDE developers.
Generated on Fri Nov 8 2024 12:02:42 by doxygen 1.12.0 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.