resources.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 
00019 import sys
00020 
00021 import rospy
00022 import os
00023 
00024 from python_qt_binding.QtGui import *
00025 from python_qt_binding.QtCore import *
00026 from python_qt_binding import loadUi
00027 from roslib.packages import get_pkg_dir
00028 from xml.etree import ElementTree
00029 
00030 from packages import get_pkg_dir_from_prefix, \
00031                      get_ros_workspace_dir, \
00032                      get_ros_workspace_src_dir
00033 
00034 class _Image:
00035     
00036     def __init__(self, node, rsc_path):
00037         
00038         self.label   = ""
00039         self.src     = ""
00040         self.width   = 0
00041         self.height  = 0
00042         self.scale   = True
00043         self.preload = False
00044         self.pixmap  = None
00045         
00046         try:
00047             self._read_img_node(node)
00048         except Exception as ex:
00049             raise Exception(ex)
00050         
00051         self.src = os.path.join(rsc_path, self.src)
00052         
00053         if self.preload:
00054             self.pixmap = _Image.loadPixmap(self)
00055         
00056         
00057     def _read_img_node(self, node):
00058         
00059         if len(node.attrib.keys()) != 6:
00060             raise Exception('<img .../> takes exactly 6 arguments (%i given) !'%len(node.attrib.keys()))
00061         
00062         for k, v in node.attrib.items():
00063             
00064             if k == 'label':
00065                 self.label = v
00066             elif  k == 'src':
00067                 self.src = v
00068             elif  k == 'width':
00069                 self.width = int(v)
00070             elif  k == 'height':
00071                 self.height = int(v)
00072             elif  k == 'auto-scale':
00073                 if v.lower() == 'false':
00074                     self.scale = False 
00075                 else:
00076                     self.scale = True
00077             elif  k == 'preload':
00078                 if v.lower() == 'true':
00079                     self.preload = True 
00080                 else:
00081                     self.preload = False
00082             else:
00083                 raise Exception('Inconstante parameter type <img %s="..."/>!'%k)
00084             
00085     def isPreloaded(self):
00086         return self.preload
00087     
00088     @staticmethod
00089     def loadPixmap(img_desc):
00090         
00091         try:
00092             px = QPixmap(img_desc.src)
00093             
00094             if img_desc.scale is True :
00095                 px = px.scaled(img_desc.width, img_desc.height,
00096                                Qt.KeepAspectRatio,
00097                                Qt.SmoothTransformation)
00098             return px
00099         except Exception as ex:
00100             raise Exception(ex)
00101     
00102     def getPixmap(self, w = None, h = None):
00103         
00104         rescale = False
00105         if w is not None and h is not None:
00106             if w != self.width or h != self.height:
00107                 self.width  = w
00108                 self.height = h
00109                 rescale = True
00110         
00111         if self.isPreloaded():
00112             if rescale:
00113                 self.pixmap = _Image.loadPixmap(self)
00114             return self.pixmap
00115         else:
00116             return _Image.loadPixmap(self)
00117         
00118 class QAgiImageRessource:
00119     
00120     def __init__(self, xnode):
00121         
00122         if xnode is None or 'path' not in xnode.attrib.keys():
00123             return
00124         
00125         self._img_rsc = {}
00126         ipath = get_pkg_dir_from_prefix(xnode.attrib['path'])
00127         
00128         if not os.path.isdir(ipath):
00129             raise Exception("Invalid path from images ressource !")
00130         
00131         for img_node in xnode:
00132             img = _Image(img_node, ipath)
00133             self._img_rsc.update({img.label : img})
00134     
00135     def getPixmap(self, key, w=None, h=None):
00136         
00137         try:
00138             img = self._img_rsc[key]
00139             return img.getPixmap(w,h)
00140         except Exception as ex:
00141             raise Exception(str(ex))
00142         
00143 #     def getPixmap(self, key, size):
00144 #         self.getPixmap(key, size.width(), size.height())
00145         
00146     def getPixmapSize(self, key):
00147         try:
00148             px = self._img_rsc[key]
00149             return QSize(px.width, px.height)
00150         except Exception as ex:
00151             raise Exception(str(ex))
00152         
00153     def getIcon(self, key):
00154         try:
00155             ico = self._img_rsc[key]
00156             return QIcon(ico.src)
00157         except Exception as ex:
00158             raise Exception(str(ex))
00159     
00160     def getIconSize(self, key):
00161         try:
00162             ico = self._img_rsc[key]
00163             return QSize(ico.width, ico.height)
00164         except Exception as ex:
00165             raise Exception(str(ex))
00166         
00167 class QAgiUiRessource:
00168     def __init__(self, xnode):
00169         
00170         if xnode is None or 'path' not in xnode.attrib.keys():
00171             return
00172         
00173         self._uis_rsc = {}
00174         gpath = get_pkg_dir_from_prefix(xnode.attrib['path'])
00175         
00176         if not os.path.isdir(gpath):
00177             raise Exception("Invalid path from ui ressource !")
00178         
00179         for ui in xnode:
00180             uipath = '%s/%s'%(gpath, ui.attrib['src'])
00181             self._uis_rsc.update({ui.attrib['label']: uipath})
00182         
00183     def __getitem__(self, key):
00184         try:
00185             return self._uis_rsc[key]
00186         except Exception as ex:
00187             raise Exception(ex)
00188         
00189     def load(self, key, widget):
00190         try:
00191             loadUi(self.__getitem__(key), widget)
00192         except Exception as ex:
00193             raise ex
00194         
00195 class QAgiYamlRessource:
00196     def __init__(self, xnode):
00197         
00198         if xnode is None or 'path' not in xnode.attrib.keys():
00199             return
00200         
00201         self._yamls_rsc = {}
00202         gpath = get_pkg_dir_from_prefix(xnode.attrib['path'])
00203         
00204         if not os.path.isdir(gpath):
00205             raise Exception("Invalid path from yamls ressource !")
00206         
00207         for yaml in xnode:
00208             yamlpath = '%s/%s'%(gpath, yaml.attrib['src'])
00209             self._yamls_rsc.update({yaml.attrib['label']: yamlpath})
00210         
00211     def __getitem__(self, key):
00212         try:
00213             return self._yamls_rsc[key]
00214         except Exception as ex:
00215             raise Exception(ex)
00216 
00217 class QAgiStyleSheetRessource:
00218     
00219     def __init__(self, xnode):
00220         
00221         self._node = xnode
00222         self._theme = "default"
00223         
00224         if "theme" in self._node.attrib.keys():
00225             self._theme = self._node.attrib["theme"]
00226     
00227     def __getitem__(self, key):
00228         
00229         xpath = ""
00230         stylesheet = ""
00231         
00232         if '.' in key:
00233             keys = key.split('.')
00234             xpath = './sheet[@name="%s"]'%keys[0]
00235             for i in range(1, len(keys)):
00236                 xpath+='/sheet[@name="%s"]'%keys[i]
00237         else:
00238             xpath = './sheet[@name="%s"]'%key
00239             
00240         xpath += '/%s'%self._theme
00241         
00242 #         print xpath
00243         
00244         try:
00245             sheet = self._node.find(xpath)
00246             stylesheet = sheet.text
00247         except:
00248             rospy.logerr('Style sheet "%s" was not found !'%key)
00249         
00250         return stylesheet
00251     
00252 class QAgiTraductionRessource:
00253     
00254     def __init__(self, xnode):
00255         
00256         self._node = xnode
00257         self._lng = "en"
00258         
00259         if "lng" in self._node.attrib.keys():
00260             self._lng = self._node.attrib["lng"]
00261     
00262     def __getitem__(self, key):
00263         
00264         trad  = str(key)
00265         xpath = './translate[@src="%s"]/%s'%(str(key), self._lng)
00266         
00267         try:
00268             trad = self._node.find(xpath).text
00269         except:
00270             rospy.logerr('Traduction from "%s" not found !'%key)
00271         
00272         return trad
00273 
00274 class QAgiResources:
00275     
00276     DEFAULT_RSC_NAMES = ["rsc","resource","resources"]
00277     
00278     def __init__(self, package, dir):
00279         
00280         tree = None
00281         root = None
00282         rsc  = None
00283         
00284         if dir is None:
00285             rsc = self.find_default_rsc_file(package)
00286             if rsc is None:
00287                 raise Exception("Connot find ressources file in pakage '%s'"%package)
00288         else:
00289             rsc = os.path.join(get_pkg_dir(package), dir)
00290         
00291         try:
00292             tree = ElementTree.parse(rsc)
00293             root = tree.getroot()
00294         except Exception as e:
00295             raise Exception(e)
00296         
00297         for node in root:
00298             if node.tag == "uis":
00299                 setattr(self, node.tag, QAgiUiRessource(node))
00300             elif node.tag == "images":
00301                 setattr(self, node.tag, QAgiImageRessource(node))
00302             elif node.tag == "yamls":
00303                 setattr(self, node.tag, QAgiYamlRessource(node))
00304             elif node.tag == "traductions":
00305                 setattr(self, node.tag, QAgiTraductionRessource(node))
00306             elif node.tag == "styles":
00307                 setattr(self, node.tag, QAgiStyleSheetRessource(node))
00308             
00309         
00310     def find_default_rsc_file(self, pkg):
00311         
00312         pkg_path = get_pkg_dir(pkg)
00313         
00314         for name in self.DEFAULT_RSC_NAMES:
00315             dir = os.path.join(pkg_path, name)
00316             if os.path.isdir(dir):
00317                 return os.path.join(dir,self.find_rsc_xml(dir))
00318         return None
00319     
00320     def find_rsc_xml(self, rsc_dir):
00321         
00322         for file in os.listdir(rsc_dir):
00323             file_split = file.split(".")
00324             if file_split[0] in self.DEFAULT_RSC_NAMES and file_split[-1] == "xml":
00325                 return file
00326         return None
00327     
00328 def loadRsc(package, dir=None):
00329     return QAgiResources(package, dir)
00330 
00331 import copy
00332 
00333 def loadRes(package):
00334     
00335     from packages import QAgiPackages
00336     
00337     res_class_name = ''
00338     
00339     for subs in package.split('_'):
00340         res_class_name+=subs[0].upper()+subs[1:]
00341     res_class_name+="Res"
00342     
00343     print 'Loading ressource name : %s'%res_class_name
00344     
00345     return QAgiPackages.__pkg__(package).__module__('resources.res').__import__(res_class_name)
00346     


airbus_pyqt_extend
Author(s): Martin Matignon
autogenerated on Thu Jun 6 2019 17:59:16