]> SALOME platform Git repositories - modules/gui.git/commitdiff
Salome HOME
CCAR: add a salome plugins manager for python plugins. It enables
authorcaremoli <caremoli>
Fri, 26 Mar 2010 16:59:03 +0000 (16:59 +0000)
committercaremoli <caremoli>
Fri, 26 Mar 2010 16:59:03 +0000 (16:59 +0000)
a user to add menu entries in the SALOME Tools/Plugins menu that activate
functionalities (GUI and engine) written in Python

src/SalomeApp/Makefile.am
src/SalomeApp/SalomeApp_Application.cxx
src/SalomeApp/salome_pluginsmanager.py [new file with mode: 0644]

index 614de706bcee1e6c48a0a80f881391f67e662a58..594450bdfe5c5d8dcfdfec4010b15d59bd6a930d 100755 (executable)
@@ -94,6 +94,9 @@ MOC_FILES =                                   \
 
 nodist_libSalomeApp_la_SOURCES = $(MOC_FILES)
 
+# python modules
+salomepython_PYTHON = salome_pluginsmanager.py
+
 dist_salomeres_DATA =          \
        resources/SalomeApp.ini \
        resources/SalomeApp.xml
index 753f3a113f04573c61c02d43a74790ea07bff8e3..3ef1725343d26d698f5263ff29421b154a78d516 100644 (file)
@@ -305,6 +305,17 @@ void SalomeApp_Application::createActions()
   createMenu( separator(), toolsMenu, -1, 15, -1 );
 
   createExtraActions();
