Salome HOME
updated copyright message
[modules/gui.git] / src / SalomeApp / salome_pluginsmanager.py
index fc63c95b4dfe480c37382519e64563197c797cf8..fb27befd0309fa6a3af9ca59cb7a9ec1ef2a793b 100644 (file)
@@ -1,4 +1,5 @@
-# Copyright (C) 2007-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+# -*- coding: utf-8 -*-
+# Copyright (C) 2007-2023  CEA, EDF, OPEN CASCADE
 #
 # This library is free software; you can redistribute it and/or
 # modify it under the terms of the GNU Lesser General Public
 
 """
 This module is imported from C++ SalomeApp_Application and initialized
-(call to initialize function with 4 parameters) module : 0 if it's
-plugins manager at the application level 1 if it is at the module
-level name : the name of the plugins manager. This name is used to
-build the name of the plugins files basemenuname : the name of the
-menu into we want to add the menu of the plugins ("Tools" for example)
-menuname : the name of plugins menu
+(call to initialize function with 4 parameters)
+module :       0 if it is plugins manager at the application level, 1 if it is at the module level
+name :         the name of the plugins manager. This name is used to build the name of the plugins files
+basemenuname : the name of the menu into we want to add the menu of the plugins ("Tools" for example)
+menuname :     the name of plugins menu
 
 A plugins manager is created when calling initialize.
 
@@ -44,7 +44,7 @@ name salome_plugins.py (example follows)::
   import salome_pluginsmanager
 
   def about(context):
-    from PyQt4.QtGui import QMessageBox
+    from qtsalome import QMessageBox
     QMessageBox.about(None, "About SALOME pluginmanager", "SALOME plugins manager in SALOME virtual application ")
 
   salome_pluginsmanager.AddFunction('About plugins','About SALOME pluginmanager',about)
@@ -54,8 +54,7 @@ AddFunction.  It is possible to customize this presentation by getting
 the entries list (salome_pluginsmanager.entries()) and modifying it in
 place. For example, you can do that :
 salome_pluginsmanager.entries().sort() to order them alphabetically or
-salome_pluginsmanager.entries().remove("a") to remove the entry named
-"a".
+salome_pluginsmanager.entries().remove("a") to remove the entry named "a".
 
 It is possible to put entries in submenus. You only need to give a
 name with / to the entry. for example::
@@ -78,14 +77,12 @@ In short to add a plugin:
 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
+from qtsalome import *
 
 import salome
 
@@ -105,14 +102,14 @@ plugins={}
 current_plugins_manager=None
 
 def initialize(module,name,basemenuname,menuname):
-  if not plugins.has_key(name):
+  if name not in plugins:
     if module:
       plugins[name]={}
     else:
       plugins[name]=[]
   if module:
     d=sgPyQt.getDesktop()
-    if plugins[name].has_key(d):return
+    if d in plugins[name]:return
     plugins[name][d]=PluginsManager(module,name,basemenuname,menuname)
   else:
     plugins[name].append(PluginsManager(module,name,basemenuname,menuname))
@@ -120,17 +117,18 @@ def initialize(module,name,basemenuname,menuname):
 class Context:
     def __init__(self,sgpyqt):
         self.sg=sgpyqt
-        self.studyId=salome.sg.getActiveStudyId()
-        self.study= salome.myStudyManager.GetStudyByID(self.studyId)
+        self.study=salome.myStudy
 
 def find_menu(smenu):
   lmenus=smenu.split("|")
+  # Take first element from the list
   main=lmenus.pop(0).strip()
   menu=sgPyQt.getPopupMenu(main)
   return findMenu(lmenus,menu)
 
 def findMenu(lmenu,menu):
   if not lmenu:return menu
+  # Take first element from the list
   m=lmenu.pop(0).strip()
   for a in menu.actions():
     if a.menu():
@@ -158,19 +156,23 @@ class PluginsManager:
         self.lasttime=0
         self.plugindirs=[]
         self.plugins_files=[]
+        self.toolbar = None
 
         # MODULES plugins directory.
         # The SALOME modules may provides natively some plugins. These
         # MODULES plugins are supposed to be located in the
         # installation folder of the module, in the subdirectory
         # "share/salome/plugins". We first look for these directories.
+        searched = []
         for key in os.environ.keys():
           if key.endswith("_ROOT_DIR"):
             rootpath=os.environ[key]
             dirpath=os.path.join(rootpath,PLUGIN_PATH_PATTERN)
-            if os.path.isdir(dirpath) and dirpath not in self.plugindirs:
+            if os.path.isdir(dirpath) and dirpath not in self.plugindirs + searched:
               logger.debug("Looking for plugins in the directory %s ..."%dirpath)
               walktree(dirpath,self.analyseFile)
+              if dirpath not in self.plugindirs and dirpath not in searched:
+                searched.append(dirpath)
 
         # USER plugins directory
         user_dir = os.path.expanduser("~/.config/salome/Plugins")
@@ -199,15 +201,18 @@ class PluginsManager:
         self.basemenu = find_menu(self.basemenuname)
 
         if self.module:
-          self.menu=QtGui.QMenu(self.menuname)
+          self.menu=QMenu(self.menuname)
           mid=sgPyQt.createMenu(self.menu.menuAction(),self.basemenuname)
         else:
-          self.menu=QtGui.QMenu(self.menuname,self.basemenu)
+          self.menu=QMenu(self.menuname,self.basemenu)
           self.basemenu.addMenu(self.menu)
+        self.toolbar=sgPyQt.createTool(self.menuname)
 
         self.menu.menuAction().setVisible(False)
 
-        self.basemenu.connect(self.basemenu, QtCore.SIGNAL("aboutToShow()"), self.importPlugins)
+        self.basemenu.aboutToShow.connect(self.importPlugins)
+
+        self.importPlugins() # to create toolbar immediately
 
     def analyseFile(self,filename):
       """
