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