+
+  // import Python module that manages SALOME plugins
+  PyGILState_STATE gstate = PyGILState_Ensure();
+  PyObject* pluginsmanager=PyImport_ImportModule((char*)"salome_pluginsmanager");
+  PyObject* res=PyObject_CallMethod( pluginsmanager, (char*)"initialize", (char*)"");
+  if(res==NULL)
+    PyErr_Print();
+  Py_XDECREF(res);
+  PyGILState_Release(gstate);
+  // end of SALOME plugins loading
+
 }
 
 /*!
diff --git a/src/SalomeApp/salome_pluginsmanager.py b/src/SalomeApp/salome_pluginsmanager.py
new file mode 100644 (file)
index 0000000..6dfb9f2
--- /dev/null
@@ -0,0 +1,159 @@
+"""
+This module is imported from C++ SalomeApp_Application
+and initialized (call to initialize function)
+
+A plugins manager is created at import (singleton object).
+
+The plugins manager creates a submenu Plugins in the Tools menu.
+
+The plugins manager searches in $HOME/.salome/Plugins, $HOME/$APPLI/Plugins, $SALOME_PLUGINS_PATH directories
+files named salome_plugins.py and executes them.
+
+These files should contain python code that register functions into the plugins manager.
+
+salome_plugins.py example::
+
+  import salome_pluginsmanager
+
+  def about(context):
+    from PyQt4.QtGui import QMessageBox
+    QMessageBox.about(None, "About SALOME pluginmanager", "SALOME plugins manager in SALOME virtual application ")
+
+  salome_pluginsmanager.AddFunction('Mesh Box','Create a box and mesh',mesh)
+
+First import the python module salome_pluginsmanager
+Second write a function with one argument context (it's an object with 3 attributes)
+Third register the function with a call to AddFunction (entry in menu plugins, tooltip, function)
+
+context attributes:
+- sg : the SALOME Swig interface
+- studyId : the SALOME studyId that must be used to execute the plugin
+- study : the SALOME study object that must be used to execute the plugin
+"""
+
+import os,sys,traceback
+from PyQt4 import QtGui
+from PyQt4 import QtCore
+
+import salome
+
+SEP=":"
+
+# Get SALOME PyQt interface
+import SalomePyQt
+sgPyQt = SalomePyQt.SalomePyQt()
+
+# Get SALOME Swig interface
+import libSALOME_Swig
+sg = libSALOME_Swig.SALOMEGUI_Swig()
+
+def initialize():
+  plugins.activate()
+
+class Context:
+    def __init__(self,sg):
+        self.sg=sg
+        self.studyId=salome.sg.getActiveStudyId()
+        self.study= salome.myStudyManager.GetStudyByID(self.studyId)
+
+class Plugins:
+    def __init__(self):
+        self.registry={}
+        self.handlers={}
+        self.lasttime=0
+        self.plugindirs=[]
+        self.plugins_files=[]
+
+        # USER plugins directory
+        user_dir = os.path.expanduser("~/.salome/Plugins")
+        self.plugindirs.append(user_dir)
+
+        # APPLI plugins directory
+        appli=os.getenv("APPLI")
+        if appli:
+          appli_dir=os.path.join(os.path.expanduser("~"),appli,"Plugins")
+          self.plugindirs.append(appli_dir)
+
+        #SALOME_PLUGINS_PATH environment variable (list of directories separated by ":")
+        pluginspath=os.getenv("SALOME_PLUGINS_PATH")
+        if pluginspath:
+          for directory in pluginspath.split(SEP):
+            self.plugindirs.append(directory)
+
+        self.menu=QtGui.QMenu("Plugins",sgPyQt.getPopupMenu(SalomePyQt.Tools))
+        self.menu.connect(self.menu,QtCore.SIGNAL("aboutToShow()"),self.importPlugins)
+
+    def AddFunction(self,name,description,script,script_type=None):
+        """ Add a plugin function
+        """
+        self.registry[name]=script,description,script_type
+
+        def handler(obj=self,script=script):
+          try:
+            script(Context(sgPyQt))
+          except:
+            s=traceback.format_exc()
+            QtGui.QMessageBox.warning(None,"Exception occured",s)
+
+        self.handlers[name]=handler
+
+    def importPlugins(self):
+        """Import the salome_plugins module that contains plugins definition """
+        if self.lasttime ==0:
+          studyId=sg.getActiveStudyId()
+          if studyId == 0:
+             self.menu.clear()
+             self.menu.addAction("No active study : open or load a new one")
+             return
+          else:
+             salome.salome_init(embedded=1)
+
+        lasttime=0
+
+        plugins_files=[]
+        for directory in self.plugindirs:
+          salome_plugins_file = os.path.join(directory,"salome_plugins.py")
+          if os.path.isfile(salome_plugins_file):
+            plugins_files.append((directory,salome_plugins_file))
+            lasttime=max(lasttime,os.path.getmtime(salome_plugins_file))
+
+        plugins_files.sort()
+
+        if not plugins_files:
+          self.registry.clear()
+          self.handlers.clear()
+          self.lasttime=0
+          self.menu.clear()
+          return
+
+        if self.plugins_files != plugins_files or lasttime > self.lasttime:
+          self.registry.clear()
+          self.handlers.clear()
+          self.lasttime=lasttime
+          for directory,salome_plugins_file in plugins_files:
+            if directory not in sys.path:
+              sys.path.insert(0,directory)
+            execfile(salome_plugins_file,globals(),{})
+          self.updateMenu()
+
+    def updateMenu(self):
+        """Update the Plugins menu"""
+        self.menu.clear()
+        for name,handler in self.handlers.items():
+            act=self.menu.addAction(name,handler)
+
+    def activate(self):
+        """Add the Plugins menu to the Tools menu"""
+        tools_menu= sgPyQt.getPopupMenu(SalomePyQt.Tools)
+        tools_menu.addMenu(self.menu)
+
+    def deactivate(self):
+        """Remove the Plugins menu from Tools menu (not implemented)"""
+
+plugins=Plugins()
+
+def AddFunction(name,description,script,script_type=None):
+   """ Add a plugin function
+       Called by a user to register a function (script)
+   """
+   return plugins.AddFunction(name,description,script,script_type)