@@ -222,10 +227,10 @@ class PluginsManager:
           self.plugindirs.append(dirpath)
           logger.debug("The directory %s has been added to plugin paths"%dirpath)
         
-    def AddFunction(self,name,description,script):
+    def AddFunction(self,name,description,script,icon=None):
         """ Add a plugin function
         """
-        self.registry[name]=script,description
+        self.registry[name]=script,description,icon
         self.entries.append(name)
 
         def handler(obj=self,script=script):
@@ -233,19 +238,19 @@ class PluginsManager:
             script(Context(sgPyQt))
           except:
             s=traceback.format_exc()
-            QtGui.QMessageBox.warning(None,"Exception occured",s)
+            QMessageBox.warning(None,"Exception occured",s)
 
         self.handlers[name]=handler
 
     def importPlugins(self):
         """Execute the salome_plugins file that contains plugins definition """
-        studyId=sg.getActiveStudyId()
-        if studyId == 0:
-          self.menu.clear()
-          self.menu.menuAction().setVisible(False)
-          return
-        elif self.lasttime ==0:
-          salome.salome_init(embedded=1)
+        ior_fake_ns = None
+        prefix_ior = "--iorfakens="
+        presence_ior = [elt for elt in QApplication.arguments() if elt[:len(prefix_ior)]==prefix_ior]
+        if any(presence_ior):
+          ior_fake_ns = presence_ior[-1][len(prefix_ior):]
+        if self.lasttime ==0 or salome.myStudy == None:
+          salome.salome_init(embedded=True,iorfakensfile=ior_fake_ns)
 
         lasttime=0
 
@@ -276,12 +281,15 @@ class PluginsManager:
           self.entries=[]
           self.lasttime=lasttime
           for directory,plugins_file in plugins_files:
+            logger.debug("look for python path: %s"%directory)
             if directory not in sys.path:
               sys.path.insert(0,directory)
+              logger.debug("The directory %s has been added to PYTHONPATH"%directory)
             try:
-              execfile(plugins_file,globals(),{})
+              with open(plugins_file, 'rb') as fp:
+                exec(compile(fp.read(), plugins_file, 'exec'), globals(), {})
             except:
-              logger.fatal("Error while loading plugins from file %s"%plugins_file)
+              logger.critical("Error while loading plugins from file %s"%plugins_file)
               traceback.print_exc()
 
           self.updateMenu()
@@ -289,6 +297,7 @@ class PluginsManager:
     def updateMenu(self):
         """Update the Plugins menu"""
         self.menu.clear()
+        sgPyQt.clearTool(self.menuname)
         for entry in self.entries:
           names=entry.split("/")
           if len(names) < 1:continue
@@ -303,10 +312,10 @@ class PluginsManager:
                 submenus[str(menu.title())]=menu
             while len(names) > 1:
               name=names.pop(0)
-              if submenus.has_key(name):
+              if name in submenus:
                 amenu=submenus[name]
               else:
-                amenu=QtGui.QMenu(name,parentMenu)
+                amenu=QMenu(name,parentMenu)
                 parentMenu.addMenu(amenu)
                 submenus[name]=amenu
               parentMenu=amenu
@@ -314,14 +323,18 @@ class PluginsManager:
           name=names.pop(0)
           act=parentMenu.addAction(name,self.handlers[entry])
           act.setStatusTip(self.registry[entry][1])
+          icon = self.registry[entry][2] if len(self.registry[entry])>2 else None
+          if icon is not None and not icon.isNull() and icon.availableSizes():
+            act.setIcon(icon)
+            sgPyQt.createTool(act, self.toolbar)
 
         self.menu.menuAction().setVisible(True)
 
-def AddFunction(name,description,script):
+def AddFunction(name,description,script,icon=None):
    """ Add a plugin function
        Called by a user to register a function (script)
    """
-   return current_plugins_manager.AddFunction(name,description,script)
+   return current_plugins_manager.AddFunction(name,description,script,icon)
 
 def entries():
   """ Return the list of entries in menu: can be sorted or modified in place to customize menu content """