CodeFileTreeNode.py
changeset 1124 b1705000eba1
parent 1100 1f46424c6220
child 1146 510d1ea1f6c1
equal deleted inserted replaced
1123:55ed55ef7aea 1124:b1705000eba1
     1 import os
     1 import os
     2 from xml.dom import minidom
     2 from xml.dom import minidom
     3 import cPickle
     3 import cPickle
     4 
     4 
     5 from xmlclass import *
     5 from xmlclass import GenerateClassesFromXSDstring, UpdateXMLClassGlobals
     6 
     6 
     7 from PLCControler import UndoBuffer
     7 from PLCControler import UndoBuffer
     8 from editors.CodeFileEditor import SECTIONS_NAMES
       
     9 
     8 
    10 CodeFileClasses = GenerateClassesFromXSD(os.path.join(os.path.dirname(__file__), "code_file.xsd"))
     9 CODEFILE_XSD = """<?xml version="1.0" encoding="ISO-8859-1" ?>
       
    10 <xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema">
       
    11   <xsd:element name="%(codefile_name)s">
       
    12     <xsd:complexType>
       
    13       <xsd:sequence>
       
    14         %(includes_section)s
       
    15         <xsd:element name="variables">
       
    16           <xsd:complexType>
       
    17             <xsd:sequence>
       
    18               <xsd:element name="variable" minOccurs="0" maxOccurs="unbounded">
       
    19                 <xsd:complexType>
       
    20                   <xsd:attribute name="name" type="xsd:string" use="required"/>
       
    21                   <xsd:attribute name="type" type="xsd:string" use="required"/>
       
    22                   <xsd:attribute name="class" use="optional">
       
    23                     <xsd:simpleType>
       
    24                       <xsd:restriction base="xsd:string">
       
    25                         <xsd:enumeration value="input"/>
       
    26                         <xsd:enumeration value="memory"/>
       
    27                         <xsd:enumeration value="output"/>
       
    28                       </xsd:restriction>
       
    29                     </xsd:simpleType>
       
    30                   </xsd:attribute>
       
    31                   <xsd:attribute name="initial" type="xsd:string" use="optional" default=""/>
       
    32                 </xsd:complexType>
       
    33               </xsd:element>
       
    34             </xsd:sequence>
       
    35           </xsd:complexType>
       
    36         </xsd:element>
       
    37         %(sections)s
       
    38       </xsd:sequence>
       
    39     </xsd:complexType>
       
    40   </xsd:element>
       
    41   <xsd:complexType name="CodeText">
       
    42     <xsd:annotation>
       
    43       <xsd:documentation>Formatted text according to parts of XHTML 1.1</xsd:documentation>
       
    44     </xsd:annotation>
       
    45     <xsd:sequence>
       
    46       <xsd:any namespace="http://www.w3.org/1999/xhtml" processContents="lax"/>
       
    47     </xsd:sequence>
       
    48   </xsd:complexType>
       
    49 </xsd:schema>"""
       
    50 
       
    51 SECTION_TAG_ELEMENT = "<xsd:element name=\"%s\" type=\"CodeText\"/>"
    11 
    52 
    12 class CodeFile:
    53 class CodeFile:
    13     
    54     
       
    55     CODEFILE_NAME = "CodeFile"
       
    56     SECTIONS_NAMES = []
       
    57     
    14     def __init__(self):
    58     def __init__(self):
       
    59         sections_str = {"codefile_name": self.CODEFILE_NAME}
       
    60         if "includes" in self.SECTIONS_NAMES:
       
    61             sections_str["includes_section"] = SECTION_TAG_ELEMENT % "includes"
       
    62         else:
       
    63             sections_str["includes_section"] = ""
       
    64         sections_str["sections"] = "\n".join(
       
    65             [SECTION_TAG_ELEMENT % name
       
    66              for name in self.SECTIONS_NAMES if name != "includes"])
       
    67         
       
    68         self.CodeFileClasses = GenerateClassesFromXSDstring(
       
    69             CODEFILE_XSD % sections_str)
       
    70         
    15         filepath = self.CodeFileName()
    71         filepath = self.CodeFileName()
    16         
    72         
    17         self.CodeFile = CodeFileClasses["CodeFile"]()
    73         self.CodeFile = self.CodeFileClasses[self.CODEFILE_NAME]()
    18         if os.path.isfile(filepath):
    74         if os.path.isfile(filepath):
    19             xmlfile = open(filepath, 'r')
    75             xmlfile = open(filepath, 'r')
    20             tree = minidom.parse(xmlfile)
    76             tree = minidom.parse(xmlfile)
    21             xmlfile.close()
    77             xmlfile.close()
    22             
    78             
    23             for child in tree.childNodes:
    79             for child in tree.childNodes:
    24                 if child.nodeType == tree.ELEMENT_NODE and child.nodeName in ["CodeFile", "CFile"]:
    80                 if child.nodeType == tree.ELEMENT_NODE and child.nodeName in [self.CODEFILE_NAME]:
    25                     self.CodeFile.loadXMLTree(child, ["xmlns", "xmlns:xsi", "xsi:schemaLocation"])
    81                     self.CodeFile.loadXMLTree(child, ["xmlns", "xmlns:xsi", "xsi:schemaLocation"])
    26                     self.CreateCodeFileBuffer(True)
    82                     self.CreateCodeFileBuffer(True)
    27         else:
    83         else:
    28             self.CreateCodeFileBuffer(False)
    84             self.CreateCodeFileBuffer(False)
    29             self.OnCTNSave()
    85             self.OnCTNSave()
    35         return self.GetCTRoot().GetDataTypes(basetypes=basetypes)
    91         return self.GetCTRoot().GetDataTypes(basetypes=basetypes)
    36 
    92 
    37     def SetVariables(self, variables):
    93     def SetVariables(self, variables):
    38         self.CodeFile.variables.setvariable([])
    94         self.CodeFile.variables.setvariable([])
    39         for var in variables:
    95         for var in variables:
    40             variable = CodeFileClasses["variables_variable"]()
    96             variable = self.CodeFileClasses["variables_variable"]()
    41             variable.setname(var["Name"])
    97             variable.setname(var["Name"])
    42             variable.settype(var["Type"])
    98             variable.settype(var["Type"])
    43             variable.setinitial(var["Initial"])
    99             variable.setinitial(var["Initial"])
    44             self.CodeFile.variables.appendvariable(variable)
   100             self.CodeFile.variables.appendvariable(variable)
    45     
   101     
    46     def GetVariables(self):
   102     def GetVariables(self):
    47         datas = []
   103         datas = []
    48         for var in self.CodeFile.variables.getvariable():
   104         for var in self.CodeFile.variables.getvariable():
    49             datas.append({"Name" : var.getname(), "Type" : var.gettype(), "Initial" : var.getinitial()})
   105             datas.append({"Name" : var.getname(), 
       
   106                           "Type" : var.gettype(), 
       
   107                           "Initial" : var.getinitial()})
    50         return datas
   108         return datas
    51 
   109 
    52     def SetTextParts(self, parts):
   110     def SetTextParts(self, parts):
    53         for section, code_object in zip(
   111         for section in self.SECTIONS_NAMES:
    54             SECTIONS_NAMES,
   112             section_code = parts.get(section)
    55             [self.CodeFile.includes,
   113             if section_code is not None:
    56              self.CodeFile.globals,
   114                 getattr(self.CodeFile, section).settext(section_code)
    57              self.CodeFile.initFunction,
   115     
    58              self.CodeFile.cleanUpFunction,
       
    59              self.CodeFile.retrieveFunction,
       
    60              self.CodeFile.publishFunction]):
       
    61             code_object.settext(parts[section])
       
    62         
       
    63     def GetTextParts(self):
   116     def GetTextParts(self):
    64         parts = {}
   117         return dict([(section, getattr(self.CodeFile, section).gettext())
    65         for section, code_object in zip(
   118                      for section in self.SECTIONS_NAMES])
    66             SECTIONS_NAMES,
   119             
    67             [self.CodeFile.includes,
       
    68              self.CodeFile.globals,
       
    69              self.CodeFile.initFunction,
       
    70              self.CodeFile.cleanUpFunction,
       
    71              self.CodeFile.retrieveFunction,
       
    72              self.CodeFile.publishFunction]):
       
    73             parts[section] = code_object.gettext()
       
    74         return parts
       
    75                 
       
    76     def CTNTestModified(self):
   120     def CTNTestModified(self):
    77         return self.ChangesToSave or not self.CodeFileIsSaved()    
   121         return self.ChangesToSave or not self.CodeFileIsSaved()    
    78 
   122 
    79     def OnCTNSave(self, from_project_path=None):
   123     def OnCTNSave(self, from_project_path=None):
    80         filepath = self.CodeFileName()
   124         filepath = self.CodeFileName()
    81         
   125         
    82         text = "<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"no\"?>\n"
   126         text = "<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"no\"?>\n"
    83         extras = {"xmlns":"http://www.w3.org/2001/XMLSchema",
   127         text += self.CodeFile.generateXMLText(self.CODEFILE_NAME, 0)
    84                   "xmlns:xsi":"http://www.w3.org/2001/XMLSchema-instance",
       
    85                   "xsi:schemaLocation" : "code_file.xsd"}
       
    86         text += self.CodeFile.generateXMLText("CodeFile", 0, extras)
       
    87 
   128 
    88         xmlfile = open(filepath,"w")
   129         xmlfile = open(filepath,"w")
    89         xmlfile.write(text.encode("utf-8"))
   130         xmlfile.write(text.encode("utf-8"))
    90         xmlfile.close()
   131         xmlfile.close()
    91         
   132         
   101 
   142 
   102 #-------------------------------------------------------------------------------
   143 #-------------------------------------------------------------------------------
   103 #                      Current Buffering Management Functions
   144 #                      Current Buffering Management Functions
   104 #-------------------------------------------------------------------------------
   145 #-------------------------------------------------------------------------------
   105 
   146 
       
   147     def cPickle_loads(self, str_obj):
       
   148         UpdateXMLClassGlobals(self.CodeFileClasses)
       
   149         return cPickle.loads(str_obj)
       
   150 
       
   151     def cPickle_dumps(self, obj):
       
   152         UpdateXMLClassGlobals(self.CodeFileClasses)
       
   153         return cPickle.dumps(obj)
       
   154 
   106     """
   155     """
   107     Return a copy of the codefile model
   156     Return a copy of the codefile model
   108     """
   157     """
   109     def Copy(self, model):
   158     def Copy(self, model):
   110         return cPickle.loads(cPickle.dumps(model))
   159         return self.cPickle_loads(self.cPickle_dumps(model))
   111 
   160 
   112     def CreateCodeFileBuffer(self, saved):
   161     def CreateCodeFileBuffer(self, saved):
   113         self.Buffering = False
   162         self.Buffering = False
   114         self.CodeFileBuffer = UndoBuffer(cPickle.dumps(self.CodeFile), saved)
   163         self.CodeFileBuffer = UndoBuffer(self.cPickle_dumps(self.CodeFile), saved)
   115 
   164 
   116     def BufferCodeFile(self):
   165     def BufferCodeFile(self):
   117         self.CodeFileBuffer.Buffering(cPickle.dumps(self.CodeFile))
   166         self.CodeFileBuffer.Buffering(self.cPickle_dumps(self.CodeFile))
   118     
   167     
   119     def StartBuffering(self):
   168     def StartBuffering(self):
   120         self.Buffering = True
   169         self.Buffering = True
   121         
   170         
   122     def EndBuffering(self):
   171     def EndBuffering(self):
   123         if self.Buffering:
   172         if self.Buffering:
   124             self.CodeFileBuffer.Buffering(cPickle.dumps(self.CodeFile))
   173             self.CodeFileBuffer.Buffering(self.cPickle_dumps(self.CodeFile))
   125             self.Buffering = False
   174             self.Buffering = False
   126     
   175     
   127     def MarkCodeFileAsSaved(self):
   176     def MarkCodeFileAsSaved(self):
   128         self.EndBuffering()
   177         self.EndBuffering()
   129         self.CodeFileBuffer.CurrentSaved()
   178         self.CodeFileBuffer.CurrentSaved()
   131     def CodeFileIsSaved(self):
   180     def CodeFileIsSaved(self):
   132         return self.CodeFileBuffer.IsCurrentSaved() and not self.Buffering
   181         return self.CodeFileBuffer.IsCurrentSaved() and not self.Buffering
   133         
   182         
   134     def LoadPrevious(self):
   183     def LoadPrevious(self):
   135         self.EndBuffering()
   184         self.EndBuffering()
   136         self.CodeFile = cPickle.loads(self.CodeFileBuffer.Previous())
   185         self.CodeFile = self.cPickle_loads(self.CodeFileBuffer.Previous())
   137     
   186     
   138     def LoadNext(self):
   187     def LoadNext(self):
   139         self.CodeFile = cPickle.loads(self.CodeFileBuffer.Next())
   188         self.CodeFile = self.cPickle_loads(self.CodeFileBuffer.Next())
   140     
   189     
   141     def GetBufferState(self):
   190     def GetBufferState(self):
   142         first = self.CodeFileBuffer.IsFirst() and not self.Buffering
   191         first = self.CodeFileBuffer.IsFirst() and not self.Buffering
   143         last = self.CodeFileBuffer.IsLast()
   192         last = self.CodeFileBuffer.IsLast()
   144         return not first, not last
   193         return not first, not last