8#include "SearchRunnerManager.h"
10#include "GeoDataPlacemark.h"
11#include "MarbleDebug.h"
13#include "MarblePlacemarkModel.h"
15#include "PluginManager.h"
16#include "RunnerTask.h"
17#include "SearchRunnerPlugin.h"
18#include "routing/RouteRequest.h"
19#include "routing/RoutingProfilesModel.h"
31class Q_DECL_HIDDEN SearchRunnerManager::Private
34 Private(SearchRunnerManager *parent,
const MarbleModel *marbleModel);
40 void cleanupSearchTask(SearchTask *task);
41 void notifySearchResultChange();
42 void notifySearchFinished();
44 SearchRunnerManager *
const q;
45 const MarbleModel *
const m_marbleModel;
46 const PluginManager *m_pluginManager;
48 GeoDataLatLonBox m_lastPreferredBox;
50 MarblePlacemarkModel m_model;
55SearchRunnerManager::Private::Private(SearchRunnerManager *parent,
const MarbleModel *marbleModel)
57 , m_marbleModel(marbleModel)
58 , m_pluginManager(marbleModel->pluginManager())
59 , m_model(new MarblePlacemarkModel(parent))
61 m_model.setPlacemarkContainer(&m_placemarkContainer);
62 qRegisterMetaType<QList<GeoDataPlacemark *>>(
"QList<GeoDataPlacemark*>");
69 for (T *plugin : plugins) {
70 if ((m_marbleModel && m_marbleModel->workOffline() && !plugin->canWorkOffline())) {
74 if (!plugin->canWork()) {
78 if (m_marbleModel && !plugin->supportsCelestialBody(m_marbleModel->planet()->id())) {
90 mDebug() <<
"Runner reports" << result.
size() <<
" search results";
95 int start = m_placemarkContainer.size();
97 bool distanceCompare = m_marbleModel->planet() !=
nullptr;
98 for (
int i = 0; i < result.
size(); ++i) {
100 for (
int j = 0; j < m_placemarkContainer.size(); ++j) {
102 && (result[i]->coordinate().sphericalDistanceTo(m_placemarkContainer[j]->coordinate()) * m_marbleModel->planet()->radius() < 1)) {
107 m_placemarkContainer.append(result[i]);
111 m_model.addPlacemarks(
start, count);
112 m_modelMutex.unlock();
113 notifySearchResultChange();
116void SearchRunnerManager::Private::cleanupSearchTask(SearchTask *task)
118 m_searchTasks.removeAll(task);
119 mDebug() <<
"removing search task" << m_searchTasks.size() << (quintptr)task;
120 if (m_searchTasks.isEmpty()) {
121 if (m_placemarkContainer.isEmpty()) {
122 notifySearchResultChange();
124 notifySearchFinished();
128void SearchRunnerManager::Private::notifySearchResultChange()
130 Q_EMIT q->searchResultChanged(&m_model);
131 Q_EMIT q->searchResultChanged(m_placemarkContainer);
134void SearchRunnerManager::Private::notifySearchFinished()
136 Q_EMIT q->searchFinished(m_lastSearchTerm);
137 Q_EMIT q->placemarkSearchFinished();
140SearchRunnerManager::SearchRunnerManager(
const MarbleModel *marbleModel,
QObject *parent)
142 , d(new Private(this, marbleModel))
149SearchRunnerManager::~SearchRunnerManager()
154void SearchRunnerManager::findPlacemarks(
const QString &searchTerm,
const GeoDataLatLonBox &preferred)
156 if (searchTerm == d->m_lastSearchTerm && preferred == d->m_lastPreferredBox) {
157 d->notifySearchResultChange();
158 d->notifySearchFinished();
162 d->m_lastSearchTerm = searchTerm;
163 d->m_lastPreferredBox = preferred;
165 d->m_searchTasks.
clear();
167 d->m_modelMutex.lock();
168 bool placemarkContainerChanged =
false;
169 if (!d->m_placemarkContainer.isEmpty()) {
170 d->m_model.removePlacemarks(QStringLiteral(
"PlacemarkRunnerManager"), 0, d->m_placemarkContainer.size());
171 qDeleteAll(d->m_placemarkContainer);
172 d->m_placemarkContainer.clear();
173 placemarkContainerChanged =
true;
175 d->m_modelMutex.unlock();
176 if (placemarkContainerChanged) {
177 d->notifySearchResultChange();
181 d->notifySearchFinished();
186 for (
const SearchRunnerPlugin *plugin : std::as_const(plugins)) {
187 auto task =
new SearchTask(plugin->newRunner(),
this, d->m_marbleModel, searchTerm, preferred);
188 connect(task, SIGNAL(finished(SearchTask *)),
this, SLOT(cleanupSearchTask(SearchTask *)));
189 d->m_searchTasks <<
task;
190 mDebug() <<
"search task " << plugin->nameId() <<
" " << (quintptr)task;
193 for (SearchTask *task : std::as_const(d->m_searchTasks)) {
198 d->cleanupSearchTask(
nullptr);
207 connect(&watchdog, SIGNAL(timeout()), &localEventLoop, SLOT(
quit()));
210 watchdog.
start(timeout);
211 findPlacemarks(searchTerm, preferred);
212 localEventLoop.
exec();
213 return d->m_placemarkContainer;
218#include "moc_SearchRunnerManager.cpp"
This file contains the headers for MarbleModel.
Q_SCRIPTABLE Q_NOREPLY void start()
Binds a QML item to a specific geodetic location in screen coordinates.
int exec(ProcessEventsFlags flags)
bool isEmpty() const const
qsizetype size() const const
bool isEmpty() const const
QString trimmed() const const
QTaskBuilder< Task > task(Task &&task)
QFuture< ArgsType< Signal > > connect(Sender *sender, Signal signal)
QThreadPool * globalInstance()
void setMaxThreadCount(int maxThreadCount)
void start(Callable &&callableToRun, int priority)
void setSingleShot(bool singleShot)