Marble

SearchBackend.cpp
1 // SPDX-License-Identifier: LGPL-2.1-or-later
2 //
3 // SPDX-FileCopyrightText: 2015 Gábor Péterffy <[email protected]>
4 //
5 
6 #include "SearchBackend.h"
7 
8 #include "SearchRunnerManager.h"
9 #include "MarbleModel.h"
10 #include "Coordinate.h"
11 
12 #include <QCompleter>
13 
14 using namespace Marble;
15 
16 
17 SearchBackend::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 
33 void SearchBackend::search(const QString &place)
34 {
35  if (m_marbleQuickItem)
36  {
37  m_searchManager->searchPlacemarks(place);
38  }
39 }
40 
41 void 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  }
59  QAbstractProxyModel *model = qobject_cast<QAbstractProxyModel*>(m_completer->completionModel());
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 
81 QObject * SearchBackend::marbleQuickItem()
82 {
83  return m_marbleQuickItem;
84 }
85 
86 MarblePlacemarkModel *SearchBackend::completionModel()
87 {
88  return m_completionModel;
89 }
90 
91 const QObject * SearchBackend::marbleQuickItem() const
92 {
93  return m_marbleQuickItem;
94 }
95 
96 Placemark *SearchBackend::selectedPlacemark()
97 {
98  return &m_selectedPlacemark;
99 }
100 
101 void 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 
114 void 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());
136  m_completer->setCompletionRole(Qt::DisplayRole);
137  m_completer->setCaseSensitivity(Qt::CaseInsensitive);
138 
139  emit marbleQuickItemChanged(marbleQuickItem);
140  }
141 }
142 
143 void SearchBackend::updateSearchResult(QAbstractItemModel *result)
144 {
145  m_placemarkModel = qobject_cast<MarblePlacemarkModel*>(result);
146  emit searchResultChanged(m_placemarkModel);
147 }
148 
149 GeoDataPlacemark *SearchBackend::placemarkFromQVariant(const QVariant &data)
150 {
151  if( !data.isValid() ) {
152  return nullptr;
153  }
154  GeoDataObject *object = qvariant_cast<GeoDataObject*>( data );
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"
bool isEmpty() const const
bool isValid() const const
DisplayRole
int size() const const
CaseInsensitive
virtual QModelIndex mapToSource(const QModelIndex &proxyIndex) const const=0
@ PopularityIndexRole
The popularity index.
void clear()
void append(const T &value)
@ ObjectPointerRole
The pointer to a specific object.
A base class for all geodata objects.
Definition: GeoDataObject.h:43
bool isEmpty() const const
Binds a QML item to a specific geodetic location in screen coordinates.
Wraps a GeoDataPlacemark for QML access.
Definition: Placemark.h:21
a class representing a point of interest on the map
bool startsWith(const QString &s, Qt::CaseSensitivity cs) const const
virtual QModelIndex index(int row, int column, const QModelIndex &parent) const const=0
int size() const const
This class represents a model of all place marks which are currently available through a given Placem...
This file is part of the KDE documentation.
Documentation copyright © 1996-2023 The KDE developers.
Generated on Mon Oct 2 2023 03:52:10 by doxygen 1.8.17 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.