Commit a854dddd authored by Kenneth Moreland's avatar Kenneth Moreland
Browse files

ENH: Add ability to embed a python script in a plugin and then use it as

a module in paraview scripting (with the import command).
parent ad04642b
......@@ -156,6 +156,69 @@ MACRO(ADD_SERVER_MANAGER_EXTENSION OUTSRCS Name XMLFile)
ENDMACRO(ADD_SERVER_MANAGER_EXTENSION)
MACRO(ADD_PYTHON_EXTENSION OUTSRCS NAME)
SET(PYSRCFILES ${ARGN})
SET(WRAP_PY_HEADERS)
SET(WRAP_PYTHON_INCLUDES)
SET(PY_MODULE_LIST)
SET(PY_LOADER_LIST)
SET(PY_PACKAGE_FLAGS)
IF (PARAVIEW_PROCESS_XML_EXECUTABLE)
SET(QT_COMPONENTS_GUI_RESOURCES_CONTENTS)
FOREACH(PYFILE ${PYSRCFILES})
GET_FILENAME_COMPONENT(PYFILE_ABSOLUTE "${PYFILE}" ABSOLUTE)
GET_FILENAME_COMPONENT(PYFILE_PACKAGE "${PYFILE}" PATH)
GET_FILENAME_COMPONENT(PYFILE_NAME "${PYFILE}" NAME_WE)
SET(PACKAGE_FLAG "0")
IF (PYFILE_PACKAGE)
STRING(REPLACE "/" "." PYFILE_PACKAGE "${PYFILE_PACKAGE}")
IF (${PYFILE_NAME} STREQUAL "__init__")
SET(PYFILE_MODULE "${PYFILE_PACKAGE}")
SET(PACKAGE_FLAG "1")
ELSE (${PYFILE_NAME} STREQUAL "__init__")
SET(PYFILE_MODULE "${PYFILE_PACKAGE}.${PYFILE_NAME}")
ENDIF (${PYFILE_NAME} STREQUAL "__init__")
ELSE (PYFILE_PACKAGE)
SET(PYFILE_MODULE "${PYFILE_NAME}")
ENDIF (PYFILE_PACKAGE)
STRING(REPLACE "." "_" PYFILE_MODULE_MANGLED "${PYFILE_MODULE}")
SET(PY_HEADER "${CMAKE_CURRENT_BINARY_DIR}/WrappedPython_${NAME}_${PYFILE_MODULE_MANGLED}.h")
ADD_CUSTOM_COMMAND(
OUTPUT "${PY_HEADER}"
DEPENDS "${PYFILE_ABSOLUTE}" "${PARAVIEW_PROCESS_XML_EXECUTABLE}"
COMMAND "${PARAVIEW_PROCESS_XML_EXECUTABLE}"
ARGS "${PY_HEADER}" "module_${PYFILE_MODULE_MANGLED}_" "_string" "_source" "${PYFILE_ABSOLUTE}"
)
SET(WRAP_PY_HEADERS ${WRAP_PY_HEADERS} "${PY_HEADER}")
SET(WRAP_PYTHON_INCLUDES
"${WRAP_PYTHON_INCLUDES}#include \"${PY_HEADER}\"\n")
IF(PY_MODULE_LIST)
SET(PY_MODULE_LIST
"${PY_MODULE_LIST},\n \"${PYFILE_MODULE}\"")
SET(PY_LOADER_LIST
"${PY_LOADER_LIST},\n module_${PYFILE_MODULE_MANGLED}_${PYFILE_NAME}_source()")
SET(PY_PACKAGE_FLAGS "${PY_PACKAGE_FLAGS}, ${PACKAGE_FLAG}")
ELSE(PY_MODULE_LIST)
SET(PY_MODULE_LIST "\"${PYFILE_MODULE}\"")
SET(PY_LOADER_LIST
"module_${PYFILE_MODULE_MANGLED}_${PYFILE_NAME}_source()")
SET(PY_PACKAGE_FLAGS "${PACKAGE_FLAG}")
ENDIF(PY_MODULE_LIST)
ENDFOREACH(PYFILE ${PYSRCFILES})
# Create source code to get Python source from the plugin.
SET(PY_INIT_SRC
"${CMAKE_CURRENT_BINARY_DIR}/vtkPVPythonPluginInit_${NAME}.cxx")
CONFIGURE_FILE(
"${ParaView_SOURCE_DIR}/Utilities/VTKPythonWrapping/vtkPVPythonPluginInit.cxx.in"
"${PY_INIT_SRC}" @ONLY)
SET(${OUTSRCS} "${PY_INIT_SRC}" "${WRAP_PY_HEADERS}")
ELSE (PARAVIEW_PROCESS_XML_EXECUTABLE)
MESSAGE("kwProcessXML not found. Plugin may not build correctly")
ENDIF (PARAVIEW_PROCESS_XML_EXECUTABLE)
ENDMACRO(ADD_PYTHON_EXTENSION)
# create implementation for a custom object panel interface
# ADD_PARAVIEW_OBJECT_PANEL(
# OUTIFACES
......@@ -690,6 +753,7 @@ ENDMACRO(PARAVIEW_QT4_ADD_RESOURCES)
# SERVER_MANAGER_SOURCES will be wrapped
# SERVER_MANAGER_XML will be embedded and give to the client when loaded
# SERVER_SOURCES is for other source files
# PYTHON_MODULES allows you to embed python sources as modules
# GUI_INTERFACES is to specify which GUI plugin interfaces were implemented
# GUI_RESOURCES is to specify qrc files
# GUI_RESOURCE_FILES is to specify xml files to create a qrc file from
......@@ -699,6 +763,7 @@ ENDMACRO(PARAVIEW_QT4_ADD_RESOURCES)
# [SERVER_MANAGER_SOURCES source files]
# [SERVER_MANAGER_XML XMLFile]
# [SERVER_SOURCES source files]
# [PYTHON_MODULES python source files]
# [GUI_INTERFACES interface1 interface2]
# [GUI_RESOURCES qrc1 qrc2]
# [GUI_RESOURCE_FILES xml1 xml2]
......@@ -712,20 +777,22 @@ MACRO(ADD_PARAVIEW_PLUGIN NAME VERSION)
SET(QT_RCS)
SET(GUI_SRCS)
SET(SM_SRCS)
SET(PY_SRCS)
SET(ARG_GUI_INTERFACES)
SET(ARG_GUI_RESOURCES)
SET(ARG_GUI_RESOURCE_FILES)
SET(ARG_SERVER_MANAGER_SOURCES)
SET(ARG_SERVER_MANAGER_XML)
SET(ARG_PYTHON_MODULES)
SET(ARG_SOURCES)
SET(ARG_SERVER_SOURCES)
SET(ARG_GUI_SOURCES)
INCLUDE_DIRECTORIES(${CMAKE_CURRENT_SOURCE_DIR})
INCLUDE_DIRECTORIES(${CMAKE_CURRENT_BINARY_DIR})
PV_PLUGIN_PARSE_ARGUMENTS(ARG
"SERVER_MANAGER_SOURCES;SERVER_MANAGER_XML;SERVER_SOURCES;GUI_INTERFACES;GUI_RESOURCES;GUI_RESOURCE_FILES;GUI_SOURCES;SOURCES"
"SERVER_MANAGER_SOURCES;SERVER_MANAGER_XML;SERVER_SOURCES;PYTHON_MODULES;GUI_INTERFACES;GUI_RESOURCES;GUI_RESOURCE_FILES;GUI_SOURCES;SOURCES"
"" ${ARGN} )
IF(ARG_SERVER_MANAGER_SOURCES OR ARG_SERVER_MANAGER_XML)
......@@ -733,6 +800,14 @@ MACRO(ADD_PARAVIEW_PLUGIN NAME VERSION)
${ARG_SERVER_MANAGER_SOURCES})
ENDIF(ARG_SERVER_MANAGER_SOURCES OR ARG_SERVER_MANAGER_XML)
IF (ARG_PYTHON_MODULES)
IF (PARAVIEW_ENABLE_PYTHON)
ADD_PYTHON_EXTENSION(PY_SRCS ${NAME} ${ARG_PYTHON_MODULES})
ELSE (PARAVIEW_ENABLE_PYTHON)
MESSAGE(STATUS "Python parameters ignored for ${NAME} plugin because PARAVIEW_ENABLE_PYTHON is off.")
ENDIF (PARAVIEW_ENABLE_PYTHON)
ENDIF (ARG_PYTHON_MODULES)
IF(PARAVIEW_BUILD_QT_GUI)
IF(ARG_GUI_RESOURCE_FILES)
SET(QT_COMPONENTS_GUI_RESOURCES_CONTENTS)
......@@ -769,7 +844,11 @@ MACRO(ADD_PARAVIEW_PLUGIN NAME VERSION)
ENDIF(PARAVIEW_BUILD_QT_GUI)
SET(SM_SRCS ${ARG_SERVER_MANAGER_SOURCES} ${SM_SRCS} ${ARG_SERVER_SOURCES})
SET(SM_SRCS
${ARG_SERVER_MANAGER_SOURCES}
${SM_SRCS}
${ARG_SERVER_SOURCES}
${PY_SRCS})
IF(GUI_SRCS OR SM_SRCS OR ARG_SOURCES)
IF(PARAVIEW_PLUGINLIST_TXT)
......
......@@ -183,7 +183,7 @@ int main(int argc, char* argv[])
{
vtkstd::string fname = argv[cc];
vtkstd::string moduleName;
vtksys::RegularExpression mnrex(".*/(.*).(xml|pvsm)$");
vtksys::RegularExpression mnrex(".*/(.*).(xml|pvsm|py)$");
if ( mnrex.find(fname) )
{
moduleName = mnrex.match(1);
......
......@@ -40,17 +40,25 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include <QDir>
#include <QResource>
#include "vtkSMXMLParser.h"
#include "vtkIntArray.h"
#include "vtkProcessModule.h"
#include "vtkPVEnvironmentInformation.h"
#include "vtkPVEnvironmentInformationHelper.h"
#include "vtkPVPluginLoader.h"
#include "vtkPVPythonModule.h"
#include "vtkSMXMLParser.h"
#include "vtkStringArray.h"
#include "vtkProcessModule.h"
#include "vtkSMObject.h"
#include "vtkSMProxyManager.h"
#include "vtkSMProxy.h"
#include "vtkPVEnvironmentInformation.h"
#include "vtkPVEnvironmentInformationHelper.h"
#include "vtkToolkits.h"
#include "vtksys/SystemTools.hxx"
#include "vtkSmartPointer.h"
#define VTK_CREATE(type, name) \
vtkSmartPointer<type> name = vtkSmartPointer<type>::New()
#include "pqApplicationCore.h"
#include "pqAutoStartInterface.h"
#include "pqFileDialogModel.h"
......@@ -126,10 +134,27 @@ pqPluginManager::LoadStatus pqPluginManager::loadServerExtension(pqServer* serve
QList<QVariant> xmls = pqSMAdaptor::getMultipleElementProperty(prop);
foreach(QVariant xml, xmls)
{
vtkSmartPointer<vtkSMXMLParser> parser = vtkSmartPointer<vtkSMXMLParser>::New();
VTK_CREATE(vtkSMXMLParser, parser);
parser->Parse(xml.toString().toAscii().data());
parser->ProcessConfiguration(vtkSMObject::GetProxyManager());
}
#ifdef VTK_WRAP_PYTHON
prop = pxy->GetProperty("PythonModuleNames");
QList<QVariant> names = pqSMAdaptor::getMultipleElementProperty(prop);
prop = pxy->GetProperty("PythonModuleSources");
QList<QVariant> sources = pqSMAdaptor::getMultipleElementProperty(prop);
prop = pxy->GetProperty("PythonPackageFlags");
QList<QVariant> pflags = pqSMAdaptor::getMultipleElementProperty(prop);
for (int i = 0; i < names.size(); i++)
{
VTK_CREATE(vtkPVPythonModule, module);
module->SetFullName(names[i].toString().toAscii().data());
module->SetSource(sources[i].toString().toAscii().data());
module->SetIsPackage(pflags[i].toInt());
vtkPVPythonModule::RegisterModule(module);
}
#endif //VTK_WRAP_PYTHON
}
else
{
......@@ -141,19 +166,33 @@ pqPluginManager::LoadStatus pqPluginManager::loadServerExtension(pqServer* serve
}
else
{
vtkSmartPointer<vtkPVPluginLoader> loader =
vtkSmartPointer<vtkPVPluginLoader>::New();
VTK_CREATE(vtkPVPluginLoader, loader);
loader->SetFileName(lib.toAscii().data());
success = loader->GetLoaded() ? LOADED : NOTLOADED;
if(success == LOADED)
{
int i;
vtkStringArray* xmls = loader->GetServerManagerXML();
for(int i=0; i<xmls->GetNumberOfValues(); i++)
for(i=0; i<xmls->GetNumberOfValues(); i++)
{
vtkSmartPointer<vtkSMXMLParser> parser = vtkSmartPointer<vtkSMXMLParser>::New();
VTK_CREATE(vtkSMXMLParser, parser);
parser->Parse(xmls->GetValue(i).c_str());
parser->ProcessConfiguration(vtkSMObject::GetProxyManager());
}
#ifdef VTK_WRAP_PYTHON
vtkStringArray *names = loader->GetPythonModuleNames();
vtkStringArray *sources = loader->GetPythonModuleSources();
vtkIntArray *pflags = loader->GetPythonPackageFlags();
for (i = 0; i < names->GetNumberOfValues(); i++)
{
VTK_CREATE(vtkPVPythonModule, module);
module->SetFullName(names->GetValue(i).c_str());
module->SetSource(sources->GetValue(i).c_str());
module->SetIsPackage(pflags->GetValue(i));
vtkPVPythonModule::RegisterModule(module);
}
#endif //VTK_WRAP_PYTHON
}
else
{
......
......@@ -62,6 +62,7 @@ SET(Kit_SRCS
vtkPVOpenGLExtensionsInformation.cxx
vtkPVPluginLoader.cxx
vtkPVProgressHandler.cxx
vtkPVPythonModule.cxx
vtkPVSelectionInformation.cxx
vtkPVServerInformation.cxx
vtkPVServerOptions.cxx
......
......@@ -18,12 +18,13 @@
#include "vtkProcessModule.h"
#include "vtkClientServerInterpreter.h"
#include "vtkDynamicLoader.h"
#include "vtkIntArray.h"
#include "vtkPVOptions.h"
#include "vtkStringArray.h"
#include <vtksys/SystemTools.hxx>
vtkStandardNewMacro(vtkPVPluginLoader);
vtkCxxRevisionMacro(vtkPVPluginLoader, "1.8");
vtkCxxRevisionMacro(vtkPVPluginLoader, "1.9");
#ifdef _WIN32
// __cdecl gives an unmangled name
......@@ -34,6 +35,8 @@ vtkCxxRevisionMacro(vtkPVPluginLoader, "1.8");
typedef const char* (C_DECL *PluginXML1)();
typedef void (C_DECL *PluginXML2)(int&, char**&);
typedef void (C_DECL *PluginPython)(int&, const char **&, const char **&,
const int *&);
typedef void (C_DECL *PluginInit)(vtkClientServerInterpreter*);
......@@ -46,6 +49,9 @@ vtkPVPluginLoader::vtkPVPluginLoader()
this->SearchPaths = NULL;
this->ServerManagerXML = vtkStringArray::New();
this->PythonModuleNames = vtkStringArray::New();
this->PythonModuleSources = vtkStringArray::New();
this->PythonPackageFlags = vtkIntArray::New();
vtksys::String paths;
const char* env = vtksys::SystemTools::GetEnv("PV_PLUGIN_PATH");
......@@ -82,6 +88,18 @@ vtkPVPluginLoader::~vtkPVPluginLoader()
{
this->ServerManagerXML->Delete();
}
if(this->PythonModuleNames)
{
this->PythonModuleNames->Delete();
}
if(this->PythonModuleSources)
{
this->PythonModuleSources->Delete();
}
if(this->PythonPackageFlags)
{
this->PythonPackageFlags->Delete();
}
if(this->Error)
{
......@@ -132,9 +150,12 @@ void vtkPVPluginLoader::SetFileName(const char* file)
PluginXML2 xml2 =
(PluginXML2)vtkDynamicLoader::GetSymbolAddress(lib, "ParaViewPluginXMLList");
PluginPython python =
(PluginPython)vtkDynamicLoader::GetSymbolAddress(lib, "ParaViewPluginPythonSourceList");
PluginInit init =
(PluginInit)vtkDynamicLoader::GetSymbolAddress(lib, "ParaViewPluginInit");
if(xml1 || xml2 || init)
if(xml1 || xml2 || python || init)
{
this->Loaded = 1;
if(init)
......@@ -161,6 +182,23 @@ void vtkPVPluginLoader::SetFileName(const char* file)
this->ServerManagerXML->SetValue(i, vtkStdString(xml[i]));
}
}
if (python)
{
int num;
const char **name;
const char **source;
const int *packages;
(*python)(num, name, source, packages);
this->PythonModuleNames->SetNumberOfTuples(num);
this->PythonModuleSources->SetNumberOfTuples(num);
this->PythonPackageFlags->SetNumberOfTuples(num);
for (int i = 0; i < num; i++)
{
this->PythonModuleNames->SetValue(i, vtkStdString(name[i]));
this->PythonModuleSources->SetValue(i, vtkStdString(source[i]));
this->PythonPackageFlags->SetValue(i, packages[i]);
}
}
this->Modified();
}
else
......
......@@ -22,6 +22,7 @@
#include "vtkObject.h"
class vtkIntArray;
class vtkStringArray;
class VTK_EXPORT vtkPVPluginLoader : public vtkObject
......@@ -41,6 +42,25 @@ public:
// the string array contains chunks of XML to process
vtkGetObjectMacro(ServerManagerXML, vtkStringArray);
// Description:
// Get a list of Python modules from a loaded plugin. The string array
// contains full names of Python modules.
vtkGetObjectMacro(PythonModuleNames, vtkStringArray);
// Description:
// Get the Python source for the Python modules in a loaded plugin. The
// string array contains the Python source for a given module. The entries in
// this array correspond to the entries of the same index in the
// PythonModuleNames array.
vtkGetObjectMacro(PythonModuleSources, vtkStringArray);
// Description:
// Get a list of flags specifying whether a given module is really a package.
// A 1 for package, 0 for module. The entries in this array correspond to the
// entries of the same index in the PythonModuleNames and PythonModuleSources
// arrays.
vtkGetObjectMacro(PythonPackageFlags, vtkIntArray);
// Desctiption:
// Get whether the plugin is loaded
vtkGetMacro(Loaded, int);
......@@ -64,6 +84,9 @@ protected:
char* FileName;
int Loaded;
vtkStringArray* ServerManagerXML;
vtkStringArray* PythonModuleNames;
vtkStringArray* PythonModuleSources;
vtkIntArray* PythonPackageFlags;
char* Error;
char* SearchPaths;
......
/*=========================================================================
Program: Visualization Toolkit
Module: vtkPVPythonModule.cxx
Copyright (c) Ken Martin, Will Schroeder, Bill Lorensen
All rights reserved.
See Copyright.txt or http://www.kitware.com/Copyright.htm for details.
This software is distributed WITHOUT ANY WARRANTY; without even
the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
PURPOSE. See the above copyright notice for more information.
=========================================================================*/
/*-------------------------------------------------------------------------
Copyright 2009 Sandia Corporation.
Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation,
the U.S. Government retains certain rights in this software.
-------------------------------------------------------------------------*/
#include "vtkPVPythonModule.h"
#include "vtkDebugLeaksManager.h"
#include "vtkObjectFactory.h"
#include "vtkSmartPointer.h"
#include <string.h>
#include <vtkstd/list>
//=============================================================================
// The static structure holding all of the registered modules.
typedef vtkstd::list<vtkSmartPointer<vtkPVPythonModule> > vtkPVPythonModuleContainerType;
static vtkPVPythonModuleContainerType vtkPVPythonModuleRegisteredModules;
void vtkPVPythonModule::RegisterModule(vtkPVPythonModule *module)
{
vtkPVPythonModuleRegisteredModules.push_front(module);
}
vtkPVPythonModule *vtkPVPythonModule::GetModule(const char *fullname)
{
vtkPVPythonModuleContainerType::iterator iter;
for (iter = vtkPVPythonModuleRegisteredModules.begin();
iter != vtkPVPythonModuleRegisteredModules.end(); iter++)
{
if (strcmp((*iter)->GetFullName(), fullname) == 0)
{
return *iter;
}
}
return NULL;
}
//=============================================================================
vtkCxxRevisionMacro(vtkPVPythonModule, "1.1");
vtkStandardNewMacro(vtkPVPythonModule);
//-----------------------------------------------------------------------------
vtkPVPythonModule::vtkPVPythonModule()
{
this->Source = NULL;
this->FullName = NULL;
this->IsPackage = 0;
}
vtkPVPythonModule::~vtkPVPythonModule()
{
this->SetSource(NULL);
this->SetFullName(NULL);
}
void vtkPVPythonModule::PrintSelf(ostream &os, vtkIndent indent)
{
this->Superclass::PrintSelf(os, indent);
os << indent << "FullName: " << this->FullName << endl;
os << indent << "IsPackage: " << this->IsPackage << endl;
os << indent << "Source: " << endl << this->Source << endl;
}
/*=========================================================================
Program: Visualization Toolkit
Module: vtkPVPythonModule.h
Copyright (c) Ken Martin, Will Schroeder, Bill Lorensen
All rights reserved.
See Copyright.txt or http://www.kitware.com/Copyright.htm for details.
This software is distributed WITHOUT ANY WARRANTY; without even
the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
PURPOSE. See the above copyright notice for more information.
=========================================================================*/
/*-------------------------------------------------------------------------
Copyright 2009 Sandia Corporation.
Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation,
the U.S. Government retains certain rights in this software.
-------------------------------------------------------------------------*/
// .NAME vtkPVPythonModule - Stores code and option for python modules
//
// .SECTION Description
//
// vtkPVPythonModule is a simple class that stores some Python source code that
// makes up a Python module as well as some state variables about the module
// (such as its name).
//
#ifndef __vtkPVPythonModule_h
#define __vtkPVPythonModule_h
#include "vtkObject.h"
class VTK_EXPORT vtkPVPythonModule : public vtkObject
{
public:
vtkTypeRevisionMacro(vtkPVPythonModule, vtkObject);
static vtkPVPythonModule *New();
virtual void PrintSelf(ostream &os, vtkIndent indent);
// Description:
// Set/get the full Python source for this module.
vtkGetStringMacro(Source);
vtkSetStringMacro(Source);
// Description:
// Set/get the full name for this module (e.g. package.subpackage.module).
vtkGetStringMacro(FullName);
vtkSetStringMacro(FullName);
// Description:
// Set/get a flag indicating whether this module is actually a package (which
// can have submodules).
vtkGetMacro(IsPackage, int);
vtkSetMacro(IsPackage, int);
vtkBooleanMacro(IsPackage, int);
// Description:
// Register the Python module. Once registered, the module can be retrieved
// with GetModule and HaveModule. Python interpreters can query these
// global methods in a custom import mechanism.
static void RegisterModule(vtkPVPythonModule *module);
// Description:
// Return the registered Python module with the given full module name. If
// no such module has been registered, this returns NULL.
static vtkPVPythonModule *GetModule(const char *fullname);
// Description:
// Returns 1 if a Python module with the given full name has been registered,
// 0 otherwise.
static int HasModule(const char *fullname) {
return (vtkPVPythonModule::GetModule(fullname) != NULL);
}
protected:
vtkPVPythonModule();
~vtkPVPythonModule();
char *Source;
char *FullName;
int IsPackage;
private:
vtkPVPythonModule(const vtkPVPythonModule &); // Not implemented
void operator=(const vtkPVPythonModule &); // Not implemented
};
#endif //__vtkPVPythonModule_h
......@@ -2256,6 +2256,24 @@
<StringArrayHelper />
</StringVectorProperty>
<StringVectorProperty name="PythonModuleNames"
command="GetPythonModuleNames"
information_only="1">
<StringArrayHelper />
</StringVectorProperty>
<StringVectorProperty name="PythonModuleSources"
command="GetPythonModuleSources"
information_only="1">
<StringArrayHelper />
</StringVectorProperty>
<IntVectorProperty name="PythonPackageFlags"
command="GetPythonPackageFlags"
information_only="1">
<IntArrayInformationHelper />
</IntVectorProperty>
<!-- End of PluginLoader -->
</Proxy>
......
......@@ -2014,6 +2014,26 @@ def CreateRepresentation(aProxy, view, **extraArgs):
view.Representations.append(proxy)
return proxy
class _ModuleLoader(object):
def find_module(self, fullname, path=None):
if vtkPVPythonModule.HasModule(fullname):
return self
else:
return None
def load_module(self, fullname):
import imp
moduleInfo = vtkPVPythonModule.GetModule(fullname)
if not moduleInfo:
raise ImportError
module = sys.modules.setdefault(fullname, imp.new_module(fullname))
module.__file__ = "<%s>" % moduleInfo.GetFullName()
module.__loader__ = self
if moduleInfo.GetIsPackage:
module.__path__ = moduleInfo.GetFullName()
code = compile(moduleInfo.GetSource(), module.__file__, 'exec')
exec code in module.__dict__
return module
def LoadPlugin(filename, connection=None):
""" Given a filename and a connection (optional, otherwise uses
ActiveConnection), loads a plugin. It then updates the sources,
......@@ -2036,15 +2056,34 @@ def LoadPlugin(filename, connection=None):
# Make sure that the plugin was loaded successfully
if pld.GetProperty("Loaded").GetElement(0):
# Get the XML, parse it and load it
xmlstring = pld.GetProperty("ServerManagerXML").GetElement(0)
if xmlstring:
parser = vtkSMXMLParser()