Commit 55b040cd authored by Bernhard Beschow's avatar Bernhard Beschow
Browse files

API change: split class RunnerPlugin into Search-, ReverseGeocoding-, Routing-...

API change: split class RunnerPlugin into Search-, ReverseGeocoding-, Routing- and ParseRunnerPlugin

== Motivation ==
Splitting the RunnerPlugin class into separate classes scales better since each plugin class can be tailored much better to fit its domain.
This improves the internal structure of Marble as well as eases plugin writing since there will be no unused API per plugin type.

== For Plugin Implementers ==
Since every plugin is now required to have exactly one capability, the former RunnerPlugin::Capability enum as well as the capability getter and setter methods are not needed any more and have been removed.
The former RenderPlungin::canWork() method, which has only been transferred to a subset of the new runner plugin classes, does not take parameters any more.
The remaining (esp. virtual) methods have been transferred as needed. See the new runner plugin classes for more details.
Note: the Q_INTERFACES() macro in implementing classes has to be updated, too.

REVIEW: 104840
parent 0d2a8d60
......@@ -202,7 +202,10 @@ set(marblewidget_SRCS
AutoNavigation.cpp
RunnerPlugin.cpp
SearchRunnerPlugin.cpp
ReverseGeocodingRunnerPlugin.cpp
RoutingRunnerPlugin.cpp
ParseRunnerPlugin.cpp
MarbleAbstractRunner.cpp
RunnerTask.cpp
......@@ -398,7 +401,10 @@ else (APPLE AND QTONLY)
RenderPluginInterface.h
MarbleRunnerManager.h
MarbleAbstractRunner.h
RunnerPlugin.h
SearchRunnerPlugin.h
ReverseGeocodingRunnerPlugin.h
RoutingRunnerPlugin.h
ParseRunnerPlugin.h
LayerInterface.h
PluginAboutDialog.h
marble_export.h
......
......@@ -18,7 +18,10 @@
#include "GeoDataDocument.h"
#include "GeoDataPlacemark.h"
#include "PluginManager.h"
#include "RunnerPlugin.h"
#include "ParseRunnerPlugin.h"
#include "ReverseGeocodingRunnerPlugin.h"
#include "RoutingRunnerPlugin.h"
#include "SearchRunnerPlugin.h"
#include "RunnerTask.h"
#include "routing/RouteRequest.h"
#include "routing/RoutingProfilesModel.h"
......@@ -53,7 +56,8 @@ public:
~MarbleRunnerManagerPrivate();
QList<RunnerPlugin*> plugins( RunnerPlugin::Capability capability );
template<typename T>
QList<T*> plugins( const QList<T*> &plugins );
QList<RunnerTask*> m_searchTasks;
QList<RunnerTask*> m_reverseTasks;
......@@ -93,20 +97,16 @@ MarbleRunnerManagerPrivate::~MarbleRunnerManagerPrivate()
// nothing to do
}
QList<RunnerPlugin*> MarbleRunnerManagerPrivate::plugins( RunnerPlugin::Capability capability )
template<typename T>
QList<T*> MarbleRunnerManagerPrivate::plugins( const QList<T*> &plugins )
{
QList<RunnerPlugin*> result;
QList<RunnerPlugin*> plugins = m_pluginManager->runnerPlugins();
foreach( RunnerPlugin* plugin, plugins ) {
if ( !plugin->supports( capability ) ) {
continue;
}
QList<T*> result;
foreach( T* plugin, plugins ) {
if ( ( m_marbleModel && m_marbleModel->workOffline() && !plugin->canWorkOffline() ) ) {
continue;
}
if ( !plugin->canWork( capability ) ) {
if ( !plugin->canWork() ) {
continue;
}
......@@ -207,8 +207,8 @@ void MarbleRunnerManager::findPlacemarks( const QString &searchTerm )
return;
}
QList<RunnerPlugin*> plugins = d->plugins( RunnerPlugin::Search );
foreach( const RunnerPlugin* plugin, plugins ) {
QList<const SearchRunnerPlugin*> plugins = d->plugins( d->m_pluginManager->searchRunnerPlugins() );
foreach( const SearchRunnerPlugin* plugin, plugins ) {
SearchTask* task = new SearchTask( plugin, this, d->m_marbleModel, searchTerm );
connect( task, SIGNAL( finished( RunnerTask* ) ), this, SLOT( cleanupSearchTask( RunnerTask* ) ) );
d->m_searchTasks << task;
......@@ -262,8 +262,8 @@ void MarbleRunnerManager::reverseGeocoding( const GeoDataCoordinates &coordinate
d->m_reverseTasks.clear();
d->m_reverseGeocodingResult.clear();
d->m_reverseGeocodingResults.removeAll( coordinates );
QList<RunnerPlugin*> plugins = d->plugins( RunnerPlugin::ReverseGeocoding );
foreach( const RunnerPlugin* plugin, plugins ) {
QList<const ReverseGeocodingRunnerPlugin*> plugins = d->plugins( d->m_pluginManager->reverseGeocodingRunnerPlugins() );
foreach( const ReverseGeocodingRunnerPlugin* plugin, plugins ) {
ReverseGeocodingTask* task = new ReverseGeocodingTask( plugin, this, d->m_marbleModel, coordinates );
connect( task, SIGNAL( finished( RunnerTask* ) ), this, SLOT( cleanupReverseGeocodingTask(RunnerTask*) ) );
mDebug() << "reverse task " << plugin->nameId() << " " << (long)task;
......@@ -312,8 +312,8 @@ void MarbleRunnerManager::retrieveRoute( const RouteRequest *request )
d->m_routingTasks.clear();
d->m_routingResult.clear();
QList<RunnerPlugin*> plugins = d->plugins( RunnerPlugin::Routing );
foreach( const RunnerPlugin* plugin, plugins ) {
QList<RoutingRunnerPlugin*> plugins = d->plugins( d->m_pluginManager->routingRunnerPlugins() );
foreach( RoutingRunnerPlugin* plugin, plugins ) {
if ( !profile.name().isEmpty() && !profile.pluginSettings().contains( plugin->nameId() ) ) {
continue;
}
......@@ -357,8 +357,8 @@ QVector<GeoDataDocument*> MarbleRunnerManager::searchRoute( const RouteRequest *
void MarbleRunnerManager::parseFile( const QString &fileName, DocumentRole role )
{
QList<RunnerPlugin*> plugins = d->plugins( RunnerPlugin::Parsing );
foreach( const RunnerPlugin *plugin, plugins ) {
QList<const ParseRunnerPlugin*> plugins = d->m_pluginManager->parsingRunnerPlugins();
foreach( const ParseRunnerPlugin *plugin, plugins ) {
ParsingTask *task = new ParsingTask( plugin, this, fileName, role );
connect( task, SIGNAL( finished( RunnerTask* ) ), this, SLOT( cleanupParsingTask(RunnerTask*) ) );
mDebug() << "parse task " << plugin->nameId() << " " << (long)task;
......
//
// This file is part of the Marble Virtual Globe.
//
// This program is free software licensed under the GNU LGPL. You can
// find a copy of this license in LICENSE.txt in the top directory of
// the source code.
//
// Copyright 2010 Dennis Nienhüser <earthwings@gentoo.org>
// Copyright 2011 Thibaut Gridel <tgridel@free.fr>
// Copyright 2012 Bernhard Beschow <bbeschow@cs.tu-berlin.de>
//
#include "ParseRunnerPlugin.h"
namespace Marble
{
class ParseRunnerPlugin::Private
{
public:
Private();
};
ParseRunnerPlugin::Private::Private()
{
// nothing to do
}
ParseRunnerPlugin::ParseRunnerPlugin( QObject* parent ) :
QObject( parent ),
d( new Private )
{
}
ParseRunnerPlugin::~ParseRunnerPlugin()
{
delete d;
}
QIcon ParseRunnerPlugin::icon() const
{
return QIcon();
}
}
#include "ParseRunnerPlugin.moc"
//
// This file is part of the Marble Virtual Globe.
//
// This program is free software licensed under the GNU LGPL. You can
// find a copy of this license in LICENSE.txt in the top directory of
// the source code.
//
// Copyright 2010 Dennis Nienhüser <earthwings@gentoo.org>
// Copyright 2011 Thibaut Gridel <tgridel@free.fr>
// Copyright 2012 Bernhard Beschow <bbeschow@cs.tu-berlin.de>
//
#ifndef MARBLE_PARSERUNNERPLUGIN_H
#define MARBLE_PARSERUNNERPLUGIN_H
#include <QtCore/QObject>
#include "PluginInterface.h"
namespace Marble
{
class MarbleAbstractRunner;
/**
* A plugin for Marble to execute a parsing task.
*/
class MARBLE_EXPORT ParseRunnerPlugin : public QObject, public PluginInterface
{
Q_OBJECT
public:
/** Constructor with optional parent object */
explicit ParseRunnerPlugin( QObject* parent = 0 );
/** Destructor */
virtual ~ParseRunnerPlugin();
/**
* @brief Returns the string that should appear in the user interface.
*
* For example, "Google Earth KML" should be returned for the kml parsing plugin.
*/
virtual QString guiString() const = 0;
/** Plugin factory method to create a new runner instance.
* Method caller gets ownership of the returned object
*/
virtual MarbleAbstractRunner* newRunner() const = 0;
// Overridden methods with default implementations
virtual QIcon icon() const;
private:
class Private;
Private *const d;
};
}
Q_DECLARE_INTERFACE( Marble::ParseRunnerPlugin, "org.kde.Marble.ParseRunnerPlugin/1.00" )
#endif // MARBLE_PARSERUNNERPLUGIN_H
......@@ -25,7 +25,10 @@
#include "NetworkPlugin.h"
#include "PositionProviderPlugin.h"
#include "AbstractFloatItem.h"
#include "RunnerPlugin.h"
#include "ParseRunnerPlugin.h"
#include "ReverseGeocodingRunnerPlugin.h"
#include "RoutingRunnerPlugin.h"
#include "SearchRunnerPlugin.h"
namespace Marble
{
......@@ -46,7 +49,10 @@ class PluginManagerPrivate
QList<const RenderPlugin *> m_renderPluginTemplates;
QList<const NetworkPlugin *> m_networkPluginTemplates;
QList<const PositionProviderPlugin *> m_positionProviderPluginTemplates;
QList<RunnerPlugin *> m_runnerPlugins;
QList<const SearchRunnerPlugin *> m_searchRunnerPlugins;
QList<const ReverseGeocodingRunnerPlugin *> m_reverseGeocodingRunnerPlugins;
QList<RoutingRunnerPlugin *> m_routingRunnerPlugins;
QList<const ParseRunnerPlugin *> m_parsingRunnerPlugins;
};
PluginManagerPrivate::~PluginManagerPrivate()
......@@ -82,10 +88,28 @@ QList<const PositionProviderPlugin *> PluginManager::positionProviderPlugins() c
return d->m_positionProviderPluginTemplates;
}
QList<RunnerPlugin *> PluginManager::runnerPlugins() const
QList<const SearchRunnerPlugin *> PluginManager::searchRunnerPlugins() const
{
d->loadPlugins();
return d->m_runnerPlugins;
return d->m_searchRunnerPlugins;
}
QList<const ReverseGeocodingRunnerPlugin *> PluginManager::reverseGeocodingRunnerPlugins() const
{
d->loadPlugins();
return d->m_reverseGeocodingRunnerPlugins;
}
QList<RoutingRunnerPlugin *> PluginManager::routingRunnerPlugins() const
{
d->loadPlugins();
return d->m_routingRunnerPlugins;
}
QList<const ParseRunnerPlugin *> PluginManager::parsingRunnerPlugins() const
{
d->loadPlugins();
return d->m_parsingRunnerPlugins;
}
/** Append obj to the given plugins list if it inherits both T and U */
......@@ -140,7 +164,10 @@ void PluginManagerPrivate::loadPlugins()
Q_ASSERT( m_renderPluginTemplates.isEmpty() );
Q_ASSERT( m_networkPluginTemplates.isEmpty() );
Q_ASSERT( m_positionProviderPluginTemplates.isEmpty() );
Q_ASSERT( m_runnerPlugins.isEmpty() );
Q_ASSERT( m_searchRunnerPlugins.isEmpty() );
Q_ASSERT( m_reverseGeocodingRunnerPlugins.isEmpty() );
Q_ASSERT( m_routingRunnerPlugins.isEmpty() );
Q_ASSERT( m_parsingRunnerPlugins.isEmpty() );
foreach( const QString &fileName, pluginFileNameList ) {
// mDebug() << fileName << " - " << MarbleDirs::pluginPath( fileName );
......@@ -156,8 +183,14 @@ void PluginManagerPrivate::loadPlugins()
( obj, loader, m_networkPluginTemplates );
isPlugin = isPlugin || appendPlugin<PositionProviderPlugin, PositionProviderPluginInterface>
( obj, loader, m_positionProviderPluginTemplates );
isPlugin = isPlugin || appendPlugin<RunnerPlugin, RunnerPlugin>
( obj, loader, m_runnerPlugins ); // intentionally T==U
isPlugin = isPlugin || appendPlugin<SearchRunnerPlugin, SearchRunnerPlugin>
( obj, loader, m_searchRunnerPlugins ); // intentionally T==U
isPlugin = isPlugin || appendPlugin<ReverseGeocodingRunnerPlugin, ReverseGeocodingRunnerPlugin>
( obj, loader, m_reverseGeocodingRunnerPlugins ); // intentionally T==U
isPlugin = isPlugin || appendPlugin<RoutingRunnerPlugin, RoutingRunnerPlugin>
( obj, loader, m_routingRunnerPlugins ); // intentionally T==U
isPlugin = isPlugin || appendPlugin<ParseRunnerPlugin, ParseRunnerPlugin>
( obj, loader, m_parsingRunnerPlugins ); // intentionally T==U
if ( !isPlugin ) {
mDebug() << "Plugin failure:" << fileName << "is a plugin, but it does not implement the "
<< "right interfaces or it was compiled against an old version of Marble. Ignoring it.";
......
......@@ -24,7 +24,10 @@ class NetworkPlugin;
class PositionProviderPlugin;
class AbstractFloatItem;
class PluginManagerPrivate;
class RunnerPlugin;
class SearchRunnerPlugin;
class ReverseGeocodingRunnerPlugin;
class RoutingRunnerPlugin;
class ParseRunnerPlugin;
/**
* @short The class that handles Marble's plugins.
......@@ -74,10 +77,28 @@ class MARBLE_EXPORT PluginManager
QList<const PositionProviderPlugin *> positionProviderPlugins() const;
/**
* Returns all runner plugins.
* @note: Runner plugins are owned by the PluginManager, do not delete them
* Returns all search runner plugins.
* @note: Runner plugins are owned by the PluginManager, do not delete them.
*/
QList<RunnerPlugin *> runnerPlugins() const;
QList<const SearchRunnerPlugin *> searchRunnerPlugins() const;
/**
* Returns all reverse geocoding runner plugins.
* @note: The runner plugins are owned by the PluginManager, do not delete them.
*/
QList<const ReverseGeocodingRunnerPlugin *> reverseGeocodingRunnerPlugins() const;
/**
* Returns all routing runner plugins.
* @note: The runner plugins are owned by the PluginManager, do not delete them.
*/
QList<RoutingRunnerPlugin *> routingRunnerPlugins() const;
/**
* Returns all parse runner plugins.
* @note: The runner plugins are owned by the PluginManager, do not delete them.
*/
QList<const ParseRunnerPlugin *> parsingRunnerPlugins() const;
private:
Q_DISABLE_COPY( PluginManager )
......
//
// This file is part of the Marble Virtual Globe.
//
// This program is free software licensed under the GNU LGPL. You can
// find a copy of this license in LICENSE.txt in the top directory of
// the source code.
//
// Copyright 2010 Dennis Nienhüser <earthwings@gentoo.org>
// Copyright 2011 Thibaut Gridel <tgridel@free.fr>
// Copyright 2012 Bernhard Beschow <bbeschow@cs.tu-berlin.de>
//
#include "ReverseGeocodingRunnerPlugin.h"
namespace Marble
{
class ReverseGeocodingRunnerPlugin::Private
{
public:
QStringList m_supportedCelestialBodies;
bool m_canWorkOffline;
Private();
};
ReverseGeocodingRunnerPlugin::Private::Private()
: m_canWorkOffline( true )
{
// nothing to do
}
ReverseGeocodingRunnerPlugin::ReverseGeocodingRunnerPlugin( QObject* parent ) :
QObject( parent ),
d( new Private )
{
}
ReverseGeocodingRunnerPlugin::~ReverseGeocodingRunnerPlugin()
{
delete d;
}
QIcon ReverseGeocodingRunnerPlugin::icon() const
{
return QIcon();
}
bool ReverseGeocodingRunnerPlugin::supportsCelestialBody( const QString &celestialBodyId ) const
{
if ( d->m_supportedCelestialBodies.isEmpty() ) {
return true;
}
return d->m_supportedCelestialBodies.contains( celestialBodyId );
}
void ReverseGeocodingRunnerPlugin::setSupportedCelestialBodies( const QStringList &celestialBodies )
{
d->m_supportedCelestialBodies = celestialBodies;
}
void ReverseGeocodingRunnerPlugin::setCanWorkOffline( bool canWorkOffline )
{
d->m_canWorkOffline = canWorkOffline;
}
bool ReverseGeocodingRunnerPlugin::canWorkOffline() const
{
return d->m_canWorkOffline;
}
bool ReverseGeocodingRunnerPlugin::canWork() const
{
return true;
}
}
#include "ReverseGeocodingRunnerPlugin.moc"
//
// This file is part of the Marble Virtual Globe.
//
// This program is free software licensed under the GNU LGPL. You can
// find a copy of this license in LICENSE.txt in the top directory of
// the source code.
//
// Copyright 2010 Dennis Nienhüser <earthwings@gentoo.org>
// Copyright 2011 Thibaut Gridel <tgridel@free.fr>
// Copyright 2012 Bernhard Beschow <bbeschow@cs.tu-berlin.de>
//
#ifndef MARBLE_REVERSEGEOCODINGRUNNERPLUGIN_H
#define MARBLE_REVERSEGEOCODINGRUNNERPLUGIN_H
#include <QtCore/QObject>
#include "PluginInterface.h"
namespace Marble
{
class MarbleAbstractRunner;
/**
* A plugin for Marble to execute a reverse geocoding task.
*/
class MARBLE_EXPORT ReverseGeocodingRunnerPlugin : public QObject, public PluginInterface
{
Q_OBJECT
public:
/** Constructor with optional parent object */
explicit ReverseGeocodingRunnerPlugin( QObject* parent = 0 );
/** Destructor */
virtual ~ReverseGeocodingRunnerPlugin();
/**
* @brief Returns the string that should appear in the user interface.
*
* For example, "Nominatim" should be returned for the Nominatim reverse geocoding plugin.
*/
virtual QString guiString() const = 0;
/** Plugin factory method to create a new runner instance.
* Method caller gets ownership of the returned object
*/
virtual MarbleAbstractRunner* newRunner() const = 0;
/** True if the plugin supports its tasks on the given planet */
bool supportsCelestialBody( const QString &celestialBodyId ) const;
/** True if the plugin can execute its tasks without network access */
bool canWorkOffline() const;
/**
* @brief Returns @code true @endcode if the plugin is able to perform its claimed task.
*
* The default implementation returns @code true @endcode. This method can be
* overridden for example to indicate an incomplete installation.
*/
virtual bool canWork() const;
// Overridden methods with default implementations
virtual QIcon icon() const;
protected:
void setSupportedCelestialBodies( const QStringList &celestialBodies );
void setCanWorkOffline( bool canWorkOffline );
private:
class Private;
Private * const d;
};
}
Q_DECLARE_INTERFACE( Marble::ReverseGeocodingRunnerPlugin, "org.kde.Marble.ReverseGeocodingRunnerPlugin/1.0" )
#endif // MARBLE_REVERSEGEOCODINGRUNNERPLUGIN_H
......@@ -7,63 +7,49 @@
//
// Copyright 2010 Dennis Nienhüser <earthwings@gentoo.org>
// Copyright 2011 Thibaut Gridel <tgridel@free.fr>
// Copyright 2012 Bernhard Beschow <bbeschow@cs.tu-berlin.de>
//
#include "RunnerPlugin.h"
#include "RoutingRunnerPlugin.h"
namespace Marble
{
class RunnerPluginPrivate
class RoutingRunnerPlugin::Private
{
public:
RunnerPlugin::Capabilities m_capabilities;
QStringList m_supportedCelestialBodies;
bool m_canWorkOffline;
QString m_statusMessage;
RunnerPluginPrivate();
Private();
};
RunnerPluginPrivate::RunnerPluginPrivate() : m_canWorkOffline( true )
RoutingRunnerPlugin::Private::Private()
: m_canWorkOffline( true )
{
// nothing to do
}
RunnerPlugin::RunnerPlugin( QObject* parent ) : QObject( parent ),
d( new RunnerPluginPrivate )
RoutingRunnerPlugin::RoutingRunnerPlugin( QObject *parent ) :
QObject( parent ),
d( new Private )
{
setCapabilities( RunnerPlugin::None );
}
RunnerPlugin::~RunnerPlugin()
RoutingRunnerPlugin::~RoutingRunnerPlugin()
{
delete d;
}
RunnerPlugin::Capabilities RunnerPlugin::capabilities() const
{
return d->m_capabilities;
}
bool RunnerPlugin::supports( Capability capability ) const
{
return d->m_capabilities & capability;
}
void RunnerPlugin::setCapabilities( Capabilities capabilities )
{
d->m_capabilities = capabilities;
}
QIcon RunnerPlugin::icon() const
QIcon RoutingRunnerPlugin::icon() const
{
return QIcon();
}
bool RunnerPlugin::supportsCelestialBody( const QString &celestialBodyId ) const
bool RoutingRunnerPlugin::supportsCelestialBody( const QString &celestialBodyId ) const
{
if ( d->m_supportedCelestialBodies.isEmpty() ) {
return true;
......@@ -72,51 +58,51 @@ bool RunnerPlugin::supportsCelestialBody( const QString &celestialBodyId ) const
return d->m_supportedCelestialBodies.contains( celestialBodyId );
}
void RunnerPlugin::setSupportedCelestialBodies( const QStringList &celestialBodies )
void RoutingRunnerPlugin::setSupportedCelestialBodies( const QStringList &celestialBodies )
{
d->m_supportedCelestialBodies = celestialBodies;
}
void RunnerPlugin::setCanWorkOffline( bool canWorkOffline )
void RoutingRunnerPlugin::setCanWorkOffline( bool canWorkOffline )
{
d->m_canWorkOffline = canWorkOffline;