Skip to content

Commit

Permalink
Manage python plugins loaded state in python utils.py module.
Browse files Browse the repository at this point in the history
This allows seamless loading/unloading of plugins by plugin installer.


git-svn-id: http://svn.osgeo.org/qgis/trunk/qgis@12552 c8812cc2-4d05-0410-92ff-de0c093fc19c
  • Loading branch information
wonder committed Dec 20, 2009
1 parent df933c3 commit 7d11220
Show file tree
Hide file tree
Showing 7 changed files with 97 additions and 40 deletions.
21 changes: 19 additions & 2 deletions python/utils.py
Expand Up @@ -91,6 +91,9 @@ def uninstallConsoleHooks():
# dictionary of plugins
plugins = {}

# list of active (started) plugins
active_plugins = []

def pluginMetadata(packageName, fct):
""" fetch metadata from a plugin """
try:
Expand Down Expand Up @@ -125,7 +128,9 @@ def loadPlugin(packageName):

def startPlugin(packageName):
""" initialize the plugin """
global plugins, iface
global plugins, active_plugins, iface

if packageName in active_plugins: return False

package = sys.modules[packageName]

Expand All @@ -147,20 +152,32 @@ def startPlugin(packageName):
showException(sys.exc_type, sys.exc_value, sys.exc_traceback, msg)
return False

# add to active plugins
active_plugins.append(packageName)

return True


def unloadPlugin(packageName):
""" unload and delete plugin! """
global plugins
global plugins, active_plugins

if not plugins.has_key(packageName): return False
if packageName not in active_plugins: return False

try:
plugins[packageName].unload()
del plugins[packageName]
active_plugins.remove(packageName)
return True
except Exception, e:
msg = QCoreApplication.translate("Python", "Error while unloading plugin %1").arg(packageName)
showException(sys.exc_type, sys.exc_value, sys.exc_traceback, msg)
return False

def isPluginLoaded(packageName):
""" find out whether a plugin is active (i.e. has been started) """
global plugins, active_plugins

if not plugins.has_key(packageName): return False
return (packageName in active_plugins)
11 changes: 2 additions & 9 deletions src/app/qgspluginmetadata.cpp
Expand Up @@ -21,12 +21,10 @@
#include "qgspluginmetadata.h"
QgsPluginMetadata::QgsPluginMetadata( QString _libraryPath,
QString _name,
QgisPlugin * _plugin,
bool _python ):
QgisPlugin * _plugin ):
m_name( _name ),
libraryPath( _libraryPath ),
m_plugin( _plugin ),
m_python( _python )
m_plugin( _plugin )
{

}
Expand All @@ -45,8 +43,3 @@ QgisPlugin *QgsPluginMetadata::plugin()
{
return m_plugin;
}

bool QgsPluginMetadata::isPython()
{
return m_python;
}
4 changes: 1 addition & 3 deletions src/app/qgspluginmetadata.h
Expand Up @@ -30,16 +30,14 @@ class QgisPlugin;
class QgsPluginMetadata
{
public:
QgsPluginMetadata( QString _libraryPath, QString _name, QgisPlugin *_plugin, bool _python = false );
QgsPluginMetadata( QString _libraryPath, QString _name, QgisPlugin *_plugin );
QString name();
QString library();
QgisPlugin *plugin();
bool isPython();
private:
QString m_name;
QString libraryPath;
QgisPlugin *m_plugin;
bool m_python;
};
#endif //QGSPLUGINMETADATA_H

75 changes: 49 additions & 26 deletions src/app/qgspluginregistry.cpp
Expand Up @@ -68,16 +68,30 @@ void QgsPluginRegistry::setPythonUtils( QgsPythonUtils* pythonUtils )
bool QgsPluginRegistry::isLoaded( QString key )
{
QMap<QString, QgsPluginMetadata>::iterator it = mPlugins.find( key );
return ( it != mPlugins.end() );
if ( it != mPlugins.end() ) // found a c++ plugin?
return true;

if ( mPythonUtils && mPythonUtils->isEnabled() )
{
return mPythonUtils->isPluginLoaded( key );
}

return false;
}

QString QgsPluginRegistry::library( QString key )
{
QMap<QString, QgsPluginMetadata>::iterator it = mPlugins.find( key );
if ( it == mPlugins.end() )
return QString();
if ( it != mPlugins.end() )
return it->library();

return it->library();
if ( mPythonUtils && mPythonUtils->isEnabled() )
{
if ( mPythonUtils->isPluginLoaded( key ) )
return key;
}

return QString();
}

QgisPlugin *QgsPluginRegistry::plugin( QString key )
Expand All @@ -86,15 +100,19 @@ QgisPlugin *QgsPluginRegistry::plugin( QString key )
if ( it == mPlugins.end() )
return NULL;

// note: not used by python plugins

return it->plugin();
}

