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