svghmi/svghmi.py
branchsvghmi
changeset 2816 d813ecfe8941
parent 2815 77b2a3757e66
child 2817 45bbfb2e120f
equal deleted inserted replaced
2815:77b2a3757e66 2816:d813ecfe8941
    10 import os
    10 import os
    11 import shutil
    11 import shutil
    12 from itertools import izip, imap
    12 from itertools import izip, imap
    13 from pprint import pprint, pformat
    13 from pprint import pprint, pformat
    14 import hashlib
    14 import hashlib
       
    15 import weakref
    15 
    16 
    16 import wx
    17 import wx
       
    18 import wx.dataview as dv
       
    19 
       
    20 from lxml import etree
       
    21 from lxml.etree import XSLTApplyError
    17 
    22 
    18 import util.paths as paths
    23 import util.paths as paths
    19 from POULibrary import POULibrary
    24 from POULibrary import POULibrary
    20 from docutil import open_svg, get_inkscape_path
    25 from docutil import open_svg, get_inkscape_path
    21 from lxml import etree
       
    22 
    26 
    23 from util.ProcessLogger import ProcessLogger
    27 from util.ProcessLogger import ProcessLogger
    24 from runtime.typemapping import DebugTypesSize
    28 from runtime.typemapping import DebugTypesSize
    25 import targets
    29 import targets
       
    30 from editors.ConfTreeNodeEditor import ConfTreeNodeEditor
       
    31 from XSLTransform import XSLTransform
    26 
    32 
    27 HMI_TYPES_DESC = {
    33 HMI_TYPES_DESC = {
    28     "HMI_NODE":{},
    34     "HMI_NODE":{},
    29     "HMI_STRING":{},
    35     "HMI_STRING":{},
    30     "HMI_INT":{},
    36     "HMI_INT":{},
    31     "HMI_REAL":{}
    37     "HMI_REAL":{}
    32 }
    38 }
    33 
    39 
    34 HMI_TYPES = HMI_TYPES_DESC.keys()
    40 HMI_TYPES = HMI_TYPES_DESC.keys()
    35 
    41 
    36 from XSLTransform import XSLTransform
       
    37 from lxml.etree import XSLTApplyError
       
    38 
    42 
    39 ScriptDirectory = paths.AbsDir(__file__)
    43 ScriptDirectory = paths.AbsDir(__file__)
    40 
    44 
    41 class HMITreeNode(object):
    45 class HMITreeNode(object):
    42     def __init__(self, path, name, nodetype, iectype = None, vartype = None, hmiclass = None):
    46     def __init__(self, path, name, nodetype, iectype = None, vartype = None, hmiclass = None):
   125 # note: this only works because library's Generate_C is 
   129 # note: this only works because library's Generate_C is 
   126 #       systematicaly invoked before CTN's CTNGenerate_C
   130 #       systematicaly invoked before CTN's CTNGenerate_C
   127 
   131 
   128 hmi_tree_root = None
   132 hmi_tree_root = None
   129 
   133 
       
   134 hmi_tree_updated = None
       
   135 
   130 class SVGHMILibrary(POULibrary):
   136 class SVGHMILibrary(POULibrary):
   131     def GetLibraryPath(self):
   137     def GetLibraryPath(self):
   132          return paths.AbsNeighbourFile(__file__, "pous.xml")
   138          return paths.AbsNeighbourFile(__file__, "pous.xml")
   133 
   139 
   134     def Generate_C(self, buildpath, varlist, IECCFLAGS):
   140     def Generate_C(self, buildpath, varlist, IECCFLAGS):
   135         global hmi_tree_root, hmi_tree_unique_id 
   141         global hmi_tree_root, hmi_tree_updated, hmi_tree_unique_id 
   136 
   142 
   137         """
   143         """
   138         PLC Instance Tree:
   144         PLC Instance Tree:
   139           prog0
   145           prog0
   140            +->v1 HMI_INT
   146            +->v1 HMI_INT
   191                 kwargs['hmiclass'] = path[-1]
   197                 kwargs['hmiclass'] = path[-1]
   192             else:
   198             else:
   193                 name = path[-1]
   199                 name = path[-1]
   194             new_node = HMITreeNode(path, name, derived, v["type"], v["vartype"], **kwargs)
   200             new_node = HMITreeNode(path, name, derived, v["type"], v["vartype"], **kwargs)
   195             hmi_tree_root.place_node(new_node)
   201             hmi_tree_root.place_node(new_node)
       
   202 
       
   203         if hmi_tree_updated is not None:
       
   204             hmi_tree_updated()
   196 
   205 
   197         variable_decl_array = []
   206         variable_decl_array = []
   198         extern_variables_declarations = []
   207         extern_variables_declarations = []
   199         buf_index = 0
   208         buf_index = 0
   200         item_count = 0
   209         item_count = 0
   260         runtimefile.close()
   269         runtimefile.close()
   261 
   270 
   262         return ((["svghmi"], [(gen_svghmi_c_path, IECCFLAGS)], True), "",
   271         return ((["svghmi"], [(gen_svghmi_c_path, IECCFLAGS)], True), "",
   263                 ("runtime_svghmi0.py", open(runtimefile_path, "rb")))
   272                 ("runtime_svghmi0.py", open(runtimefile_path, "rb")))
   264 
   273 
       
   274 
       
   275 class SVGHMIEditor(ConfTreeNodeEditor):
       
   276     CONFNODEEDITOR_TABS = [
       
   277         (_("HMI Tree"), "CreateHMITreeView")]
       
   278 
       
   279     def SVGHMIEditorUpdater(self):
       
   280         selfref = weakref.ref(self)
       
   281         def SVGHMIEditorUpdate():
       
   282             o = selfref()
       
   283             if o is not None:
       
   284                 wx.CallAfter(o.MakeTree)
       
   285         return SVGHMIEditorUpdate
       
   286 
       
   287     def CreateHMITreeView(self, parent):
       
   288         global hmi_tree_updated 
       
   289 
       
   290         dvtc = dv.DataViewTreeCtrl(parent)
       
   291         isz = (16,16)
       
   292         self.ImageList = il = wx.ImageList(*isz)
       
   293         self.fldridx     = il.AddIcon(wx.ArtProvider.GetIcon(wx.ART_FOLDER,      wx.ART_OTHER, isz))
       
   294         self.fldropenidx = il.AddIcon(wx.ArtProvider.GetIcon(wx.ART_FOLDER_OPEN, wx.ART_OTHER, isz))
       
   295         self.fileidx     = il.AddIcon(wx.ArtProvider.GetIcon(wx.ART_NORMAL_FILE, wx.ART_OTHER, isz))
       
   296         dvtc.SetImageList(il)
       
   297 
       
   298 
       
   299         self.HMITreeView = dvtc
       
   300         hmi_tree_updated = self.SVGHMIEditorUpdater()
       
   301         self.MakeTree()
       
   302         return self.HMITreeView
       
   303 
       
   304     def _recurseTree(self, current_hmitree_root, current_dvtc_root):
       
   305         dvtc = self.HMITreeView
       
   306         for c in current_hmitree_root.children:
       
   307             if hasattr(c, "children"):
       
   308                 display_name = ('{} (class={})'.format(c.name, c.hmiclass)) \
       
   309                                if c.hmiclass is not None else c.name
       
   310                 dvtc_child = dvtc.AppendContainer(
       
   311                                  current_dvtc_root, display_name,
       
   312                                  self.fldridx, self.fldropenidx)
       
   313 
       
   314                 self._recurseTree(c,dvtc_child)
       
   315             else:
       
   316                 display_name = '{} {}'.format(c.nodetype[4:], c.name)
       
   317                 dvtc.AppendContainer(
       
   318                     current_dvtc_root, display_name,
       
   319                     self.fileidx, self.fileidx)
       
   320 
       
   321     def MakeTree(self):
       
   322         global hmi_tree_root 
       
   323         
       
   324         dvtc = self.HMITreeView
       
   325 
       
   326         dvtc.Freeze()
       
   327         dvtc.DeleteAllItems()
       
   328 
       
   329         root_display_name = _("Please build to see HMI Tree") if hmi_tree_root is None else "HMI"
       
   330         root = dvtc.AppendContainer(dv.NullDataViewItem,
       
   331                                     root_display_name,
       
   332                                     self.fldridx, self.fldropenidx)
       
   333         if hmi_tree_root is not None:
       
   334             self._recurseTree(hmi_tree_root, root)
       
   335         dvtc.Thaw()
       
   336 
   265 class SVGHMI(object):
   337 class SVGHMI(object):
   266     XSD = """<?xml version="1.0" encoding="utf-8" ?>
   338     XSD = """<?xml version="1.0" encoding="utf-8" ?>
   267     <xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema">
   339     <xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema">
   268       <xsd:element name="SVGHMI">
   340       <xsd:element name="SVGHMI">
   269         <xsd:complexType>
   341         <xsd:complexType>
   272           <xsd:attribute name="port" type="xsd:string" use="optional" default="8080"/>
   344           <xsd:attribute name="port" type="xsd:string" use="optional" default="8080"/>
   273         </xsd:complexType>
   345         </xsd:complexType>
   274       </xsd:element>
   346       </xsd:element>
   275     </xsd:schema>
   347     </xsd:schema>
   276     """
   348     """
   277     # TODO : add comma separated supported language list
   349 
       
   350     EditorType = SVGHMIEditor
   278 
   351 
   279     ConfNodeMethods = [
   352     ConfNodeMethods = [
   280         {
   353         {
   281             "bitmap":    "ImportSVG",
   354             "bitmap":    "ImportSVG",
   282             "name":    _("Import SVG"),
   355             "name":    _("Import SVG"),