bool QgsPluginRegistry::isPythonPlugin( QString key )
{
QMap<QString, QgsPluginMetadata>::iterator it = mPlugins.find( key );
if ( it == mPlugins.end() )
return false;
return it->isPython();
if ( mPythonUtils && mPythonUtils->isEnabled() )
{
if ( mPythonUtils->isPluginLoaded( key ) )
return true;
}
return false;
}

void QgsPluginRegistry::addPlugin( QString key, QgsPluginMetadata metadata )
Expand All @@ -104,16 +122,24 @@ void QgsPluginRegistry::addPlugin( QString key, QgsPluginMetadata metadata )

void QgsPluginRegistry::dump()
{
QgsDebugMsg( "PLUGINS IN REGISTRY: key -> (name, library, isPython)" );
QgsDebugMsg( "PLUGINS IN REGISTRY: key -> (name, library)" );
for ( QMap<QString, QgsPluginMetadata>::iterator it = mPlugins.begin();
it != mPlugins.end();
it++ )
{
QgsDebugMsg( QString( "PLUGIN: %1 -> (%2, %3, %4)" )
QgsDebugMsg( QString( "PLUGIN: %1 -> (%2, %3)" )
.arg( it.key() )
.arg( it->name() )
.arg( it->library() )
.arg( it->isPython() ) );
.arg( it->library() ) );
}

if ( mPythonUtils && mPythonUtils->isEnabled() )
{
QgsDebugMsg( "PYTHON PLUGINS IN REGISTRY:" );
foreach( QString pluginName, mPythonUtils->listActivePlugins() )
{
QgsDebugMsg( pluginName );
}
}
}

Expand All @@ -126,6 +152,8 @@ void QgsPluginRegistry::removePlugin( QString key )
{
mPlugins.erase( it );
}

// python plugins are removed when unloaded
}

void QgsPluginRegistry::unloadAll()
Expand All @@ -134,19 +162,17 @@ void QgsPluginRegistry::unloadAll()
it != mPlugins.end();
it++ )
{
if ( isPythonPlugin( it.key() ) )
{
if ( mPythonUtils )
mPythonUtils->unloadPlugin( it->library() );
else
QgsDebugMsg( "warning: python utils is NULL" );
}
if ( it->plugin() )
it->plugin()->unload();
else
QgsDebugMsg( "warning: plugin is NULL:" + it.key() );
}

if ( mPythonUtils && mPythonUtils->isEnabled() )
{
foreach( QString pluginName, mPythonUtils->listActivePlugins() )
{
if ( it->plugin() )
it->plugin()->unload();
else
QgsDebugMsg( "warning: plugin is NULL:" + it.key() );
mPythonUtils->unloadPlugin( pluginName );
}
}
}
Expand Down Expand Up @@ -222,9 +248,6 @@ void QgsPluginRegistry::loadPythonPlugin( QString packageName )

QString pluginName = mPythonUtils->getPluginMetadata( packageName, "name" );

// add to plugin registry
addPlugin( packageName, QgsPluginMetadata( packageName, pluginName, NULL, true ) );

// add to settings
settings.setValue( "/PythonPlugins/" + packageName, true );
std::cout << "Loaded : " << pluginName.toLocal8Bit().constData() << " (package: "
Expand Down
6 changes: 6 additions & 0 deletions src/python/qgspythonutils.h
Expand Up @@ -76,6 +76,12 @@ class PYTHON_EXPORT QgsPythonUtils
//! return list of all available python plugins
virtual QStringList pluginList() = 0;

//! return whether the plugin is loaded (active)
virtual bool isPluginLoaded( QString packageName ) = 0;

//! return a list of active plugins
virtual QStringList listActivePlugins() = 0;

//! load python plugin (import)
virtual bool loadPlugin( QString packageName ) = 0;

Expand Down
14 changes: 14 additions & 0 deletions src/python/qgspythonutilsimpl.cpp
Expand Up @@ -475,3 +475,17 @@ bool QgsPythonUtilsImpl::unloadPlugin( QString packageName )
evalString( "qgis.utils.unloadPlugin('" + packageName + "')", output );
return ( output == "True" );
}

bool QgsPythonUtilsImpl::isPluginLoaded( QString packageName )
{
QString output;
evalString( "qgis.utils.isPluginLoaded('" + packageName + "')", output );
return ( output == "True" );
}

QStringList QgsPythonUtilsImpl::listActivePlugins()
{
QString output;
evalString( "'\\n'.join(qgis.utils.active_plugins)", output );
return output.split( QChar( '\n' ) );
}
6 changes: 6 additions & 0 deletions src/python/qgspythonutilsimpl.h
Expand Up @@ -98,6 +98,12 @@ class QgsPythonUtilsImpl : public QgsPythonUtils
//! return list of all available python plugins
QStringList pluginList();

//! return whether the plugin is loaded (active)
virtual bool isPluginLoaded( QString packageName );

//! return a list of active plugins
virtual QStringList listActivePlugins();

//! load python plugin (import)
bool loadPlugin( QString packageName );

Expand Down

0 comments on commit 7d11220

Please sign in to comment.