9#include "PluginManager.h"
12#include <QPluginLoader>
13#include <QElapsedTimer>
17#include "MarbleDirs.h"
18#include "MarbleDebug.h"
19#include "RenderPlugin.h"
20#include "PositionProviderPlugin.h"
21#include "ParseRunnerPlugin.h"
22#include "ReverseGeocodingRunnerPlugin.h"
23#include "RoutingRunnerPlugin.h"
24#include "SearchRunnerPlugin.h"
25#include <config-marble.h>
30class PluginManagerPrivate
33 PluginManagerPrivate(PluginManager* parent)
34 : m_pluginsLoaded(false),
39 ~PluginManagerPrivate();
51 PluginManager* m_parent;
63PluginManagerPrivate::~PluginManagerPrivate()
68PluginManager::PluginManager(
QObject *parent ) :
QObject( parent ),
69 d( new PluginManagerPrivate(this) )
73 installPluginsFromAssets();
77PluginManager::~PluginManager()
85 return d->m_renderPluginTemplates;
91 d->m_renderPluginTemplates << plugin;
92 emit renderPluginsChanged();
98 return d->m_positionProviderPluginTemplates;
104 d->m_positionProviderPluginTemplates << plugin;
105 emit positionProviderPluginsChanged();
111 return d->m_searchRunnerPlugins;
117 d->m_searchRunnerPlugins << plugin;
118 emit searchRunnerPluginsChanged();
124 return d->m_reverseGeocodingRunnerPlugins;
130 d->m_reverseGeocodingRunnerPlugins << plugin;
131 emit reverseGeocodingRunnerPluginsChanged();
137 return d->m_routingRunnerPlugins;
143 d->m_routingRunnerPlugins << plugin;
144 emit routingRunnerPluginsChanged();
150 return d->m_parsingRunnerPlugins;
156 d->m_parsingRunnerPlugins << plugin;
157 emit parseRunnerPluginsChanged();
160void PluginManager::blacklistPlugin(
const QString &filename)
162 PluginManagerPrivate::m_blacklist << MARBLE_SHARED_LIBRARY_PREFIX + filename;
165void PluginManager::whitelistPlugin(
const QString &filename)
167 PluginManagerPrivate::m_whitelist << MARBLE_SHARED_LIBRARY_PREFIX + filename;
171template<
class Iface,
class Plugin>
174 if ( qobject_cast<Iface*>( obj ) && qobject_cast<Plugin>( obj ) ) {
177 <<
"plugin loaded from" << (loader ? loader->
fileName() :
"<static>");
178 auto plugin = qobject_cast<Plugin>( obj );
189 bool isPlugin = appendPlugin<RenderPluginInterface>
190 ( obj, loader, m_renderPluginTemplates );
191 isPlugin = isPlugin || appendPlugin<PositionProviderPluginInterface>
192 ( obj, loader, m_positionProviderPluginTemplates );
193 isPlugin = isPlugin || appendPlugin<SearchRunnerPlugin>
194 ( obj, loader, m_searchRunnerPlugins );
195 isPlugin = isPlugin || appendPlugin<ReverseGeocodingRunnerPlugin>
196 ( obj, loader, m_reverseGeocodingRunnerPlugins );
197 isPlugin = isPlugin || appendPlugin<RoutingRunnerPlugin>
198 ( obj, loader, m_routingRunnerPlugins );
199 isPlugin = isPlugin || appendPlugin<ParseRunnerPlugin>
200 ( obj, loader, m_parsingRunnerPlugins );
202 qWarning() <<
"Ignoring the following plugin since it couldn't be loaded:" << (loader ? loader->
fileName() :
"<static>");
203 mDebug() <<
"Plugin failure:" << (loader ? loader->
fileName() :
"<static>") <<
"is a plugin, but it does not implement the "
204 <<
"right interfaces or it was compiled against an old version of Marble. Ignoring it.";
209void PluginManagerPrivate::loadPlugins()
218 mDebug() <<
"Starting to load Plugins.";
224 Q_ASSERT( m_renderPluginTemplates.isEmpty() );
225 Q_ASSERT( m_positionProviderPluginTemplates.isEmpty() );
226 Q_ASSERT( m_searchRunnerPlugins.isEmpty() );
227 Q_ASSERT( m_reverseGeocodingRunnerPlugins.isEmpty() );
228 Q_ASSERT( m_routingRunnerPlugins.isEmpty() );
229 Q_ASSERT( m_parsingRunnerPlugins.isEmpty() );
231 bool foundPlugin =
false;
232 for(
const QString &fileName: pluginFileNameList ) {
235 if (!m_whitelist.isEmpty() && !m_whitelist.contains(baseName) && !m_whitelist.contains(libBaseName)) {
236 mDebug() <<
"Ignoring non-whitelisted plugin " << fileName;
239 if (m_blacklist.contains(baseName) || m_blacklist.contains(libBaseName)) {
240 mDebug() <<
"Ignoring blacklisted plugin " << fileName;
245 QString const path = MarbleDirs::pluginPath( fileName );
248 if ( !m_pluginPaths.contains( targetFile.canonicalFilePath() ) ) {
250 qDebug() <<
"Ignoring file " <<
path <<
" which is not among the currently installed plugins";
259 bool isPlugin = addPlugin(obj, loader);
266 qWarning() <<
"Ignoring to load the following file since it doesn't look like a valid Marble plugin:" <<
path <<
endl
273 for (
auto obj : staticPlugins) {
274 if (addPlugin(obj,
nullptr)) {
279 if ( !foundPlugin ) {
282 if ( MarbleDirs::marblePluginPath().isEmpty() )
284 pluginPaths +=
"System Path: " + MarbleDirs::pluginSystemPath() +
"\nLocal Path: " + MarbleDirs::pluginLocalPath();
288 "No plugins were loaded, please check if the plugins were installed in one of the following paths:\n" + pluginPaths
289 +
"\n\nAlso check if the plugin is compiled against the right version of Marble. " +
290 "Analyzing the debug messages inside a debugger might give more insight." );
292 qWarning() <<
"No plugins loaded. Please check if the plugins were installed in the correct path,"
293 <<
"or if any errors occurred while loading plugins.";
297 m_pluginsLoaded =
true;
299 mDebug() <<
"Time elapsed:" << t.
elapsed() <<
"ms";
303 void PluginManager::installPluginsFromAssets()
const
305 d->m_pluginPaths.clear();
307 QDir pluginHome(MarbleDirs::localPath());
308 pluginHome.mkpath(MarbleDirs::pluginLocalPath());
309 pluginHome.setCurrent(MarbleDirs::pluginLocalPath());
313 for(
const QString &existingPlugin: existingPlugins) {
317 for (
const QString & file: copyList) {
320 pluginHome.mkpath(target);
323 QFile temporaryFile(MarbleDirs::pluginSystemPath() +
QLatin1Char(
'/') + file);
324 temporaryFile.copy(target);
326 d->m_pluginPaths << targetFile.canonicalFilePath();
334#include "moc_PluginManager.cpp"
A plugin for Marble to execute a parsing task.
The abstract class that provides position information.
The abstract class that creates a renderable item.
A plugin for Marble to execute a reverse geocoding task.
A plugin for Marble to execute a routing task.
A plugin for Marble to execute a placemark search.
QString path(const QString &relativePath)
Binds a QML item to a specific geodetic location in screen coordinates.
bool appendPlugin(QObject *obj, const QPluginLoader *loader, QList< Plugin > &plugins)
Append obj to the given plugins list if it inherits both T and U.
QCA_EXPORT QStringList pluginPaths()
QStringList entryList(Filters filters, SortFlags sort) const const
qint64 elapsed() const const
QString baseName() const const
StandardButton warning(QWidget *parent, const QString &title, const QString &text, StandardButtons buttons, StandardButton defaultButton)
QString errorString() const const
QObjectList staticInstances()
QTextStream & endl(QTextStream &stream)