CodeFileTreeNode.py
changeset 1315 ff14a66bbd12
parent 1153 5bdd82497925
child 1330 96b242e4c59d
equal deleted inserted replaced
1314:822d483197ad 1315:ff14a66bbd12
     1 import os
     1 import os, re
     2 from xml.dom import minidom
     2 
     3 import cPickle
     3 from copy import deepcopy
     4 
     4 from lxml import etree
     5 from xmlclass import GenerateClassesFromXSDstring, UpdateXMLClassGlobals
     5 from xmlclass import GenerateParserFromXSDstring
     6 
     6 
     7 from PLCControler import UndoBuffer
     7 from PLCControler import UndoBuffer
     8 
     8 
     9 CODEFILE_XSD = """<?xml version="1.0" encoding="ISO-8859-1" ?>
     9 CODEFILE_XSD = """<?xml version="1.0" encoding="ISO-8859-1" ?>
    10 <xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema">
    10 <xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema"
       
    11             xmlns:xhtml="http://www.w3.org/1999/xhtml">
    11   <xsd:element name="%(codefile_name)s">
    12   <xsd:element name="%(codefile_name)s">
    12     <xsd:complexType>
    13     <xsd:complexType>
    13       <xsd:sequence>
    14       <xsd:sequence>
    14         %(includes_section)s
    15         %(includes_section)s
    15         <xsd:element name="variables">
    16         <xsd:element name="variables">
    63             sections_str["includes_section"] = ""
    64             sections_str["includes_section"] = ""
    64         sections_str["sections"] = "\n".join(
    65         sections_str["sections"] = "\n".join(
    65             [SECTION_TAG_ELEMENT % name
    66             [SECTION_TAG_ELEMENT % name
    66              for name in self.SECTIONS_NAMES if name != "includes"])
    67              for name in self.SECTIONS_NAMES if name != "includes"])
    67         
    68         
    68         self.CodeFileClasses = GenerateClassesFromXSDstring(
    69         self.CodeFileParser = GenerateParserFromXSDstring(
    69             CODEFILE_XSD % sections_str)
    70             CODEFILE_XSD % sections_str)
       
    71         self.CodeFileVariables = etree.XPath("variables/variable")
    70         
    72         
    71         filepath = self.CodeFileName()
    73         filepath = self.CodeFileName()
    72         
    74         
    73         self.CodeFile = self.CodeFileClasses[self.CODEFILE_NAME]()
       
    74         if os.path.isfile(filepath):
    75         if os.path.isfile(filepath):
    75             xmlfile = open(filepath, 'r')
    76             xmlfile = open(filepath, 'r')
    76             tree = minidom.parse(xmlfile)
    77             codefile_xml = xmlfile.read()
    77             xmlfile.close()
    78             xmlfile.close()
    78             
    79             
    79             for child in tree.childNodes:
    80             codefile_xml = codefile_xml.replace(
    80                 if child.nodeType == tree.ELEMENT_NODE and child.nodeName in [self.CODEFILE_NAME]:
    81                 '<%s>' % self.CODEFILE_NAME, 
    81                     self.CodeFile.loadXMLTree(child, ["xmlns", "xmlns:xsi", "xsi:schemaLocation"])
    82                 '<%s xmlns:xhtml="http://www.w3.org/1999/xhtml">' % self.CODEFILE_NAME)
    82                     self.CreateCodeFileBuffer(True)
    83             for cre, repl in [
       
    84                 (re.compile("(?<!<xhtml:p>)(?:<!\[CDATA\[)"), "<xhtml:p><![CDATA["),
       
    85                 (re.compile("(?:]]>)(?!</xhtml:p>)"), "]]></xhtml:p>")]:
       
    86                 codefile_xml = cre.sub(repl, codefile_xml)
       
    87             self.CodeFile = etree.fromstring(codefile_xml, self.CodeFileParser)    
       
    88             self.CreateCodeFileBuffer(True)
       
    89         
    83         else:
    90         else:
       
    91             self.CodeFile = self.CodeFileParser.CreateRoot()
    84             self.CreateCodeFileBuffer(False)
    92             self.CreateCodeFileBuffer(False)
    85             self.OnCTNSave()
    93             self.OnCTNSave()
    86 
    94 
    87     def GetBaseTypes(self):
    95     def GetBaseTypes(self):
    88         return self.GetCTRoot().GetBaseTypes()
    96         return self.GetCTRoot().GetBaseTypes()
    97                   for var in self.CodeFile.variables.getvariable()]))
   105                   for var in self.CodeFile.variables.getvariable()]))
    98 
   106 
    99     def SetVariables(self, variables):
   107     def SetVariables(self, variables):
   100         self.CodeFile.variables.setvariable([])
   108         self.CodeFile.variables.setvariable([])
   101         for var in variables:
   109         for var in variables:
   102             variable = self.CodeFileClasses["variables_variable"]()
   110             variable = self.CodeFileParser.CreateElement("variable", "variables")
   103             variable.setname(var["Name"])
   111             variable.setname(var["Name"])
   104             variable.settype(var["Type"])
   112             variable.settype(var["Type"])
   105             variable.setinitial(var["Initial"])
   113             variable.setinitial(var["Initial"])
   106             self.CodeFile.variables.appendvariable(variable)
   114             self.CodeFile.variables.appendvariable(variable)
   107     
   115     
   108     def GetVariables(self):
   116     def GetVariables(self):
   109         datas = []
   117         datas = []
   110         for var in self.CodeFile.variables.getvariable():
   118         for var in self.CodeFileVariables(self.CodeFile):
   111             datas.append({"Name" : var.getname(), 
   119             datas.append({"Name" : var.getname(), 
   112                           "Type" : var.gettype(), 
   120                           "Type" : var.gettype(), 
   113                           "Initial" : var.getinitial()})
   121                           "Initial" : var.getinitial()})
   114         return datas
   122         return datas
   115 
   123 
   116     def SetTextParts(self, parts):
   124     def SetTextParts(self, parts):
   117         for section in self.SECTIONS_NAMES:
   125         for section in self.SECTIONS_NAMES:
   118             section_code = parts.get(section)
   126             section_code = parts.get(section)
   119             if section_code is not None:
   127             if section_code is not None:
   120                 getattr(self.CodeFile, section).settext(section_code)
   128                 getattr(self.CodeFile, section).setanyText(section_code)
   121     
   129     
   122     def GetTextParts(self):
   130     def GetTextParts(self):
   123         return dict([(section, getattr(self.CodeFile, section).gettext())
   131         return dict([(section, getattr(self.CodeFile, section).getanyText())
   124                      for section in self.SECTIONS_NAMES])
   132                      for section in self.SECTIONS_NAMES])
   125             
   133             
   126     def CTNTestModified(self):
   134     def CTNTestModified(self):
   127         return self.ChangesToSave or not self.CodeFileIsSaved()    
   135         return self.ChangesToSave or not self.CodeFileIsSaved()    
   128 
   136 
   129     def OnCTNSave(self, from_project_path=None):
   137     def OnCTNSave(self, from_project_path=None):
   130         filepath = self.CodeFileName()
   138         filepath = self.CodeFileName()
   131         
   139         
   132         text = "<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"no\"?>\n"
       
   133         text += self.CodeFile.generateXMLText(self.CODEFILE_NAME, 0)
       
   134 
       
   135         xmlfile = open(filepath,"w")
   140         xmlfile = open(filepath,"w")
   136         xmlfile.write(text.encode("utf-8"))
   141         xmlfile.write(etree.tostring(
       
   142             self.CodeFile, 
       
   143             pretty_print=True, 
       
   144             xml_declaration=True, 
       
   145             encoding='utf-8'))
   137         xmlfile.close()
   146         xmlfile.close()
   138         
   147         
   139         self.MarkCodeFileAsSaved()
   148         self.MarkCodeFileAsSaved()
   140         return True
   149         return True
   141 
   150 
   142     def CTNGlobalInstances(self):
   151     def CTNGlobalInstances(self):
   143         current_location = self.GetCurrentLocation()
   152         current_location = self.GetCurrentLocation()
   144         return [(variable.getname(),
   153         return [(variable.getname(),
   145                  variable.gettype(),
   154                  variable.gettype(),
   146                  variable.getinitial())
   155                  variable.getinitial())
   147                 for variable in self.CodeFile.variables.variable]
   156                 for variable in self.CodeFileVariables(self.CodeFile)]
   148 
   157 
   149 #-------------------------------------------------------------------------------
   158 #-------------------------------------------------------------------------------
   150 #                      Current Buffering Management Functions
   159 #                      Current Buffering Management Functions
   151 #-------------------------------------------------------------------------------
   160 #-------------------------------------------------------------------------------
   152 
       
   153     def cPickle_loads(self, str_obj):
       
   154         UpdateXMLClassGlobals(self.CodeFileClasses)
       
   155         return cPickle.loads(str_obj)
       
   156 
       
   157     def cPickle_dumps(self, obj):
       
   158         UpdateXMLClassGlobals(self.CodeFileClasses)
       
   159         return cPickle.dumps(obj)
       
   160 
   161 
   161     """
   162     """
   162     Return a copy of the codefile model
   163     Return a copy of the codefile model
   163     """
   164     """
   164     def Copy(self, model):
   165     def Copy(self, model):
   165         return self.cPickle_loads(self.cPickle_dumps(model))
   166         return deepcopy(model)
   166 
   167 
   167     def CreateCodeFileBuffer(self, saved):
   168     def CreateCodeFileBuffer(self, saved):
   168         self.Buffering = False
   169         self.Buffering = False
   169         self.CodeFileBuffer = UndoBuffer(self.cPickle_dumps(self.CodeFile), saved)
   170         self.CodeFileBuffer = UndoBuffer(self.CodeFileParser.Dumps(self.CodeFile), saved)
   170 
   171 
   171     def BufferCodeFile(self):
   172     def BufferCodeFile(self):
   172         self.CodeFileBuffer.Buffering(self.cPickle_dumps(self.CodeFile))
   173         self.CodeFileBuffer.Buffering(self.CodeFileParser.Dumps(self.CodeFile))
   173     
   174     
   174     def StartBuffering(self):
   175     def StartBuffering(self):
   175         self.Buffering = True
   176         self.Buffering = True
   176         
   177         
   177     def EndBuffering(self):
   178     def EndBuffering(self):
   178         if self.Buffering:
   179         if self.Buffering:
   179             self.CodeFileBuffer.Buffering(self.cPickle_dumps(self.CodeFile))
   180             self.CodeFileBuffer.Buffering(self.CodeFileParser.Dumps(self.CodeFile))
   180             self.Buffering = False
   181             self.Buffering = False
   181     
   182     
   182     def MarkCodeFileAsSaved(self):
   183     def MarkCodeFileAsSaved(self):
   183         self.EndBuffering()
   184         self.EndBuffering()
   184         self.CodeFileBuffer.CurrentSaved()
   185         self.CodeFileBuffer.CurrentSaved()
   186     def CodeFileIsSaved(self):
   187     def CodeFileIsSaved(self):
   187         return self.CodeFileBuffer.IsCurrentSaved() and not self.Buffering
   188         return self.CodeFileBuffer.IsCurrentSaved() and not self.Buffering
   188         
   189         
   189     def LoadPrevious(self):
   190     def LoadPrevious(self):
   190         self.EndBuffering()
   191         self.EndBuffering()
   191         self.CodeFile = self.cPickle_loads(self.CodeFileBuffer.Previous())
   192         self.CodeFile = self.CodeFileParser.Loads(self.CodeFileBuffer.Previous())
   192     
   193     
   193     def LoadNext(self):
   194     def LoadNext(self):
   194         self.CodeFile = self.cPickle_loads(self.CodeFileBuffer.Next())
   195         self.CodeFile = self.CodeFileParser.Loads(self.CodeFileBuffer.Next())
   195     
   196     
   196     def GetBufferState(self):
   197     def GetBufferState(self):
   197         first = self.CodeFileBuffer.IsFirst() and not self.Buffering
   198         first = self.CodeFileBuffer.IsFirst() and not self.Buffering
   198         last = self.CodeFileBuffer.IsLast()
   199         last = self.CodeFileBuffer.IsLast()
   199         return not first, not last
   200         return not first, not last