plugin_provider.py
Go to the documentation of this file.
00001 #!/usr/bin/env python
00002 #
00003 # Copyright 2015 Airbus
00004 # Copyright 2017 Fraunhofer Institute for Manufacturing Engineering and Automation (IPA)
00005 #
00006 # Licensed under the Apache License, Version 2.0 (the "License");
00007 # you may not use this file except in compliance with the License.
00008 # You may obtain a copy of the License at
00009 #
00010 #   http://www.apache.org/licenses/LICENSE-2.0
00011 #
00012 # Unless required by applicable law or agreed to in writing, software
00013 # distributed under the License is distributed on an "AS IS" BASIS,
00014 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
00015 # See the License for the specific language governing permissions and
00016 # limitations under the License.
00017 
00018 import rospy
00019 import uuid
00020 import os
00021 import sys
00022 
00023 import __builtin__
00024 import traceback
00025 from xml.etree import ElementTree
00026 from roslib.packages import get_pkg_dir
00027 
00028 from python_qt_binding.QtGui import *
00029 from python_qt_binding.QtCore import *
00030 
00031 from airbus_pyqt_extend.QtAgiCore import QAgiPackages, get_pkg_dir_from_prefix
00032 from airbus_pyqt_extend.QtAgiGui import QAgiPopup
00033 
00034 from airbus_cobot_gui.util import Parameters, CobotGuiException
00035 
00036 ## @package: plugin_provider
00037 ## @version 4.0
00038 ## @author  Matignon Martin
00039 ## @date    Last modified 28/02/2014
00040 ## @class PluginProvider
00041 ## @brief Class for load Python plugin package.
00042 class PluginProvider:
00043     
00044     """
00045     PluginProvider interacts with ros plugin package. The first is its
00046     import plugin, and the second is the set plugin configuration which
00047     it reads.
00048     """
00049     
00050     PLUGIN_SOURCES_LOCATION = 'src'
00051     
00052     def __init__(self, parent, xml_register_dir):
00053         """! The constructor."""
00054         
00055         self._context = parent.getContext()
00056         
00057         #Check dir 
00058         if not os.path.isfile(xml_register_dir):
00059             raise CobotGuiException('Plugin register file "%s" in package "airbus_cobot_gui" not found'
00060                                      %(xml_register_dir))
00061         
00062         #Parse xml file
00063         try:
00064             self._plugin_register = ElementTree.parse(xml_register_dir)
00065         except Exception as e:
00066             raise CobotGuiException(str(e))
00067         
00068     def getPkgByName(self, name):
00069         
00070         root = self._plugin_register.getroot()
00071         
00072         #Find and read node label
00073         plugin_desc = root.find('./plugin[@label="%s"]'%name)
00074         
00075         if plugin_desc is None:
00076             raise CobotGuiException('Cannot found package from plugin named "%ss"'%name)
00077         
00078         return plugin_desc.attrib['package']
00079     
00080     def getInstance(self, plugin_name, plugin_node=None):
00081         """! Load Python package and provide plugin instance.
00082         @param plugin_name: plugin name.
00083         @type plugin_name: String.
00084         
00085         @param plugin_node: plugin xml element tree.
00086         @type plugin_node: Element.
00087         
00088         @return plugin_instance: plugin instance.
00089         @type plugin_instance: Plugin.
00090         """
00091         
00092         plugin_pkg_name = None
00093         
00094         try:
00095             
00096             plugin_pkg_name = self.getPkgByName(plugin_name)
00097             
00098         except Exception as ex:
00099             self._context.getLogger().err(str(ex))
00100             return None
00101         
00102         plugin_dir = get_pkg_dir(plugin_pkg_name)
00103         
00104         plugin_descriptor_file = os.path.join(plugin_dir,"plugin_descriptor.xml")
00105         
00106         if not os.path.isfile(plugin_descriptor_file):
00107             self._context.getLogger().err('Cannot found plugin_descriptor.xml into plugin %s'%plugin_name)
00108             return None
00109         
00110         plugin_descriptor_root = ElementTree.parse(plugin_descriptor_file).getroot()
00111         
00112         plugin_import = plugin_descriptor_root.find('import')
00113          
00114         plugin_module_path = plugin_import.attrib['module']
00115         plugin_class_name = plugin_import.attrib['class']
00116         
00117         sys.path.append(os.path.join(plugin_dir,self.PLUGIN_SOURCES_LOCATION))
00118         
00119         plugin_class_ref = None
00120         
00121         try:
00122             #Import plugin package module
00123             module = __builtin__.__import__(plugin_module_path,
00124                                             fromlist=[plugin_class_name],
00125                                             level=0)
00126             
00127         except Exception as ex:
00128             self._context.getLogger().err("Cannot import plugin '%s' !\n%s"%(plugin_name, str(ex)))
00129             return None
00130         
00131         #Get referance to plugin class
00132         plugin_class_ref = getattr(module, plugin_class_name)
00133         
00134         if plugin_class_ref is None:
00135             self._context.getLogger().err("Cannot found plugin class '%s' !"%plugin_class_name)
00136             return None
00137         
00138         plugin_instance = plugin_class_ref(self._context)
00139         
00140         plugin_params = PluginProvider.getParameters(plugin_descriptor_root, plugin_node)
00141         
00142         plugin_instance.setup(plugin_descriptor_root, plugin_params)
00143         
00144         return plugin_instance
00145     
00146     @staticmethod
00147     def getParameters(plugin_descriptor, plugin_node):
00148         
00149         parameters = Parameters()
00150         
00151         # Try to provide plugin parameters in plugin_descriptor.xml
00152         descriptor_params = plugin_descriptor.find("setup/parameters")
00153         
00154         # Add parameters, if parameters found in plugin_descriptor.xml
00155         if descriptor_params is not None:
00156             for param in descriptor_params:
00157                 # Append parameters
00158                 parameters.putParam(param.attrib['name'], param.attrib['value'])
00159                 
00160         if plugin_node is not None:
00161             # Check if parameters remapped in airbus_cobot_gui config launch
00162             if plugin_node.find("param") is not None:
00163                 
00164                 for param in plugin_node.iter('param'):
00165                     # Update or append parameters
00166                     parameters.putParam(param.attrib['name'], param.attrib['value'])
00167         
00168         return parameters
00169     
00170 class PluginsGroupPopup(QAgiPopup):
00171     
00172     def __init__(self, parent):
00173         QAgiPopup.__init__(self, parent)
00174         
00175         self._context = parent.getContext()
00176         
00177         self.setAttribute(Qt.WA_TranslucentBackground)
00178         self.setFixedWidth(100)
00179         self.setRelativePosition(QAgiPopup.TopLeft, QAgiPopup.TopRight)
00180         
00181         self._launchers_layout = QVBoxLayout(self)
00182         self._launchers_layout.setContentsMargins(2, 2, 2, 2)
00183         self._launchers_layout.setSpacing(15)
00184     
00185     def setupLaunchers(self, launchers):
00186         
00187         for launcher in launchers:
00188             self.connect(launcher, SIGNAL('clicked()'), self.close)
00189             self._launchers_layout.addWidget(launcher)
00190         
00191 class PluginsGroup(QPushButton):
00192     
00193     def __init__(self, parent, xgroup):
00194         
00195         QPushButton.__init__(self, parent)
00196         
00197         self.setFocusPolicy(Qt.NoFocus)
00198         self.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Preferred)
00199         self.setIconSize(QSize(80,80))
00200         self.setEnabled(False)
00201         
00202         self._context = parent.getContext()
00203         self._context.addUserEventListener(self.onUserChanged)
00204         
00205         self._min_access_rights = 3
00206         self._launchers = []
00207         
00208         self.setup(xgroup)
00209         
00210     def setup(self, xgroup):
00211         
00212         group_name = ""
00213         icon_path = ""
00214         
00215         try:
00216             group_name = xgroup.attrib['name']
00217             icon_path = xgroup.attrib['icon']
00218         except:
00219             self._context.getLogger().err("Not name or icon found for plugin group !")
00220             return
00221         
00222         icon_path = get_pkg_dir_from_prefix(icon_path)
00223         
00224         if os.path.isfile(icon_path):
00225             self.setIcon(QIcon(icon_path))
00226         else:
00227             self.setStyleSheet("background-color:rgba(255,0,0,80%);\
00228                                                  border-radius: 10px;\
00229                                                  font-size: 12pt;\
00230                                                  font-weight:60;\
00231                                                  color: #ffffff;")
00232             self.setText(group_name)
00233         
00234     def add(self, launcher):
00235         
00236         launcher.setStyleSheet("background:none;")#R.values.styles.no_background)
00237         
00238         self._launchers.append(launcher)
00239         
00240         if launcher.getAccessRights() < self._min_access_rights:
00241             self._min_access_rights = launcher.getAccessRights()
00242         
00243     def getContext(self):
00244         self._context
00245         
00246     def onUserChanged(self, user):
00247         
00248         if user.getUserPrivilege() < self._min_access_rights:
00249             self.setEnabled(False)
00250         else:
00251             self.setEnabled(True)
00252     
00253     def mousePressEvent(self, event):
00254         
00255         popup = PluginsGroupPopup(self)
00256         popup.setupLaunchers(self._launchers)
00257         
00258         popup.show_()
00259         
00260 ##Unittest
00261 if __name__ == "__main__":
00262     from python_qt_binding.QtGui import *
00263     from python_qt_binding.QtCore import *
00264     from airbus_cobot_gui.context import Context
00265     
00266     rospy.init_node('plugin_privider_test')
00267     
00268     a = QApplication(sys.argv)
00269     utt_appli = QMainWindow()
00270 
00271     context = Context(utt_appli)
00272     
00273     provider = PluginProvider(context, "/home/nhg/AIRBUS/airbus_coop/src/airbus_coop/src/gui/plugins/plugins_register.xml")
00274     
00275     plugin = provider.getPluginInstance("SSM")
00276     
00277     utt_appli.setCentralWidget(plugin)
00278     
00279     plugin.onStart()
00280     
00281     utt_appli.show()
00282     a.exec_()
00283     
00284     
00285 
00286 #End of file
00287 


airbus_cobot_gui
Author(s): Martin Matignon
autogenerated on Thu Jun 6 2019 17:59:19