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 "SearchRunnerManager.h"
9#include "MarbleModel.h"
10#include "Coordinate.h"
11
12#include <QCompleter>
13
14using namespace Marble;
15
16
17SearchBackend::SearchBackend(QObject *parent) :
18 QObject(parent),
19 m_searchManager( nullptr ),
20 m_marbleQuickItem( nullptr ),
21 m_placemarkModel( nullptr ),
22 m_completer( nullptr ),
23 m_completionModel( new MarblePlacemarkModel ),
24 m_completionContainer( new QVector<GeoDataPlacemark*>() ),
25 m_selectedPlacemark( )
26{
27 m_model.setSortRole( MarblePlacemarkModel::PopularityIndexRole );
28 m_model.sort(0);
29 m_model.setDynamicSortFilter(true);
30 m_completionModel->setPlacemarkContainer(m_completionContainer);
31}
32
33void SearchBackend::search(const QString &place)
34{
35 if (m_marbleQuickItem)
36 {
37 m_searchManager->searchPlacemarks(place);
38 }
39}
40
41void SearchBackend::setCompletionPrefix(const QString &prefix)
42{
43 if( m_completer != nullptr && m_completer->completionPrefix() != prefix ) {
44 if (!m_lastSuccessfulCompletion.isEmpty()
45 && prefix.startsWith(m_lastSuccessfulCompletion)
46 && prefix.size() > m_lastSuccessfulCompletion.size()) {
47 return;
48 }
49
50 m_completionModel->removePlacemarks(QStringLiteral("Completion model"), 0, m_completionModel->rowCount());
51 m_completionContainer->clear();
52 QString const lastPrefix = m_completer->completionPrefix();
53 m_completer->setCompletionPrefix(prefix);
54 if( prefix.isEmpty() ) {
55 emit completionModelChanged(m_completionModel);
56 return;
57 }
60 for( int i = 0; i<m_completer->completionModel()->rowCount(); ++i ) {
61 QModelIndex index = model->mapToSource(model->index(i,0));
62 QVariant data = m_marbleQuickItem->model()->placemarkModel()->data(index, MarblePlacemarkModel::ObjectPointerRole);
63 GeoDataPlacemark *placemark = placemarkFromQVariant(data);
64 if( placemark != nullptr ) {
65 container->append(placemark);
66 }
67 }
68 if (container->isEmpty() && prefix.startsWith(lastPrefix) ) {
69 m_lastSuccessfulCompletion = lastPrefix;
70 } else if (!container->isEmpty()) {
71 m_lastSuccessfulCompletion.clear();
72 }
73 m_completionModel->setPlacemarkContainer(container);
74 m_completionModel->addPlacemarks(0, container->size());
75 delete m_completionContainer;
76 m_completionContainer = container;
77 emit completionModelChanged(m_completionModel);
78 }
79}
80
81QObject * SearchBackend::marbleQuickItem()
82{
83 return m_marbleQuickItem;
84}
85
86MarblePlacemarkModel *SearchBackend::completionModel()
87{
88 return m_completionModel;
89}
90
91const QObject * SearchBackend::marbleQuickItem() const
92{
93 return m_marbleQuickItem;
94}
95
96Placemark *SearchBackend::selectedPlacemark()
97{
98 return &m_selectedPlacemark;
99}
100
101void SearchBackend::setSelectedPlacemark(int placemarkIndex)
102{
103 QVariant data = m_placemarkModel->data(m_placemarkModel->index(placemarkIndex), MarblePlacemarkModel::ObjectPointerRole);
104 GeoDataPlacemark *placemark = placemarkFromQVariant(data);
105 if( placemark == nullptr ) {
106 return;
107 }
108
109 m_selectedPlacemark.setGeoDataPlacemark(*placemark);
110 m_marbleQuickItem->centerOn(*placemark, true);
111 emit selectedPlacemarkChanged(&m_selectedPlacemark);
112}
113
114void SearchBackend::setMarbleQuickItem(QObject *marbleQuickItem)
115{
116 MarbleQuickItem * item = qobject_cast<MarbleQuickItem*>(marbleQuickItem);
117 if (m_marbleQuickItem == item)
118 {
119 return;
120 }
121
122 if (item)
123 {
124 delete m_searchManager;
125 delete m_completer;
126 m_marbleQuickItem = item;
127 m_searchManager = new SearchRunnerManager(m_marbleQuickItem->model(), this);
128
129 connect(m_searchManager, SIGNAL(searchResultChanged(QAbstractItemModel*)),
130 this, SLOT(updateSearchResult(QAbstractItemModel*)));
131 connect(m_searchManager, SIGNAL(searchFinished(QString)),
132 this, SIGNAL(searchFinished(QString)));
133
134 m_completer = new QCompleter();
135 m_completer->setModel(m_marbleQuickItem->model()->placemarkModel());
138
139 emit marbleQuickItemChanged(marbleQuickItem);
140 }
141}
142
143void SearchBackend::updateSearchResult(QAbstractItemModel *result)
144{
145 m_placemarkModel = qobject_cast<MarblePlacemarkModel*>(result);
146 emit searchResultChanged(m_placemarkModel);
147}
148
149GeoDataPlacemark *SearchBackend::placemarkFromQVariant(const QVariant &data)
150{
151 if( !data.isValid() ) {
152 return nullptr;
153 }
155 if( object == nullptr ) {
156 return nullptr;
157 }
158 GeoDataPlacemark *placemark = dynamic_cast<GeoDataPlacemark*>( object );
159 if( placemark == nullptr ) {
160 return nullptr;
161 }
162 return placemark;
163}
164
165#include "moc_SearchBackend.cpp"
This file contains the headers for MarbleModel.
A base class for all geodata objects.
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:22
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=0
virtual QModelIndex index(int row, int column, const QModelIndex &parent) const const override
virtual QModelIndex mapToSource(const QModelIndex &proxyIndex) const const=0
void setCaseSensitivity(Qt::CaseSensitivity caseSensitivity)
QAbstractItemModel * completionModel() const const
void setCompletionRole(int role)
void setModel(QAbstractItemModel *model)
void append(QList< T > &&value)
bool isEmpty() const const
qsizetype size() const const
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 Tue Mar 26 2024 11:18:17 by doxygen 1.10.0 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.