plcopen/plcopen.py
changeset 1329 9d0cb01312f0
parent 1322 0a9227f743b3
child 1330 96b242e4c59d
equal deleted inserted replaced
1288:adc79fc44079 1329:9d0cb01312f0
    21 #You should have received a copy of the GNU General Public
    21 #You should have received a copy of the GNU General Public
    22 #License along with this library; if not, write to the Free Software
    22 #License along with this library; if not, write to the Free Software
    23 #Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
    23 #Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
    24 
    24 
    25 from xmlclass import *
    25 from xmlclass import *
    26 from structures import *
       
    27 from types import *
    26 from types import *
    28 import os, re
    27 import os, re
    29 from collections import OrderedDict
    28 from lxml import etree
    30 """
    29 """
    31 Dictionary that makes the relation between var names in plcopen and displayed values
    30 Dictionary that makes the relation between var names in plcopen and displayed values
    32 """
    31 """
    33 VarTypes = {"Local" : "localVars", "Temp" : "tempVars", "Input" : "inputVars",
    32 VarTypes = {"Local" : "localVars", "Temp" : "tempVars", "Input" : "inputVars",
    34             "Output" : "outputVars", "InOut" : "inOutVars", "External" : "externalVars",
    33             "Output" : "outputVars", "InOut" : "inOutVars", "External" : "externalVars",
   120         end = TextLenInRowColumn(text[:result.end() - 1])
   119         end = TextLenInRowColumn(text[:result.end() - 1])
   121         test_result.append((start, end, "\n".join(lines[start[0]:end[0] + 1])))
   120         test_result.append((start, end, "\n".join(lines[start[0]:end[0] + 1])))
   122         result = criteria["pattern"].search(text, result.end())
   121         result = criteria["pattern"].search(text, result.end())
   123     return test_result
   122     return test_result
   124 
   123 
   125 PLCOpenClasses = GenerateClassesFromXSD(os.path.join(os.path.split(__file__)[0], "tc6_xml_v201.xsd"))
   124 PLCOpenParser = GenerateParserFromXSD(os.path.join(os.path.split(__file__)[0], "tc6_xml_v201.xsd"))
   126 
   125 PLCOpen_XPath = lambda xpath: etree.XPath(xpath, namespaces=PLCOpenParser.NSMAP)
   127 ElementNameToClass = {}
   126 
   128 
   127 LOAD_POU_PROJECT_TEMPLATE = """
   129 cls = PLCOpenClasses.get("formattedText", None)
   128 <project xmlns:ns1="http://www.plcopen.org/xml/tc6_0201" 
       
   129          xmlns:xhtml="http://www.w3.org/1999/xhtml" 
       
   130          xmlns:xsd="http://www.w3.org/2001/XMLSchema" 
       
   131          xmlns="http://www.plcopen.org/xml/tc6_0201">
       
   132   <fileHeader companyName="" productName="" productVersion="" 
       
   133               creationDateTime="1970-01-01T00:00:00"/>
       
   134   <contentHeader name="paste_project">
       
   135     <coordinateInfo>
       
   136       <fbd><scaling x="0" y="0"/></fbd>
       
   137       <ld><scaling x="0" y="0"/></ld>
       
   138       <sfc><scaling x="0" y="0"/></sfc>
       
   139     </coordinateInfo>
       
   140   </contentHeader>
       
   141   <types>
       
   142     <dataTypes/>
       
   143     <pous>%s</pous>
       
   144   </types>
       
   145   <instances>
       
   146     <configurations/>
       
   147   </instances>
       
   148 </project>
       
   149 """
       
   150 
       
   151 def LOAD_POU_INSTANCES_PROJECT_TEMPLATE(body_type):
       
   152     return LOAD_POU_PROJECT_TEMPLATE % """
       
   153 <pou name="paste_pou" pouType="program">
       
   154   <body>
       
   155     <%(body_type)s>%%s</%(body_type)s>
       
   156   </body>
       
   157 </pou>""" % locals()
       
   158 
       
   159 def LoadProject(filepath):
       
   160     project_file = open(filepath)
       
   161     project_xml = project_file.read().replace(
       
   162         "http://www.plcopen.org/xml/tc6.xsd", 
       
   163         "http://www.plcopen.org/xml/tc6_0201")
       
   164     for cre, repl in [
       
   165         (re.compile("(?<!<xhtml:p>)(?:<!\[CDATA\[)"), "<xhtml:p><![CDATA["),
       
   166         (re.compile("(?:]]>)(?!</xhtml:p>)"), "]]></xhtml:p>")]:
       
   167         project_xml = cre.sub(repl, project_xml)
       
   168     project_file.close()
       
   169     
       
   170     return etree.fromstring(project_xml, PLCOpenParser)
       
   171 
       
   172 project_pou_xpath = PLCOpen_XPath("/ppx:project/ppx:types/ppx:pous/ppx:pou")
       
   173 def LoadPou(xml_string):
       
   174     root = etree.fromstring(
       
   175         LOAD_POU_PROJECT_TEMPLATE % xml_string, 
       
   176         PLCOpenParser)
       
   177     return project_pou_xpath(root)[0]
       
   178 
       
   179 project_pou_instances_xpath = {
       
   180     body_type: PLCOpen_XPath(
       
   181         "/ppx:project/ppx:types/ppx:pous/ppx:pou[@name='paste_pou']/ppx:body/ppx:%s/*" % body_type)
       
   182     for body_type in ["FBD", "LD", "SFC"]}
       
   183 def LoadPouInstances(xml_string, body_type):
       
   184     root = etree.fromstring(
       
   185         LOAD_POU_INSTANCES_PROJECT_TEMPLATE(body_type) % xml_string, 
       
   186         PLCOpenParser)
       
   187     return project_pou_instances_xpath[body_type](root)
       
   188 
       
   189 def SaveProject(project, filepath):
       
   190     project_file = open(filepath, 'w')
       
   191     project_file.write(etree.tostring(
       
   192         project, 
       
   193         pretty_print=True, 
       
   194         xml_declaration=True, 
       
   195         encoding='utf-8'))
       
   196     project_file.close()
       
   197 
       
   198 cls = PLCOpenParser.GetElementClass("formattedText")
   130 if cls:
   199 if cls:
   131     def updateElementName(self, old_name, new_name):
   200     def updateElementName(self, old_name, new_name):
   132         text = self.text
   201         text = self.getanyText()
   133         index = text.find(old_name)
   202         index = text.find(old_name)
   134         while index != -1:
   203         while index != -1:
   135             if index > 0 and (text[index - 1].isalnum() or text[index - 1] == "_"):
   204             if index > 0 and (text[index - 1].isalnum() or text[index - 1] == "_"):
   136                 index = text.find(old_name, index + len(old_name))
   205                 index = text.find(old_name, index + len(old_name))
   137             elif index < len(text) - len(old_name) and (text[index + len(old_name)].isalnum() or text[index + len(old_name)] == "_"):
   206             elif index < len(text) - len(old_name) and (text[index + len(old_name)].isalnum() or text[index + len(old_name)] == "_"):
   138                 index = text.find(old_name, index + len(old_name))
   207                 index = text.find(old_name, index + len(old_name))
   139             else:
   208             else:
   140                 text = text[:index] + new_name + text[index + len(old_name):]
   209                 text = text[:index] + new_name + text[index + len(old_name):]
   141                 index = text.find(old_name, index + len(new_name))
   210                 index = text.find(old_name, index + len(new_name))
   142         self.text = text
   211         self.setanyText(text)
   143     setattr(cls, "updateElementName", updateElementName)
   212     setattr(cls, "updateElementName", updateElementName)
   144     
   213     
   145     def updateElementAddress(self, address_model, new_leading):
   214     def updateElementAddress(self, address_model, new_leading):
   146         text = self.text
   215         text = self.getanyText()
   147         startpos = 0
   216         startpos = 0
   148         result = address_model.search(text, startpos)
   217         result = address_model.search(text, startpos)
   149         while result is not None:
   218         while result is not None:
   150             groups = result.groups()
   219             groups = result.groups()
   151             new_address = groups[0] + new_leading + groups[2]
   220             new_address = groups[0] + new_leading + groups[2]
   152             text = text[:result.start()] + new_address + text[result.end():]
   221             text = text[:result.start()] + new_address + text[result.end():]
   153             startpos = result.start() + len(new_address)
   222             startpos = result.start() + len(new_address)
   154             result = address_model.search(self.text, startpos)
   223             result = address_model.search(text, startpos)
   155         self.text = text
   224         self.setanyText(text)
   156     setattr(cls, "updateElementAddress", updateElementAddress)
   225     setattr(cls, "updateElementAddress", updateElementAddress)
   157     
   226     
   158     def hasblock(self, block_type):
   227     def hasblock(self, block_type):
   159         text = self.text.upper()
   228         text = self.getanyText().upper()
   160         index = text.find(block_type.upper())
   229         index = text.find(block_type.upper())
   161         while index != -1:
   230         while index != -1:
   162             if (not (index > 0 and (text[index - 1].isalnum() or text[index - 1] == "_")) and 
   231             if (not (index > 0 and (text[index - 1].isalnum() or text[index - 1] == "_")) and 
   163                 not (index < len(text) - len(block_type) and text[index + len(block_type)] != "(")):
   232                 not (index < len(text) - len(block_type) and text[index + len(block_type)] != "(")):
   164                 return True
   233                 return True
   165             index = text.find(block_type.upper(), index + len(block_type))
   234             index = text.find(block_type.upper(), index + len(block_type))
   166         return False
   235         return False
   167     setattr(cls, "hasblock", hasblock)
   236     setattr(cls, "hasblock", hasblock)
   168     
   237     
   169     def Search(self, criteria, parent_infos):
   238     def Search(self, criteria, parent_infos):
   170         return [(tuple(parent_infos),) + result for result in TestTextElement(self.gettext(), criteria)]
   239         return [(tuple(parent_infos),) + result for result in TestTextElement(self.getanyText(), criteria)]
   171     setattr(cls, "Search", Search)
   240     setattr(cls, "Search", Search)
   172     
   241     
   173 cls = PLCOpenClasses.get("project", None)
   242 cls = PLCOpenParser.GetElementClass("project")
   174 if cls:
   243 if cls:
   175     cls.singleLineAttributes = False
       
   176     cls.EnumeratedDataTypeValues = {}
       
   177     cls.CustomDataTypeRange = {}
       
   178     cls.CustomTypeHierarchy = {}
       
   179     cls.ElementUsingTree = {}
       
   180     cls.CustomBlockTypes = OrderedDict()
       
   181     
   244     
   182     def setname(self, name):
   245     def setname(self, name):
   183         self.contentHeader.setname(name)
   246         self.contentHeader.setname(name)
   184     setattr(cls, "setname", setname)
   247     setattr(cls, "setname", setname)
   185         
   248         
   186     def getname(self):
   249     def getname(self):
   187         return self.contentHeader.getname()
   250         return self.contentHeader.getname()
   188     setattr(cls, "getname", getname)
   251     setattr(cls, "getname", getname)
   189     
   252     
   190     def getfileHeader(self):
   253     def getfileHeader(self):
   191         fileheader = {}
   254         fileheader_obj = self.fileHeader
   192         for name, value in [("companyName", self.fileHeader.getcompanyName()),
   255         return {
   193                             ("companyURL", self.fileHeader.getcompanyURL()),
   256             attr: value if value is not None else ""
   194                             ("productName", self.fileHeader.getproductName()),
   257             for attr, value in [
   195                             ("productVersion", self.fileHeader.getproductVersion()),
   258                 ("companyName", fileheader_obj.getcompanyName()),
   196                             ("productRelease", self.fileHeader.getproductRelease()),
   259                 ("companyURL", fileheader_obj.getcompanyURL()),
   197                             ("creationDateTime", self.fileHeader.getcreationDateTime()),
   260                 ("productName", fileheader_obj.getproductName()),
   198                             ("contentDescription", self.fileHeader.getcontentDescription())]:
   261                 ("productVersion", fileheader_obj.getproductVersion()),
       
   262                 ("productRelease", fileheader_obj.getproductRelease()),
       
   263                 ("creationDateTime", fileheader_obj.getcreationDateTime()),
       
   264                 ("contentDescription", fileheader_obj.getcontentDescription())]
       
   265         }
       
   266     setattr(cls, "getfileHeader", getfileHeader)
       
   267     
       
   268     def setfileHeader(self, fileheader):
       
   269         fileheader_obj = self.fileHeader
       
   270         for attr in ["companyName", "companyURL", "productName",
       
   271                      "productVersion", "productRelease", "creationDateTime",
       
   272                      "contentDescription"]:
       
   273             value = fileheader.get(attr)
   199             if value is not None:
   274             if value is not None:
   200                 fileheader[name] = value
   275                 setattr(fileheader_obj, attr, value)
   201             else:
       
   202                 fileheader[name] = ""
       
   203         return fileheader
       
   204     setattr(cls, "getfileHeader", getfileHeader)
       
   205     
       
   206     def setfileHeader(self, fileheader):
       
   207         if fileheader.has_key("companyName"):
       
   208             self.fileHeader.setcompanyName(fileheader["companyName"])
       
   209         if fileheader.has_key("companyURL"):
       
   210             self.fileHeader.setcompanyURL(fileheader["companyURL"])
       
   211         if fileheader.has_key("productName"):
       
   212             self.fileHeader.setproductName(fileheader["productName"])
       
   213         if fileheader.has_key("productVersion"):
       
   214             self.fileHeader.setproductVersion(fileheader["productVersion"])
       
   215         if fileheader.has_key("productRelease"):
       
   216             self.fileHeader.setproductRelease(fileheader["productRelease"])
       
   217         if fileheader.has_key("creationDateTime"):
       
   218             self.fileHeader.setcreationDateTime(fileheader["creationDateTime"])
       
   219         if fileheader.has_key("contentDescription"):
       
   220             self.fileHeader.setcontentDescription(fileheader["contentDescription"])
       
   221     setattr(cls, "setfileHeader", setfileHeader)
   276     setattr(cls, "setfileHeader", setfileHeader)
   222     
   277     
   223     def getcontentHeader(self):
   278     def getcontentHeader(self):
   224         contentheader = {}
   279         contentheader_obj = self.contentHeader
   225         for name, value in [("projectName", self.contentHeader.getname()),
   280         contentheader = {
   226                             ("projectVersion", self.contentHeader.getversion()),
   281             attr: value if value is not None else ""
   227                             ("modificationDateTime", self.contentHeader.getmodificationDateTime()),
   282             for attr, value in [
   228                             ("organization", self.contentHeader.getorganization()),
   283                 ("projectName", contentheader_obj.getname()),
   229                             ("authorName", self.contentHeader.getauthor()),
   284                 ("projectVersion", contentheader_obj.getversion()),
   230                             ("language", self.contentHeader.getlanguage())]:
   285                 ("modificationDateTime", contentheader_obj.getmodificationDateTime()),
   231             if value is not None:
   286                 ("organization", contentheader_obj.getorganization()),
   232                 contentheader[name] = value
   287                 ("authorName", contentheader_obj.getauthor()),
   233             else:
   288                 ("language", contentheader_obj.getlanguage())]
   234                 contentheader[name] = ""
   289         }
   235         contentheader["pageSize"] = self.contentHeader.getpageSize()
   290         contentheader["pageSize"] = self.contentHeader.getpageSize()
   236         contentheader["scaling"] = self.contentHeader.getscaling()
   291         contentheader["scaling"] = self.contentHeader.getscaling()
   237         return contentheader
   292         return contentheader
   238     setattr(cls, "getcontentHeader", getcontentHeader)
   293     setattr(cls, "getcontentHeader", getcontentHeader)
   239     
   294     
   240     def setcontentHeader(self, contentheader):
   295     def setcontentHeader(self, contentheader):
   241         if contentheader.has_key("projectName"):
   296         contentheader_obj = self.contentHeader
   242             self.contentHeader.setname(contentheader["projectName"])
   297         for attr, value in contentheader.iteritems():
   243         if contentheader.has_key("projectVersion"):
   298             func = {"projectName": contentheader_obj.setname,
   244             self.contentHeader.setversion(contentheader["projectVersion"])
   299                     "projectVersion": contentheader_obj.setversion,
   245         if contentheader.has_key("modificationDateTime"):
   300                     "authorName": contentheader_obj.setauthor,
   246             self.contentHeader.setmodificationDateTime(contentheader["modificationDateTime"])
   301                     "pageSize": lambda v: contentheader_obj.setpageSize(*v),
   247         if contentheader.has_key("organization"):
   302                     "scaling": contentheader_obj.setscaling}.get(attr)
   248             self.contentHeader.setorganization(contentheader["organization"])
   303             if func is not None:
   249         if contentheader.has_key("authorName"):
   304                 func(value)
   250             self.contentHeader.setauthor(contentheader["authorName"])
   305             elif attr in ["modificationDateTime", "organization", "language"]:
   251         if contentheader.has_key("language"):
   306                 setattr(contentheader_obj, attr, value)
   252             self.contentHeader.setlanguage(contentheader["language"])
       
   253         if contentheader.has_key("pageSize"):
       
   254             self.contentHeader.setpageSize(*contentheader["pageSize"])
       
   255         if contentheader.has_key("scaling"):
       
   256             self.contentHeader.setscaling(contentheader["scaling"])
       
   257     setattr(cls, "setcontentHeader", setcontentHeader)
   307     setattr(cls, "setcontentHeader", setcontentHeader)
   258     
   308     
   259     def getdataTypes(self):
   309     def gettypeElementFunc(element_type):
   260         return self.types.getdataTypeElements()
   310         elements_xpath = PLCOpen_XPath(
       
   311             "ppx:types/ppx:%(element_type)ss/ppx:%(element_type)s[@name=$name]" % locals())
       
   312         def gettypeElement(self, name):
       
   313             elements = elements_xpath(self, name=name)
       
   314             if len(elements) == 1:
       
   315                 return elements[0]
       
   316             return None
       
   317         return gettypeElement
       
   318     
       
   319     datatypes_xpath = PLCOpen_XPath("ppx:types/ppx:dataTypes/ppx:dataType")
       
   320     filtered_datatypes_xpath = PLCOpen_XPath(
       
   321         "ppx:types/ppx:dataTypes/ppx:dataType[@name!=$exclude]")
       
   322     def getdataTypes(self, exclude=None):
       
   323         if exclude is not None:
       
   324             return filtered_datatypes_xpath(self, exclude=exclude)
       
   325         return datatypes_xpath(self)
   261     setattr(cls, "getdataTypes", getdataTypes)
   326     setattr(cls, "getdataTypes", getdataTypes)
   262     
   327     
   263     def getdataType(self, name):
   328     setattr(cls, "getdataType", gettypeElementFunc("dataType"))
   264         return self.types.getdataTypeElement(name)
       
   265     setattr(cls, "getdataType", getdataType)
       
   266     
   329     
   267     def appenddataType(self, name):
   330     def appenddataType(self, name):
   268         if self.CustomTypeHierarchy.has_key(name):
   331         if self.getdataType(name) is not None:
   269             raise ValueError, "\"%s\" Data Type already exists !!!"%name
   332             raise ValueError, "\"%s\" Data Type already exists !!!"%name
   270         self.types.appenddataTypeElement(name)
   333         self.types.appenddataTypeElement(name)
   271         self.AddCustomDataType(self.getdataType(name))
       
   272     setattr(cls, "appenddataType", appenddataType)
   334     setattr(cls, "appenddataType", appenddataType)
   273         
   335         
   274     def insertdataType(self, index, datatype):
   336     def insertdataType(self, index, datatype):
   275         self.types.insertdataTypeElement(index, datatype)
   337         self.types.insertdataTypeElement(index, datatype)
   276         self.AddCustomDataType(datatype)
       
   277     setattr(cls, "insertdataType", insertdataType)
   338     setattr(cls, "insertdataType", insertdataType)
   278     
   339     
   279     def removedataType(self, name):
   340     def removedataType(self, name):
   280         self.types.removedataTypeElement(name)
   341         self.types.removedataTypeElement(name)
   281         self.RefreshDataTypeHierarchy()
       
   282         self.RefreshElementUsingTree()
       
   283     setattr(cls, "removedataType", removedataType)
   342     setattr(cls, "removedataType", removedataType)
   284     
   343     
   285     def getpous(self):
   344     def getpous(self, exclude=None, filter=[]):
   286         return self.types.getpouElements()
   345         return self.xpath(
       
   346             "ppx:types/ppx:pous/ppx:pou%s%s" % 
       
   347                 (("[@name!='%s']" % exclude) if exclude is not None else '',
       
   348                  ("[%s]" % " or ".join(
       
   349                     map(lambda x: "@pouType='%s'" % x, filter)))
       
   350                  if len(filter) > 0 else ""),
       
   351             namespaces=PLCOpenParser.NSMAP)
   287     setattr(cls, "getpous", getpous)
   352     setattr(cls, "getpous", getpous)
   288     
   353     
   289     def getpou(self, name):
   354     setattr(cls, "getpou", gettypeElementFunc("pou"))
   290         return self.types.getpouElement(name)
       
   291     setattr(cls, "getpou", getpou)
       
   292     
   355     
   293     def appendpou(self, name, pou_type, body_type):
   356     def appendpou(self, name, pou_type, body_type):
   294         self.types.appendpouElement(name, pou_type, body_type)
   357         self.types.appendpouElement(name, pou_type, body_type)
   295         self.AddCustomBlockType(self.getpou(name))
       
   296     setattr(cls, "appendpou", appendpou)
   358     setattr(cls, "appendpou", appendpou)
   297         
   359         
   298     def insertpou(self, index, pou):
   360     def insertpou(self, index, pou):
   299         self.types.insertpouElement(index, pou)
   361         self.types.insertpouElement(index, pou)
   300         self.AddCustomBlockType(pou)
       
   301     setattr(cls, "insertpou", insertpou)
   362     setattr(cls, "insertpou", insertpou)
   302     
   363     
   303     def removepou(self, name):
   364     def removepou(self, name):
   304         self.types.removepouElement(name)
   365         self.types.removepouElement(name)
   305         self.RefreshCustomBlockTypes()
       
   306         self.RefreshElementUsingTree()
       
   307     setattr(cls, "removepou", removepou)
   366     setattr(cls, "removepou", removepou)
   308 
   367 
       
   368     configurations_xpath = PLCOpen_XPath(
       
   369         "ppx:instances/ppx:configurations/ppx:configuration")
   309     def getconfigurations(self):
   370     def getconfigurations(self):
   310         configurations = self.instances.configurations.getconfiguration()
   371         return configurations_xpath(self)
   311         if configurations:
       
   312             return configurations
       
   313         return []
       
   314     setattr(cls, "getconfigurations", getconfigurations)
   372     setattr(cls, "getconfigurations", getconfigurations)
   315 
   373 
       
   374     configuration_xpath = PLCOpen_XPath(
       
   375         "ppx:instances/ppx:configurations/ppx:configuration[@name=$name]")
   316     def getconfiguration(self, name):
   376     def getconfiguration(self, name):
   317         for configuration in self.instances.configurations.getconfiguration():
   377         configurations = configuration_xpath(self, name=name)
   318             if configuration.getname() == name:
   378         if len(configurations) == 1:
   319                 return configuration
   379             return configurations[0]
   320         return None
   380         return None
   321     setattr(cls, "getconfiguration", getconfiguration)
   381     setattr(cls, "getconfiguration", getconfiguration)
   322 
   382 
   323     def addconfiguration(self, name):
   383     def addconfiguration(self, name):
   324         for configuration in self.instances.configurations.getconfiguration():
   384         if self.getconfiguration(name) is not None:
   325             if configuration.getname() == name:
   385             raise ValueError, _("\"%s\" configuration already exists !!!") % name
   326                 raise ValueError, _("\"%s\" configuration already exists !!!")%name
   386         new_configuration = PLCOpenParser.CreateElement("configuration", "configurations")
   327         new_configuration = PLCOpenClasses["configurations_configuration"]()
       
   328         new_configuration.setname(name)
   387         new_configuration.setname(name)
   329         self.instances.configurations.appendconfiguration(new_configuration)
   388         self.instances.configurations.appendconfiguration(new_configuration)
   330     setattr(cls, "addconfiguration", addconfiguration)    
   389     setattr(cls, "addconfiguration", addconfiguration)    
   331 
   390 
   332     def removeconfiguration(self, name):
   391     def removeconfiguration(self, name):
   333         found = False
   392         configuration = self.getconfiguration(name)
   334         for idx, configuration in enumerate(self.instances.configurations.getconfiguration()):
   393         if configuration is None:
   335             if configuration.getname() == name:
   394             raise ValueError, ("\"%s\" configuration doesn't exist !!!") % name
   336                 self.instances.configurations.removeconfiguration(idx)
   395         self.instances.configurations.remove(configuration)
   337                 found = True
       
   338                 break
       
   339         if not found:
       
   340             raise ValueError, ("\"%s\" configuration doesn't exist !!!")%name
       
   341     setattr(cls, "removeconfiguration", removeconfiguration)
   396     setattr(cls, "removeconfiguration", removeconfiguration)
   342 
   397     
       
   398     resources_xpath = PLCOpen_XPath(
       
   399         "ppx:instances/ppx:configurations/ppx:configuration[@name=$configname]/ppx:resource[@name=$name]")
   343     def getconfigurationResource(self, config_name, name):
   400     def getconfigurationResource(self, config_name, name):
   344         configuration = self.getconfiguration(config_name)
   401         resources = resources_xpath(self, configname=config_name, name=name)
   345         if configuration:
   402         if len(resources) == 1:
   346             for resource in configuration.getresource():
   403             return resources[0]
   347                 if resource.getname() == name:
       
   348                     return resource
       
   349         return None
   404         return None
   350     setattr(cls, "getconfigurationResource", getconfigurationResource)
   405     setattr(cls, "getconfigurationResource", getconfigurationResource)
   351 
   406 
   352     def addconfigurationResource(self, config_name, name):
   407     def addconfigurationResource(self, config_name, name):
       
   408         if self.getconfigurationResource(config_name, name) is not None:
       
   409             raise ValueError, _("\"%s\" resource already exists in \"%s\" configuration !!!") % (name, config_name)
   353         configuration = self.getconfiguration(config_name)
   410         configuration = self.getconfiguration(config_name)
   354         if configuration:
   411         if configuration is not None:
   355             for resource in configuration.getresource():
   412             new_resource = PLCOpenParser.CreateElement("resource", "configuration")
   356                 if resource.getname() == name:
       
   357                     raise ValueError, _("\"%s\" resource already exists in \"%s\" configuration !!!")%(name, config_name)
       
   358             new_resource = PLCOpenClasses["configuration_resource"]()
       
   359             new_resource.setname(name)
   413             new_resource.setname(name)
   360             configuration.appendresource(new_resource)
   414             configuration.appendresource(new_resource)
   361     setattr(cls, "addconfigurationResource", addconfigurationResource)
   415     setattr(cls, "addconfigurationResource", addconfigurationResource)
   362 
   416 
   363     def removeconfigurationResource(self, config_name, name):
   417     def removeconfigurationResource(self, config_name, name):
   364         configuration = self.getconfiguration(config_name)
   418         configuration = self.getconfiguration(config_name)
   365         if configuration:
   419         found = False
   366             found = False
   420         if configuration is not None:
   367             for idx, resource in enumerate(configuration.getresource()):
   421             resource = self.getconfigurationResource(config_name, name)
   368                 if resource.getname() == name:
   422             if resource is not None:
   369                     configuration.removeresource(idx)
   423                 configuration.remove(resource)
   370                     found = True
   424                 found = True
   371                     break
   425         if not found:
   372             if not found:
   426             raise ValueError, _("\"%s\" resource doesn't exist in \"%s\" configuration !!!")%(name, config_name)
   373                 raise ValueError, _("\"%s\" resource doesn't exist in \"%s\" configuration !!!")%(name, config_name)
       
   374     setattr(cls, "removeconfigurationResource", removeconfigurationResource)
   427     setattr(cls, "removeconfigurationResource", removeconfigurationResource)
   375 
   428 
   376     def updateElementName(self, old_name, new_name):
   429     def updateElementName(self, old_name, new_name):
   377         for datatype in self.types.getdataTypeElements():
   430         for datatype in self.getdataTypes():
   378             datatype.updateElementName(old_name, new_name)
   431             datatype.updateElementName(old_name, new_name)
   379         for pou in self.types.getpouElements():
   432         for pou in self.getpous():
   380             pou.updateElementName(old_name, new_name)
   433             pou.updateElementName(old_name, new_name)
   381         for configuration in self.instances.configurations.getconfiguration():
   434         for configuration in self.getconfigurations():
   382             configuration.updateElementName(old_name, new_name)
   435             configuration.updateElementName(old_name, new_name)
   383     setattr(cls, "updateElementName", updateElementName)
   436     setattr(cls, "updateElementName", updateElementName)
   384 
   437 
   385     def updateElementAddress(self, old_leading, new_leading):
   438     def updateElementAddress(self, old_leading, new_leading):
   386         address_model = re.compile(FILTER_ADDRESS_MODEL % old_leading)
   439         address_model = re.compile(FILTER_ADDRESS_MODEL % old_leading)
   387         for pou in self.types.getpouElements():
   440         for pou in self.getpous():
   388             pou.updateElementAddress(address_model, new_leading)
   441             pou.updateElementAddress(address_model, new_leading)
   389         for configuration in self.instances.configurations.getconfiguration():
   442         for configuration in self.getconfigurations():
   390             configuration.updateElementAddress(address_model, new_leading)
   443             configuration.updateElementAddress(address_model, new_leading)
   391     setattr(cls, "updateElementAddress", updateElementAddress)
   444     setattr(cls, "updateElementAddress", updateElementAddress)
   392 
   445 
   393     def removeVariableByAddress(self, address):
   446     def removeVariableByAddress(self, address):
   394         for pou in self.types.getpouElements():
   447         for pou in self.getpous():
   395             pou.removeVariableByAddress(address)
   448             pou.removeVariableByAddress(address)
   396         for configuration in self.instances.configurations.getconfiguration():
   449         for configuration in self.getconfigurations():
   397             configuration.removeVariableByAddress(address)
   450             configuration.removeVariableByAddress(address)
   398     setattr(cls, "removeVariableByAddress", removeVariableByAddress)
   451     setattr(cls, "removeVariableByAddress", removeVariableByAddress)
   399 
   452 
   400     def removeVariableByFilter(self, leading):
   453     def removeVariableByFilter(self, leading):
   401         address_model = re.compile(FILTER_ADDRESS_MODEL % leading)
   454         address_model = re.compile(FILTER_ADDRESS_MODEL % leading)
   402         for pou in self.types.getpouElements():
   455         for pou in self.getpous():
   403             pou.removeVariableByFilter(address_model)
   456             pou.removeVariableByFilter(address_model)
   404         for configuration in self.instances.configurations.getconfiguration():
   457         for configuration in self.getconfigurations():
   405             configuration.removeVariableByFilter(address_model)
   458             configuration.removeVariableByFilter(address_model)
   406     setattr(cls, "removeVariableByFilter", removeVariableByFilter)
   459     setattr(cls, "removeVariableByFilter", removeVariableByFilter)
   407 
   460 
   408     def RefreshDataTypeHierarchy(self):
   461     enumerated_values_xpath = PLCOpen_XPath(
   409         self.EnumeratedDataTypeValues = {}
   462         "ppx:types/ppx:dataTypes/ppx:dataType/ppx:baseType/ppx:enum/ppx:values/ppx:value")
   410         self.CustomDataTypeRange = {}
   463     def GetEnumeratedDataTypeValues(self):
   411         self.CustomTypeHierarchy = {}
   464         return [value.getname() for value in enumerated_values_xpath(self)]
   412         for datatype in self.getdataTypes():
       
   413             self.AddCustomDataType(datatype)
       
   414     setattr(cls, "RefreshDataTypeHierarchy", RefreshDataTypeHierarchy)
       
   415 
       
   416     def AddCustomDataType(self, datatype):
       
   417         name = datatype.getname()
       
   418         basetype_content = datatype.getbaseType().getcontent()
       
   419         if basetype_content["value"] is None:
       
   420             self.CustomTypeHierarchy[name] = basetype_content["name"]
       
   421         elif basetype_content["name"] in ["string", "wstring"]:
       
   422             self.CustomTypeHierarchy[name] = basetype_content["name"].upper()
       
   423         elif basetype_content["name"] == "derived":
       
   424             self.CustomTypeHierarchy[name] = basetype_content["value"].getname()
       
   425         elif basetype_content["name"] in ["subrangeSigned", "subrangeUnsigned"]:
       
   426             range = (basetype_content["value"].range.getlower(), 
       
   427                      basetype_content["value"].range.getupper())
       
   428             self.CustomDataTypeRange[name] = range
       
   429             base_type = basetype_content["value"].baseType.getcontent()
       
   430             if base_type["value"] is None:
       
   431                 self.CustomTypeHierarchy[name] = base_type["name"]
       
   432             else:
       
   433                 self.CustomTypeHierarchy[name] = base_type["value"].getname()
       
   434         else:
       
   435             if basetype_content["name"] == "enum":
       
   436                 values = []
       
   437                 for value in basetype_content["value"].values.getvalue():
       
   438                     values.append(value.getname())
       
   439                 self.EnumeratedDataTypeValues[name] = values
       
   440             self.CustomTypeHierarchy[name] = "ANY_DERIVED"
       
   441     setattr(cls, "AddCustomDataType", AddCustomDataType)
       
   442 
       
   443     # Update Block types with user-defined pou added
       
   444     def RefreshCustomBlockTypes(self):
       
   445         # Reset the tree of user-defined pou cross-use
       
   446         self.CustomBlockTypes = OrderedDict()
       
   447         for pou in self.getpous():
       
   448             self.AddCustomBlockType(pou)
       
   449     setattr(cls, "RefreshCustomBlockTypes", RefreshCustomBlockTypes)
       
   450 
       
   451     def AddCustomBlockType(self, pou): 
       
   452         pou_name = pou.getname()
       
   453         pou_type = pou.getpouType()
       
   454         block_infos = {"name" : pou_name, "type" : pou_type, "extensible" : False,
       
   455                        "inputs" : [], "outputs" : [], "comment" : pou.getdescription(),
       
   456                        "generate" : generate_block, "initialise" : initialise_block}
       
   457         if pou.getinterface():
       
   458             return_type = pou.interface.getreturnType()
       
   459             if return_type:
       
   460                 var_type = return_type.getcontent()
       
   461                 if var_type["name"] == "derived":
       
   462                     block_infos["outputs"].append(("OUT", var_type["value"].getname(), "none"))
       
   463                 elif var_type["name"] in ["string", "wstring"]:
       
   464                     block_infos["outputs"].append(("OUT", var_type["name"].upper(), "none"))
       
   465                 else:
       
   466                     block_infos["outputs"].append(("OUT", var_type["name"], "none"))
       
   467             for type, varlist in pou.getvars():
       
   468                 if type == "InOut":
       
   469                     for var in varlist.getvariable():
       
   470                         var_type = var.type.getcontent()
       
   471                         if var_type["name"] == "derived":
       
   472                             block_infos["inputs"].append((var.getname(), var_type["value"].getname(), "none"))
       
   473                             block_infos["outputs"].append((var.getname(), var_type["value"].getname(), "none"))
       
   474                         elif var_type["name"] in ["string", "wstring"]:
       
   475                             block_infos["inputs"].append((var.getname(), var_type["name"].upper(), "none"))
       
   476                             block_infos["outputs"].append((var.getname(), var_type["name"].upper(), "none"))
       
   477                         else:
       
   478                             block_infos["inputs"].append((var.getname(), var_type["name"], "none"))
       
   479                             block_infos["outputs"].append((var.getname(), var_type["name"], "none"))
       
   480                 elif type == "Input":
       
   481                     for var in varlist.getvariable():
       
   482                         var_type = var.type.getcontent()
       
   483                         if var_type["name"] == "derived":
       
   484                             block_infos["inputs"].append((var.getname(), var_type["value"].getname(), "none"))
       
   485                         elif var_type["name"] in ["string", "wstring"]:
       
   486                             block_infos["inputs"].append((var.getname(), var_type["name"].upper(), "none"))
       
   487                         else:
       
   488                             block_infos["inputs"].append((var.getname(), var_type["name"], "none"))
       
   489                 elif type == "Output":
       
   490                     for var in varlist.getvariable():
       
   491                         var_type = var.type.getcontent()
       
   492                         if var_type["name"] == "derived":
       
   493                             block_infos["outputs"].append((var.getname(), var_type["value"].getname(), "none"))
       
   494                         elif var_type["name"] in ["string", "wstring"]:
       
   495                             block_infos["outputs"].append((var.getname(), var_type["name"].upper(), "none"))
       
   496                         else:
       
   497                             block_infos["outputs"].append((var.getname(), var_type["name"], "none"))    
       
   498         block_infos["usage"] = "\n (%s) => (%s)" % (", ".join(["%s:%s" % (input[1], input[0]) for input in block_infos["inputs"]]),
       
   499                                                     ", ".join(["%s:%s" % (output[1], output[0]) for output in block_infos["outputs"]]))
       
   500         self.CustomBlockTypes[pou_name]=block_infos
       
   501     setattr(cls, "AddCustomBlockType", AddCustomBlockType)
       
   502 
       
   503     def AddElementUsingTreeInstance(self, name, type_infos):
       
   504         typename = type_infos.getname()
       
   505         elements = self.ElementUsingTree.setdefault(typename, set())
       
   506         elements.add(name)
       
   507     setattr(cls, "AddElementUsingTreeInstance", AddElementUsingTreeInstance)
       
   508     
       
   509     def RefreshElementUsingTree(self):
       
   510         # Reset the tree of user-defined element cross-use
       
   511         self.ElementUsingTree = {}
       
   512         pous = self.getpous()
       
   513         datatypes = self.getdataTypes()
       
   514         # Analyze each datatype
       
   515         for datatype in datatypes:
       
   516             name = datatype.getname()
       
   517             basetype_content = datatype.baseType.getcontent()
       
   518             if basetype_content["name"] == "derived":
       
   519                 self.AddElementUsingTreeInstance(name,
       
   520                                                  basetype_content["value"])
       
   521             elif basetype_content["name"] in ["subrangeSigned", "subrangeUnsigned", "array"]:
       
   522                 base_type = basetype_content["value"].baseType.getcontent()
       
   523                 if base_type["name"] == "derived":
       
   524                     self.AddElementUsingTreeInstance(name, base_type["value"])
       
   525             elif basetype_content["name"] == "struct":
       
   526                 for element in basetype_content["value"].getvariable():
       
   527                     type_content = element.type.getcontent()
       
   528                     if type_content["name"] == "derived":
       
   529                         self.AddElementUsingTreeInstance(name, type_content["value"])
       
   530         # Analyze each pou
       
   531         for pou in pous:
       
   532             name = pou.getname()
       
   533             if pou.interface:
       
   534                 # Extract variables from every varLists
       
   535                 for type, varlist in pou.getvars():
       
   536                     for var in varlist.getvariable():
       
   537                         vartype_content = var.gettype().getcontent()
       
   538                         if vartype_content["name"] == "derived":
       
   539                             self.AddElementUsingTreeInstance(name, vartype_content["value"])
       
   540         
       
   541     setattr(cls, "RefreshElementUsingTree", RefreshElementUsingTree)
       
   542 
       
   543     def GetParentType(self, type):
       
   544         if self.CustomTypeHierarchy.has_key(type):
       
   545             return self.CustomTypeHierarchy[type]
       
   546         elif TypeHierarchy.has_key(type):
       
   547             return TypeHierarchy[type]
       
   548         return None
       
   549     setattr(cls, "GetParentType", GetParentType)
       
   550 
       
   551     def GetBaseType(self, type):
       
   552         parent_type = self.GetParentType(type)
       
   553         if parent_type is not None:
       
   554             if parent_type.startswith("ANY"):
       
   555                 return type
       
   556             else:
       
   557                 return self.GetBaseType(parent_type)
       
   558         return None
       
   559     setattr(cls, "GetBaseType", GetBaseType)
       
   560 
       
   561     def GetSubrangeBaseTypes(self, exclude):
       
   562         derived = []
       
   563         for type in self.CustomTypeHierarchy.keys():
       
   564             for base_type in DataTypeRange.keys():
       
   565                 if self.IsOfType(type, base_type) and not self.IsOfType(type, exclude):
       
   566                     derived.append(type)
       
   567                     break
       
   568         return derived
       
   569     setattr(cls, "GetSubrangeBaseTypes", GetSubrangeBaseTypes)
       
   570 
       
   571     """
       
   572     returns true if the given data type is the same that "reference" meta-type or one of its types.
       
   573     """
       
   574     def IsOfType(self, type, reference):
       
   575         if reference is None:
       
   576             return True
       
   577         elif type == reference:
       
   578             return True
       
   579         else:
       
   580             parent_type = self.GetParentType(type)
       
   581             if parent_type is not None:
       
   582                 return self.IsOfType(parent_type, reference)
       
   583         return False
       
   584     setattr(cls, "IsOfType", IsOfType)
       
   585 
       
   586     # Return if pou given by name is used by another pou
       
   587     def ElementIsUsed(self, name):
       
   588         elements = self.ElementUsingTree.get(name, None)
       
   589         return elements is not None
       
   590     setattr(cls, "ElementIsUsed", ElementIsUsed)
       
   591 
       
   592     def DataTypeIsDerived(self, name):
       
   593         return name in self.CustomTypeHierarchy.values()
       
   594     setattr(cls, "DataTypeIsDerived", DataTypeIsDerived)
       
   595 
       
   596     # Return if pou given by name is directly or undirectly used by the reference pou
       
   597     def ElementIsUsedBy(self, name, reference):
       
   598         elements = self.ElementUsingTree.get(name, set())
       
   599         # Test if pou is directly used by reference
       
   600         if reference in elements:
       
   601             return True
       
   602         else:
       
   603             # Test if pou is undirectly used by reference, by testing if pous
       
   604             # that directly use pou is directly or undirectly used by reference
       
   605             selffn = self.ElementIsUsedBy
       
   606             for element in elements:
       
   607                 if selffn(element, reference):
       
   608                     return True
       
   609         return False
       
   610     setattr(cls, "ElementIsUsedBy", ElementIsUsedBy)
       
   611 
       
   612     def GetDataTypeRange(self, type):
       
   613         if self.CustomDataTypeRange.has_key(type):
       
   614             return self.CustomDataTypeRange[type]
       
   615         elif DataTypeRange.has_key(type):
       
   616             return DataTypeRange[type]
       
   617         else:
       
   618             parent_type = self.GetParentType(type)
       
   619             if parent_type is not None:
       
   620                 return self.GetDataTypeRange(parent_type)
       
   621         return None
       
   622     setattr(cls, "GetDataTypeRange", GetDataTypeRange)
       
   623 
       
   624     def GetEnumeratedDataTypeValues(self, type = None):
       
   625         if type is None:
       
   626             all_values = []
       
   627             for values in self.EnumeratedDataTypeValues.values():
       
   628                 all_values.extend(values)
       
   629             return all_values
       
   630         elif self.EnumeratedDataTypeValues.has_key(type):
       
   631             return self.EnumeratedDataTypeValues[type]
       
   632         return []
       
   633     setattr(cls, "GetEnumeratedDataTypeValues", GetEnumeratedDataTypeValues)
   465     setattr(cls, "GetEnumeratedDataTypeValues", GetEnumeratedDataTypeValues)
   634 
       
   635     # Function that returns the block definition associated to the block type given
       
   636     def GetCustomBlockType(self, typename, inputs = None):
       
   637         customblocktype = self.CustomBlockTypes.get(typename,None)
       
   638         if customblocktype is not None:
       
   639             if inputs is not None and inputs != "undefined":
       
   640                 customblock_inputs = tuple([var_type for name, var_type, modifier in customblocktype["inputs"]])
       
   641                 if inputs == customblock_inputs:
       
   642                     return customblocktype
       
   643             else:
       
   644                 return customblocktype
       
   645         return None
       
   646     setattr(cls, "GetCustomBlockType", GetCustomBlockType)
       
   647 
       
   648     # Return Block types checking for recursion
       
   649     def GetCustomBlockTypes(self, exclude = None, onlyfunctions = False):
       
   650         if exclude is not None:
       
   651             return [customblocktype for name,customblocktype in self.CustomBlockTypes.iteritems()
       
   652                 if (customblocktype["type"] != "program"
       
   653                     and name != exclude
       
   654                     and not self.ElementIsUsedBy(exclude, name)
       
   655                     and not (onlyfunctions and customblocktype["type"] != "function"))]
       
   656         return [customblocktype for customblocktype in self.CustomBlockTypes.itervalues()
       
   657             if (customblocktype["type"] != "program"
       
   658                 and not (onlyfunctions and customblocktype["type"] != "function"))]
       
   659     setattr(cls, "GetCustomBlockTypes", GetCustomBlockTypes)
       
   660 
       
   661     # Return Function Block types checking for recursion
       
   662     def GetCustomFunctionBlockTypes(self, exclude = None):
       
   663         if exclude is not None:
       
   664             return [customblocktype for name,customblocktype in self.CustomBlockTypes.iteritems()
       
   665                 if (customblocktype["type"] == "functionBlock" 
       
   666                     and name != exclude 
       
   667                     and not self.ElementIsUsedBy(exclude, name))]
       
   668         return [customblocktype for customblocktype in self.CustomBlockTypes.itervalues()
       
   669             if customblocktype["type"] == "functionBlock"]
       
   670     setattr(cls, "GetCustomFunctionBlockTypes", GetCustomFunctionBlockTypes)
       
   671 
       
   672     # Return Block types checking for recursion
       
   673     def GetCustomBlockResource(self):
       
   674         return [customblocktype for customblocktype in self.CustomBlockTypes.itervalues()
       
   675             if customblocktype["type"] == "program"]
       
   676     setattr(cls, "GetCustomBlockResource", GetCustomBlockResource)
       
   677 
       
   678     # Return Data Types checking for recursion
       
   679     def GetCustomDataTypes(self, exclude = "", only_locatable = False):
       
   680         customdatatypes = []
       
   681         for customdatatype in self.getdataTypes():
       
   682             if not only_locatable or self.IsLocatableType(customdatatype):
       
   683                 customdatatype_name = customdatatype.getname()
       
   684                 if customdatatype_name != exclude and not self.ElementIsUsedBy(exclude, customdatatype_name):
       
   685                     customdatatypes.append({"name": customdatatype_name, "infos": customdatatype})
       
   686         return customdatatypes
       
   687     setattr(cls, "GetCustomDataTypes", GetCustomDataTypes)
       
   688 
       
   689     # Return if Data Type can be used for located variables
       
   690     def IsLocatableType(self, datatype):
       
   691         basetype_content = datatype.baseType.getcontent()
       
   692         if basetype_content["name"] in ["enum", "struct"]:
       
   693             return False
       
   694         elif basetype_content["name"] == "derived":
       
   695             base_type = self.getdataType(basetype_content["value"].getname())
       
   696             if base_type is not None:
       
   697                 return self.IsLocatableType(base_type)
       
   698         elif basetype_content["name"] == "array":
       
   699             array_base_type = basetype_content["value"].baseType.getcontent()
       
   700             if array_base_type["value"] is not None and array_base_type["name"] not in ["string", "wstring"]:
       
   701                 base_type = self.getdataType(array_base_type["value"].getname())
       
   702                 if base_type is not None:
       
   703                     return self.IsLocatableType(base_type)
       
   704         return True
       
   705     setattr(cls, "IsLocatableType", IsLocatableType)
       
   706 
   466 
   707     def Search(self, criteria, parent_infos=[]):
   467     def Search(self, criteria, parent_infos=[]):
   708         result = self.types.Search(criteria, parent_infos)
   468         result = self.types.Search(criteria, parent_infos)
   709         for configuration in self.instances.configurations.getconfiguration():
   469         for configuration in self.instances.configurations.getconfiguration():
   710             result.extend(configuration.Search(criteria, parent_infos))
   470             result.extend(configuration.Search(criteria, parent_infos))
   711         return result
   471         return result
   712     setattr(cls, "Search", Search)
   472     setattr(cls, "Search", Search)
   713 
   473 
   714 cls = PLCOpenClasses.get("project_fileHeader", None)
   474 cls = PLCOpenParser.GetElementClass("contentHeader", "project")
   715 if cls:
   475 if cls:
   716     cls.singleLineAttributes = False
       
   717 
       
   718 cls = PLCOpenClasses.get("project_contentHeader", None)
       
   719 if cls:
       
   720     cls.singleLineAttributes = False
       
   721     
   476     
   722     def setpageSize(self, width, height):
   477     def setpageSize(self, width, height):
   723         self.coordinateInfo.setpageSize(width, height)
   478         self.coordinateInfo.setpageSize(width, height)
   724     setattr(cls, "setpageSize", setpageSize)
   479     setattr(cls, "setpageSize", setpageSize)
   725     
   480     
   738         scaling["LD"] = self.coordinateInfo.getscaling("LD")
   493         scaling["LD"] = self.coordinateInfo.getscaling("LD")
   739         scaling["SFC"] = self.coordinateInfo.getscaling("SFC")
   494         scaling["SFC"] = self.coordinateInfo.getscaling("SFC")
   740         return scaling
   495         return scaling
   741     setattr(cls, "getscaling", getscaling)
   496     setattr(cls, "getscaling", getscaling)
   742 
   497 
   743 cls = PLCOpenClasses.get("contentHeader_coordinateInfo", None)
   498 cls = PLCOpenParser.GetElementClass("coordinateInfo", "contentHeader")
   744 if cls:
   499 if cls:
   745     def setpageSize(self, width, height):
   500     def setpageSize(self, width, height):
   746         if width == 0 and height == 0:
   501         if width == 0 and height == 0:
   747             self.deletepageSize()
   502             self.deletepageSize()
   748         else:
   503         else:
   807 def _removeConfigurationResourceVariableByAddress(self, address):
   562 def _removeConfigurationResourceVariableByAddress(self, address):
   808     for varlist in self.getglobalVars():
   563     for varlist in self.getglobalVars():
   809         variables = varlist.getvariable()
   564         variables = varlist.getvariable()
   810         for i in xrange(len(variables)-1, -1, -1):
   565         for i in xrange(len(variables)-1, -1, -1):
   811             if variables[i].getaddress() == address:
   566             if variables[i].getaddress() == address:
   812                 variables.pop(i)
   567                 variables.remove(variables[i])
   813 
   568 
   814 def _removeConfigurationResourceVariableByFilter(self, address_model):
   569 def _removeConfigurationResourceVariableByFilter(self, address_model):
   815     for varlist in self.getglobalVars():
   570     for varlist in self.getglobalVars():
   816         variables = varlist.getvariable()
   571         variables = varlist.getvariable()
   817         for i in xrange(len(variables)-1, -1, -1):
   572         for i in xrange(len(variables)-1, -1, -1):
   818             var_address = variables[i].getaddress()
   573             var_address = variables[i].getaddress()
   819             if var_address is not None:
   574             if var_address is not None:
   820                 result = address_model.match(var_address)
   575                 result = address_model.match(var_address)
   821                 if result is not None:
   576                 if result is not None:
   822                     variables.pop(i)
   577                     variables.remove(variables[i])
   823 
   578 
   824 def _SearchInConfigurationResource(self, criteria, parent_infos=[]):
   579 def _SearchInConfigurationResource(self, criteria, parent_infos=[]):
   825     search_result = _Search([("name", self.getname())], criteria, parent_infos)
   580     search_result = _Search([("name", self.getname())], criteria, parent_infos)
   826     var_number = 0
   581     var_number = 0
   827     for varlist in self.getglobalVars():
   582     for varlist in self.getglobalVars():
   837         for variable in variables:
   592         for variable in variables:
   838             search_result.extend(variable.Search(criteria, parent_infos + [variable_type, var_number]))
   593             search_result.extend(variable.Search(criteria, parent_infos + [variable_type, var_number]))
   839             var_number += 1
   594             var_number += 1
   840     return search_result
   595     return search_result
   841 
   596 
   842 cls = PLCOpenClasses.get("configurations_configuration", None)
   597 cls = PLCOpenParser.GetElementClass("configuration", "configurations")
   843 if cls:
   598 if cls:
   844     
   599     
   845     def addglobalVar(self, type, name, location="", description=""):
   600     def addglobalVar(self, var_type, name, location="", description=""):
   846         globalvars = self.getglobalVars()
   601         globalvars = self.getglobalVars()
   847         if len(globalvars) == 0:
   602         if len(globalvars) == 0:
   848             globalvars.append(PLCOpenClasses["varList"]())
   603             globalvars.append(PLCOpenParser.CreateElement("varList"))
   849         var = PLCOpenClasses["varListPlain_variable"]()
   604         var = PLCOpenParser.CreateElement("variable", "varListPlain")
   850         var.setname(name)
   605         var.setname(name)
   851         var_type = PLCOpenClasses["dataType"]()
       
   852         if type in [x for x,y in TypeHierarchy_list if not x.startswith("ANY")]:
       
   853             if type == "STRING":
       
   854                 var_type.setcontent({"name" : "string", "value" : PLCOpenClasses["elementaryTypes_string"]()})
       
   855             elif type == "WSTRING":
       
   856                 var_type.setcontent({"name" : "wstring", "value" : PLCOpenClasses["elementaryTypes_wstring"]()})
       
   857             else:
       
   858                 var_type.setcontent({"name" : type, "value" : None})
       
   859         else:
       
   860             derived_type = PLCOpenClasses["derivedTypes_derived"]()
       
   861             derived_type.setname(type)
       
   862             var_type.setcontent({"name" : "derived", "value" : derived_type})
       
   863         var.settype(var_type)
   606         var.settype(var_type)
   864         if location != "":
   607         if location != "":
   865             var.setaddress(location)
   608             var.setaddress(location)
   866         if description != "":
   609         if description != "":
   867             ft = PLCOpenClasses["formattedText"]()
   610             ft = PLCOpenParser.CreateElement("documentation", "variable")
   868             ft.settext(description)
   611             ft.setanyText(description)
   869             var.setdocumentation(ft)
   612             var.setdocumentation(ft)
   870         globalvars[-1].appendvariable(var)
   613         globalvars[-1].appendvariable(var)
   871     setattr(cls, "addglobalVar", addglobalVar)
   614     setattr(cls, "addglobalVar", addglobalVar)
   872     
   615     
   873     def updateElementName(self, old_name, new_name):
   616     def updateElementName(self, old_name, new_name):
   894             for resource in self.getresource():
   637             for resource in self.getresource():
   895                 search_result.extend(resource.Search(criteria, parent_infos))
   638                 search_result.extend(resource.Search(criteria, parent_infos))
   896         return search_result
   639         return search_result
   897     setattr(cls, "Search", Search)
   640     setattr(cls, "Search", Search)
   898     
   641     
   899 cls = PLCOpenClasses.get("configuration_resource", None)
   642 cls = PLCOpenParser.GetElementClass("resource", "configuration")
   900 if cls:
   643 if cls:
   901     def updateElementName(self, old_name, new_name):
   644     def updateElementName(self, old_name, new_name):
   902         _updateConfigurationResourceElementName(self, old_name, new_name)
   645         _updateConfigurationResourceElementName(self, old_name, new_name)
   903         for instance in self.getpouInstance():
   646         for instance in self.getpouInstance():
   904             instance.updateElementName(old_name, new_name)
   647             instance.updateElementName(old_name, new_name)
   935             search_result.extend(instance.Search(criteria, parent_infos + ["instance", instance_number]))
   678             search_result.extend(instance.Search(criteria, parent_infos + ["instance", instance_number]))
   936             instance_number += 1
   679             instance_number += 1
   937         return search_result
   680         return search_result
   938     setattr(cls, "Search", Search)
   681     setattr(cls, "Search", Search)
   939 
   682 
   940 cls = PLCOpenClasses.get("resource_task", None)
   683 cls = PLCOpenParser.GetElementClass("task", "resource")
   941 if cls:
   684 if cls:
   942     def compatibility(self, tree):
   685     def compatibility(self, tree):
   943         if tree.hasAttribute("interval"):
   686         if tree.hasAttribute("interval"):
   944             interval = GetAttributeValue(tree._attrs["interval"])
   687             interval = GetAttributeValue(tree._attrs["interval"])
   945             result = time_model.match(interval)
   688             result = time_model.match(interval)
   984                         ("interval", self.getinterval()),
   727                         ("interval", self.getinterval()),
   985                         ("priority", str(self.getpriority()))],
   728                         ("priority", str(self.getpriority()))],
   986                        criteria, parent_infos)
   729                        criteria, parent_infos)
   987     setattr(cls, "Search", Search)
   730     setattr(cls, "Search", Search)
   988 
   731 
   989 cls = PLCOpenClasses.get("pouInstance", None)
   732 cls = PLCOpenParser.GetElementClass("pouInstance")
   990 if cls:
   733 if cls:
   991     def compatibility(self, tree):
   734     def compatibility(self, tree):
   992         if tree.hasAttribute("type"):
   735         if tree.hasAttribute("type"):
   993             NodeRenameAttr(tree, "type", "typeName")
   736             NodeRenameAttr(tree, "type", "typeName")
   994     setattr(cls, "compatibility", compatibility)
   737     setattr(cls, "compatibility", compatibility)
  1002         return _Search([("name", self.getname()), 
   745         return _Search([("name", self.getname()), 
  1003                         ("type", self.gettypeName())],
   746                         ("type", self.gettypeName())],
  1004                        criteria, parent_infos)
   747                        criteria, parent_infos)
  1005     setattr(cls, "Search", Search)
   748     setattr(cls, "Search", Search)
  1006 
   749 
  1007 cls = PLCOpenClasses.get("varListPlain_variable", None)
   750 cls = PLCOpenParser.GetElementClass("variable", "varListPlain")
  1008 if cls:
   751 if cls:
  1009     def gettypeAsText(self):
   752     def gettypeAsText(self):
  1010         vartype_content = self.gettype().getcontent()
   753         vartype_content = self.gettype().getcontent()
       
   754         vartype_content_name = vartype_content.getLocalTag()
  1011         # Variable type is a user data type
   755         # Variable type is a user data type
  1012         if vartype_content["name"] == "derived":
   756         if vartype_content_name == "derived":
  1013             return vartype_content["value"].getname()
   757             return vartype_content.getname()
  1014         # Variable type is a string type
   758         # Variable type is a string type
  1015         elif vartype_content["name"] in ["string", "wstring"]:
   759         elif vartype_content_name in ["string", "wstring"]:
  1016             return vartype_content["name"].upper()
   760             return vartype_content_name.upper()
  1017         # Variable type is an array
   761         # Variable type is an array
  1018         elif vartype_content["name"] == "array":
   762         elif vartype_content_name == "array":
  1019             base_type = vartype_content["value"].baseType.getcontent()
   763             base_type = vartype_content.baseType.getcontent()
       
   764             base_type_name = base_type.getLocalTag()
  1020             # Array derived directly from a user defined type 
   765             # Array derived directly from a user defined type 
  1021             if base_type["name"] == "derived":
   766             if base_type_name == "derived":
  1022                 basetype_name = base_type["value"].getname()
   767                 basetype_name = base_type.getname()
  1023             # Array derived directly from a string type 
   768             # Array derived directly from a string type 
  1024             elif base_type["name"] in ["string", "wstring"]:
   769             elif base_type_name in ["string", "wstring"]:
  1025                 basetype_name = base_type["name"].upper()
   770                 basetype_name = base_type_name.upper()
  1026             # Array derived directly from an elementary type 
   771             # Array derived directly from an elementary type 
  1027             else:
   772             else:
  1028                 basetype_name = base_type["name"]
   773                 basetype_name = base_type_name
  1029             return "ARRAY [%s] OF %s" % (",".join(map(lambda x : "%s..%s" % (x.getlower(), x.getupper()), vartype_content["value"].getdimension())), basetype_name)
   774             return "ARRAY [%s] OF %s" % (",".join(map(lambda x : "%s..%s" % (x.getlower(), x.getupper()), vartype_content.getdimension())), basetype_name)
  1030         # Variable type is an elementary type
   775         # Variable type is an elementary type
  1031         return vartype_content["name"]
   776         return vartype_content_name
  1032     setattr(cls, "gettypeAsText", gettypeAsText)
   777     setattr(cls, "gettypeAsText", gettypeAsText)
  1033     
   778     
  1034     def Search(self, criteria, parent_infos=[]):
   779     def Search(self, criteria, parent_infos=[]):
  1035         search_result = _Search([("name", self.getname()), 
   780         search_result = _Search([("name", self.getname()), 
  1036                                  ("type", self.gettypeAsText()),
   781                                  ("type", self.gettypeAsText()),
  1043         if doc is not None:
   788         if doc is not None:
  1044             search_result.extend(doc.Search(criteria, parent_infos + ["documentation"]))
   789             search_result.extend(doc.Search(criteria, parent_infos + ["documentation"]))
  1045         return search_result
   790         return search_result
  1046     setattr(cls, "Search", Search)
   791     setattr(cls, "Search", Search)
  1047 
   792 
  1048 cls = PLCOpenClasses.get("project_types", None)
   793 cls = PLCOpenParser.GetElementClass("types", "project")
  1049 if cls:
   794 if cls:
  1050     def getdataTypeElements(self):
   795     def getdataTypeElements(self):
  1051         return self.dataTypes.getdataType()
   796         return self.dataTypes.getdataType()
  1052     setattr(cls, "getdataTypeElements", getdataTypeElements)
   797     setattr(cls, "getdataTypeElements", getdataTypeElements)
  1053     
   798     
  1058                 return element
   803                 return element
  1059         return None
   804         return None
  1060     setattr(cls, "getdataTypeElement", getdataTypeElement)
   805     setattr(cls, "getdataTypeElement", getdataTypeElement)
  1061 
   806 
  1062     def appenddataTypeElement(self, name):
   807     def appenddataTypeElement(self, name):
  1063         new_datatype = PLCOpenClasses["dataTypes_dataType"]()
   808         new_datatype = PLCOpenParser.CreateElement("dataType", "dataTypes")
       
   809         self.dataTypes.appenddataType(new_datatype)
  1064         new_datatype.setname(name)
   810         new_datatype.setname(name)
  1065         new_datatype.baseType.setcontent({"name" : "BOOL", "value" : None})
   811         new_datatype.baseType.setcontent(PLCOpenParser.CreateElement("BOOL", "dataType"))
  1066         self.dataTypes.appenddataType(new_datatype)
       
  1067     setattr(cls, "appenddataTypeElement", appenddataTypeElement)
   812     setattr(cls, "appenddataTypeElement", appenddataTypeElement)
  1068     
   813     
  1069     def insertdataTypeElement(self, index, dataType):
   814     def insertdataTypeElement(self, index, dataType):
  1070         self.dataTypes.insertdataType(index, dataType)
   815         self.dataTypes.insertdataType(index, dataType)
  1071     setattr(cls, "insertdataTypeElement", insertdataTypeElement)
   816     setattr(cls, "insertdataTypeElement", insertdataTypeElement)
  1072     
   817     
  1073     def removedataTypeElement(self, name):
   818     def removedataTypeElement(self, name):
  1074         found = False
   819         found = False
  1075         for idx, element in enumerate(self.dataTypes.getdataType()):
   820         for element in self.dataTypes.getdataType():
  1076             if element.getname() == name:
   821             if element.getname() == name:
  1077                 self.dataTypes.removedataType(idx)
   822                 self.dataTypes.remove(element)
  1078                 found = True
   823                 found = True
  1079                 break
   824                 break
  1080         if not found:
   825         if not found:
  1081             raise ValueError, _("\"%s\" Data Type doesn't exist !!!")%name
   826             raise ValueError, _("\"%s\" Data Type doesn't exist !!!")%name
  1082     setattr(cls, "removedataTypeElement", removedataTypeElement)
   827     setattr(cls, "removedataTypeElement", removedataTypeElement)
  1095 
   840 
  1096     def appendpouElement(self, name, pou_type, body_type):
   841     def appendpouElement(self, name, pou_type, body_type):
  1097         for element in self.pous.getpou():
   842         for element in self.pous.getpou():
  1098             if element.getname() == name:
   843             if element.getname() == name:
  1099                 raise ValueError, _("\"%s\" POU already exists !!!")%name
   844                 raise ValueError, _("\"%s\" POU already exists !!!")%name
  1100         new_pou = PLCOpenClasses["pous_pou"]()
   845         new_pou = PLCOpenParser.CreateElement("pou", "pous")
       
   846         self.pous.appendpou(new_pou)
  1101         new_pou.setname(name)
   847         new_pou.setname(name)
  1102         new_pou.setpouType(pou_type)
   848         new_pou.setpouType(pou_type)
  1103         new_pou.appendbody(PLCOpenClasses["body"]())
   849         new_pou.appendbody(PLCOpenParser.CreateElement("body", "pou"))
  1104         new_pou.setbodyType(body_type)
   850         new_pou.setbodyType(body_type)
  1105         self.pous.appendpou(new_pou)
       
  1106     setattr(cls, "appendpouElement", appendpouElement)
   851     setattr(cls, "appendpouElement", appendpouElement)
  1107         
   852         
  1108     def insertpouElement(self, index, pou):
   853     def insertpouElement(self, index, pou):
  1109         self.pous.insertpou(index, pou)
   854         self.pous.insertpou(index, pou)
  1110     setattr(cls, "insertpouElement", insertpouElement)
   855     setattr(cls, "insertpouElement", insertpouElement)
  1111     
   856     
  1112     def removepouElement(self, name):
   857     def removepouElement(self, name):
  1113         found = False
   858         found = False
  1114         for idx, element in enumerate(self.pous.getpou()):
   859         for element in self.pous.getpou():
  1115             if element.getname() == name:
   860             if element.getname() == name:
  1116                 self.pous.removepou(idx)
   861                 self.pous.remove(element)
  1117                 found = True
   862                 found = True
  1118                 break
   863                 break
  1119         if not found:
   864         if not found:
  1120             raise ValueError, _("\"%s\" POU doesn't exist !!!")%name
   865             raise ValueError, _("\"%s\" POU doesn't exist !!!")%name
  1121     setattr(cls, "removepouElement", removepouElement)
   866     setattr(cls, "removepouElement", removepouElement)
  1131     setattr(cls, "Search", Search)
   876     setattr(cls, "Search", Search)
  1132 
   877 
  1133 def _updateBaseTypeElementName(self, old_name, new_name):
   878 def _updateBaseTypeElementName(self, old_name, new_name):
  1134     self.baseType.updateElementName(old_name, new_name)
   879     self.baseType.updateElementName(old_name, new_name)
  1135 
   880 
  1136 cls = PLCOpenClasses.get("dataTypes_dataType", None)
   881 cls = PLCOpenParser.GetElementClass("dataType", "dataTypes")
  1137 if cls:
   882 if cls:
  1138     setattr(cls, "updateElementName", _updateBaseTypeElementName)
   883     setattr(cls, "updateElementName", _updateBaseTypeElementName)
  1139     
   884     
  1140     def Search(self, criteria, parent_infos=[]):
   885     def Search(self, criteria, parent_infos=[]):
  1141         search_result = []
   886         search_result = []
  1147             if self.initialValue is not None:
   892             if self.initialValue is not None:
  1148                 search_result.extend(_Search([("initial", self.initialValue.getvalue())], criteria, parent_infos))
   893                 search_result.extend(_Search([("initial", self.initialValue.getvalue())], criteria, parent_infos))
  1149         return search_result
   894         return search_result
  1150     setattr(cls, "Search", Search)
   895     setattr(cls, "Search", Search)
  1151 
   896 
  1152 cls = PLCOpenClasses.get("dataType", None)
   897 cls = PLCOpenParser.GetElementClass("dataType")
  1153 if cls:
   898 if cls:
  1154     
   899     
  1155     def updateElementName(self, old_name, new_name):
   900     def updateElementName(self, old_name, new_name):
  1156         if self.content["name"] in ["derived", "array", "subrangeSigned", "subrangeUnsigned"]:
   901         content_name = self.content.getLocalTag()
  1157             self.content["value"].updateElementName(old_name, new_name)
   902         if content_name in ["derived", "array", "subrangeSigned", "subrangeUnsigned"]:
  1158         elif self.content["name"] == "struct":
   903             self.content.updateElementName(old_name, new_name)
  1159             for element in self.content["value"].getvariable():
   904         elif content_name == "struct":
       
   905             for element in self.content.getvariable():
  1160                 element_type = element.type.updateElementName(old_name, new_name)
   906                 element_type = element.type.updateElementName(old_name, new_name)
  1161     setattr(cls, "updateElementName", updateElementName)
   907     setattr(cls, "updateElementName", updateElementName)
  1162 
   908 
  1163     def Search(self, criteria, parent_infos=[]):
   909     def Search(self, criteria, parent_infos=[]):
  1164         search_result = []
   910         search_result = []
  1165         if self.content["name"] in ["derived", "array", "enum", "subrangeSigned", "subrangeUnsigned"]:
   911         content_name = self.content.getLocalTag()
  1166             search_result.extend(self.content["value"].Search(criteria, parent_infos))
   912         if content_name in ["derived", "array", "enum", "subrangeSigned", "subrangeUnsigned"]:
  1167         elif self.content["name"] == "struct":
   913             search_result.extend(self.content.Search(criteria, parent_infos + ["base"]))
  1168             for i, element in enumerate(self.content["value"].getvariable()):
   914         elif content_name == "struct":
       
   915             for i, element in enumerate(self.content.getvariable()):
  1169                 search_result.extend(element.Search(criteria, parent_infos + ["struct", i]))
   916                 search_result.extend(element.Search(criteria, parent_infos + ["struct", i]))
  1170         else:
   917         else:
  1171             basetype = self.content["name"]
   918             if content_name in ["string", "wstring"]:
  1172             if basetype in ["string", "wstring"]:
   919                 content_name = content_name.upper()
  1173                 basetype = basetype.upper()
   920             search_result.extend(_Search([("base", content_name)], criteria, parent_infos))
  1174             search_result.extend(_Search([("base", basetype)], criteria, parent_infos))
       
  1175         return search_result
   921         return search_result
  1176     setattr(cls, "Search", Search)
   922     setattr(cls, "Search", Search)
  1177 
   923 
  1178 cls = PLCOpenClasses.get("derivedTypes_array", None)
   924 cls = PLCOpenParser.GetElementClass("derived", "dataType")
       
   925 if cls:
       
   926     def updateElementName(self, old_name, new_name):
       
   927         if self.name == old_name:
       
   928             self.name = new_name
       
   929     setattr(cls, "updateElementName", updateElementName)
       
   930     
       
   931     def Search(self, criteria, parent_infos=[]):
       
   932         return [(tuple(parent_infos),) + result for result in TestTextElement(self.name, criteria)]
       
   933     setattr(cls, "Search", Search)
       
   934 
       
   935 cls = PLCOpenParser.GetElementClass("array", "dataType")
  1179 if cls:
   936 if cls:
  1180     setattr(cls, "updateElementName", _updateBaseTypeElementName)
   937     setattr(cls, "updateElementName", _updateBaseTypeElementName)
  1181     
   938     
  1182     def Search(self, criteria, parent_infos=[]):
   939     def Search(self, criteria, parent_infos=[]):
  1183         search_result = self.baseType.Search(criteria, parent_infos)
   940         search_result = self.baseType.Search(criteria, parent_infos)
  1193     search_result.extend(_Search([("lower", self.range.getlower()),
   950     search_result.extend(_Search([("lower", self.range.getlower()),
  1194                                   ("upper", self.range.getupper())],
   951                                   ("upper", self.range.getupper())],
  1195                                  criteria, parent_infos))
   952                                  criteria, parent_infos))
  1196     return search_result
   953     return search_result
  1197 
   954 
  1198 cls = PLCOpenClasses.get("derivedTypes_subrangeSigned", None)
   955 cls = PLCOpenParser.GetElementClass("subrangeSigned", "dataType")
  1199 if cls:
   956 if cls:
  1200     setattr(cls, "updateElementName", _updateBaseTypeElementName)
   957     setattr(cls, "updateElementName", _updateBaseTypeElementName)
  1201     setattr(cls, "Search", _SearchInSubrange)
   958     setattr(cls, "Search", _SearchInSubrange)
  1202 
   959 
  1203 cls = PLCOpenClasses.get("derivedTypes_subrangeUnsigned", None)
   960 cls = PLCOpenParser.GetElementClass("subrangeUnsigned", "dataType")
  1204 if cls:
   961 if cls:
  1205     setattr(cls, "updateElementName", _updateBaseTypeElementName)
   962     setattr(cls, "updateElementName", _updateBaseTypeElementName)
  1206     setattr(cls, "Search", _SearchInSubrange)
   963     setattr(cls, "Search", _SearchInSubrange)
  1207 
   964 
  1208 cls = PLCOpenClasses.get("derivedTypes_enum", None)
   965 cls = PLCOpenParser.GetElementClass("enum", "dataType")
  1209 if cls:
   966 if cls:
  1210     
   967     
  1211     def updateElementName(self, old_name, new_name):
   968     def updateElementName(self, old_name, new_name):
  1212         pass
   969         pass
  1213     setattr(cls, "updateElementName", updateElementName)
   970     setattr(cls, "updateElementName", updateElementName)
  1214     
   971     
       
   972     enumerated_datatype_values_xpath = PLCOpen_XPath("ppx:values/ppx:value")
  1215     def Search(self, criteria, parent_infos=[]):
   973     def Search(self, criteria, parent_infos=[]):
  1216         search_result = []
   974         search_result = []
  1217         for i, value in enumerate(self.values.getvalue()):
   975         for i, value in enumerate(enumerated_datatype_values_xpath(self)):
  1218             for result in TestTextElement(value.getname(), criteria):
   976             for result in TestTextElement(value.getname(), criteria):
  1219                 search_result.append((tuple(parent_infos + ["value", i]),) + result)
   977                 search_result.append((tuple(parent_infos + ["value", i]),) + result)
  1220         return search_result
   978         return search_result
  1221     setattr(cls, "Search", Search)
   979     setattr(cls, "Search", Search)
  1222 
   980 
  1223 cls = PLCOpenClasses.get("pous_pou", None)
   981 def _getvariableTypeinfos(variable_type):
  1224 if cls:
   982     type_content = variable_type.getcontent()
       
   983     type_content_type = type_content.getLocalTag()
       
   984     if type_content_type == "derived":
       
   985         return type_content.getname()
       
   986     return type_content_type.upper()
       
   987     
       
   988 cls = PLCOpenParser.GetElementClass("pou", "pous")
       
   989 if cls:
       
   990     
       
   991     block_inputs_xpath = PLCOpen_XPath(
       
   992         "ppx:interface/*[self::ppx:inputVars or self::ppx:inOutVars]/ppx:variable")
       
   993     block_outputs_xpath = PLCOpen_XPath(
       
   994         "ppx:interface/*[self::ppx:outputVars or self::ppx:inOutVars]/ppx:variable")
       
   995     def getblockInfos(self): 
       
   996         block_infos = {
       
   997             "name" : self.getname(), 
       
   998             "type" : self.getpouType(), 
       
   999             "extensible" : False,
       
  1000             "inputs" : [], 
       
  1001             "outputs" : [], 
       
  1002             "comment" : self.getdescription()}
       
  1003         if self.interface is not None:
       
  1004             return_type = self.interface.getreturnType()
       
  1005             if return_type is not None:
       
  1006                 block_infos["outputs"].append(
       
  1007                     ("OUT", _getvariableTypeinfos(return_type), "none"))
       
  1008             block_infos["inputs"].extend(
       
  1009                 [(var.getname(), _getvariableTypeinfos(var.type), "none")
       
  1010                  for var in block_inputs_xpath(self)])
       
  1011             block_infos["outputs"].extend(
       
  1012                 [(var.getname(), _getvariableTypeinfos(var.type), "none")
       
  1013                  for var in block_outputs_xpath(self)])
       
  1014             
       
  1015         block_infos["usage"] = ("\n (%s) => (%s)" % 
       
  1016             (", ".join(["%s:%s" % (input[1], input[0]) 
       
  1017                         for input in block_infos["inputs"]]),
       
  1018              ", ".join(["%s:%s" % (output[1], output[0]) 
       
  1019                         for output in block_infos["outputs"]])))
       
  1020         return block_infos
       
  1021     setattr(cls, "getblockInfos", getblockInfos)
  1225     
  1022     
  1226     def setdescription(self, description):
  1023     def setdescription(self, description):
  1227         doc = self.getdocumentation()
  1024         doc = self.getdocumentation()
  1228         if doc is None:
  1025         if doc is None:
  1229             doc = PLCOpenClasses["formattedText"]()
  1026             doc = PLCOpenParser.CreateElement("documentation", "pou")
  1230             self.setdocumentation(doc)
  1027             self.setdocumentation(doc)
  1231         doc.settext(description)
  1028         doc.setanyText(description)
  1232     setattr(cls, "setdescription", setdescription)
  1029     setattr(cls, "setdescription", setdescription)
  1233     
  1030     
  1234     def getdescription(self):
  1031     def getdescription(self):
  1235         doc = self.getdocumentation()
  1032         doc = self.getdocumentation()
  1236         if doc is not None:
  1033         if doc is not None:
  1237             return doc.gettext()
  1034             return doc.getanyText()
  1238         return ""
  1035         return ""
  1239     setattr(cls, "getdescription", getdescription)
  1036     setattr(cls, "getdescription", getdescription)
  1240     
  1037     
  1241     def setbodyType(self, type):
  1038     def setbodyType(self, body_type):
  1242         if len(self.body) > 0:
  1039         if len(self.body) > 0:
  1243             if type == "IL":
  1040             if body_type in ["IL", "ST", "LD", "FBD", "SFC"]:
  1244                 self.body[0].setcontent({"name" : "IL", "value" : PLCOpenClasses["formattedText"]()})
  1041                 self.body[0].setcontent(PLCOpenParser.CreateElement(body_type, "body"))
  1245             elif type == "ST":
       
  1246                 self.body[0].setcontent({"name" : "ST", "value" : PLCOpenClasses["formattedText"]()})
       
  1247             elif type == "LD":
       
  1248                 self.body[0].setcontent({"name" : "LD", "value" : PLCOpenClasses["body_LD"]()})
       
  1249             elif type == "FBD":
       
  1250                 self.body[0].setcontent({"name" : "FBD", "value" : PLCOpenClasses["body_FBD"]()})
       
  1251             elif type == "SFC":
       
  1252                 self.body[0].setcontent({"name" : "SFC", "value" : PLCOpenClasses["body_SFC"]()})
       
  1253             else:
  1042             else:
  1254                 raise ValueError, "%s isn't a valid body type!"%type
  1043                 raise ValueError, "%s isn't a valid body type!"%type
  1255     setattr(cls, "setbodyType", setbodyType)
  1044     setattr(cls, "setbodyType", setbodyType)
  1256     
  1045     
  1257     def getbodyType(self):
  1046     def getbodyType(self):
  1258         if len(self.body) > 0:
  1047         if len(self.body) > 0:
  1259             return self.body[0].getcontent()["name"]
  1048             return self.body[0].getcontent().getLocalTag()
  1260     setattr(cls, "getbodyType", getbodyType)
  1049     setattr(cls, "getbodyType", getbodyType)
  1261     
  1050     
  1262     def resetexecutionOrder(self):
  1051     def resetexecutionOrder(self):
  1263         if len(self.body) > 0:
  1052         if len(self.body) > 0:
  1264             self.body[0].resetexecutionOrder()
  1053             self.body[0].resetexecutionOrder()
  1272     def setelementExecutionOrder(self, instance, new_executionOrder):
  1061     def setelementExecutionOrder(self, instance, new_executionOrder):
  1273         if len(self.body) > 0:
  1062         if len(self.body) > 0:
  1274             self.body[0].setelementExecutionOrder(instance, new_executionOrder)
  1063             self.body[0].setelementExecutionOrder(instance, new_executionOrder)
  1275     setattr(cls, "setelementExecutionOrder", setelementExecutionOrder)
  1064     setattr(cls, "setelementExecutionOrder", setelementExecutionOrder)
  1276     
  1065     
  1277     def addinstance(self, name, instance):
  1066     def addinstance(self, instance):
  1278         if len(self.body) > 0:
  1067         if len(self.body) > 0:
  1279             self.body[0].appendcontentInstance(name, instance)
  1068             self.body[0].appendcontentInstance(instance)
  1280     setattr(cls, "addinstance", addinstance)
  1069     setattr(cls, "addinstance", addinstance)
  1281     
  1070     
  1282     def getinstances(self):
  1071     def getinstances(self):
  1283         if len(self.body) > 0:
  1072         if len(self.body) > 0:
  1284             return self.body[0].getcontentInstances()
  1073             return self.body[0].getcontentInstances()
  1324         if self.interface is not None:
  1113         if self.interface is not None:
  1325             reverse_types = {}
  1114             reverse_types = {}
  1326             for name, value in VarTypes.items():
  1115             for name, value in VarTypes.items():
  1327                 reverse_types[value] = name
  1116                 reverse_types[value] = name
  1328             for varlist in self.interface.getcontent():
  1117             for varlist in self.interface.getcontent():
  1329                 vars.append((reverse_types[varlist["name"]], varlist["value"]))
  1118                 vars.append((reverse_types[varlist.getLocalTag()], varlist))
  1330         return vars
  1119         return vars
  1331     setattr(cls, "getvars", getvars)
  1120     setattr(cls, "getvars", getvars)
  1332     
  1121     
  1333     def setvars(self, vars):
  1122     def setvars(self, vars):
  1334         if self.interface is None:
  1123         if self.interface is None:
  1335             self.interface = PLCOpenClasses["pou_interface"]()
  1124             self.interface = PLCOpenParser.CreateElement("interface", "pou")
  1336         self.interface.setcontent([])
  1125         self.interface.setcontent(vars)
  1337         for vartype, varlist in vars:
       
  1338             self.interface.appendcontent({"name" : VarTypes[vartype], "value" : varlist})
       
  1339     setattr(cls, "setvars", setvars)
  1126     setattr(cls, "setvars", setvars)
  1340     
  1127     
  1341     def addpouLocalVar(self, type, name, location="", description=""):
  1128     def addpouLocalVar(self, var_type, name, location="", description=""):
  1342         self.addpouVar(type, name, location=location, description=description)
  1129         self.addpouVar(var_type, name, location=location, description=description)
  1343     setattr(cls, "addpouLocalVar", addpouLocalVar)
  1130     setattr(cls, "addpouLocalVar", addpouLocalVar)
  1344         
  1131         
  1345     def addpouExternalVar(self, type, name):
  1132     def addpouExternalVar(self, var_type, name):
  1346         self.addpouVar(type, name, "externalVars")
  1133         self.addpouVar(type, name, "externalVars")
  1347     setattr(cls, "addpouExternalVar", addpouExternalVar)
  1134     setattr(cls, "addpouExternalVar", addpouExternalVar)
  1348     
  1135     
  1349     def addpouVar(self, type, name, var_class="localVars", location="", description=""):
  1136     def addpouVar(self, var_type, name, var_class="localVars", location="", description=""):
  1350         if self.interface is None:
  1137         if self.interface is None:
  1351             self.interface = PLCOpenClasses["pou_interface"]()
  1138             self.interface = PLCOpenParser.CreateElement("interface", "pou")
  1352         content = self.interface.getcontent()
  1139         content = self.interface.getcontent()
  1353         if len(content) == 0 or content[-1]["name"] != var_class:
  1140         if len(content) == 0:
  1354             content.append({"name" : var_class, "value" : PLCOpenClasses["interface_%s" % var_class]()})
  1141             varlist = PLCOpenParser.CreateElement(var_class, "interface")
       
  1142             self.interface.setcontent([varlist])
       
  1143         elif content[-1] != var_class:
       
  1144             varlist = PLCOpenParser.CreateElement(var_class, "interface")
       
  1145             content[-1].addnext(varlist)
  1355         else:
  1146         else:
  1356             varlist = content[-1]["value"]
  1147             varlist = content[-1]
  1357             variables = varlist.getvariable()
  1148             variables = varlist.getvariable()
  1358             if varlist.getconstant() or varlist.getretain() or len(variables) > 0 and variables[0].getaddress():
  1149             if varlist.getconstant() or varlist.getretain() or len(variables) > 0 and variables[0].getaddress():
  1359                 content.append({"name" : var_class, "value" : PLCOpenClasses["interface_%s" % var_class]()})
  1150                 varlist = PLCOpenParser.CreateElement(var_class, "interface")
  1360         var = PLCOpenClasses["varListPlain_variable"]()
  1151                 content[-1].addnext(varlist)
       
  1152         var = PLCOpenParser.CreateElement("variable", "varListPlain")
  1361         var.setname(name)
  1153         var.setname(name)
  1362         var_type = PLCOpenClasses["dataType"]()
       
  1363         if type in [x for x,y in TypeHierarchy_list if not x.startswith("ANY")]:
       
  1364             if type == "STRING":
       
  1365                 var_type.setcontent({"name" : "string", "value" : PLCOpenClasses["elementaryTypes_string"]()})
       
  1366             elif type == "WSTRING":
       
  1367                 var_type.setcontent({"name" : "wstring", "value" : PLCOpenClasses["elementaryTypes_wstring"]()})
       
  1368             else:
       
  1369                 var_type.setcontent({"name" : type, "value" : None})
       
  1370         else:
       
  1371             derived_type = PLCOpenClasses["derivedTypes_derived"]()
       
  1372             derived_type.setname(type)
       
  1373             var_type.setcontent({"name" : "derived", "value" : derived_type})
       
  1374         var.settype(var_type)
  1154         var.settype(var_type)
  1375         if location != "":
  1155         if location != "":
  1376             var.setaddress(location)
  1156             var.setaddress(location)
  1377         if description != "":
  1157         if description != "":
  1378             ft = PLCOpenClasses["formattedText"]()
  1158             ft = PLCOpenParser.CreateElement("documentation", "variable")
  1379             ft.settext(description)
  1159             ft.setanyText(description)
  1380             var.setdocumentation(ft)
  1160             var.setdocumentation(ft)
  1381         
  1161         
  1382         content[-1]["value"].appendvariable(var)
  1162         varlist.appendvariable(var)
  1383     setattr(cls, "addpouVar", addpouVar)
  1163     setattr(cls, "addpouVar", addpouVar)
  1384     
  1164     
  1385     def changepouVar(self, old_type, old_name, new_type, new_name):
  1165     def changepouVar(self, old_type, old_name, new_type, new_name):
  1386         if self.interface is not None:
  1166         if self.interface is not None:
  1387             content = self.interface.getcontent()
  1167             content = self.interface.getcontent()
  1388             for varlist in content:
  1168             for varlist in content:
  1389                 variables = varlist["value"].getvariable()
  1169                 variables = varlist.getvariable()
  1390                 for var in variables:
  1170                 for var in variables:
  1391                     if var.getname() == old_name:
  1171                     if var.getname() == old_name:
  1392                         vartype_content = var.gettype().getcontent()
  1172                         vartype_content = var.gettype().getcontent()
  1393                         if vartype_content["name"] == "derived" and vartype_content["value"].getname() == old_type:
  1173                         if vartype_content.getLocalTag() == "derived" and vartype_content.getname() == old_type:
  1394                             var.setname(new_name)
  1174                             var.setname(new_name)
  1395                             vartype_content["value"].setname(new_type)
  1175                             vartype_content.setname(new_type)
  1396                             return
  1176                             return
  1397     setattr(cls, "changepouVar", changepouVar)
  1177     setattr(cls, "changepouVar", changepouVar)
  1398     
  1178     
  1399     def removepouVar(self, type, name):
  1179     def removepouVar(self, var_type, name):
  1400         if self.interface is not None:
  1180         if self.interface is not None:
  1401             content = self.interface.getcontent()
  1181             content = self.interface.getcontent()
  1402             for varlist in content:
  1182             for varlist in content:
  1403                 variables = varlist["value"].getvariable()
  1183                 for var in varlist.getvariable():
  1404                 for var in variables:
       
  1405                     if var.getname() == name:
  1184                     if var.getname() == name:
  1406                         vartype_content = var.gettype().getcontent()
  1185                         vartype_content = var.gettype().getcontent()
  1407                         if vartype_content["name"] == "derived" and vartype_content["value"].getname() == type:
  1186                         if vartype_content.getLocalTag() == "derived" and vartype_content.getname() == var_type:
  1408                             variables.remove(var)
  1187                             varlist.remove(var)
  1409                             break
  1188                             break
  1410                 if len(varlist["value"].getvariable()) == 0:
  1189                 if len(varlist.getvariable()) == 0:
  1411                     content.remove(varlist)
  1190                     content.remove(varlist)
  1412                     break
  1191                     break
  1413     setattr(cls, "removepouVar", removepouVar)
  1192     setattr(cls, "removepouVar", removepouVar)
  1414     
  1193     
  1415     def hasblock(self, name=None, block_type=None):
  1194     def hasblock(self, name=None, block_type=None):
  1416         if self.getbodyType() in ["FBD", "LD", "SFC"]:
  1195         if self.getbodyType() in ["FBD", "LD", "SFC"]:
  1417             for instance in self.getinstances():
  1196             for instance in self.getinstances():
  1418                 if (isinstance(instance, PLCOpenClasses["fbdObjects_block"]) and 
  1197                 if (isinstance(instance, PLCOpenParser.GetElementClass("block", "fbdObjects")) and 
  1419                     (name and instance.getinstanceName() == name or
  1198                     (name and instance.getinstanceName() == name or
  1420                      block_type and instance.gettypeName() == block_type)):
  1199                      block_type and instance.gettypeName() == block_type)):
  1421                     return True
  1200                     return True
  1422             if self.transitions:
  1201             if self.transitions:
  1423                 for transition in self.transitions.gettransition():
  1202                 for transition in self.transitions.gettransition():
  1432         elif block_type is not None and len(self.body) > 0:
  1211         elif block_type is not None and len(self.body) > 0:
  1433             return self.body[0].hasblock(block_type)
  1212             return self.body[0].hasblock(block_type)
  1434         return False
  1213         return False
  1435     setattr(cls, "hasblock", hasblock)
  1214     setattr(cls, "hasblock", hasblock)
  1436     
  1215     
  1437     def addtransition(self, name, type):
  1216     def addtransition(self, name, body_type):
  1438         if not self.transitions:
  1217         if self.transitions is None:
  1439             self.addtransitions()
  1218             self.addtransitions()
  1440             self.transitions.settransition([])
  1219             self.transitions.settransition([])
  1441         transition = PLCOpenClasses["transitions_transition"]()
  1220         transition = PLCOpenParser.CreateElement("transition", "transitions")
       
  1221         self.transitions.appendtransition(transition)
  1442         transition.setname(name)
  1222         transition.setname(name)
  1443         transition.setbodyType(type)
  1223         transition.setbodyType(body_type)
  1444         if type == "ST":
  1224         if body_type == "ST":
  1445             transition.settext(":= ;")
  1225             transition.setanyText(":= ;")
  1446         elif type == "IL":
  1226         elif body_type == "IL":
  1447             transition.settext("\tST\t%s"%name)
  1227             transition.setanyText("\tST\t%s"%name)
  1448         self.transitions.appendtransition(transition)
       
  1449     setattr(cls, "addtransition", addtransition)
  1228     setattr(cls, "addtransition", addtransition)
  1450     
  1229     
  1451     def gettransition(self, name):
  1230     def gettransition(self, name):
  1452         if self.transitions:
  1231         if self.transitions is not None:
  1453             for transition in self.transitions.gettransition():
  1232             for transition in self.transitions.gettransition():
  1454                 if transition.getname() == name:
  1233                 if transition.getname() == name:
  1455                     return transition
  1234                     return transition
  1456         return None
  1235         return None
  1457     setattr(cls, "gettransition", gettransition)
  1236     setattr(cls, "gettransition", gettransition)
  1458         
  1237         
  1459     def gettransitionList(self):
  1238     def gettransitionList(self):
  1460         if self.transitions:
  1239         if self.transitions is not None:
  1461             return self.transitions.gettransition()
  1240             return self.transitions.gettransition()
  1462         return []
  1241         return []
  1463     setattr(cls, "gettransitionList", gettransitionList)
  1242     setattr(cls, "gettransitionList", gettransitionList)
  1464     
  1243     
  1465     def removetransition(self, name):
  1244     def removetransition(self, name):
  1466         if self.transitions:
  1245         if self.transitions is not None:
  1467             transitions = self.transitions.gettransition()
       
  1468             i = 0
       
  1469             removed = False
  1246             removed = False
  1470             while i < len(transitions) and not removed:
  1247             for transition in self.transitions.gettransition():
  1471                 if transitions[i].getname() == name:
  1248                 if transition.getname() == name:
  1472                     if transitions[i].getbodyType() in ["FBD", "LD", "SFC"]:
  1249                     if transition.getbodyType() in ["FBD", "LD", "SFC"]:
  1473                         for instance in transitions[i].getinstances():
  1250                         for instance in transition.getinstances():
  1474                             if isinstance(instance, PLCOpenClasses["fbdObjects_block"]):
  1251                             if isinstance(instance, PLCOpenParser.GetElementClass("block", "fbdObjects")):
  1475                                 self.removepouVar(instance.gettypeName(), 
  1252                                 self.removepouVar(instance.gettypeName(), 
  1476                                                   instance.getinstanceName())
  1253                                                   instance.getinstanceName())
  1477                     transitions.pop(i)
  1254                     self.transitions.remove(transition)
  1478                     removed = True
  1255                     removed = True
  1479                 i += 1
  1256                     break
  1480             if not removed:
  1257             if not removed:
  1481                 raise ValueError, _("Transition with name %s doesn't exist!")%name
  1258                 raise ValueError, _("Transition with name %s doesn't exist!")%name
  1482     setattr(cls, "removetransition", removetransition)
  1259     setattr(cls, "removetransition", removetransition)
  1483 
  1260 
  1484     def addaction(self, name, type):
  1261     def addaction(self, name, body_type):
  1485         if not self.actions:
  1262         if self.actions is None:
  1486             self.addactions()
  1263             self.addactions()
  1487             self.actions.setaction([])
  1264             self.actions.setaction([])
  1488         action = PLCOpenClasses["actions_action"]()
  1265         action = PLCOpenParser.CreateElement("action", "actions")
       
  1266         self.actions.appendaction(action)
  1489         action.setname(name)
  1267         action.setname(name)
  1490         action.setbodyType(type)
  1268         action.setbodyType(body_type)
  1491         self.actions.appendaction(action)
       
  1492     setattr(cls, "addaction", addaction)
  1269     setattr(cls, "addaction", addaction)
  1493     
  1270     
  1494     def getaction(self, name):
  1271     def getaction(self, name):
  1495         if self.actions:
  1272         if self.actions is not None:
  1496             for action in self.actions.getaction():
  1273             for action in self.actions.getaction():
  1497                 if action.getname() == name:
  1274                 if action.getname() == name:
  1498                     return action
  1275                     return action
  1499         return None
  1276         return None
  1500     setattr(cls, "getaction", getaction)
  1277     setattr(cls, "getaction", getaction)
  1504             return self.actions.getaction()
  1281             return self.actions.getaction()
  1505         return []
  1282         return []
  1506     setattr(cls, "getactionList", getactionList)
  1283     setattr(cls, "getactionList", getactionList)
  1507     
  1284     
  1508     def removeaction(self, name):
  1285     def removeaction(self, name):
  1509         if self.actions:
  1286         if self.actions is not None:
  1510             actions = self.actions.getaction()
       
  1511             i = 0
       
  1512             removed = False
  1287             removed = False
  1513             while i < len(actions) and not removed:
  1288             for action in self.actions.getaction():
  1514                 if actions[i].getname() == name:
  1289                 if action.getname() == name:
  1515                     if actions[i].getbodyType() in ["FBD", "LD", "SFC"]:
  1290                     if action.getbodyType() in ["FBD", "LD", "SFC"]:
  1516                         for instance in actions[i].getinstances():
  1291                         for instance in action.getinstances():
  1517                             if isinstance(instance, PLCOpenClasses["fbdObjects_block"]):
  1292                             if isinstance(instance, PLCOpenParser.GetElementClass("block", "fbdObjects")):
  1518                                 self.removepouVar(instance.gettypeName(), 
  1293                                 self.removepouVar(instance.gettypeName(), 
  1519                                                   instance.getinstanceName())
  1294                                                   instance.getinstanceName())
  1520                     actions.pop(i)
  1295                     self.actions.remove(action)
  1521                     removed = True
  1296                     removed = True
  1522                 i += 1
  1297                     break
  1523             if not removed:
  1298             if not removed:
  1524                 raise ValueError, _("Action with name %s doesn't exist!")%name
  1299                 raise ValueError, _("Action with name %s doesn't exist!")%name
  1525     setattr(cls, "removeaction", removeaction)
  1300     setattr(cls, "removeaction", removeaction)
  1526 
  1301 
  1527     def updateElementName(self, old_name, new_name):
  1302     def updateElementName(self, old_name, new_name):
  1528         if self.interface:
  1303         if self.interface is not None:
  1529             for content in self.interface.getcontent():
  1304             for content in self.interface.getcontent():
  1530                 for var in content["value"].getvariable():
  1305                 for var in content.getvariable():
  1531                     var_address = var.getaddress()
  1306                     var_address = var.getaddress()
  1532                     if var_address is not None:
  1307                     if var_address is not None:
  1533                         if var_address == old_name:
  1308                         if var_address == old_name:
  1534                             var.setaddress(new_name)
  1309                             var.setaddress(new_name)
  1535                         if var.getname() == old_name:
  1310                         if var.getname() == old_name:
  1536                             var.setname(new_name)
  1311                             var.setname(new_name)
  1537                     var_type_content = var.gettype().getcontent()
  1312                     var_type_content = var.gettype().getcontent()
  1538                     if var_type_content["name"] == "derived":
  1313                     if var_type_content.getLocalTag() == "derived":
  1539                         if var_type_content["value"].getname() == old_name:
  1314                         if var_type_content.getname() == old_name:
  1540                             var_type_content["value"].setname(new_name)
  1315                             var_type_content.setname(new_name)
  1541         self.body[0].updateElementName(old_name, new_name)
  1316         self.body[0].updateElementName(old_name, new_name)
  1542         for action in self.getactionList():
  1317         for action in self.getactionList():
  1543             action.updateElementName(old_name, new_name)
  1318             action.updateElementName(old_name, new_name)
  1544         for transition in self.gettransitionList():
  1319         for transition in self.gettransitionList():
  1545             transition.updateElementName(old_name, new_name)
  1320             transition.updateElementName(old_name, new_name)
  1546     setattr(cls, "updateElementName", updateElementName)
  1321     setattr(cls, "updateElementName", updateElementName)
  1547 
  1322 
  1548     def updateElementAddress(self, address_model, new_leading):
  1323     def updateElementAddress(self, address_model, new_leading):
  1549         if self.interface:
  1324         if self.interface is not None:
  1550             for content in self.interface.getcontent():
  1325             for content in self.interface.getcontent():
  1551                 for var in content["value"].getvariable():
  1326                 for var in content.getvariable():
  1552                     var_address = var.getaddress()
  1327                     var_address = var.getaddress()
  1553                     if var_address is not None:
  1328                     if var_address is not None:
  1554                         var.setaddress(update_address(var_address, address_model, new_leading))
  1329                         var.setaddress(update_address(var_address, address_model, new_leading))
  1555         self.body[0].updateElementAddress(address_model, new_leading)
  1330         self.body[0].updateElementAddress(address_model, new_leading)
  1556         for action in self.getactionList():
  1331         for action in self.getactionList():
  1558         for transition in self.gettransitionList():
  1333         for transition in self.gettransitionList():
  1559             transition.updateElementAddress(address_model, new_leading)
  1334             transition.updateElementAddress(address_model, new_leading)
  1560     setattr(cls, "updateElementAddress", updateElementAddress)
  1335     setattr(cls, "updateElementAddress", updateElementAddress)
  1561 
  1336 
  1562     def removeVariableByAddress(self, address):
  1337     def removeVariableByAddress(self, address):
  1563         if self.interface:
  1338         if self.interface is not None:
  1564             for content in self.interface.getcontent():
  1339             for content in self.interface.getcontent():
  1565                 variables = content["value"].getvariable()
  1340                 for variable in content.getvariable():
  1566                 for i in xrange(len(variables)-1, -1, -1):
  1341                     if variable.getaddress() == address:
  1567                     if variables[i].getaddress() == address:
  1342                         content.remove(variable)
  1568                         variables.pop(i)
       
  1569     setattr(cls, "removeVariableByAddress", removeVariableByAddress)
  1343     setattr(cls, "removeVariableByAddress", removeVariableByAddress)
  1570 
  1344 
  1571     def removeVariableByFilter(self, address_model):
  1345     def removeVariableByFilter(self, address_model):
  1572         if self.interface:
  1346         if self.interface is not None:
  1573             for content in self.interface.getcontent():
  1347             for content in self.interface.getcontent():
  1574                 variables = content["value"].getvariable()
  1348                 for variable in content.getvariable():
  1575                 for i in xrange(len(variables)-1, -1, -1):
  1349                     var_address = variable.getaddress()
  1576                     var_address = variables[i].getaddress()
       
  1577                     if var_address is not None:
  1350                     if var_address is not None:
  1578                         result = address_model.match(var_address)
  1351                         result = address_model.match(var_address)
  1579                         if result is not None:
  1352                         if result is not None:
  1580                             variables.pop(i)
  1353                             content.remove(variable)
  1581     setattr(cls, "removeVariableByFilter", removeVariableByFilter)
  1354     setattr(cls, "removeVariableByFilter", removeVariableByFilter)
  1582     
  1355     
  1583     def Search(self, criteria, parent_infos=[]):
  1356     def Search(self, criteria, parent_infos=[]):
  1584         search_result = []
  1357         search_result = []
  1585         filter = criteria["filter"]
  1358         filter = criteria["filter"]
  1587             parent_infos = parent_infos + ["P::%s" % self.getname()]
  1360             parent_infos = parent_infos + ["P::%s" % self.getname()]
  1588             search_result.extend(_Search([("name", self.getname())], criteria, parent_infos))
  1361             search_result.extend(_Search([("name", self.getname())], criteria, parent_infos))
  1589             if self.interface is not None:
  1362             if self.interface is not None:
  1590                 var_number = 0
  1363                 var_number = 0
  1591                 for content in self.interface.getcontent():
  1364                 for content in self.interface.getcontent():
  1592                     variable_type = searchResultVarTypes.get(content["value"], "var_local")
  1365                     variable_type = searchResultVarTypes.get(content, "var_local")
  1593                     variables = content["value"].getvariable()
  1366                     variables = content.getvariable()
  1594                     for modifier, has_modifier in [("constant", content["value"].getconstant()),
  1367                     for modifier, has_modifier in [("constant", content.getconstant()),
  1595                                                    ("retain", content["value"].getretain()),
  1368                                                    ("retain", content.getretain()),
  1596                                                    ("non_retain", content["value"].getnonretain())]:
  1369                                                    ("non_retain", content.getnonretain())]:
  1597                         if has_modifier:
  1370                         if has_modifier:
  1598                             for result in TestTextElement(modifier, criteria):
  1371                             for result in TestTextElement(modifier, criteria):
  1599                                 search_result.append((tuple(parent_infos + [variable_type, (var_number, var_number + len(variables)), modifier]),) + result)
  1372                                 search_result.append((tuple(parent_infos + [variable_type, (var_number, var_number + len(variables)), modifier]),) + result)
  1600                             break
  1373                             break
  1601                     for variable in variables:
  1374                     for variable in variables:
  1608             for transition in self.gettransitionList():
  1381             for transition in self.gettransitionList():
  1609                 search_result.extend(transition.Search(criteria, parent_infos))
  1382                 search_result.extend(transition.Search(criteria, parent_infos))
  1610         return search_result
  1383         return search_result
  1611     setattr(cls, "Search", Search)
  1384     setattr(cls, "Search", Search)
  1612 
  1385 
  1613 def setbodyType(self, type):
  1386 def setbodyType(self, body_type):
  1614     if type == "IL":
  1387     if body_type in ["IL", "ST", "LD", "FBD", "SFC"]:
  1615         self.body.setcontent({"name" : "IL", "value" : PLCOpenClasses["formattedText"]()})
  1388         self.body.setcontent(PLCOpenParser.CreateElement(body_type, "body"))
  1616     elif type == "ST":
       
  1617         self.body.setcontent({"name" : "ST", "value" : PLCOpenClasses["formattedText"]()})
       
  1618     elif type == "LD":
       
  1619         self.body.setcontent({"name" : "LD", "value" : PLCOpenClasses["body_LD"]()})
       
  1620     elif type == "FBD":
       
  1621         self.body.setcontent({"name" : "FBD", "value" : PLCOpenClasses["body_FBD"]()})
       
  1622     elif type == "SFC":
       
  1623         self.body.setcontent({"name" : "SFC", "value" : PLCOpenClasses["body_SFC"]()})
       
  1624     else:
  1389     else:
  1625         raise ValueError, "%s isn't a valid body type!"%type
  1390         raise ValueError, "%s isn't a valid body type!"%type
  1626 
  1391 
  1627 def getbodyType(self):
  1392 def getbodyType(self):
  1628     return self.body.getcontent()["name"]
  1393     return self.body.getcontent().getLocalTag()
  1629 
  1394 
  1630 def resetexecutionOrder(self):
  1395 def resetexecutionOrder(self):
  1631     self.body.resetexecutionOrder()
  1396     self.body.resetexecutionOrder()
  1632 
  1397 
  1633 def compileexecutionOrder(self):
  1398 def compileexecutionOrder(self):
  1634     self.body.compileexecutionOrder()
  1399     self.body.compileexecutionOrder()
  1635 
  1400 
  1636 def setelementExecutionOrder(self, instance, new_executionOrder):
  1401 def setelementExecutionOrder(self, instance, new_executionOrder):
  1637     self.body.setelementExecutionOrder(instance, new_executionOrder)
  1402     self.body.setelementExecutionOrder(instance, new_executionOrder)
  1638 
  1403 
  1639 def addinstance(self, name, instance):
  1404 def addinstance(self, instance):
  1640     self.body.appendcontentInstance(name, instance)
  1405     self.body.appendcontentInstance(instance)
  1641 
  1406 
  1642 def getinstances(self):
  1407 def getinstances(self):
  1643     return self.body.getcontentInstances()
  1408     return self.body.getcontentInstances()
  1644 
  1409 
  1645 def getinstance(self, id):
  1410 def getinstance(self, id):
  1661     return self.body.gettext()
  1426     return self.body.gettext()
  1662 
  1427 
  1663 def hasblock(self, name=None, block_type=None):
  1428 def hasblock(self, name=None, block_type=None):
  1664     if self.getbodyType() in ["FBD", "LD", "SFC"]:
  1429     if self.getbodyType() in ["FBD", "LD", "SFC"]:
  1665         for instance in self.getinstances():
  1430         for instance in self.getinstances():
  1666             if (isinstance(instance, PLCOpenClasses["fbdObjects_block"]) and 
  1431             if (isinstance(instance, PLCOpenParser.GetElementClass("block", "fbdObjects")) and 
  1667                 (name and instance.getinstanceName() == name or
  1432                 (name and instance.getinstanceName() == name or
  1668                  block_type and instance.gettypeName() == block_type)):
  1433                  block_type and instance.gettypeName() == block_type)):
  1669                 return True
  1434                 return True
  1670     elif block_type is not None:
  1435     elif block_type is not None:
  1671         return self.body.hasblock(block_type)
  1436         return self.body.hasblock(block_type)
  1676 
  1441 
  1677 def updateElementAddress(self, address_model, new_leading):
  1442 def updateElementAddress(self, address_model, new_leading):
  1678     self.body.updateElementAddress(address_model, new_leading)
  1443     self.body.updateElementAddress(address_model, new_leading)
  1679     
  1444     
  1680 
  1445 
  1681 cls = PLCOpenClasses.get("transitions_transition", None)
  1446 cls = PLCOpenParser.GetElementClass("transition", "transitions")
  1682 if cls:
  1447 if cls:
  1683     setattr(cls, "setbodyType", setbodyType)
  1448     setattr(cls, "setbodyType", setbodyType)
  1684     setattr(cls, "getbodyType", getbodyType)
  1449     setattr(cls, "getbodyType", getbodyType)
  1685     setattr(cls, "resetexecutionOrder", resetexecutionOrder)
  1450     setattr(cls, "resetexecutionOrder", resetexecutionOrder)
  1686     setattr(cls, "compileexecutionOrder", compileexecutionOrder)
  1451     setattr(cls, "compileexecutionOrder", compileexecutionOrder)
  1704             search_result.append((tuple(parent_infos + ["name"]),) + result)
  1469             search_result.append((tuple(parent_infos + ["name"]),) + result)
  1705         search_result.extend(self.body.Search(criteria, parent_infos))
  1470         search_result.extend(self.body.Search(criteria, parent_infos))
  1706         return search_result
  1471         return search_result
  1707     setattr(cls, "Search", Search)
  1472     setattr(cls, "Search", Search)
  1708 
  1473 
  1709 cls = PLCOpenClasses.get("actions_action", None)
  1474 cls = PLCOpenParser.GetElementClass("action", "actions")
  1710 if cls:
  1475 if cls:
  1711     setattr(cls, "setbodyType", setbodyType)
  1476     setattr(cls, "setbodyType", setbodyType)
  1712     setattr(cls, "getbodyType", getbodyType)
  1477     setattr(cls, "getbodyType", getbodyType)
  1713     setattr(cls, "resetexecutionOrder", resetexecutionOrder)
  1478     setattr(cls, "resetexecutionOrder", resetexecutionOrder)
  1714     setattr(cls, "compileexecutionOrder", compileexecutionOrder)
  1479     setattr(cls, "compileexecutionOrder", compileexecutionOrder)
  1732             search_result.append((tuple(parent_infos + ["name"]),) + result)
  1497             search_result.append((tuple(parent_infos + ["name"]),) + result)
  1733         search_result.extend(self.body.Search(criteria, parent_infos))
  1498         search_result.extend(self.body.Search(criteria, parent_infos))
  1734         return search_result
  1499         return search_result
  1735     setattr(cls, "Search", Search)
  1500     setattr(cls, "Search", Search)
  1736 
  1501 
  1737 cls = PLCOpenClasses.get("body", None)
  1502 cls = PLCOpenParser.GetElementClass("body")
  1738 if cls:
  1503 if cls:
  1739     cls.currentExecutionOrderId = 0
  1504     cls.currentExecutionOrderId = 0
  1740     cls.instances_dict = {}
       
  1741     
       
  1742     setattr(cls, "_init_", getattr(cls, "__init__"))
       
  1743     
       
  1744     def __init__(self, *args, **kwargs):
       
  1745         self._init_(*args, **kwargs)
       
  1746         self.instances_dict = {}
       
  1747     setattr(cls, "__init__", __init__)
       
  1748     
       
  1749     setattr(cls, "_loadXMLTree", getattr(cls, "loadXMLTree"))
       
  1750     
       
  1751     def loadXMLTree(self, *args, **kwargs):
       
  1752         self._loadXMLTree(*args, **kwargs)
       
  1753         if self.content["name"] in ["LD","FBD","SFC"]:
       
  1754             self.instances_dict = dict(
       
  1755                 [(element["value"].getlocalId(), element)
       
  1756                  for element in self.content["value"].getcontent()])
       
  1757     setattr(cls, "loadXMLTree", loadXMLTree)
       
  1758     
  1505     
  1759     def resetcurrentExecutionOrderId(self):
  1506     def resetcurrentExecutionOrderId(self):
  1760         object.__setattr__(self, "currentExecutionOrderId", 0)
  1507         object.__setattr__(self, "currentExecutionOrderId", 0)
  1761     setattr(cls, "resetcurrentExecutionOrderId", resetcurrentExecutionOrderId)
  1508     setattr(cls, "resetcurrentExecutionOrderId", resetcurrentExecutionOrderId)
  1762     
  1509     
  1764         object.__setattr__(self, "currentExecutionOrderId", self.currentExecutionOrderId + 1)
  1511         object.__setattr__(self, "currentExecutionOrderId", self.currentExecutionOrderId + 1)
  1765         return self.currentExecutionOrderId
  1512         return self.currentExecutionOrderId
  1766     setattr(cls, "getnewExecutionOrderId", getnewExecutionOrderId)
  1513     setattr(cls, "getnewExecutionOrderId", getnewExecutionOrderId)
  1767     
  1514     
  1768     def resetexecutionOrder(self):
  1515     def resetexecutionOrder(self):
  1769         if self.content["name"] == "FBD":
  1516         if self.content.getLocalTag() == "FBD":
  1770             for element in self.content["value"].getcontent():
  1517             for element in self.content.getcontent():
  1771                 if not isinstance(element["value"], (PLCOpenClasses.get("commonObjects_comment", None), 
  1518                 if not isinstance(element, (PLCOpenParser.GetElementClass("comment", "commonObjects"), 
  1772                                                      PLCOpenClasses.get("commonObjects_connector", None), 
  1519                                             PLCOpenParser.GetElementClass("connector", "commonObjects"), 
  1773                                                      PLCOpenClasses.get("commonObjects_continuation", None))):
  1520                                             PLCOpenParser.GetElementClass("continuation", "commonObjects"))):
  1774                     element["value"].setexecutionOrderId(0)
  1521                     element.setexecutionOrderId(0)
  1775         else:
  1522         else:
  1776             raise TypeError, _("Can only generate execution order on FBD networks!")
  1523             raise TypeError, _("Can only generate execution order on FBD networks!")
  1777     setattr(cls, "resetexecutionOrder", resetexecutionOrder)
  1524     setattr(cls, "resetexecutionOrder", resetexecutionOrder)
  1778     
  1525     
  1779     def compileexecutionOrder(self):
  1526     def compileexecutionOrder(self):
  1780         if self.content["name"] == "FBD":
  1527         if self.content.getLocalTag() == "FBD":
  1781             self.resetexecutionOrder()
  1528             self.resetexecutionOrder()
  1782             self.resetcurrentExecutionOrderId()
  1529             self.resetcurrentExecutionOrderId()
  1783             for element in self.content["value"].getcontent():
  1530             for element in self.content.getcontent():
  1784                 if isinstance(element["value"], PLCOpenClasses.get("fbdObjects_outVariable", None)) and element["value"].getexecutionOrderId() == 0:
  1531                 if isinstance(element, PLCOpenParser.GetElementClass("outVariable", "fbdObjects")) and element.getexecutionOrderId() == 0:
  1785                     connections = element["value"].connectionPointIn.getconnections()
  1532                     connections = element.connectionPointIn.getconnections()
  1786                     if connections and len(connections) == 1:
  1533                     if connections and len(connections) == 1:
  1787                         self.compileelementExecutionOrder(connections[0])
  1534                         self.compileelementExecutionOrder(connections[0])
  1788                     element["value"].setexecutionOrderId(self.getnewExecutionOrderId())
  1535                     element.setexecutionOrderId(self.getnewExecutionOrderId())
  1789         else:
  1536         else:
  1790             raise TypeError, _("Can only generate execution order on FBD networks!")
  1537             raise TypeError, _("Can only generate execution order on FBD networks!")
  1791     setattr(cls, "compileexecutionOrder", compileexecutionOrder)
  1538     setattr(cls, "compileexecutionOrder", compileexecutionOrder)
  1792     
  1539     
  1793     def compileelementExecutionOrder(self, link):
  1540     def compileelementExecutionOrder(self, link):
  1794         if self.content["name"] == "FBD":
  1541         if self.content.getLocalTag() == "FBD":
  1795             localid = link.getrefLocalId()
  1542             localid = link.getrefLocalId()
  1796             instance = self.getcontentInstance(localid)
  1543             instance = self.getcontentInstance(localid)
  1797             if isinstance(instance, PLCOpenClasses.get("fbdObjects_block", None)) and instance.getexecutionOrderId() == 0:
  1544             if isinstance(instance, PLCOpenParser.GetElementClass("block", "fbdObjects")) and instance.getexecutionOrderId() == 0:
  1798                 for variable in instance.inputVariables.getvariable():
  1545                 for variable in instance.inputVariables.getvariable():
  1799                     connections = variable.connectionPointIn.getconnections()
  1546                     connections = variable.connectionPointIn.getconnections()
  1800                     if connections and len(connections) == 1:
  1547                     if connections and len(connections) == 1:
  1801                         self.compileelementExecutionOrder(connections[0])
  1548                         self.compileelementExecutionOrder(connections[0])
  1802                 instance.setexecutionOrderId(self.getnewExecutionOrderId())
  1549                 instance.setexecutionOrderId(self.getnewExecutionOrderId())
  1803             elif isinstance(instance, PLCOpenClasses.get("commonObjects_continuation", None)) and instance.getexecutionOrderId() == 0:
  1550             elif isinstance(instance, PLCOpenParser.GetElementClass("continuation", "commonObjects")) and instance.getexecutionOrderId() == 0:
  1804                 name = instance.getname()
  1551                 name = instance.getname()
  1805                 for tmp_instance in self.getcontentInstances():
  1552                 for tmp_instance in self.getcontentInstances():
  1806                     if isinstance(tmp_instance, PLCOpenClasses.get("commonObjects_connector", None)) and tmp_instance.getname() == name and tmp_instance.getexecutionOrderId() == 0:
  1553                     if isinstance(tmp_instance, PLCOpenParser.GetElementClass("connector", "commonObjects")) and tmp_instance.getname() == name and tmp_instance.getexecutionOrderId() == 0:
  1807                         connections = tmp_instance.connectionPointIn.getconnections()
  1554                         connections = tmp_instance.connectionPointIn.getconnections()
  1808                         if connections and len(connections) == 1:
  1555                         if connections and len(connections) == 1:
  1809                             self.compileelementExecutionOrder(connections[0])
  1556                             self.compileelementExecutionOrder(connections[0])
  1810         else:
  1557         else:
  1811             raise TypeError, _("Can only generate execution order on FBD networks!")
  1558             raise TypeError, _("Can only generate execution order on FBD networks!")
  1812     setattr(cls, "compileelementExecutionOrder", compileelementExecutionOrder)
  1559     setattr(cls, "compileelementExecutionOrder", compileelementExecutionOrder)
  1813     
  1560     
  1814     def setelementExecutionOrder(self, instance, new_executionOrder):
  1561     def setelementExecutionOrder(self, instance, new_executionOrder):
  1815         if self.content["name"] == "FBD":
  1562         if self.content.getLocalTag() == "FBD":
  1816             old_executionOrder = instance.getexecutionOrderId()
  1563             old_executionOrder = instance.getexecutionOrderId()
  1817             if old_executionOrder is not None and old_executionOrder != 0 and new_executionOrder != 0:
  1564             if old_executionOrder is not None and old_executionOrder != 0 and new_executionOrder != 0:
  1818                 for element in self.content["value"].getcontent():
  1565                 for element in self.content.getcontent():
  1819                     if element["value"] != instance and not isinstance(element["value"], PLCOpenClasses.get("commonObjects_comment", None)):
  1566                     if element != instance and not isinstance(element, PLCOpenParser.GetElementClass("comment", "commonObjects")):
  1820                         element_executionOrder = element["value"].getexecutionOrderId()
  1567                         element_executionOrder = element.getexecutionOrderId()
  1821                         if old_executionOrder <= element_executionOrder <= new_executionOrder:
  1568                         if old_executionOrder <= element_executionOrder <= new_executionOrder:
  1822                             element["value"].setexecutionOrderId(element_executionOrder - 1)
  1569                             element.setexecutionOrderId(element_executionOrder - 1)
  1823                         if new_executionOrder <= element_executionOrder <= old_executionOrder:
  1570                         if new_executionOrder <= element_executionOrder <= old_executionOrder:
  1824                             element["value"].setexecutionOrderId(element_executionOrder + 1)
  1571                             element.setexecutionOrderId(element_executionOrder + 1)
  1825             instance.setexecutionOrderId(new_executionOrder)
  1572             instance.setexecutionOrderId(new_executionOrder)
  1826         else:
  1573         else:
  1827             raise TypeError, _("Can only generate execution order on FBD networks!")
  1574             raise TypeError, _("Can only generate execution order on FBD networks!")
  1828     setattr(cls, "setelementExecutionOrder", setelementExecutionOrder)
  1575     setattr(cls, "setelementExecutionOrder", setelementExecutionOrder)
  1829     
  1576     
  1830     def appendcontentInstance(self, name, instance):
  1577     def appendcontentInstance(self, instance):
  1831         if self.content["name"] in ["LD","FBD","SFC"]:
  1578         if self.content.getLocalTag() in ["LD","FBD","SFC"]:
  1832             element = {"name" : name, "value" : instance}
  1579             self.content.appendcontent(instance)
  1833             self.content["value"].appendcontent(element)
       
  1834             self.instances_dict[instance.getlocalId()] = element
       
  1835         else:
  1580         else:
  1836             raise TypeError, _("%s body don't have instances!")%self.content["name"]
  1581             raise TypeError, _("%s body don't have instances!")%self.content.getLocalTag()
  1837     setattr(cls, "appendcontentInstance", appendcontentInstance)
  1582     setattr(cls, "appendcontentInstance", appendcontentInstance)
  1838     
  1583     
  1839     def getcontentInstances(self):
  1584     def getcontentInstances(self):
  1840         if self.content["name"] in ["LD","FBD","SFC"]:
  1585         if self.content.getLocalTag() in ["LD","FBD","SFC"]:
  1841             instances = []
  1586             return self.content.getcontent()
  1842             for element in self.content["value"].getcontent():
       
  1843                 instances.append(element["value"])
       
  1844             return instances
       
  1845         else:
  1587         else:
  1846             raise TypeError, _("%s body don't have instances!")%self.content["name"]
  1588             raise TypeError, _("%s body don't have instances!")%self.content.getLocalTag()
  1847     setattr(cls, "getcontentInstances", getcontentInstances)
  1589     setattr(cls, "getcontentInstances", getcontentInstances)
  1848 
  1590     
  1849     def getcontentInstance(self, id):
  1591     instance_by_id_xpath = PLCOpen_XPath("*[@localId=$localId]")
  1850         if self.content["name"] in ["LD","FBD","SFC"]:
  1592     instance_by_name_xpath = PLCOpen_XPath("ppx:block[@instanceName=$name]")
  1851             instance = self.instances_dict.get(id, None)
  1593     def getcontentInstance(self, local_id):
  1852             if instance is not None:
  1594         if self.content.getLocalTag() in ["LD","FBD","SFC"]:
  1853                 return instance["value"]
  1595             instance = instance_by_id_xpath(self.content, localId=local_id)
       
  1596             if len(instance) > 0:
       
  1597                 return instance[0]
  1854             return None
  1598             return None
  1855         else:
  1599         else:
  1856             raise TypeError, _("%s body don't have instances!")%self.content["name"]
  1600             raise TypeError, _("%s body don't have instances!")%self.content.getLocalTag()
  1857     setattr(cls, "getcontentInstance", getcontentInstance)
  1601     setattr(cls, "getcontentInstance", getcontentInstance)
  1858     
  1602     
  1859     def getcontentRandomInstance(self, exclude):
  1603     def getcontentRandomInstance(self, exclude):
  1860         if self.content["name"] in ["LD","FBD","SFC"]:
  1604         if self.content.getLocalTag() in ["LD","FBD","SFC"]:
  1861             ids = self.instances_dict.viewkeys() - exclude
  1605             instance = self.content.xpath("*%s[position()=1]" %  
  1862             if len(ids) > 0:
  1606                 ("[not(%s)]" % " or ".join(
  1863                 return self.instances_dict[ids.pop()]["value"]
  1607                     map(lambda x: "@localId=%d" % x, exclude))
       
  1608                 if len(exclude) > 0 else ""))
       
  1609             if len(instance) > 0:
       
  1610                 return instance[0]
  1864             return None
  1611             return None
  1865         else:
  1612         else:
  1866             raise TypeError, _("%s body don't have instances!")%self.content["name"]
  1613             raise TypeError, _("%s body don't have instances!")%self.content.getLocalTag()
  1867     setattr(cls, "getcontentRandomInstance", getcontentRandomInstance)
  1614     setattr(cls, "getcontentRandomInstance", getcontentRandomInstance)
  1868     
  1615     
  1869     def getcontentInstanceByName(self, name):
  1616     def getcontentInstanceByName(self, name):
  1870         if self.content["name"] in ["LD","FBD","SFC"]:
  1617         if self.content.getLocalTag() in ["LD","FBD","SFC"]:
  1871             for element in self.content["value"].getcontent():
  1618             instance = instance_by_name_xpath(self.content)
  1872                 if isinstance(element["value"], PLCOpenClasses.get("fbdObjects_block", None)) and element["value"].getinstanceName() == name:
  1619             if len(instance) > 0:
  1873                     return element["value"]
  1620                 return instance[0]
       
  1621             return None
  1874         else:
  1622         else:
  1875             raise TypeError, _("%s body don't have instances!")%self.content["name"]
  1623             raise TypeError, _("%s body don't have instances!")%self.content.getLocalTag()
  1876     setattr(cls, "getcontentInstanceByName", getcontentInstanceByName)
  1624     setattr(cls, "getcontentInstanceByName", getcontentInstanceByName)
  1877     
  1625     
  1878     def removecontentInstance(self, id):
  1626     def removecontentInstance(self, local_id):
  1879         if self.content["name"] in ["LD","FBD","SFC"]:
  1627         if self.content.getLocalTag() in ["LD","FBD","SFC"]:
  1880             element = self.instances_dict.pop(id, None)
  1628             instance = instance_by_id_xpath(self.content, localId=local_id)
  1881             if element is not None:
  1629             if len(instance) > 0:
  1882                 self.content["value"].getcontent().remove(element)
  1630                 self.content.remove(instance[0])
  1883             else:
  1631             else:
  1884                 raise ValueError, _("Instance with id %d doesn't exist!")%id
  1632                 raise ValueError, _("Instance with id %d doesn't exist!")%id
  1885         else:
  1633         else:
  1886             raise TypeError, "%s body don't have instances!"%self.content["name"]
  1634             raise TypeError, "%s body don't have instances!"%self.content.getLocalTag()
  1887     setattr(cls, "removecontentInstance", removecontentInstance)
  1635     setattr(cls, "removecontentInstance", removecontentInstance)
  1888     
  1636     
  1889     def settext(self, text):
  1637     def settext(self, text):
  1890         if self.content["name"] in ["IL","ST"]:
  1638         if self.content.getLocalTag() in ["IL","ST"]:
  1891             self.content["value"].settext(text)
  1639             self.content.setanyText(text)
  1892         else:
  1640         else:
  1893             raise TypeError, _("%s body don't have text!")%self.content["name"]
  1641             raise TypeError, _("%s body don't have text!")%self.content.getLocalTag()
  1894     setattr(cls, "settext", settext)
  1642     setattr(cls, "settext", settext)
  1895 
  1643 
  1896     def gettext(self):
  1644     def gettext(self):
  1897         if self.content["name"] in ["IL","ST"]:
  1645         if self.content.getLocalTag() in ["IL","ST"]:
  1898             return self.content["value"].gettext()
  1646             return self.content.getanyText()
  1899         else:
  1647         else:
  1900             raise TypeError, _("%s body don't have text!")%self.content["name"]
  1648             raise TypeError, _("%s body don't have text!")%self.content.getLocalTag()
  1901     setattr(cls, "gettext", gettext)
  1649     setattr(cls, "gettext", gettext)
  1902     
  1650     
  1903     def hasblock(self, block_type):
  1651     def hasblock(self, block_type):
  1904         if self.content["name"] in ["IL","ST"]:
  1652         if self.content.getLocalTag() in ["IL","ST"]:
  1905             return self.content["value"].hasblock(block_type)
  1653             return self.content.hasblock(block_type)
  1906         else:
  1654         else:
  1907             raise TypeError, _("%s body don't have text!")%self.content["name"]
  1655             raise TypeError, _("%s body don't have text!")%self.content.getLocalTag()
  1908     setattr(cls, "hasblock", hasblock)
  1656     setattr(cls, "hasblock", hasblock)
  1909     
  1657     
  1910     def updateElementName(self, old_name, new_name):
  1658     def updateElementName(self, old_name, new_name):
  1911         if self.content["name"] in ["IL", "ST"]:
  1659         if self.content.getLocalTag() in ["IL", "ST"]:
  1912             self.content["value"].updateElementName(old_name, new_name)
  1660             self.content.updateElementName(old_name, new_name)
  1913         else:
  1661         else:
  1914             for element in self.content["value"].getcontent():
  1662             for element in self.content.getcontent():
  1915                 element["value"].updateElementName(old_name, new_name)
  1663                 element.updateElementName(old_name, new_name)
  1916     setattr(cls, "updateElementName", updateElementName)
  1664     setattr(cls, "updateElementName", updateElementName)
  1917 
  1665 
  1918     def updateElementAddress(self, address_model, new_leading):
  1666     def updateElementAddress(self, address_model, new_leading):
  1919         if self.content["name"] in ["IL", "ST"]:
  1667         if self.content.getLocalTag() in ["IL", "ST"]:
  1920             self.content["value"].updateElementAddress(address_model, new_leading)
  1668             self.content.updateElementAddress(address_model, new_leading)
  1921         else:
  1669         else:
  1922             for element in self.content["value"].getcontent():
  1670             for element in self.content.getcontent():
  1923                 element["value"].updateElementAddress(address_model, new_leading)
  1671                 element.updateElementAddress(address_model, new_leading)
  1924     setattr(cls, "updateElementAddress", updateElementAddress)
  1672     setattr(cls, "updateElementAddress", updateElementAddress)
  1925 
  1673 
  1926     def Search(self, criteria, parent_infos=[]):
  1674     def Search(self, criteria, parent_infos=[]):
  1927         if self.content["name"] in ["IL", "ST"]:
  1675         if self.content.getLocalTag() in ["IL", "ST"]:
  1928             search_result = self.content["value"].Search(criteria, parent_infos + ["body", 0])
  1676             search_result = self.content.Search(criteria, parent_infos + ["body", 0])
  1929         else:
  1677         else:
  1930             search_result = []
  1678             search_result = []
  1931             for element in self.content["value"].getcontent():
  1679             for element in self.content.getcontent():
  1932                 search_result.extend(element["value"].Search(criteria, parent_infos))
  1680                 search_result.extend(element.Search(criteria, parent_infos))
  1933         return search_result
  1681         return search_result
  1934     setattr(cls, "Search", Search)
  1682     setattr(cls, "Search", Search)
  1935 
  1683 
  1936 def getx(self):
  1684 def getx(self):
  1937     return self.position.getx()
  1685     return self.position.getx()
  1970     return bbox
  1718     return bbox
  1971 
  1719 
  1972 def _filterConnections(connectionPointIn, localId, connections):
  1720 def _filterConnections(connectionPointIn, localId, connections):
  1973     in_connections = connectionPointIn.getconnections()
  1721     in_connections = connectionPointIn.getconnections()
  1974     if in_connections is not None:
  1722     if in_connections is not None:
  1975         to_delete = []
  1723         for connection in in_connections:
  1976         for i, connection in enumerate(in_connections):
       
  1977             connected = connection.getrefLocalId()
  1724             connected = connection.getrefLocalId()
  1978             if not connections.has_key((localId, connected)) and \
  1725             if not connections.has_key((localId, connected)) and \
  1979                not connections.has_key((connected, localId)):
  1726                not connections.has_key((connected, localId)):
  1980                 to_delete.append(i)
  1727                 connectionPointIn.remove(connection)
  1981         to_delete.reverse()
       
  1982         for i in to_delete:
       
  1983             connectionPointIn.removeconnection(i)
       
  1984 
  1728 
  1985 def _filterConnectionsSingle(self, connections):
  1729 def _filterConnectionsSingle(self, connections):
  1986     if self.connectionPointIn is not None:
  1730     if self.connectionPointIn is not None:
  1987         _filterConnections(self.connectionPointIn, self.localId, connections)
  1731         _filterConnections(self.connectionPointIn, self.localId, connections)
  1988 
  1732 
  1989 def _filterConnectionsMultiple(self, connections):
  1733 def _filterConnectionsMultiple(self, connections):
  1990     for connectionPointIn in self.getconnectionPointIn():
  1734     for connectionPointIn in self.getconnectionPointIn():
  1991         _filterConnections(connectionPointIn, self.localId, connections)
  1735         _filterConnections(connectionPointIn, self.localId, connections)
  1992 
  1736 
  1993 def _getconnectionsdefinition(instance, connections_end):
  1737 def _getconnectionsdefinition(instance, connections_end):
  1994     id = instance.getlocalId()
  1738     local_id = instance.getlocalId()
  1995     return dict([((id, end), True) for end in connections_end])
  1739     return dict([((local_id, end), True) for end in connections_end])
  1996 
  1740 
  1997 def _updateConnectionsId(connectionPointIn, translation):
  1741 def _updateConnectionsId(connectionPointIn, translation):
  1998     connections_end = []
  1742     connections_end = []
  1999     connections = connectionPointIn.getconnections()
  1743     connections = connectionPointIn.getconnections()
  2000     if connections is not None:
  1744     if connections is not None:
  2061     "update": {"none": lambda self, translation: {},
  1805     "update": {"none": lambda self, translation: {},
  2062                "single": _updateConnectionsIdSingle,
  1806                "single": _updateConnectionsIdSingle,
  2063                "multiple": _updateConnectionsIdMultiple},
  1807                "multiple": _updateConnectionsIdMultiple},
  2064 }
  1808 }
  2065 
  1809 
  2066 def _initElementClass(name, classname, connectionPointInType="none"):
  1810 def _initElementClass(name, parent, connectionPointInType="none"):
  2067     ElementNameToClass[name] = classname
  1811     cls = PLCOpenParser.GetElementClass(name, parent)
  2068     cls = PLCOpenClasses.get(classname, None)
       
  2069     if cls:
  1812     if cls:
  2070         setattr(cls, "getx", getx)
  1813         setattr(cls, "getx", getx)
  2071         setattr(cls, "gety", gety)
  1814         setattr(cls, "gety", gety)
  2072         setattr(cls, "setx", setx)
  1815         setattr(cls, "setx", setx)
  2073         setattr(cls, "sety", sety)
  1816         setattr(cls, "sety", sety)
  2144             infos["outputs"].append(_getconnectioninfos(self, self.connectionPointOut, False, "default"))
  1887             infos["outputs"].append(_getconnectioninfos(self, self.connectionPointOut, False, "default"))
  2145         return infos
  1888         return infos
  2146     return getvariableinfos
  1889     return getvariableinfos
  2147 
  1890 
  2148 def _getconnectorinfosFunction(type):
  1891 def _getconnectorinfosFunction(type):
  2149     def getvariableinfos(self):
  1892     def getconnectorinfos(self):
  2150         infos = _getelementinfos(self)
  1893         infos = _getelementinfos(self)
  2151         infos["type"] = type
  1894         infos["type"] = type
  2152         infos["specific_values"]["name"] = self.getname()
  1895         infos["specific_values"]["name"] = self.getname()
  2153         if type == "connector":
  1896         if type == "connector":
  2154             infos["inputs"].append(_getconnectioninfos(self, self.connectionPointIn, True))
  1897             infos["inputs"].append(_getconnectioninfos(self, self.connectionPointIn, True))
  2155         elif type == "continuation":
  1898         elif type == "continuation":
  2156             infos["outputs"].append(_getconnectioninfos(self, self.connectionPointOut))
  1899             infos["outputs"].append(_getconnectioninfos(self, self.connectionPointOut))
  2157         return infos
  1900         return infos
  2158     return getvariableinfos
  1901     return getconnectorinfos
  2159 
  1902 
  2160 def _getpowerrailinfosFunction(type):
  1903 def _getpowerrailinfosFunction(type):
  2161     def getpowerrailinfos(self):
  1904     def getpowerrailinfos(self):
  2162         infos = _getelementinfos(self)
  1905         infos = _getelementinfos(self)
  2163         infos["type"] = type
  1906         infos["type"] = type
  2170                 infos["outputs"].append(_getconnectioninfos(self, connectionPointOut))
  1913                 infos["outputs"].append(_getconnectioninfos(self, connectionPointOut))
  2171             infos["specific_values"]["connectors"] = len(infos["outputs"])
  1914             infos["specific_values"]["connectors"] = len(infos["outputs"])
  2172         return infos
  1915         return infos
  2173     return getpowerrailinfos
  1916     return getpowerrailinfos
  2174 
  1917 
  2175 def _getldelementinfosFunction(type):
  1918 def _getldelementinfosFunction(ld_element_type):
  2176     def getldelementinfos(self):
  1919     def getldelementinfos(self):
  2177         infos = _getelementinfos(self)
  1920         infos = _getelementinfos(self)
  2178         infos["type"] = type
  1921         infos["type"] = ld_element_type
  2179         specific_values = infos["specific_values"]
  1922         specific_values = infos["specific_values"]
  2180         specific_values["name"] = self.getvariable()
  1923         specific_values["name"] = self.getvariable()
  2181         _getexecutionOrder(self, specific_values)
  1924         _getexecutionOrder(self, specific_values)
  2182         specific_values["negated"] = self.getnegated()
  1925         specific_values["negated"] = self.getnegated()
  2183         specific_values["edge"] = self.getedge()
  1926         specific_values["edge"] = self.getedge()
  2184         if type == "coil":
  1927         if ld_element_type == "coil":
  2185             specific_values["storage"] = self.getstorage()
  1928             specific_values["storage"] = self.getstorage()
  2186         infos["inputs"].append(_getconnectioninfos(self, self.connectionPointIn, True))
  1929         infos["inputs"].append(_getconnectioninfos(self, self.connectionPointIn, True))
  2187         infos["outputs"].append(_getconnectioninfos(self, self.connectionPointOut))
  1930         infos["outputs"].append(_getconnectioninfos(self, self.connectionPointOut))
  2188         return infos
  1931         return infos
  2189     return getldelementinfos
  1932     return getldelementinfos
  2208             infos["outputs"].append(_getconnectioninfos(self, self.connectionPointOut))
  1951             infos["outputs"].append(_getconnectioninfos(self, self.connectionPointOut))
  2209             infos["specific_values"]["connectors"] = len(infos["inputs"])
  1952             infos["specific_values"]["connectors"] = len(infos["inputs"])
  2210         return infos
  1953         return infos
  2211     return getdivergenceinfos
  1954     return getdivergenceinfos
  2212 
  1955 
  2213 cls = _initElementClass("comment", "commonObjects_comment")
  1956 cls = _initElementClass("comment", "commonObjects")
  2214 if cls:
  1957 if cls:
  2215     def getinfos(self):
  1958     def getinfos(self):
  2216         infos = _getelementinfos(self)
  1959         infos = _getelementinfos(self)
  2217         infos["type"] = "comment"
  1960         infos["type"] = "comment"
  2218         infos["specific_values"]["content"] = self.getcontentText()
  1961         infos["specific_values"]["content"] = self.getcontentText()
  2219         return infos
  1962         return infos
  2220     setattr(cls, "getinfos", getinfos)
  1963     setattr(cls, "getinfos", getinfos)
  2221     
  1964     
  2222     def setcontentText(self, text):
  1965     def setcontentText(self, text):
  2223         self.content.settext(text)
  1966         self.content.setanyText(text)
  2224     setattr(cls, "setcontentText", setcontentText)
  1967     setattr(cls, "setcontentText", setcontentText)
  2225         
  1968         
  2226     def getcontentText(self):
  1969     def getcontentText(self):
  2227         return self.content.gettext()
  1970         return self.content.getanyText()
  2228     setattr(cls, "getcontentText", getcontentText)
  1971     setattr(cls, "getcontentText", getcontentText)
  2229     
  1972     
  2230     def updateElementName(self, old_name, new_name):
  1973     def updateElementName(self, old_name, new_name):
  2231         self.content.updateElementName(old_name, new_name)
  1974         self.content.updateElementName(old_name, new_name)
  2232     setattr(cls, "updateElementName", updateElementName)
  1975     setattr(cls, "updateElementName", updateElementName)
  2237 
  1980 
  2238     def Search(self, criteria, parent_infos=[]):
  1981     def Search(self, criteria, parent_infos=[]):
  2239         return self.content.Search(criteria, parent_infos + ["comment", self.getlocalId(), "content"])
  1982         return self.content.Search(criteria, parent_infos + ["comment", self.getlocalId(), "content"])
  2240     setattr(cls, "Search", Search)
  1983     setattr(cls, "Search", Search)
  2241 
  1984 
  2242 cls = _initElementClass("block", "fbdObjects_block")
  1985 cls = _initElementClass("block", "fbdObjects")
  2243 if cls:
  1986 if cls:
  2244     def getBoundingBox(self):
  1987     def getBoundingBox(self):
  2245         bbox = _getBoundingBox(self)
  1988         bbox = _getBoundingBox(self)
  2246         for input in self.inputVariables.getvariable():
  1989         for input in self.inputVariables.getvariable():
  2247             bbox.union(_getConnectionsBoundingBox(input.connectionPointIn))
  1990             bbox.union(_getConnectionsBoundingBox(input.connectionPointIn))
  2296             for result in TestTextElement(variable.getformalParameter(), criteria):
  2039             for result in TestTextElement(variable.getformalParameter(), criteria):
  2297                 search_result.append((tuple(parent_infos + ["output", i]),) + result)
  2040                 search_result.append((tuple(parent_infos + ["output", i]),) + result)
  2298         return search_result
  2041         return search_result
  2299     setattr(cls, "Search", Search)
  2042     setattr(cls, "Search", Search)
  2300 
  2043 
  2301 cls = _initElementClass("leftPowerRail", "ldObjects_leftPowerRail")
  2044 cls = _initElementClass("leftPowerRail", "ldObjects")
  2302 if cls:
  2045 if cls:
  2303     setattr(cls, "getinfos", _getpowerrailinfosFunction("leftPowerRail"))
  2046     setattr(cls, "getinfos", _getpowerrailinfosFunction("leftPowerRail"))
  2304 
  2047 
  2305 cls = _initElementClass("rightPowerRail", "ldObjects_rightPowerRail", "multiple")
  2048 cls = _initElementClass("rightPowerRail", "ldObjects", "multiple")
  2306 if cls:
  2049 if cls:
  2307     setattr(cls, "getinfos", _getpowerrailinfosFunction("rightPowerRail"))
  2050     setattr(cls, "getinfos", _getpowerrailinfosFunction("rightPowerRail"))
  2308 
  2051 
  2309 cls = _initElementClass("contact", "ldObjects_contact", "single")
  2052 def _UpdateLDElementName(self, old_name, new_name):
       
  2053     if self.variable == old_name:
       
  2054         self.variable = new_name
       
  2055 
       
  2056 def _UpdateLDElementAddress(self, address_model, new_leading):
       
  2057     self.variable = update_address(self.variable, address_model, new_leading)
       
  2058 
       
  2059 def _getSearchInLDElement(ld_element_type):
       
  2060     def SearchInLDElement(self, criteria, parent_infos=[]):
       
  2061         return _Search([("reference", self.variable)], criteria, parent_infos + [ld_element_type, self.getlocalId()])
       
  2062     return SearchInLDElement
       
  2063 
       
  2064 cls = _initElementClass("contact", "ldObjects", "single")
  2310 if cls:
  2065 if cls:
  2311     setattr(cls, "getinfos", _getldelementinfosFunction("contact"))
  2066     setattr(cls, "getinfos", _getldelementinfosFunction("contact"))
  2312     
  2067     setattr(cls, "updateElementName", _UpdateLDElementName)
  2313     def updateElementName(self, old_name, new_name):
  2068     setattr(cls, "updateElementAddress", _UpdateLDElementAddress)
  2314         if self.variable == old_name:
  2069     setattr(cls, "Search", _getSearchInLDElement("contact"))
  2315             self.variable = new_name
  2070 
  2316     setattr(cls, "updateElementName", updateElementName)
  2071 cls = _initElementClass("coil", "ldObjects", "single")
  2317     
       
  2318     def updateElementAddress(self, address_model, new_leading):
       
  2319         self.variable = update_address(self.variable, address_model, new_leading)
       
  2320     setattr(cls, "updateElementAddress", updateElementAddress)
       
  2321     
       
  2322     def Search(self, criteria, parent_infos=[]):
       
  2323         return _Search([("reference", self.getvariable())], criteria, parent_infos + ["contact", self.getlocalId()])
       
  2324     setattr(cls, "Search", Search)
       
  2325 
       
  2326 cls = _initElementClass("coil", "ldObjects_coil", "single")
       
  2327 if cls:
  2072 if cls:
  2328     setattr(cls, "getinfos", _getldelementinfosFunction("coil"))
  2073     setattr(cls, "getinfos", _getldelementinfosFunction("coil"))
  2329     
  2074     setattr(cls, "updateElementName", _UpdateLDElementName)
  2330     def updateElementName(self, old_name, new_name):
  2075     setattr(cls, "updateElementAddress", _UpdateLDElementAddress)
  2331         if self.variable == old_name:
  2076     setattr(cls, "Search", _getSearchInLDElement("coil"))
  2332             self.variable = new_name
  2077 
  2333     setattr(cls, "updateElementName", updateElementName)
  2078 cls = _initElementClass("step", "sfcObjects", "single")
  2334 
       
  2335     def updateElementAddress(self, address_model, new_leading):
       
  2336         self.variable = update_address(self.variable, address_model, new_leading)
       
  2337     setattr(cls, "updateElementAddress", updateElementAddress)
       
  2338 
       
  2339     def Search(self, criteria, parent_infos=[]):
       
  2340         return _Search([("reference", self.getvariable())], criteria, parent_infos + ["coil", self.getlocalId()])
       
  2341     setattr(cls, "Search", Search)
       
  2342 
       
  2343 cls = _initElementClass("step", "sfcObjects_step", "single")
       
  2344 if cls:
  2079 if cls:
  2345     def getinfos(self):
  2080     def getinfos(self):
  2346         infos = _getelementinfos(self)
  2081         infos = _getelementinfos(self)
  2347         infos["type"] = "step"
  2082         infos["type"] = "step"
  2348         specific_values = infos["specific_values"]
  2083         specific_values = infos["specific_values"]
  2349         specific_values["name"] = self.getname()
  2084         specific_values["name"] = self.getname()
  2350         specific_values["initial"] = self.getinitialStep()
  2085         specific_values["initial"] = self.getinitialStep()
  2351         if self.connectionPointIn:
  2086         if self.connectionPointIn is not None:
  2352             infos["inputs"].append(_getconnectioninfos(self, self.connectionPointIn, True))
  2087             infos["inputs"].append(_getconnectioninfos(self, self.connectionPointIn, True))
  2353         if self.connectionPointOut:
  2088         if self.connectionPointOut is not None:
  2354             infos["outputs"].append(_getconnectioninfos(self, self.connectionPointOut))
  2089             infos["outputs"].append(_getconnectioninfos(self, self.connectionPointOut))
  2355         if self.connectionPointOutAction:
  2090         if self.connectionPointOutAction is not None:
  2356             specific_values["action"] = _getconnectioninfos(self, self.connectionPointOutAction)
  2091             specific_values["action"] = _getconnectioninfos(self, self.connectionPointOutAction)
  2357         return infos
  2092         return infos
  2358     setattr(cls, "getinfos", getinfos)
  2093     setattr(cls, "getinfos", getinfos)
  2359 
  2094 
  2360     def Search(self, criteria, parent_infos=[]):
  2095     def Search(self, criteria, parent_infos=[]):
  2361         return _Search([("name", self.getname())], criteria, parent_infos + ["step", self.getlocalId()])
  2096         return _Search([("name", self.getname())], criteria, parent_infos + ["step", self.getlocalId()])
  2362     setattr(cls, "Search", Search)
  2097     setattr(cls, "Search", Search)
  2363 
  2098 
  2364 cls = PLCOpenClasses.get("transition_condition", None)
  2099 cls = PLCOpenParser.GetElementClass("condition", "transition")
  2365 if cls:
  2100 if cls:
  2366     def compatibility(self, tree):
  2101     def compatibility(self, tree):
  2367         connections = []
  2102         connections = []
  2368         for child in tree.childNodes:
  2103         for child in tree.childNodes:
  2369             if child.nodeName == "connection":
  2104             if child.nodeName == "connection":
  2376             node.childNodes.append(relPosition)
  2111             node.childNodes.append(relPosition)
  2377             node.childNodes.extend(connections)
  2112             node.childNodes.extend(connections)
  2378             tree.childNodes = [node]
  2113             tree.childNodes = [node]
  2379     setattr(cls, "compatibility", compatibility)
  2114     setattr(cls, "compatibility", compatibility)
  2380 
  2115 
  2381 cls = _initElementClass("transition", "sfcObjects_transition")
  2116 cls = _initElementClass("transition", "sfcObjects")
  2382 if cls:
  2117 if cls:
  2383     def getinfos(self):
  2118     def getinfos(self):
  2384         infos = _getelementinfos(self)
  2119         infos = _getelementinfos(self)
  2385         infos["type"] = "transition"
  2120         infos["type"] = "transition"
  2386         specific_values = infos["specific_values"]
  2121         specific_values = infos["specific_values"]
  2397         infos["inputs"].append(_getconnectioninfos(self, self.connectionPointIn, True))
  2132         infos["inputs"].append(_getconnectioninfos(self, self.connectionPointIn, True))
  2398         infos["outputs"].append(_getconnectioninfos(self, self.connectionPointOut))
  2133         infos["outputs"].append(_getconnectioninfos(self, self.connectionPointOut))
  2399         return infos
  2134         return infos
  2400     setattr(cls, "getinfos", getinfos)
  2135     setattr(cls, "getinfos", getinfos)
  2401 
  2136 
  2402     def setconditionContent(self, type, value):
  2137     def setconditionContent(self, condition_type, value):
  2403         if not self.condition:
  2138         if self.condition is None:
  2404             self.addcondition()
  2139             self.addcondition()
  2405         if type == "reference":
  2140         if condition_type == "connection":
  2406             condition = PLCOpenClasses["condition_reference"]()
  2141             condition = PLCOpenParser.CreateElement("connectionPointIn", "condition")
       
  2142         else:
       
  2143             condition = PLCOpenParser.CreateElement(condition_type, "condition")
       
  2144         self.condition.setcontent(condition)
       
  2145         if condition_type == "reference":
  2407             condition.setname(value)
  2146             condition.setname(value)
  2408         elif type == "inline":
  2147         elif condition_type == "inline":
  2409             condition = PLCOpenClasses["condition_inline"]()
  2148             condition.setcontent(PLCOpenParser.CreateElement("ST", "inline"))
  2410             condition.setcontent({"name" : "ST", "value" : PLCOpenClasses["formattedText"]()})
       
  2411             condition.settext(value)
  2149             condition.settext(value)
  2412         elif type == "connection":
       
  2413             type = "connectionPointIn"
       
  2414             condition = PLCOpenClasses["connectionPointIn"]()
       
  2415         self.condition.setcontent({"name" : type, "value" : condition})
       
  2416     setattr(cls, "setconditionContent", setconditionContent)
  2150     setattr(cls, "setconditionContent", setconditionContent)
  2417         
  2151         
  2418     def getconditionContent(self):
  2152     def getconditionContent(self):
  2419         if self.condition:
  2153         if self.condition is not None:
  2420             content = self.condition.getcontent()
  2154             content = self.condition.getcontent()
  2421             values = {"type" : content["name"]}
  2155             values = {"type" : content.getLocalTag()}
  2422             if values["type"] == "reference":
  2156             if values["type"] == "reference":
  2423                 values["value"] = content["value"].getname()
  2157                 values["value"] = content.getname()
  2424             elif values["type"] == "inline":
  2158             elif values["type"] == "inline":
  2425                 values["value"] = content["value"].gettext()
  2159                 values["value"] = content.gettext()
  2426             elif values["type"] == "connectionPointIn":
  2160             elif values["type"] == "connectionPointIn":
  2427                 values["type"] = "connection"
  2161                 values["type"] = "connection"
  2428                 values["value"] = content["value"]
  2162                 values["value"] = content
  2429             return values
  2163             return values
  2430         return ""
  2164         return ""
  2431     setattr(cls, "getconditionContent", getconditionContent)
  2165     setattr(cls, "getconditionContent", getconditionContent)
  2432 
  2166 
  2433     def getconditionConnection(self):
  2167     def getconditionConnection(self):
  2434         if self.condition:
  2168         if self.condition is not None:
  2435             content = self.condition.getcontent()
  2169             content = self.condition.getcontent()
  2436             if content["name"] == "connectionPointIn":
  2170             if content.getLocalTag() == "connectionPointIn":
  2437                 return content["value"]
  2171                 return content
  2438         return None
  2172         return None
  2439     setattr(cls, "getconditionConnection", getconditionConnection)
  2173     setattr(cls, "getconditionConnection", getconditionConnection)
  2440 
  2174 
  2441     def getBoundingBox(self):
  2175     def getBoundingBox(self):
  2442         bbox = _getBoundingBoxSingle(self)
  2176         bbox = _getBoundingBoxSingle(self)
  2443         condition_connection = self.getconditionConnection()
  2177         condition_connection = self.getconditionConnection()
  2444         if condition_connection:
  2178         if condition_connection is not None:
  2445             bbox.union(_getConnectionsBoundingBox(condition_connection))
  2179             bbox.union(_getConnectionsBoundingBox(condition_connection))
  2446         return bbox
  2180         return bbox
  2447     setattr(cls, "getBoundingBox", getBoundingBox)
  2181     setattr(cls, "getBoundingBox", getBoundingBox)
  2448     
  2182     
  2449     def translate(self, dx, dy):
  2183     def translate(self, dx, dy):
  2450         _translateSingle(self, dx, dy)
  2184         _translateSingle(self, dx, dy)
  2451         condition_connection = self.getconditionConnection()
  2185         condition_connection = self.getconditionConnection()
  2452         if condition_connection:
  2186         if condition_connection is not None:
  2453             _translateConnections(condition_connection, dx, dy)
  2187             _translateConnections(condition_connection, dx, dy)
  2454     setattr(cls, "translate", translate)
  2188     setattr(cls, "translate", translate)
  2455     
  2189     
  2456     def filterConnections(self, connections):
  2190     def filterConnections(self, connections):
  2457         _filterConnectionsSingle(self, connections)
  2191         _filterConnectionsSingle(self, connections)
  2458         condition_connection = self.getconditionConnection()
  2192         condition_connection = self.getconditionConnection()
  2459         if condition_connection:
  2193         if condition_connection is not None:
  2460             _filterConnections(condition_connection, self.localId, connections)
  2194             _filterConnections(condition_connection, self.localId, connections)
  2461     setattr(cls, "filterConnections", filterConnections)
  2195     setattr(cls, "filterConnections", filterConnections)
  2462     
  2196     
  2463     def updateConnectionsId(self, translation):
  2197     def updateConnectionsId(self, translation):
  2464         connections_end = []
  2198         connections_end = []
  2465         if self.connectionPointIn is not None:
  2199         if self.connectionPointIn is not None:
  2466             connections_end = _updateConnectionsId(self.connectionPointIn, translation)
  2200             connections_end = _updateConnectionsId(self.connectionPointIn, translation)
  2467         condition_connection = self.getconditionConnection()
  2201         condition_connection = self.getconditionConnection()
  2468         if condition_connection:
  2202         if condition_connection is not None:
  2469             connections_end.extend(_updateConnectionsId(condition_connection, translation))
  2203             connections_end.extend(_updateConnectionsId(condition_connection, translation))
  2470         return _getconnectionsdefinition(self, connections_end)
  2204         return _getconnectionsdefinition(self, connections_end)
  2471     setattr(cls, "updateConnectionsId", updateConnectionsId)
  2205     setattr(cls, "updateConnectionsId", updateConnectionsId)
  2472 
  2206 
  2473     def updateElementName(self, old_name, new_name):
  2207     def updateElementName(self, old_name, new_name):
  2474         if self.condition:
  2208         if self.condition is not None:
  2475             content = self.condition.getcontent()
  2209             content = self.condition.getcontent()
  2476             if content["name"] == "reference":
  2210             content_name = content.getLocalTag()
  2477                 if content["value"].getname() == old_name:
  2211             if content_name == "reference":
  2478                     content["value"].setname(new_name)
  2212                 if content.getname() == old_name:
  2479             elif content["name"] == "inline":
  2213                     content.setname(new_name)
  2480                 content["value"].updateElementName(old_name, new_name)
  2214             elif content_name == "inline":
       
  2215                 content.updateElementName(old_name, new_name)
  2481     setattr(cls, "updateElementName", updateElementName)
  2216     setattr(cls, "updateElementName", updateElementName)
  2482 
  2217 
  2483     def updateElementAddress(self, address_model, new_leading):
  2218     def updateElementAddress(self, address_model, new_leading):
  2484         if self.condition:
  2219         if self.condition is not None:
  2485             content = self.condition.getcontent()
  2220             content = self.condition.getcontent()
  2486             if content["name"] == "reference":
  2221             content_name = content.getLocalTag()
  2487                 content["value"].setname(update_address(content["value"].getname(), address_model, new_leading))
  2222             if content_name == "reference":
  2488             elif content["name"] == "inline":
  2223                 content.setname(update_address(content.getname(), address_model, new_leading))
  2489                 content["value"].updateElementAddress(address_model, new_leading)
  2224             elif content_name == "inline":
       
  2225                 content.updateElementAddress(address_model, new_leading)
  2490     setattr(cls, "updateElementAddress", updateElementAddress)
  2226     setattr(cls, "updateElementAddress", updateElementAddress)
  2491 
  2227 
  2492     def getconnections(self):
  2228     def getconnections(self):
  2493         condition_connection = self.getconditionConnection()
  2229         condition_connection = self.getconditionConnection()
  2494         if condition_connection:
  2230         if condition_connection is not None:
  2495             return condition_connection.getconnections()
  2231             return condition_connection.getconnections()
  2496         return None
  2232         return None
  2497     setattr(cls, "getconnections", getconnections)
  2233     setattr(cls, "getconnections", getconnections)
  2498     
  2234     
  2499     def Search(self, criteria, parent_infos=[]):
  2235     def Search(self, criteria, parent_infos=[]):
  2500         parent_infos = parent_infos + ["transition", self.getlocalId()]
  2236         parent_infos = parent_infos + ["transition", self.getlocalId()]
  2501         search_result = []
  2237         search_result = []
  2502         content = self.condition.getcontent()
  2238         content = self.condition.getcontent()
  2503         if content["name"] == "reference":
  2239         content_name = content.getLocalTag()
  2504             search_result.extend(_Search([("reference", content["value"].getname())], criteria, parent_infos))
  2240         if content_name == "reference":
  2505         elif content["name"] == "inline":
  2241             search_result.extend(_Search([("reference", content.getname())], criteria, parent_infos))
  2506             search_result.extend(content["value"].Search(criteria, parent_infos + ["inline"]))
  2242         elif content_name == "inline":
       
  2243             search_result.extend(content.Search(criteria, parent_infos + ["inline"]))
  2507         return search_result
  2244         return search_result
  2508     setattr(cls, "Search", Search)
  2245     setattr(cls, "Search", Search)
  2509     
  2246     
  2510 cls = _initElementClass("selectionDivergence", "sfcObjects_selectionDivergence", "single")
  2247 cls = _initElementClass("selectionDivergence", "sfcObjects", "single")
  2511 if cls:
  2248 if cls:
  2512     setattr(cls, "getinfos", _getdivergenceinfosFunction(True, False))
  2249     setattr(cls, "getinfos", _getdivergenceinfosFunction(True, False))
  2513 
  2250 
  2514 cls = _initElementClass("selectionConvergence", "sfcObjects_selectionConvergence", "multiple")
  2251 cls = _initElementClass("selectionConvergence", "sfcObjects", "multiple")
  2515 if cls:
  2252 if cls:
  2516     setattr(cls, "getinfos", _getdivergenceinfosFunction(False, False))
  2253     setattr(cls, "getinfos", _getdivergenceinfosFunction(False, False))
  2517 
  2254 
  2518 cls = _initElementClass("simultaneousDivergence", "sfcObjects_simultaneousDivergence", "single")
  2255 cls = _initElementClass("simultaneousDivergence", "sfcObjects", "single")
  2519 if cls:
  2256 if cls:
  2520     setattr(cls, "getinfos", _getdivergenceinfosFunction(True, True))
  2257     setattr(cls, "getinfos", _getdivergenceinfosFunction(True, True))
  2521 
  2258 
  2522 cls = _initElementClass("simultaneousConvergence", "sfcObjects_simultaneousConvergence", "multiple")
  2259 cls = _initElementClass("simultaneousConvergence", "sfcObjects", "multiple")
  2523 if cls:
  2260 if cls:
  2524     setattr(cls, "getinfos", _getdivergenceinfosFunction(False, True))
  2261     setattr(cls, "getinfos", _getdivergenceinfosFunction(False, True))
  2525 
  2262 
  2526 cls = _initElementClass("jumpStep", "sfcObjects_jumpStep", "single")
  2263 cls = _initElementClass("jumpStep", "sfcObjects", "single")
  2527 if cls:
  2264 if cls:
  2528     def getinfos(self):
  2265     def getinfos(self):
  2529         infos = _getelementinfos(self)
  2266         infos = _getelementinfos(self)
  2530         infos["type"] = "jump"
  2267         infos["type"] = "jump"
  2531         infos["specific_values"]["target"] = self.gettargetName()
  2268         infos["specific_values"]["target"] = self.gettargetName()
  2535 
  2272 
  2536     def Search(self, criteria, parent_infos):
  2273     def Search(self, criteria, parent_infos):
  2537         return _Search([("target", self.gettargetName())], criteria, parent_infos + ["jump", self.getlocalId()])
  2274         return _Search([("target", self.gettargetName())], criteria, parent_infos + ["jump", self.getlocalId()])
  2538     setattr(cls, "Search", Search)
  2275     setattr(cls, "Search", Search)
  2539 
  2276 
  2540 cls = PLCOpenClasses.get("actionBlock_action", None)
  2277 cls = PLCOpenParser.GetElementClass("action", "actionBlock")
  2541 if cls:
  2278 if cls:
  2542     def compatibility(self, tree):
  2279     def compatibility(self, tree):
  2543         relPosition = reduce(lambda x, y: x | (y.nodeName == "relPosition"), tree.childNodes, False)
  2280         relPosition = reduce(lambda x, y: x | (y.nodeName == "relPosition"), tree.childNodes, False)
  2544         if not tree.hasAttribute("localId"):
  2281         if not tree.hasAttribute("localId"):
  2545             NodeSetAttr(tree, "localId", "0")
  2282             NodeSetAttr(tree, "localId", "0")
  2549             NodeSetAttr(node, "y", "0")
  2286             NodeSetAttr(node, "y", "0")
  2550             tree.childNodes.insert(0, node)
  2287             tree.childNodes.insert(0, node)
  2551     setattr(cls, "compatibility", compatibility)
  2288     setattr(cls, "compatibility", compatibility)
  2552     
  2289     
  2553     def setreferenceName(self, name):
  2290     def setreferenceName(self, name):
  2554         if self.reference:
  2291         if self.reference is not None:
  2555             self.reference.setname(name)
  2292             self.reference.setname(name)
  2556     setattr(cls, "setreferenceName", setreferenceName)
  2293     setattr(cls, "setreferenceName", setreferenceName)
  2557     
  2294     
  2558     def getreferenceName(self):
  2295     def getreferenceName(self):
  2559         if self.reference:
  2296         if self.reference is not None:
  2560             return self.reference.getname()
  2297             return self.reference.getname()
  2561         return None
  2298         return None
  2562     setattr(cls, "getreferenceName", getreferenceName)
  2299     setattr(cls, "getreferenceName", getreferenceName)
  2563 
  2300 
  2564     def setinlineContent(self, content):
  2301     def setinlineContent(self, content):
  2565         if self.inline:
  2302         if self.inline is not None:
  2566             self.inline.setcontent({"name" : "ST", "value" : PLCOpenClasses["formattedText"]()})
  2303             self.inline.setcontent(PLCOpenParser.CreateElement("ST", "inline"))
  2567             self.inline.settext(content)
  2304             self.inline.settext(content)
  2568     setattr(cls, "setinlineContent", setinlineContent)
  2305     setattr(cls, "setinlineContent", setinlineContent)
  2569     
  2306     
  2570     def getinlineContent(self):
  2307     def getinlineContent(self):
  2571         if self.inline:
  2308         if self.inline is not None:
  2572             return self.inline.gettext()
  2309             return self.inline.gettext()
  2573         return None
  2310         return None
  2574     setattr(cls, "getinlineContent", getinlineContent)
  2311     setattr(cls, "getinlineContent", getinlineContent)
  2575 
  2312 
  2576     def updateElementName(self, old_name, new_name):
  2313     def updateElementName(self, old_name, new_name):
  2577         if self.reference and self.reference.getname() == old_name:
  2314         if self.reference is not None and self.reference.getname() == old_name:
  2578             self.reference.setname(new_name)
  2315             self.reference.setname(new_name)
  2579         if self.inline:
  2316         if self.inline is not None:
  2580             self.inline.updateElementName(old_name, new_name)
  2317             self.inline.updateElementName(old_name, new_name)
  2581     setattr(cls, "updateElementName", updateElementName)
  2318     setattr(cls, "updateElementName", updateElementName)
  2582 
  2319 
  2583     def updateElementAddress(self, address_model, new_leading):
  2320     def updateElementAddress(self, address_model, new_leading):
  2584         if self.reference:
  2321         if self.reference is not None:
  2585             self.reference.setname(update_address(self.reference.getname(), address_model, new_leading))
  2322             self.reference.setname(update_address(self.reference.getname(), address_model, new_leading))
  2586         if self.inline:
  2323         if self.inline is not None:
  2587             self.inline.updateElementAddress(address_model, new_leading)
  2324             self.inline.updateElementAddress(address_model, new_leading)
  2588     setattr(cls, "updateElementAddress", updateElementAddress)
  2325     setattr(cls, "updateElementAddress", updateElementAddress)
  2589 
  2326 
  2590     def Search(self, criteria, parent_infos=[]):
  2327     def Search(self, criteria, parent_infos=[]):
  2591         qualifier = self.getqualifier()
  2328         qualifier = self.getqualifier()
  2597                         ("duration", self.getduration()),
  2334                         ("duration", self.getduration()),
  2598                         ("indicator", self.getindicator())],
  2335                         ("indicator", self.getindicator())],
  2599                        criteria, parent_infos)
  2336                        criteria, parent_infos)
  2600     setattr(cls, "Search", Search)
  2337     setattr(cls, "Search", Search)
  2601 
  2338 
  2602 cls = _initElementClass("actionBlock", "commonObjects_actionBlock", "single")
  2339 cls = _initElementClass("actionBlock", "commonObjects", "single")
  2603 if cls:
  2340 if cls:
  2604     def compatibility(self, tree):
  2341     def compatibility(self, tree):
  2605         for child in tree.childNodes[:]:
  2342         for child in tree.childNodes[:]:
  2606             if child.nodeName == "connectionPointOut":
  2343             if child.nodeName == "connectionPointOut":
  2607                 tree.childNodes.remove(child)
  2344                 tree.childNodes.remove(child)
  2616     setattr(cls, "getinfos", getinfos)
  2353     setattr(cls, "getinfos", getinfos)
  2617     
  2354     
  2618     def setactions(self, actions):
  2355     def setactions(self, actions):
  2619         self.action = []
  2356         self.action = []
  2620         for params in actions:
  2357         for params in actions:
  2621             action = PLCOpenClasses["actionBlock_action"]()
  2358             action = PLCOpenParser.CreateElement("action", "actionBlock")
       
  2359             self.appendaction(action)
  2622             action.setqualifier(params["qualifier"])
  2360             action.setqualifier(params["qualifier"])
  2623             if params["type"] == "reference":
  2361             if params["type"] == "reference":
  2624                 action.addreference()
  2362                 action.addreference()
  2625                 action.setreferenceName(params["value"])
  2363                 action.setreferenceName(params["value"])
  2626             else:
  2364             else:
  2628                 action.setinlineContent(params["value"])
  2366                 action.setinlineContent(params["value"])
  2629             if params.has_key("duration"):
  2367             if params.has_key("duration"):
  2630                 action.setduration(params["duration"])
  2368                 action.setduration(params["duration"])
  2631             if params.has_key("indicator"):
  2369             if params.has_key("indicator"):
  2632                 action.setindicator(params["indicator"])
  2370                 action.setindicator(params["indicator"])
  2633             self.action.append(action)
       
  2634     setattr(cls, "setactions", setactions)
  2371     setattr(cls, "setactions", setactions)
  2635 
  2372 
  2636     def getactions(self):
  2373     def getactions(self):
  2637         actions = []
  2374         actions = []
  2638         for action in self.action:
  2375         for action in self.action:
  2639             params = {}
  2376             params = {}
  2640             params["qualifier"] = action.getqualifier()
  2377             params["qualifier"] = action.getqualifier()
  2641             if params["qualifier"] is None:
  2378             if params["qualifier"] is None:
  2642                 params["qualifier"] = "N"
  2379                 params["qualifier"] = "N"
  2643             if action.getreference():
  2380             if action.getreference() is not None:
  2644                 params["type"] = "reference"
  2381                 params["type"] = "reference"
  2645                 params["value"] = action.getreferenceName()
  2382                 params["value"] = action.getreferenceName()
  2646             elif action.getinline():
  2383             elif action.getinline() is not None:
  2647                 params["type"] = "inline"
  2384                 params["type"] = "inline"
  2648                 params["value"] = action.getinlineContent()
  2385                 params["value"] = action.getinlineContent()
  2649             duration = action.getduration()
  2386             duration = action.getduration()
  2650             if duration:
  2387             if duration:
  2651                 params["duration"] = duration
  2388                 params["duration"] = duration
  2652             indicator = action.getindicator()
  2389             indicator = action.getindicator()
  2653             if indicator:
  2390             if indicator is not None:
  2654                 params["indicator"] = indicator
  2391                 params["indicator"] = indicator
  2655             actions.append(params)
  2392             actions.append(params)
  2656         return actions
  2393         return actions
  2657     setattr(cls, "getactions", getactions)
  2394     setattr(cls, "getactions", getactions)
  2658 
  2395 
  2673             search_result.extend(action.Search(criteria, parent_infos + ["action", idx]))
  2410             search_result.extend(action.Search(criteria, parent_infos + ["action", idx]))
  2674         return search_result
  2411         return search_result
  2675     setattr(cls, "Search", Search)
  2412     setattr(cls, "Search", Search)
  2676 
  2413 
  2677 def _SearchInIOVariable(self, criteria, parent_infos=[]):
  2414 def _SearchInIOVariable(self, criteria, parent_infos=[]):
  2678     return _Search([("expression", self.getexpression())], criteria, parent_infos + ["io_variable", self.getlocalId()])
  2415     return _Search([("expression", self.expression)], criteria, parent_infos + ["io_variable", self.getlocalId()])
  2679 
  2416 
  2680 cls = _initElementClass("inVariable", "fbdObjects_inVariable")
  2417 def _UpdateIOElementName(self, old_name, new_name):
       
  2418     if self.expression == old_name:
       
  2419         self.expression = new_name
       
  2420 
       
  2421 def _UpdateIOElementAddress(self, old_name, new_name):
       
  2422     self.expression = update_address(self.expression, address_model, new_leading)
       
  2423 
       
  2424 cls = _initElementClass("inVariable", "fbdObjects")
  2681 if cls:
  2425 if cls:
  2682     setattr(cls, "getinfos", _getvariableinfosFunction("input", False, True))
  2426     setattr(cls, "getinfos", _getvariableinfosFunction("input", False, True))
  2683     
  2427     setattr(cls, "updateElementName", _UpdateIOElementName)
  2684     def updateElementName(self, old_name, new_name):
  2428     setattr(cls, "updateElementAddress", _UpdateIOElementAddress)
  2685         if self.expression == old_name:
       
  2686             self.expression = new_name
       
  2687     setattr(cls, "updateElementName", updateElementName)
       
  2688 
       
  2689     def updateElementAddress(self, address_model, new_leading):
       
  2690         self.expression = update_address(self.expression, address_model, new_leading)
       
  2691     setattr(cls, "updateElementAddress", updateElementAddress)
       
  2692 
       
  2693     setattr(cls, "Search", _SearchInIOVariable)
  2429     setattr(cls, "Search", _SearchInIOVariable)
  2694 
  2430 
  2695 cls = _initElementClass("outVariable", "fbdObjects_outVariable", "single")
  2431 cls = _initElementClass("outVariable", "fbdObjects", "single")
  2696 if cls:
  2432 if cls:
  2697     setattr(cls, "getinfos", _getvariableinfosFunction("output", True, False))
  2433     setattr(cls, "getinfos", _getvariableinfosFunction("output", True, False))
  2698     
  2434     setattr(cls, "updateElementName", _UpdateIOElementName)
  2699     def updateElementName(self, old_name, new_name):
  2435     setattr(cls, "updateElementAddress", _UpdateIOElementAddress)
  2700         if self.expression == old_name:
       
  2701             self.expression = new_name
       
  2702     setattr(cls, "updateElementName", updateElementName)
       
  2703 
       
  2704     def updateElementAddress(self, address_model, new_leading):
       
  2705         self.expression = update_address(self.expression, address_model, new_leading)
       
  2706     setattr(cls, "updateElementAddress", updateElementAddress)
       
  2707 
       
  2708     setattr(cls, "Search", _SearchInIOVariable)
  2436     setattr(cls, "Search", _SearchInIOVariable)
  2709 
  2437 
  2710 cls = _initElementClass("inOutVariable", "fbdObjects_inOutVariable", "single")
  2438 cls = _initElementClass("inOutVariable", "fbdObjects", "single")
  2711 if cls:
  2439 if cls:
  2712     setattr(cls, "getinfos", _getvariableinfosFunction("inout", True, True))
  2440     setattr(cls, "getinfos", _getvariableinfosFunction("inout", True, True))
  2713     
  2441     setattr(cls, "updateElementName", _UpdateIOElementName)
  2714     def updateElementName(self, old_name, new_name):
  2442     setattr(cls, "updateElementAddress", _UpdateIOElementAddress)
  2715         if self.expression == old_name:
       
  2716             self.expression = new_name
       
  2717     setattr(cls, "updateElementName", updateElementName)
       
  2718 
       
  2719     def updateElementAddress(self, address_model, new_leading):
       
  2720         self.expression = update_address(self.expression, address_model, new_leading)
       
  2721     setattr(cls, "updateElementAddress", updateElementAddress)
       
  2722 
       
  2723     setattr(cls, "Search", _SearchInIOVariable)
  2443     setattr(cls, "Search", _SearchInIOVariable)
  2724 
  2444 
  2725 
  2445 
  2726 def _SearchInConnector(self, criteria, parent_infos=[]):
  2446 def _SearchInConnector(self, criteria, parent_infos=[]):
  2727     return _Search([("name", self.getname())], criteria, parent_infos + ["connector", self.getlocalId()])
  2447     return _Search([("name", self.getname())], criteria, parent_infos + ["connector", self.getlocalId()])
  2728 
  2448 
  2729 cls = _initElementClass("continuation", "commonObjects_continuation")
  2449 cls = _initElementClass("continuation", "commonObjects")
  2730 if cls:
  2450 if cls:
  2731     setattr(cls, "getinfos", _getconnectorinfosFunction("continuation"))
  2451     setattr(cls, "getinfos", _getconnectorinfosFunction("continuation"))
  2732     setattr(cls, "Search", _SearchInConnector)
  2452     setattr(cls, "Search", _SearchInConnector)
  2733 
  2453 
  2734     def updateElementName(self, old_name, new_name):
  2454     def updateElementName(self, old_name, new_name):
  2735         if self.name == old_name:
  2455         if self.name == old_name:
  2736             self.name = new_name
  2456             self.name = new_name
  2737     setattr(cls, "updateElementName", updateElementName)
  2457     setattr(cls, "updateElementName", updateElementName)
  2738 
  2458 
  2739 cls = _initElementClass("connector", "commonObjects_connector", "single")
  2459 cls = _initElementClass("connector", "commonObjects", "single")
  2740 if cls:
  2460 if cls:
  2741     setattr(cls, "getinfos", _getconnectorinfosFunction("connector"))
  2461     setattr(cls, "getinfos", _getconnectorinfosFunction("connector"))
  2742     setattr(cls, "Search", _SearchInConnector)
  2462     setattr(cls, "Search", _SearchInConnector)
  2743 
  2463 
  2744     def updateElementName(self, old_name, new_name):
  2464     def updateElementName(self, old_name, new_name):
  2745         if self.name == old_name:
  2465         if self.name == old_name:
  2746             self.name = new_name
  2466             self.name = new_name
  2747     setattr(cls, "updateElementName", updateElementName)
  2467     setattr(cls, "updateElementName", updateElementName)
  2748 
  2468 
  2749 cls = PLCOpenClasses.get("connection", None)
  2469 cls = PLCOpenParser.GetElementClass("connection")
  2750 if cls:
  2470 if cls:
  2751     def setpoints(self, points):
  2471     def setpoints(self, points):
  2752         self.position = []
  2472         positions = []
  2753         for point in points:
  2473         for point in points:
  2754             position = PLCOpenClasses["position"]()
  2474             position = PLCOpenParser.CreateElement("position", "connection")
  2755             position.setx(point.x)
  2475             position.setx(point.x)
  2756             position.sety(point.y)
  2476             position.sety(point.y)
  2757             self.position.append(position)
  2477             positions.append(position)
       
  2478         self.position = positions
  2758     setattr(cls, "setpoints", setpoints)
  2479     setattr(cls, "setpoints", setpoints)
  2759 
  2480 
  2760     def getpoints(self):
  2481     def getpoints(self):
  2761         points = []
  2482         points = []
  2762         for position in self.position:
  2483         for position in self.position:
  2763             points.append((position.getx(),position.gety()))
  2484             points.append((position.getx(),position.gety()))
  2764         return points
  2485         return points
  2765     setattr(cls, "getpoints", getpoints)
  2486     setattr(cls, "getpoints", getpoints)
  2766 
  2487 
  2767 cls = PLCOpenClasses.get("connectionPointIn", None)
  2488 cls = PLCOpenParser.GetElementClass("connectionPointIn")
  2768 if cls:
  2489 if cls:
  2769     def setrelPositionXY(self, x, y):
  2490     def setrelPositionXY(self, x, y):
  2770         self.relPosition = PLCOpenClasses["position"]()
  2491         self.relPosition = PLCOpenParser.CreateElement("relPosition", "connectionPointIn")
  2771         self.relPosition.setx(x)
  2492         self.relPosition.setx(x)
  2772         self.relPosition.sety(y)
  2493         self.relPosition.sety(y)
  2773     setattr(cls, "setrelPositionXY", setrelPositionXY)
  2494     setattr(cls, "setrelPositionXY", setrelPositionXY)
  2774 
  2495 
  2775     def getrelPositionXY(self):
  2496     def getrelPositionXY(self):
  2776         if self.relPosition:
  2497         if self.relPosition is not None:
  2777             return self.relPosition.getx(), self.relPosition.gety()
  2498             return self.relPosition.getx(), self.relPosition.gety()
  2778         else:
  2499         return self.relPosition
  2779             return self.relPosition
       
  2780     setattr(cls, "getrelPositionXY", getrelPositionXY)
  2500     setattr(cls, "getrelPositionXY", getrelPositionXY)
  2781 
  2501 
  2782     def addconnection(self):
  2502     def addconnection(self):
  2783         if not self.content:
  2503         self.append(PLCOpenParser.CreateElement("connection", "connectionPointIn"))
  2784             self.content = {"name" : "connection", "value" : [PLCOpenClasses["connection"]()]}
       
  2785         else:
       
  2786             self.content["value"].append(PLCOpenClasses["connection"]())
       
  2787     setattr(cls, "addconnection", addconnection)
  2504     setattr(cls, "addconnection", addconnection)
  2788 
  2505 
  2789     def removeconnection(self, idx):
  2506     def removeconnection(self, idx):
  2790         if self.content:
  2507         if len(self.content) > idx:
  2791             self.content["value"].pop(idx)
  2508             self.remove(self.content[idx])
  2792         if len(self.content["value"]) == 0:
       
  2793             self.content = None
       
  2794     setattr(cls, "removeconnection", removeconnection)
  2509     setattr(cls, "removeconnection", removeconnection)
  2795 
  2510 
  2796     def removeconnections(self):
  2511     def removeconnections(self):
  2797         if self.content:
  2512         self.content = None
  2798             self.content = None
       
  2799     setattr(cls, "removeconnections", removeconnections)
  2513     setattr(cls, "removeconnections", removeconnections)
  2800     
  2514     
       
  2515     connection_xpath = PLCOpen_XPath("ppx:connection")
       
  2516     connection_by_position_xpath = PLCOpen_XPath("ppx:connection[position()=$pos]")
  2801     def getconnections(self):
  2517     def getconnections(self):
  2802         if self.content:
  2518         return connection_xpath(self)
  2803             return self.content["value"]
       
  2804         return []
       
  2805     setattr(cls, "getconnections", getconnections)
  2519     setattr(cls, "getconnections", getconnections)
  2806     
  2520     
  2807     def setconnectionId(self, idx, id):
  2521     def getconnection(self, idx):
  2808         if self.content:
  2522         connection = connection_by_position_xpath(self, pos=idx+1)
  2809             self.content["value"][idx].setrefLocalId(id)
  2523         if len(connection) > 0:
       
  2524             return connection[0]
       
  2525         return None
       
  2526     setattr(cls, "getconnection", getconnection)
       
  2527     
       
  2528     def setconnectionId(self, idx, local_id):
       
  2529         connection = self.getconnection(idx)
       
  2530         if connection is not None:
       
  2531             connection.setrefLocalId(local_id)
  2810     setattr(cls, "setconnectionId", setconnectionId)
  2532     setattr(cls, "setconnectionId", setconnectionId)
  2811     
  2533     
  2812     def getconnectionId(self, idx):
  2534     def getconnectionId(self, idx):
  2813         if self.content:
  2535         connection = self.getconnection(idx)
  2814             return self.content["value"][idx].getrefLocalId()
  2536         if connection is not None:
       
  2537             return connection.getrefLocalId()
  2815         return None
  2538         return None
  2816     setattr(cls, "getconnectionId", getconnectionId)
  2539     setattr(cls, "getconnectionId", getconnectionId)
  2817     
  2540     
  2818     def setconnectionPoints(self, idx, points):
  2541     def setconnectionPoints(self, idx, points):
  2819         if self.content:
  2542         connection = self.getconnection(idx)
  2820             self.content["value"][idx].setpoints(points)
  2543         if connection is not None:
       
  2544             connection.setpoints(points)
  2821     setattr(cls, "setconnectionPoints", setconnectionPoints)
  2545     setattr(cls, "setconnectionPoints", setconnectionPoints)
  2822 
  2546 
  2823     def getconnectionPoints(self, idx):
  2547     def getconnectionPoints(self, idx):
  2824         if self.content:
  2548         connection = self.getconnection(idx)
  2825             return self.content["value"][idx].getpoints()
  2549         if connection is not None:
       
  2550             return connection.getpoints()
  2826         return []
  2551         return []
  2827     setattr(cls, "getconnectionPoints", getconnectionPoints)
  2552     setattr(cls, "getconnectionPoints", getconnectionPoints)
  2828 
  2553 
  2829     def setconnectionParameter(self, idx, parameter):
  2554     def setconnectionParameter(self, idx, parameter):
  2830         if self.content:
  2555         connection = self.getconnection(idx)
  2831             self.content["value"][idx].setformalParameter(parameter)
  2556         if connection is not None:
       
  2557             connection.setformalParameter(parameter)
  2832     setattr(cls, "setconnectionParameter", setconnectionParameter)
  2558     setattr(cls, "setconnectionParameter", setconnectionParameter)
  2833     
  2559     
  2834     def getconnectionParameter(self, idx):
  2560     def getconnectionParameter(self, idx):
  2835         if self.content:
  2561         connection = self.getconnection(idx)
  2836             return self.content["value"][idx].getformalParameter()
  2562         if connection is not None:
       
  2563             return connection.getformalParameter()
  2837         return None
  2564         return None
  2838     setattr(cls, "getconnectionParameter", getconnectionParameter)
  2565     setattr(cls, "getconnectionParameter", getconnectionParameter)
  2839 
  2566 
  2840 cls = PLCOpenClasses.get("connectionPointOut", None)
  2567 cls = PLCOpenParser.GetElementClass("connectionPointOut")
  2841 if cls:
  2568 if cls:
  2842     def setrelPositionXY(self, x, y):
  2569     def setrelPositionXY(self, x, y):
  2843         self.relPosition = PLCOpenClasses["position"]()
  2570         self.relPosition = PLCOpenParser.CreateElement("relPosition", "connectionPointOut")
  2844         self.relPosition.setx(x)
  2571         self.relPosition.setx(x)
  2845         self.relPosition.sety(y)
  2572         self.relPosition.sety(y)
  2846     setattr(cls, "setrelPositionXY", setrelPositionXY)
  2573     setattr(cls, "setrelPositionXY", setrelPositionXY)
  2847 
  2574 
  2848     def getrelPositionXY(self):
  2575     def getrelPositionXY(self):
  2849         if self.relPosition:
  2576         if self.relPosition is not None:
  2850             return self.relPosition.getx(), self.relPosition.gety()
  2577             return self.relPosition.getx(), self.relPosition.gety()
  2851         return self.relPosition
  2578         return self.relPosition
  2852     setattr(cls, "getrelPositionXY", getrelPositionXY)
  2579     setattr(cls, "getrelPositionXY", getrelPositionXY)
  2853 
  2580 
  2854 cls = PLCOpenClasses.get("value", None)
  2581 cls = PLCOpenParser.GetElementClass("value")
  2855 if cls:
  2582 if cls:
  2856     def setvalue(self, value):
  2583     def setvalue(self, value):
  2857         value = value.strip()
  2584         value = value.strip()
  2858         if value.startswith("[") and value.endswith("]"):
  2585         if value.startswith("[") and value.endswith("]"):
  2859             arrayValue = PLCOpenClasses["value_arrayValue"]()
  2586             content = PLCOpenParser.CreateElement("arrayValue", "value")
  2860             self.content = {"name" : "arrayValue", "value" : arrayValue}
       
  2861         elif value.startswith("(") and value.endswith(")"):
  2587         elif value.startswith("(") and value.endswith(")"):
  2862             structValue = PLCOpenClasses["value_structValue"]()
  2588             content = PLCOpenParser.CreateElement("structValue", "value")
  2863             self.content = {"name" : "structValue", "value" : structValue}
       
  2864         else:
  2589         else:
  2865             simpleValue = PLCOpenClasses["value_simpleValue"]()
  2590             content = PLCOpenParser.CreateElement("simpleValue", "value")
  2866             self.content = {"name" : "simpleValue", "value": simpleValue}
  2591         content.setvalue(value)
  2867         self.content["value"].setvalue(value)
  2592         self.setcontent(content)
  2868     setattr(cls, "setvalue", setvalue)
  2593     setattr(cls, "setvalue", setvalue)
  2869     
  2594     
  2870     def getvalue(self):
  2595     def getvalue(self):
  2871         return self.content["value"].getvalue()
  2596         return self.content.getvalue()
  2872     setattr(cls, "getvalue", getvalue)
  2597     setattr(cls, "getvalue", getvalue)
  2873 
  2598 
  2874 def extractValues(values):
  2599 def extractValues(values):
  2875     items = values.split(",")
  2600     items = values.split(",")
  2876     i = 1
  2601     i = 1
  2883             i += 1
  2608             i += 1
  2884         else:
  2609         else:
  2885             raise ValueError, _("\"%s\" is an invalid value!")%value
  2610             raise ValueError, _("\"%s\" is an invalid value!")%value
  2886     return items
  2611     return items
  2887 
  2612 
  2888 cls = PLCOpenClasses.get("value_arrayValue", None)
  2613 cls = PLCOpenParser.GetElementClass("arrayValue", "value")
  2889 if cls:
  2614 if cls:
  2890     arrayValue_model = re.compile("([0-9]*)\((.*)\)$")
  2615     arrayValue_model = re.compile("([0-9]*)\((.*)\)$")
  2891     
  2616     
  2892     def setvalue(self, value):
  2617     def setvalue(self, value):
  2893         self.value = []
  2618         elements = []
  2894         for item in extractValues(value[1:-1]):
  2619         for item in extractValues(value[1:-1]):
  2895             item = item.strip()
  2620             item = item.strip()
  2896             element = PLCOpenClasses["arrayValue_value"]()
  2621             element = PLCOpenParser.CreateElement("value", "arrayValue")
  2897             result = arrayValue_model.match(item)
  2622             result = arrayValue_model.match(item)
  2898             if result is not None:
  2623             if result is not None:
  2899                 groups = result.groups()
  2624                 groups = result.groups()
  2900                 element.setrepetitionValue(groups[0])
  2625                 element.setrepetitionValue(groups[0])
  2901                 element.setvalue(groups[1].strip())
  2626                 element.setvalue(groups[1].strip())
  2902             else:
  2627             else:
  2903                 element.setvalue(item)
  2628                 element.setvalue(item)
  2904             self.value.append(element)
  2629             elements.append(element)
       
  2630         self.value = elements
  2905     setattr(cls, "setvalue", setvalue)
  2631     setattr(cls, "setvalue", setvalue)
  2906     
  2632     
  2907     def getvalue(self):
  2633     def getvalue(self):
  2908         values = []
  2634         values = []
  2909         for element in self.value:
  2635         for element in self.value:
  2910             repetition = element.getrepetitionValue()
  2636             try:
  2911             if repetition is not None and int(repetition) > 1:
  2637                 repetition = int(element.getrepetitionValue())
       
  2638             except:
       
  2639                 repetition = 1
       
  2640             if repetition > 1:
  2912                 value = element.getvalue()
  2641                 value = element.getvalue()
  2913                 if value is None:
  2642                 if value is None:
  2914                     value = ""
  2643                     value = ""
  2915                 values.append("%s(%s)"%(repetition, value))
  2644                 values.append("%s(%s)"%(repetition, value))
  2916             else:
  2645             else:
  2917                 values.append(element.getvalue())
  2646                 values.append(element.getvalue())
  2918         return "[%s]"%", ".join(values)
  2647         return "[%s]"%", ".join(values)
  2919     setattr(cls, "getvalue", getvalue)
  2648     setattr(cls, "getvalue", getvalue)
  2920 
  2649 
  2921 cls = PLCOpenClasses.get("value_structValue", None)
  2650 cls = PLCOpenParser.GetElementClass("structValue", "value")
  2922 if cls:
  2651 if cls:
  2923     structValue_model = re.compile("(.*):=(.*)")
  2652     structValue_model = re.compile("(.*):=(.*)")
  2924     
  2653     
  2925     def setvalue(self, value):
  2654     def setvalue(self, value):
  2926         self.value = []
  2655         elements = []
  2927         for item in extractValues(value[1:-1]):
  2656         for item in extractValues(value[1:-1]):
  2928             result = structValue_model.match(item)
  2657             result = structValue_model.match(item)
  2929             if result is not None:
  2658             if result is not None:
  2930                 groups = result.groups()
  2659                 groups = result.groups()
  2931                 element = PLCOpenClasses["structValue_value"]()
  2660                 element = PLCOpenParser.CreateElement("value", "structValue")
  2932                 element.setmember(groups[0].strip())
  2661                 element.setmember(groups[0].strip())
  2933                 element.setvalue(groups[1].strip())
  2662                 element.setvalue(groups[1].strip())
  2934                 self.value.append(element)
  2663                 elements.append(element)
       
  2664         self.value = elements
  2935     setattr(cls, "setvalue", setvalue)
  2665     setattr(cls, "setvalue", setvalue)
  2936     
  2666     
  2937     def getvalue(self):
  2667     def getvalue(self):
  2938         values = []
  2668         values = []
  2939         for element in self.value:
  2669         for element in self.value:
  2940             values.append("%s := %s"%(element.getmember(), element.getvalue()))
  2670             values.append("%s := %s"%(element.getmember(), element.getvalue()))
  2941         return "(%s)"%", ".join(values)
  2671         return "(%s)"%", ".join(values)
  2942     setattr(cls, "getvalue", getvalue)
  2672     setattr(cls, "getvalue", getvalue)
       
  2673