8 #include "SearchRunnerManager.h"
10 #include "MarblePlacemarkModel.h"
11 #include "MarbleDebug.h"
14 #include "GeoDataPlacemark.h"
15 #include "PluginManager.h"
16 #include "ParseRunnerPlugin.h"
17 #include "ReverseGeocodingRunnerPlugin.h"
18 #include "RoutingRunnerPlugin.h"
19 #include "SearchRunnerPlugin.h"
20 #include "RunnerTask.h"
21 #include "routing/RouteRequest.h"
22 #include "routing/RoutingProfilesModel.h"
25 #include <QThreadPool>
34 class Q_DECL_HIDDEN SearchRunnerManager::Private
37 Private( SearchRunnerManager *parent,
const MarbleModel *marbleModel );
43 void cleanupSearchTask( SearchTask *task );
44 void notifySearchResultChange();
45 void notifySearchFinished();
47 SearchRunnerManager *
const q;
48 const MarbleModel *
const m_marbleModel;
49 const PluginManager* m_pluginManager;
51 GeoDataLatLonBox m_lastPreferredBox;
53 MarblePlacemarkModel m_model;
58 SearchRunnerManager::Private::Private( SearchRunnerManager *parent,
const MarbleModel *marbleModel ) :
60 m_marbleModel( marbleModel ),
61 m_pluginManager( marbleModel->pluginManager() ),
62 m_model( new MarblePlacemarkModel( parent ) )
64 m_model.setPlacemarkContainer( &m_placemarkContainer );
65 qRegisterMetaType<QVector<GeoDataPlacemark *> >(
"QVector<GeoDataPlacemark*>" );
72 for( T* plugin: plugins ) {
73 if ( ( m_marbleModel && m_marbleModel->workOffline() && !plugin->canWorkOffline() ) ) {
77 if ( !plugin->canWork() ) {
81 if ( m_marbleModel && !plugin->supportsCelestialBody( m_marbleModel->planet()->id() ) )
94 mDebug() <<
"Runner reports" << result.
size() <<
" search results";
99 int start = m_placemarkContainer.size();
101 bool distanceCompare = m_marbleModel->planet() !=
nullptr;
102 for(
int i=0; i<result.
size(); ++i ) {
104 for (
int j=0; j<m_placemarkContainer.size(); ++j ) {
105 if ( distanceCompare &&
106 (result[i]->coordinate().sphericalDistanceTo(m_placemarkContainer[j]->coordinate())
107 * m_marbleModel->planet()->radius() < 1 ) ) {
112 m_placemarkContainer.append( result[i] );
116 m_model.addPlacemarks(
start, count );
117 m_modelMutex.unlock();
118 notifySearchResultChange();
121 void SearchRunnerManager::Private::cleanupSearchTask( SearchTask *task )
123 m_searchTasks.removeAll( task );
124 mDebug() <<
"removing search task" << m_searchTasks.size() << (quintptr)task;
125 if ( m_searchTasks.isEmpty() ) {
126 if( m_placemarkContainer.isEmpty() ) {
127 notifySearchResultChange();
129 notifySearchFinished();
133 void SearchRunnerManager::Private::notifySearchResultChange()
135 emit q->searchResultChanged(&m_model);
136 emit q->searchResultChanged(m_placemarkContainer);
139 void SearchRunnerManager::Private::notifySearchFinished()
141 emit q->searchFinished(m_lastSearchTerm);
142 emit q->placemarkSearchFinished();
145 SearchRunnerManager::SearchRunnerManager(
const MarbleModel *marbleModel,
QObject *parent ) :
147 d( new Private( this, marbleModel ) )
154 SearchRunnerManager::~SearchRunnerManager()
159 void SearchRunnerManager::findPlacemarks(
const QString &searchTerm,
const GeoDataLatLonBox &preferred )
161 if ( searchTerm == d->m_lastSearchTerm && preferred == d->m_lastPreferredBox ) {
162 d->notifySearchResultChange();
163 d->notifySearchFinished();
167 d->m_lastSearchTerm = searchTerm;
168 d->m_lastPreferredBox = preferred;
170 d->m_searchTasks.
clear();
172 d->m_modelMutex.lock();
173 bool placemarkContainerChanged =
false;
174 if (!d->m_placemarkContainer.isEmpty()) {
175 d->m_model.removePlacemarks(
"PlacemarkRunnerManager", 0, d->m_placemarkContainer.size() );
176 qDeleteAll( d->m_placemarkContainer );
177 d->m_placemarkContainer.clear();
178 placemarkContainerChanged =
true;
180 d->m_modelMutex.unlock();
181 if (placemarkContainerChanged) {
182 d->notifySearchResultChange();
186 d->notifySearchFinished();
191 for(
const SearchRunnerPlugin *plugin: plugins ) {
192 SearchTask *task =
new SearchTask( plugin->newRunner(),
this, d->m_marbleModel, searchTerm, preferred );
193 connect( task, SIGNAL(finished(SearchTask*)),
this, SLOT(cleanupSearchTask(SearchTask*)) );
194 d->m_searchTasks << task;
195 mDebug() <<
"search task " << plugin->nameId() <<
" " << (quintptr)task;
198 for( SearchTask *task: d->m_searchTasks ) {
202 if ( plugins.isEmpty() ) {
203 d->cleanupSearchTask(
nullptr );
212 connect( &watchdog, SIGNAL(timeout()),
213 &localEventLoop, SLOT(
quit()));
214 connect(
this, SIGNAL(placemarkSearchFinished()),
217 watchdog.
start( timeout );
218 findPlacemarks( searchTerm, preferred );
219 localEventLoop.
exec();
220 return d->m_placemarkContainer;
225 #include "moc_SearchRunnerManager.cpp"