PLCControler.py
branch1.1 Korean release
changeset 1384 02fe382c4511
parent 1373 4278d5c1e414
child 1378 cbc0f64a25eb
equal deleted inserted replaced
1280:72a826dfcfbb 1384:02fe382c4511
    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 xml.dom import minidom
    25 from xml.dom import minidom
    26 from types import StringType, UnicodeType, TupleType
    26 from types import StringType, UnicodeType, TupleType
    27 import cPickle
    27 from lxml import etree
       
    28 from copy import deepcopy
    28 import os,sys,re
    29 import os,sys,re
    29 import datetime
    30 import datetime
    30 from time import localtime
    31 from time import localtime
    31 
    32 from collections import OrderedDict, namedtuple
    32 from plcopen import plcopen
    33 
    33 from plcopen.structures import *
    34 from plcopen import *
    34 from graphics.GraphicCommons import *
    35 from graphics.GraphicCommons import *
    35 from PLCGenerator import *
    36 from PLCGenerator import *
    36 
    37 
    37 duration_model = re.compile("(?:([0-9]{1,2})h)?(?:([0-9]{1,2})m(?!s))?(?:([0-9]{1,2})s)?(?:([0-9]{1,3}(?:\.[0-9]*)?)ms)?")
    38 duration_model = re.compile("(?:([0-9]{1,2})h)?(?:([0-9]{1,2})m(?!s))?(?:([0-9]{1,2})s)?(?:([0-9]{1,3}(?:\.[0-9]*)?)ms)?")
    38 
    39 
    64                   ITEM_VAR_INPUT,
    65                   ITEM_VAR_INPUT,
    65                   ITEM_VAR_OUTPUT,
    66                   ITEM_VAR_OUTPUT,
    66                   ITEM_VAR_INOUT
    67                   ITEM_VAR_INOUT
    67                  ] = range(17, 24)
    68                  ] = range(17, 24)
    68 
    69 
    69 VAR_CLASS_INFOS = {"Local" :    (plcopen.interface_localVars,    ITEM_VAR_LOCAL),
    70 VAR_CLASS_INFOS = {
    70                    "Global" :   (plcopen.interface_globalVars,   ITEM_VAR_GLOBAL),
    71     "Local":    ("localVars",    ITEM_VAR_LOCAL),
    71                    "External" : (plcopen.interface_externalVars, ITEM_VAR_EXTERNAL),
    72     "Global":   ("globalVars",   ITEM_VAR_GLOBAL),
    72                    "Temp" :     (plcopen.interface_tempVars,     ITEM_VAR_TEMP),
    73     "External": ("externalVars", ITEM_VAR_EXTERNAL),
    73                    "Input" :    (plcopen.interface_inputVars,    ITEM_VAR_INPUT),
    74     "Temp":     ("tempVars",     ITEM_VAR_TEMP),
    74                    "Output" :   (plcopen.interface_outputVars,   ITEM_VAR_OUTPUT),
    75     "Input":    ("inputVars",    ITEM_VAR_INPUT),
    75                    "InOut" :    (plcopen.interface_inOutVars,    ITEM_VAR_INOUT)
    76     "Output":   ("outputVars",   ITEM_VAR_OUTPUT),
    76                   }
    77     "InOut":    ("inOutVars",    ITEM_VAR_INOUT)}
    77 
    78 
    78 POU_TYPES = {"program": ITEM_PROGRAM,
    79 POU_TYPES = {"program": ITEM_PROGRAM,
    79              "functionBlock": ITEM_FUNCTIONBLOCK,
    80              "functionBlock": ITEM_FUNCTIONBLOCK,
    80              "function": ITEM_FUNCTION,
    81              "function": ITEM_FUNCTION,
    81             }
    82             }
    96             _("Configurations"), _("Resources"), _("Properties")]
    97             _("Configurations"), _("Resources"), _("Properties")]
    97 UNEDITABLE_NAMES = GetUneditableNames()
    98 UNEDITABLE_NAMES = GetUneditableNames()
    98 [USER_DEFINED_POUS, FUNCTIONS, FUNCTION_BLOCKS, PROGRAMS, 
    99 [USER_DEFINED_POUS, FUNCTIONS, FUNCTION_BLOCKS, PROGRAMS, 
    99  DATA_TYPES, TRANSITIONS, ACTIONS, CONFIGURATIONS, 
   100  DATA_TYPES, TRANSITIONS, ACTIONS, CONFIGURATIONS, 
   100  RESOURCES, PROPERTIES] = UNEDITABLE_NAMES
   101  RESOURCES, PROPERTIES] = UNEDITABLE_NAMES
       
   102 
       
   103 #-------------------------------------------------------------------------------
       
   104 #                 Helper object for loading library in xslt stylesheets
       
   105 #-------------------------------------------------------------------------------
       
   106 
       
   107 class LibraryResolver(etree.Resolver):
       
   108 
       
   109     def __init__(self, controller, debug=False):
       
   110         self.Controller = controller
       
   111         self.Debug = debug
       
   112 
       
   113     def resolve(self, url, pubid, context):
       
   114         lib_name = os.path.basename(url)
       
   115         if lib_name in ["project", "stdlib", "extensions"]:
       
   116             lib_el = etree.Element(lib_name)
       
   117             if lib_name == "project":
       
   118                 lib_el.append(deepcopy(self.Controller.GetProject(self.Debug)))
       
   119             elif lib_name == "stdlib":
       
   120                 for lib in [StdBlockLibrary, AddnlBlockLibrary]:
       
   121                     lib_el.append(deepcopy(lib))
       
   122             else:
       
   123                 for ctn in self.Controller.ConfNodeTypes:
       
   124                     lib_el.append(deepcopy(ctn["types"]))
       
   125             return self.resolve_string(etree.tostring(lib_el), context)
       
   126 
       
   127 #-------------------------------------------------------------------------------
       
   128 #           Helpers functions for translating list of arguments
       
   129 #                       from xslt to valid arguments
       
   130 #-------------------------------------------------------------------------------
       
   131 
       
   132 _BoolValue = lambda x: x in ["true", "0"]
       
   133 
       
   134 def _translate_args(translations, args):
       
   135     return [translate(arg[0]) if len(arg) > 0 else None 
       
   136             for translate, arg in
       
   137             zip(translations, args)]
       
   138 
       
   139 #-------------------------------------------------------------------------------
       
   140 #                 Helpers object for generating pou var list
       
   141 #-------------------------------------------------------------------------------
       
   142 
       
   143 class _VariableInfos(object):
       
   144     __slots__ = ["Name", "Class", "Option", "Location", "InitialValue", 
       
   145                  "Edit", "Documentation", "Type", "Tree", "Number"]
       
   146     def __init__(self, *args):
       
   147         for attr, value in zip(self.__slots__, args):
       
   148             setattr(self, attr, value if value is not None else "")
       
   149     def copy(self):
       
   150         return _VariableInfos(*[getattr(self, attr) for attr in self.__slots__])
       
   151 
       
   152 class VariablesInfosFactory:
       
   153     
       
   154     def __init__(self, variables):
       
   155         self.Variables = variables
       
   156         self.TreeStack = []
       
   157         self.Type = None
       
   158         self.Dimensions = None
       
   159     
       
   160     def SetType(self, context, *args):
       
   161         self.Type = args[0][0]
       
   162         
       
   163     def GetType(self):
       
   164         if len(self.Dimensions) > 0:
       
   165             return ("array", self.Type, self.Dimensions)
       
   166         return self.Type
       
   167     
       
   168     def GetTree(self):
       
   169         return (self.TreeStack.pop(-1), self.Dimensions)
       
   170     
       
   171     def AddDimension(self, context, *args):
       
   172         self.Dimensions.append(tuple(
       
   173             _translate_args([str] * 2, args)))
       
   174     
       
   175     def AddTree(self, context, *args):
       
   176         self.TreeStack.append([])
       
   177         self.Dimensions = []
       
   178     
       
   179     def AddVarToTree(self, context, *args):
       
   180         var = (args[0][0], self.Type, self.GetTree())
       
   181         self.TreeStack[-1].append(var)
       
   182     
       
   183     def AddVariable(self, context, *args):
       
   184         self.Variables.append(_VariableInfos(*(_translate_args(
       
   185             [str] * 5 + [_BoolValue] + [str], args) + 
       
   186             [self.GetType(), self.GetTree()])))
       
   187 
       
   188 #-------------------------------------------------------------------------------
       
   189 #            Helpers object for generating pou variable instance list
       
   190 #-------------------------------------------------------------------------------
       
   191 
       
   192 def class_extraction(value):
       
   193     class_type = {
       
   194         "configuration": ITEM_CONFIGURATION,
       
   195         "resource": ITEM_RESOURCE,
       
   196         "action": ITEM_ACTION,
       
   197         "transition": ITEM_TRANSITION,
       
   198         "program": ITEM_PROGRAM}.get(value)
       
   199     if class_type is not None:
       
   200         return class_type
       
   201     
       
   202     pou_type = POU_TYPES.get(value)
       
   203     if pou_type is not None:
       
   204         return pou_type
       
   205     
       
   206     var_type = VAR_CLASS_INFOS.get(value)
       
   207     if var_type is not None:
       
   208         return var_type[1]
       
   209     
       
   210     return None
       
   211 
       
   212 class _VariablesTreeItemInfos(object):
       
   213     __slots__ = ["name", "var_class", "type", "edit", "debug", "variables"]
       
   214     def __init__(self, *args):
       
   215         for attr, value in zip(self.__slots__, args):
       
   216             setattr(self, attr, value if value is not None else "")
       
   217     def copy(self):
       
   218         return _VariableTreeItem(*[getattr(self, attr) for attr in self.__slots__])
       
   219 
       
   220 class VariablesTreeInfosFactory:
       
   221     
       
   222     def __init__(self):
       
   223         self.Root = None
       
   224     
       
   225     def GetRoot(self):
       
   226         return self.Root
       
   227     
       
   228     def SetRoot(self, context, *args):
       
   229         self.Root = _VariablesTreeItemInfos(
       
   230             *([''] + _translate_args(
       
   231                 [class_extraction, str] + [_BoolValue] * 2, 
       
   232                 args) + [[]]))
       
   233 
       
   234     def AddVariable(self, context, *args):
       
   235         if self.Root is not None:
       
   236             self.Root.variables.append(_VariablesTreeItemInfos(
       
   237                 *(_translate_args(
       
   238                     [str, class_extraction, str] + [_BoolValue] * 2, 
       
   239                     args) + [[]])))
       
   240 
       
   241 #-------------------------------------------------------------------------------
       
   242 #            Helpers object for generating instances path list
       
   243 #-------------------------------------------------------------------------------
       
   244 
       
   245 class InstancesPathFactory:
       
   246     
       
   247     def __init__(self, instances):
       
   248         self.Instances = instances
       
   249         
       
   250     def AddInstance(self, context, *args):
       
   251         self.Instances.append(args[0][0])
       
   252 
       
   253 #-------------------------------------------------------------------------------
       
   254 #            Helpers object for generating instance tagname
       
   255 #-------------------------------------------------------------------------------
       
   256 
       
   257 class InstanceTagName:
       
   258 
       
   259     def __init__(self, controller):
       
   260         self.Controller = controller
       
   261         self.TagName = None
       
   262     
       
   263     def GetTagName(self):
       
   264         return self.TagName
       
   265     
       
   266     def ConfigTagName(self, context, *args):
       
   267         self.TagName = self.Controller.ComputeConfigurationName(args[0][0])
       
   268         
       
   269     def ResourceTagName(self, context, *args):
       
   270         self.TagName = self.Controller.ComputeConfigurationResourceName(args[0][0], args[1][0])
       
   271 
       
   272     def PouTagName(self, context, *args):
       
   273         self.TagName = self.Controller.ComputePouName(args[0][0])
       
   274 
       
   275     def ActionTagName(self, context, *args):
       
   276         self.TagName = self.Controller.ComputePouActionName(args[0][0], args[0][1])
       
   277 
       
   278     def TransitionTagName(self, context, *args):
       
   279         self.TagName = self.Controller.ComputePouTransitionName(args[0][0], args[0][1])
       
   280 
       
   281 #-------------------------------------------------------------------------------
       
   282 #           Helpers object for generating pou block instances list
       
   283 #-------------------------------------------------------------------------------
       
   284 
       
   285 _Point = namedtuple("Point", ["x", "y"])
       
   286 
       
   287 _BlockInstanceInfos = namedtuple("BlockInstanceInfos", 
       
   288     ["type", "id", "x", "y", "width", "height", "specific_values", "inputs", "outputs"])
       
   289 
       
   290 _BlockSpecificValues = (
       
   291     namedtuple("BlockSpecificValues", 
       
   292                ["name", "execution_order"]),
       
   293     [str, int])
       
   294 _VariableSpecificValues = (
       
   295     namedtuple("VariableSpecificValues", 
       
   296                ["name", "value_type", "execution_order"]),
       
   297     [str, str, int])
       
   298 _ConnectionSpecificValues = (
       
   299     namedtuple("ConnectionSpecificValues", ["name"]),
       
   300     [str])
       
   301 
       
   302 _PowerRailSpecificValues = (
       
   303     namedtuple("PowerRailSpecificValues", ["connectors"]),
       
   304     [int])
       
   305 
       
   306 _LDElementSpecificValues = (
       
   307     namedtuple("LDElementSpecificValues", 
       
   308                ["name", "negated", "edge", "storage", "execution_order"]),
       
   309     [str, _BoolValue, str, str, int])
       
   310 
       
   311 _DivergenceSpecificValues = (
       
   312     namedtuple("DivergenceSpecificValues", ["connectors"]),
       
   313     [int])
       
   314 
       
   315 _SpecificValuesTuples = {
       
   316     "comment": (
       
   317         namedtuple("CommentSpecificValues", ["content"]),
       
   318         [str]),
       
   319     "input": _VariableSpecificValues,
       
   320     "output": _VariableSpecificValues,
       
   321     "inout": _VariableSpecificValues,
       
   322     "connector": _ConnectionSpecificValues,
       
   323     "continuation": _ConnectionSpecificValues,
       
   324     "leftPowerRail": _PowerRailSpecificValues,
       
   325     "rightPowerRail": _PowerRailSpecificValues,
       
   326     "contact": _LDElementSpecificValues,
       
   327     "coil": _LDElementSpecificValues,
       
   328     "step": (
       
   329         namedtuple("StepSpecificValues", ["name", "initial", "action"]),
       
   330         [str, _BoolValue, lambda x: x]),
       
   331     "transition": (
       
   332         namedtuple("TransitionSpecificValues", 
       
   333                    ["priority", "condition_type", "condition", "connection"]),
       
   334         [int, str, str, lambda x: x]),
       
   335     "selectionDivergence": _DivergenceSpecificValues,
       
   336     "selectionConvergence": _DivergenceSpecificValues,
       
   337     "simultaneousDivergence": _DivergenceSpecificValues,
       
   338     "simultaneousConvergence": _DivergenceSpecificValues,
       
   339     "jump": (
       
   340         namedtuple("JumpSpecificValues", ["target"]),
       
   341         [str]),
       
   342     "actionBlock": (
       
   343         namedtuple("ActionBlockSpecificValues", ["actions"]),
       
   344         [lambda x: x]),
       
   345 }
       
   346 
       
   347 _InstanceConnectionInfos = namedtuple("InstanceConnectionInfos",
       
   348     ["name", "negated", "edge", "position", "links"])
       
   349 
       
   350 _ConnectionLinkInfos = namedtuple("ConnectionLinkInfos",
       
   351     ["refLocalId", "formalParameter", "points"])
       
   352 
       
   353 class _ActionInfos(object):
       
   354     __slots__ = ["qualifier", "type", "value", "duration", "indicator"]
       
   355     def __init__(self, *args):
       
   356         for attr, value in zip(self.__slots__, args):
       
   357             setattr(self, attr, value if value is not None else "")
       
   358     def copy(self):
       
   359         return _ActionInfos(*[getattr(self, attr) for attr in self.__slots__])
       
   360 
       
   361 class BlockInstanceFactory:
       
   362     
       
   363     def __init__(self, block_instances):
       
   364         self.BlockInstances = block_instances
       
   365         self.CurrentInstance = None
       
   366         self.SpecificValues = None
       
   367         self.CurrentConnection = None
       
   368         self.CurrentLink = None
       
   369     
       
   370     def SetSpecificValues(self, context, *args):
       
   371         self.SpecificValues = list(args)
       
   372         self.CurrentInstance = None
       
   373         self.CurrentConnection = None
       
   374         self.CurrentLink = None
       
   375     
       
   376     def AddBlockInstance(self, context, *args):
       
   377         specific_values_tuple, specific_values_translation = \
       
   378             _SpecificValuesTuples.get(args[0][0], _BlockSpecificValues)
       
   379         
       
   380         if (args[0][0] == "step" and len(self.SpecificValues) < 3 or
       
   381             args[0][0] == "transition" and len(self.SpecificValues) < 4):
       
   382             self.SpecificValues.append([None])
       
   383         elif args[0][0] == "actionBlock" and len(self.SpecificValues) < 1:
       
   384             self.SpecificValues.append([[]])
       
   385         specific_values = specific_values_tuple(*_translate_args(
       
   386             specific_values_translation, self.SpecificValues))
       
   387         self.SpecificValues = None
       
   388         
       
   389         self.CurrentInstance = _BlockInstanceInfos(
       
   390             *(_translate_args([str, int] + [float] * 4, args) + 
       
   391               [specific_values, [], []]))
       
   392         
       
   393         self.BlockInstances[self.CurrentInstance.id] = self.CurrentInstance
       
   394         
       
   395     def AddInstanceConnection(self, context, *args):
       
   396         connection_args = _translate_args(
       
   397             [str, str, _BoolValue, str, float, float], args)
       
   398         
       
   399         self.CurrentConnection = _InstanceConnectionInfos(
       
   400             *(connection_args[1:4] + [
       
   401                 _Point(*connection_args[4:6]), []]))
       
   402         
       
   403         if self.CurrentInstance is not None:
       
   404             if connection_args[0] == "input":
       
   405                 self.CurrentInstance.inputs.append(self.CurrentConnection)
       
   406             else:
       
   407                 self.CurrentInstance.outputs.append(self.CurrentConnection)
       
   408         else:
       
   409             self.SpecificValues.append([self.CurrentConnection])
       
   410     
       
   411     def AddConnectionLink(self, context, *args):
       
   412         self.CurrentLink = _ConnectionLinkInfos(
       
   413             *(_translate_args([int, str], args) + [[]]))
       
   414         self.CurrentConnection.links.append(self.CurrentLink)
       
   415     
       
   416     def AddLinkPoint(self, context, *args):
       
   417         self.CurrentLink.points.append(_Point(
       
   418             *_translate_args([float] * 2, args)))
       
   419     
       
   420     def AddAction(self, context, *args):
       
   421         if len(self.SpecificValues) == 0:
       
   422             self.SpecificValues.append([[]])
       
   423         translated_args = _translate_args([str] * 5, args)
       
   424         self.SpecificValues[0][0].append(_ActionInfos(*translated_args))
       
   425     
       
   426 pou_block_instances_xslt = etree.parse(
       
   427     os.path.join(ScriptDirectory, "plcopen", "pou_block_instances.xslt"))
   101 
   428 
   102 #-------------------------------------------------------------------------------
   429 #-------------------------------------------------------------------------------
   103 #                         Undo Buffer for PLCOpenEditor
   430 #                         Undo Buffer for PLCOpenEditor
   104 #-------------------------------------------------------------------------------
   431 #-------------------------------------------------------------------------------
   105 
   432 
   208         self.ProgramChunks = []
   535         self.ProgramChunks = []
   209         self.ProgramOffset = 0
   536         self.ProgramOffset = 0
   210         self.NextCompiledProject = None
   537         self.NextCompiledProject = None
   211         self.CurrentCompiledProject = None
   538         self.CurrentCompiledProject = None
   212         self.ConfNodeTypes = []
   539         self.ConfNodeTypes = []
       
   540         self.TotalTypesDict = StdBlckDct.copy()
       
   541         self.TotalTypes = StdBlckLst[:]
   213         self.ProgramFilePath = ""
   542         self.ProgramFilePath = ""
   214         
   543             
   215     def GetQualifierTypes(self):
   544     def GetQualifierTypes(self):
   216         return plcopen.QualifierList
   545         return QualifierList
   217 
   546 
   218     def GetProject(self, debug = False):
   547     def GetProject(self, debug = False):
   219         if debug and self.CurrentCompiledProject is not None:
   548         if debug and self.CurrentCompiledProject is not None:
   220             return self.CurrentCompiledProject
   549             return self.CurrentCompiledProject
   221         else:
   550         else:
   230         return self.Project is not None
   559         return self.Project is not None
   231 
   560 
   232     # Create a new project by replacing the current one
   561     # Create a new project by replacing the current one
   233     def CreateNewProject(self, properties):
   562     def CreateNewProject(self, properties):
   234         # Create the project
   563         # Create the project
   235         self.Project = plcopen.project()
   564         self.Project = PLCOpenParser.CreateRoot()
   236         properties["creationDateTime"] = datetime.datetime(*localtime()[:6])
   565         properties["creationDateTime"] = datetime.datetime(*localtime()[:6])
   237         self.Project.setfileHeader(properties)
   566         self.Project.setfileHeader(properties)
   238         self.Project.setcontentHeader(properties)
   567         self.Project.setcontentHeader(properties)
   239         self.SetFilePath("")
   568         self.SetFilePath("")
       
   569         
   240         # Initialize the project buffer
   570         # Initialize the project buffer
   241         self.CreateProjectBuffer(False)
   571         self.CreateProjectBuffer(False)
   242         self.ProgramChunks = []
   572         self.ProgramChunks = []
   243         self.ProgramOffset = 0
   573         self.ProgramOffset = 0
   244         self.NextCompiledProject = self.Copy(self.Project)
   574         self.NextCompiledProject = self.Copy(self.Project)
   271         variables = []
   601         variables = []
   272         project = self.GetProject(debug)
   602         project = self.GetProject(debug)
   273         if project is not None:
   603         if project is not None:
   274             for pou in project.getpous():
   604             for pou in project.getpous():
   275                 if pou_name is None or pou_name == pou.getname():
   605                 if pou_name is None or pou_name == pou.getname():
   276                     variables.extend([var["Name"] for var in self.GetPouInterfaceVars(pou, debug)])
   606                     variables.extend([var.Name for var in self.GetPouInterfaceVars(pou, debug=debug)])
   277                     for transition in pou.gettransitionList():
   607                     for transition in pou.gettransitionList():
   278                         variables.append(transition.getname())
   608                         variables.append(transition.getname())
   279                     for action in pou.getactionList():
   609                     for action in pou.getactionList():
   280                         variables.append(action.getname())
   610                         variables.append(action.getname())
   281         return variables
   611         return variables
   384             infos["values"] = [datatypes, pou_types["function"], pou_types["functionBlock"], 
   714             infos["values"] = [datatypes, pou_types["function"], pou_types["functionBlock"], 
   385                                pou_types["program"], configurations]
   715                                pou_types["program"], configurations]
   386             return infos
   716             return infos
   387         return None
   717         return None
   388 
   718 
   389     def GetPouVariableInfos(self, project, variable, var_class, debug=False):
       
   390         vartype_content = variable.gettype().getcontent()
       
   391         if vartype_content["name"] == "derived":
       
   392             var_type = vartype_content["value"].getname()
       
   393             pou_type = None
       
   394             pou = project.getpou(var_type)
       
   395             if pou is not None:
       
   396                 pou_type = pou.getpouType()
       
   397             edit = debug = pou_type is not None
       
   398             if pou_type is None:
       
   399                 block_infos = self.GetBlockType(var_type, debug = debug)
       
   400                 if block_infos is not None:
       
   401                     pou_type = block_infos["type"]
       
   402             if pou_type is not None:
       
   403                 var_class = None
       
   404                 if pou_type == "program":
       
   405                     var_class = ITEM_PROGRAM
       
   406                 elif pou_type != "function":
       
   407                     var_class = ITEM_FUNCTIONBLOCK
       
   408                 if var_class is not None:
       
   409                     return {"name": variable.getname(), 
       
   410                             "type": var_type, 
       
   411                             "class": var_class,
       
   412                             "edit": edit,
       
   413                             "debug": debug}
       
   414             elif var_type in self.GetDataTypes(debug = debug):
       
   415                 return {"name": variable.getname(), 
       
   416                         "type": var_type, 
       
   417                         "class": var_class,
       
   418                         "edit": False,
       
   419                         "debug": False}
       
   420         elif vartype_content["name"] in ["string", "wstring"]:
       
   421             return {"name": variable.getname(), 
       
   422                     "type": vartype_content["name"].upper(), 
       
   423                     "class": var_class,
       
   424                     "edit": False,
       
   425                     "debug": True}
       
   426         else:
       
   427             return {"name": variable.getname(),
       
   428                     "type": vartype_content["name"], 
       
   429                     "class": var_class,
       
   430                     "edit": False,
       
   431                     "debug": True}
       
   432         return None
       
   433 
       
   434     def GetPouVariables(self, tagname, debug = False):
   719     def GetPouVariables(self, tagname, debug = False):
   435         vars = []
       
   436         pou_type = None
   720         pou_type = None
   437         project = self.GetProject(debug)
   721         project = self.GetProject(debug)
   438         if project is not None:
   722         if project is not None:
       
   723             factory = VariablesTreeInfosFactory()
       
   724             
       
   725             parser = etree.XMLParser()
       
   726             parser.resolvers.add(LibraryResolver(self, debug))
       
   727             
       
   728             pou_variable_xslt_tree = etree.XSLT(
       
   729                 etree.parse(
       
   730                     os.path.join(ScriptDirectory, "plcopen", "pou_variables.xslt"),
       
   731                     parser), 
       
   732                 extensions = {("pou_vars_ns", name): getattr(factory, name)
       
   733                               for name in ["SetRoot", "AddVariable"]})
       
   734             
       
   735             obj = None
   439             words = tagname.split("::")
   736             words = tagname.split("::")
   440             if words[0] == "P":
   737             if words[0] == "P":
   441                 pou = project.getpou(words[1])
   738                 obj = self.GetPou(words[1], debug)
   442                 if pou is not None:
   739             elif words[0] != "D":
   443                     pou_type = pou.getpouType()
   740                 obj = self.GetEditedElement(tagname, debug)
   444                     if (pou_type in ["program", "functionBlock"] and 
   741             if obj is not None:
   445                         pou.interface is not None):
   742                 pou_variable_xslt_tree(obj)
   446                         # Extract variables from every varLists
   743                 return factory.GetRoot()
   447                         for varlist_type, varlist in pou.getvars():
   744             
   448                             var_infos = VAR_CLASS_INFOS.get(varlist_type, None)
       
   449                             if var_infos is not None:
       
   450                                 var_class = var_infos[1]
       
   451                             else:
       
   452                                 var_class = ITEM_VAR_LOCAL
       
   453                             for variable in varlist.getvariable():
       
   454                                 var_infos = self.GetPouVariableInfos(project, variable, var_class, debug)
       
   455                                 if var_infos is not None:
       
   456                                     vars.append(var_infos)
       
   457                         if pou.getbodyType() == "SFC":
       
   458                             for transition in pou.gettransitionList():
       
   459                                 vars.append({
       
   460                                     "name": transition.getname(),
       
   461                                     "type": None, 
       
   462                                     "class": ITEM_TRANSITION,
       
   463                                     "edit": True,
       
   464                                     "debug": True})
       
   465                             for action in pou.getactionList():
       
   466                                 vars.append({
       
   467                                     "name": action.getname(),
       
   468                                     "type": None, 
       
   469                                     "class": ITEM_ACTION,
       
   470                                     "edit": True,
       
   471                                     "debug": True})
       
   472                         return {"class": POU_TYPES[pou_type],
       
   473                                 "type": words[1],
       
   474                                 "variables": vars,
       
   475                                 "edit": True,
       
   476                                 "debug": True}
       
   477                 else:
       
   478                     block_infos = self.GetBlockType(words[1], debug = debug)
       
   479                     if (block_infos is not None and 
       
   480                         block_infos["type"] in ["program", "functionBlock"]):
       
   481                         for varname, vartype, varmodifier in block_infos["inputs"]:
       
   482                             vars.append({"name" : varname, 
       
   483                                          "type" : vartype, 
       
   484                                          "class" : ITEM_VAR_INPUT,
       
   485                                          "edit": False,
       
   486                                          "debug": True})
       
   487                         for varname, vartype, varmodifier in block_infos["outputs"]:
       
   488                             vars.append({"name" : varname, 
       
   489                                          "type" : vartype, 
       
   490                                          "class" : ITEM_VAR_OUTPUT,
       
   491                                          "edit": False,
       
   492                                          "debug": True})
       
   493                         return {"class": POU_TYPES[block_infos["type"]],
       
   494                                 "type": None,
       
   495                                 "variables": vars,
       
   496                                 "edit": False,
       
   497                                 "debug": False}
       
   498             elif words[0] in ['A', 'T']:
       
   499                 pou_vars = self.GetPouVariables(self.ComputePouName(words[1]), debug)
       
   500                 if pou_vars is not None:
       
   501                     if words[0] == 'A':
       
   502                         element_type = ITEM_ACTION
       
   503                     elif words[0] == 'T':
       
   504                         element_type = ITEM_TRANSITION
       
   505                     return {"class": element_type,
       
   506                             "type": None,
       
   507                             "variables": [var for var in pou_vars["variables"] 
       
   508                                           if var["class"] not in [ITEM_ACTION, ITEM_TRANSITION]],
       
   509                             "edit": True,
       
   510                             "debug": True}
       
   511             elif words[0] in ['C', 'R']:
       
   512                 if words[0] == 'C':
       
   513                     element_type = ITEM_CONFIGURATION
       
   514                     element = project.getconfiguration(words[1])
       
   515                     if element is not None:
       
   516                         for resource in element.getresource():
       
   517                             vars.append({"name": resource.getname(),
       
   518                                          "type": None,
       
   519                                          "class": ITEM_RESOURCE,
       
   520                                          "edit": True,
       
   521                                          "debug": False})
       
   522                 elif words[0] == 'R':
       
   523                     element_type = ITEM_RESOURCE
       
   524                     element = project.getconfigurationResource(words[1], words[2])
       
   525                     if element is not None:
       
   526                         for task in element.gettask():
       
   527                             for pou in task.getpouInstance():
       
   528                                 vars.append({"name": pou.getname(),
       
   529                                              "type": pou.gettypeName(),
       
   530                                              "class": ITEM_PROGRAM,
       
   531                                              "edit": True,
       
   532                                              "debug": True})
       
   533                         for pou in element.getpouInstance():
       
   534                             vars.append({"name": pou.getname(),
       
   535                                          "type": pou.gettypeName(),
       
   536                                          "class": ITEM_PROGRAM,
       
   537                                          "edit": True,
       
   538                                          "debug": True})
       
   539                 if element is not None:
       
   540                     for varlist in element.getglobalVars():
       
   541                         for variable in varlist.getvariable():
       
   542                             var_infos = self.GetPouVariableInfos(project, variable, ITEM_VAR_GLOBAL, debug)
       
   543                             if var_infos is not None:
       
   544                                 vars.append(var_infos)
       
   545                     return {"class": element_type,
       
   546                             "type": None,
       
   547                             "variables": vars,
       
   548                             "edit": True,
       
   549                             "debug": False}
       
   550         return None
   745         return None
   551 
   746 
   552     def RecursiveSearchPouInstances(self, project, pou_type, parent_path, varlists, debug = False):
   747     def GetInstanceList(self, root, name, debug = False):
   553         instances = []
   748         instances = []
   554         for varlist in varlists:
   749         project = self.GetProject(debug)
   555             for variable in varlist.getvariable():
   750         if project is not None:
   556                 vartype_content = variable.gettype().getcontent()
   751             factory = InstancesPathFactory(instances)
   557                 if vartype_content["name"] == "derived":
   752             
   558                     var_path = "%s.%s" % (parent_path, variable.getname())
   753             parser = etree.XMLParser()
   559                     var_type = vartype_content["value"].getname()
   754             parser.resolvers.add(LibraryResolver(self, debug))
   560                     if var_type == pou_type:
   755             
   561                         instances.append(var_path)
   756             instances_path_xslt_tree = etree.XSLT(
   562                     else:
   757                 etree.parse(
   563                         pou = project.getpou(var_type)
   758                     os.path.join(ScriptDirectory, "plcopen", "instances_path.xslt"),
   564                         if pou is not None and project.ElementIsUsedBy(pou_type, var_type):
   759                     parser), 
   565                             instances.extend(
   760                 extensions = {
   566                                 self.RecursiveSearchPouInstances(
   761                     ("instances_ns", "AddInstance"): factory.AddInstance})
   567                                     project, pou_type, var_path, 
   762             
   568                                     [varlist for type, varlist in pou.getvars()], 
   763             instances_path_xslt_tree(root, 
   569                                     debug))
   764                 instance_type=etree.XSLT.strparam(name))
       
   765             
   570         return instances
   766         return instances
   571                         
   767         
   572     def SearchPouInstances(self, tagname, debug = False):
   768     def SearchPouInstances(self, tagname, debug = False):
   573         project = self.GetProject(debug)
   769         project = self.GetProject(debug)
   574         if project is not None:
   770         if project is not None:
   575             words = tagname.split("::")
   771             words = tagname.split("::")
   576             if words[0] == "P":
   772             if words[0] == "P":
   577                 instances = []
   773                 return self.GetInstanceList(project, words[1])
   578                 for config in project.getconfigurations():
       
   579                     config_name = config.getname()
       
   580                     instances.extend(
       
   581                         self.RecursiveSearchPouInstances(
       
   582                             project, words[1], config_name, 
       
   583                             config.getglobalVars(), debug))
       
   584                     for resource in config.getresource():
       
   585                         res_path = "%s.%s" % (config_name, resource.getname())
       
   586                         instances.extend(
       
   587                             self.RecursiveSearchPouInstances(
       
   588                                 project, words[1], res_path, 
       
   589                                 resource.getglobalVars(), debug))
       
   590                         pou_instances = resource.getpouInstance()[:]
       
   591                         for task in resource.gettask():
       
   592                             pou_instances.extend(task.getpouInstance())
       
   593                         for pou_instance in pou_instances:
       
   594                             pou_path = "%s.%s" % (res_path, pou_instance.getname())
       
   595                             pou_type = pou_instance.gettypeName()
       
   596                             if pou_type == words[1]:
       
   597                                 instances.append(pou_path)
       
   598                             pou = project.getpou(pou_type)
       
   599                             if pou is not None and project.ElementIsUsedBy(words[1], pou_type):
       
   600                                 instances.extend(
       
   601                                     self.RecursiveSearchPouInstances(
       
   602                                         project, words[1], pou_path, 
       
   603                                         [varlist for type, varlist in pou.getvars()], 
       
   604                                         debug))
       
   605                 return instances
       
   606             elif words[0] == 'C':
   774             elif words[0] == 'C':
   607                 return [words[1]]
   775                 return [words[1]]
   608             elif words[0] == 'R':
   776             elif words[0] == 'R':
   609                 return ["%s.%s" % (words[1], words[2])]
   777                 return ["%s.%s" % (words[1], words[2])]
   610             elif words[0] in ['T', 'A']:
   778             elif words[0] in ['T', 'A']:
   611                 return ["%s.%s" % (instance, words[2])
   779                 return ["%s.%s" % (instance, words[2])
   612                         for instance in self.SearchPouInstances(
   780                         for instance in self.SearchPouInstances(
   613                             self.ComputePouName(words[1]), debug)]
   781                             self.ComputePouName(words[1]), debug)]
   614         return []
   782         return []
   615     
   783     
   616     def RecursiveGetPouInstanceTagName(self, project, pou_type, parts, debug = False):
       
   617         pou = project.getpou(pou_type)
       
   618         if pou is not None:
       
   619             if len(parts) == 0:
       
   620                 return self.ComputePouName(pou_type)
       
   621             
       
   622             for varlist_type, varlist in pou.getvars():
       
   623                 for variable in varlist.getvariable():
       
   624                     if variable.getname() == parts[0]:
       
   625                         vartype_content = variable.gettype().getcontent()
       
   626                         if vartype_content["name"] == "derived":
       
   627                             return self.RecursiveGetPouInstanceTagName(
       
   628                                             project, 
       
   629                                             vartype_content["value"].getname(),
       
   630                                             parts[1:], debug)
       
   631             
       
   632             if pou.getbodyType() == "SFC" and len(parts) == 1:
       
   633                 for action in pou.getactionList():
       
   634                     if action.getname() == parts[0]:
       
   635                         return self.ComputePouActionName(pou_type, parts[0])
       
   636                 for transition in pou.gettransitionList():
       
   637                     if transition.getname() == parts[0]:
       
   638                         return self.ComputePouTransitionName(pou_type, parts[0])
       
   639         else:
       
   640             block_infos = self.GetBlockType(pou_type, debug=debug)
       
   641             if (block_infos is not None and 
       
   642                 block_infos["type"] in ["program", "functionBlock"]):
       
   643                 
       
   644                 if len(parts) == 0:
       
   645                     return self.ComputePouName(pou_type)
       
   646                 
       
   647                 for varname, vartype, varmodifier in block_infos["inputs"] + block_infos["outputs"]:
       
   648                     if varname == parts[0]:
       
   649                         return self.RecursiveGetPouInstanceTagName(project, vartype, parts[1:], debug)
       
   650         return None
       
   651     
       
   652     def GetGlobalInstanceTagName(self, project, element, parts, debug = False):
       
   653         for varlist in element.getglobalVars():
       
   654             for variable in varlist.getvariable():
       
   655                 if variable.getname() == parts[0]:
       
   656                     vartype_content = variable.gettype().getcontent()
       
   657                     if vartype_content["name"] == "derived":                        
       
   658                         if len(parts) == 1:
       
   659                             return self.ComputePouName(
       
   660                                         vartype_content["value"].getname())
       
   661                         else:
       
   662                             return self.RecursiveGetPouInstanceTagName(
       
   663                                         project, 
       
   664                                         vartype_content["value"].getname(),
       
   665                                         parts[1:], debug)
       
   666         return None
       
   667     
       
   668     def GetPouInstanceTagName(self, instance_path, debug = False):
   784     def GetPouInstanceTagName(self, instance_path, debug = False):
   669         project = self.GetProject(debug)
   785         project = self.GetProject(debug)
   670         parts = instance_path.split(".")
   786         factory = InstanceTagName(self)
   671         if len(parts) == 1:
   787         
   672             return self.ComputeConfigurationName(parts[0])
   788         parser = etree.XMLParser()
   673         elif len(parts) == 2:
   789         parser.resolvers.add(LibraryResolver(self, debug))
   674             for config in project.getconfigurations():
   790         
   675                 if config.getname() == parts[0]:
   791         instance_tagname_xslt_tree = etree.XSLT(
   676                     result = self.GetGlobalInstanceTagName(project, 
   792             etree.parse(
   677                                                            config, 
   793                 os.path.join(ScriptDirectory, "plcopen", "instance_tagname.xslt"),
   678                                                            parts[1:],
   794                 parser), 
   679                                                            debug)
   795             extensions = {("instance_tagname_ns", name): getattr(factory, name)
   680                     if result is not None:
   796                           for name in ["ConfigTagName", "ResourceTagName",
   681                         return result
   797                                        "PouTagName", "ActionTagName", 
   682             return self.ComputeConfigurationResourceName(parts[0], parts[1])
   798                                        "TransitionTagName"]})
   683         else:
   799         
   684             for config in project.getconfigurations():
   800         instance_tagname_xslt_tree(project, 
   685                 if config.getname() == parts[0]:
   801             instance_path=etree.XSLT.strparam(instance_path))
   686                     for resource in config.getresource():
   802         
   687                         if resource.getname() == parts[1]:
   803         return factory.GetTagName()
   688                             pou_instances = resource.getpouInstance()[:]
       
   689                             for task in resource.gettask():
       
   690                                 pou_instances.extend(task.getpouInstance())
       
   691                             for pou_instance in pou_instances:
       
   692                                 if pou_instance.getname() == parts[2]:
       
   693                                     if len(parts) == 3:
       
   694                                         return self.ComputePouName(
       
   695                                                     pou_instance.gettypeName())
       
   696                                     else:
       
   697                                         return self.RecursiveGetPouInstanceTagName(
       
   698                                                     project,
       
   699                                                     pou_instance.gettypeName(),
       
   700                                                     parts[3:], debug)
       
   701                             return self.GetGlobalInstanceTagName(project, 
       
   702                                                                  resource, 
       
   703                                                                  parts[2:], 
       
   704                                                                  debug)
       
   705                     return self.GetGlobalInstanceTagName(project, 
       
   706                                                          config, 
       
   707                                                          parts[1:],
       
   708                                                          debug)
       
   709         return None
       
   710     
   804     
   711     def GetInstanceInfos(self, instance_path, debug = False):
   805     def GetInstanceInfos(self, instance_path, debug = False):
   712         tagname = self.GetPouInstanceTagName(instance_path)
   806         tagname = self.GetPouInstanceTagName(instance_path)
   713         if tagname is not None:
   807         if tagname is not None:
   714             infos = self.GetPouVariables(tagname, debug)
   808             infos = self.GetPouVariables(tagname, debug)
   715             infos["type"] = tagname
   809             infos.type = tagname
   716             return infos
   810             return infos
   717         else:
   811         else:
   718             pou_path, var_name = instance_path.rsplit(".", 1)
   812             pou_path, var_name = instance_path.rsplit(".", 1)
   719             tagname = self.GetPouInstanceTagName(pou_path)
   813             tagname = self.GetPouInstanceTagName(pou_path)
   720             if tagname is not None:
   814             if tagname is not None:
   721                 pou_infos = self.GetPouVariables(tagname, debug)
   815                 pou_infos = self.GetPouVariables(tagname, debug)
   722                 for var_infos in pou_infos["variables"]:
   816                 for var_infos in pou_infos.variables:
   723                     if var_infos["name"] == var_name:
   817                     if var_infos.name == var_name:
   724                         return var_infos
   818                         return var_infos
   725         return None
   819         return None
   726     
   820     
   727     # Return if data type given by name is used by another data type or pou
   821     # Return if data type given by name is used by another data type or pou
   728     def DataTypeIsUsed(self, name, debug = False):
   822     def DataTypeIsUsed(self, name, debug = False):
   729         project = self.GetProject(debug)
   823         project = self.GetProject(debug)
   730         if project is not None:
   824         if project is not None:
   731             return project.ElementIsUsed(name) or project.DataTypeIsDerived(name)
   825             return len(self.GetInstanceList(project, name, debug)) > 0
   732         return False
   826         return False
   733 
   827 
   734     # Return if pou given by name is used by another pou
   828     # Return if pou given by name is used by another pou
   735     def PouIsUsed(self, name, debug = False):
   829     def PouIsUsed(self, name, debug = False):
   736         project = self.GetProject(debug)
   830         project = self.GetProject(debug)
   737         if project is not None:
   831         if project is not None:
   738             return project.ElementIsUsed(name)
   832             return len(self.GetInstanceList(project, name, debug)) > 0
   739         return False
   833         return False
   740 
   834 
   741     # Return if pou given by name is directly or undirectly used by the reference pou
   835     # Return if pou given by name is directly or undirectly used by the reference pou
   742     def PouIsUsedBy(self, name, reference, debug = False):
   836     def PouIsUsedBy(self, name, reference, debug = False):
   743         project = self.GetProject(debug)
   837         pou_infos = self.GetPou(reference, debug)
   744         if project is not None:
   838         if pou_infos is not None:
   745             return project.ElementIsUsedBy(name, reference)
   839             return len(self.GetInstanceList(pou_infos, name, debug)) > 0
   746         return False
   840         return False
   747 
   841 
   748     def GenerateProgram(self, filepath=None):
   842     def GenerateProgram(self, filepath=None):
   749         errors = []
   843         errors = []
   750         warnings = []
   844         warnings = []
   828     def ProjectChangePouType(self, name, pou_type):
   922     def ProjectChangePouType(self, name, pou_type):
   829         if self.Project is not None:
   923         if self.Project is not None:
   830             pou = self.Project.getpou(name)
   924             pou = self.Project.getpou(name)
   831             if pou is not None:
   925             if pou is not None:
   832                 pou.setpouType(pou_type)
   926                 pou.setpouType(pou_type)
   833                 self.Project.RefreshCustomBlockTypes()
       
   834                 self.BufferProject()
   927                 self.BufferProject()
   835                 
   928                 
   836     def GetPouXml(self, pou_name):
   929     def GetPouXml(self, pou_name):
   837         if self.Project is not None:
   930         if self.Project is not None:
   838             pou = self.Project.getpou(pou_name)
   931             pou = self.Project.getpou(pou_name)
   839             if pou is not None:
   932             if pou is not None:
   840                 return pou.generateXMLText('pou', 0)
   933                 return pou.tostring()
   841         return None
   934         return None
   842     
   935     
   843     def PastePou(self, pou_type, pou_xml):
   936     def PastePou(self, pou_type, pou_xml):
   844         '''
   937         '''
   845         Adds the POU defined by 'pou_xml' to the current project with type 'pou_type'
   938         Adds the POU defined by 'pou_xml' to the current project with type 'pou_type'
   846         '''
   939         '''
   847         try:
   940         try:
   848             tree = minidom.parseString(pou_xml.encode("utf-8"))
   941             new_pou, error = LoadPou(pou_xml)
   849             root = tree.childNodes[0]
       
   850         except:
   942         except:
       
   943             error = ""
       
   944         if error is not None:
   851             return _("Couldn't paste non-POU object.")
   945             return _("Couldn't paste non-POU object.")
   852 
   946         
   853         if root.nodeName == "pou":
   947         name = new_pou.getname()
   854             new_pou = plcopen.pous_pou()
   948         
   855             new_pou.loadXMLTree(root)
   949         idx = 0
   856 
   950         new_name = name
   857             name = new_pou.getname()
   951         while self.Project.getpou(new_name):
       
   952             # a POU with that name already exists.
       
   953             # make a new name and test if a POU with that name exists.
       
   954             # append an incrementing numeric suffix to the POU name.
       
   955             idx += 1
       
   956             new_name = "%s%d" % (name, idx)
   858             
   957             
   859             idx = 0
   958         # we've found a name that does not already exist, use it
   860             new_name = name
   959         new_pou.setname(new_name)
   861             while self.Project.getpou(new_name):
   960         
   862                 # a POU with that name already exists.
   961         if pou_type is not None:
   863                 # make a new name and test if a POU with that name exists.
   962             orig_type = new_pou.getpouType()
   864                 # append an incrementing numeric suffix to the POU name.
   963 
   865                 idx += 1
   964             # prevent violations of POU content restrictions:
   866                 new_name = "%s%d" % (name, idx)
   965             # function blocks cannot be pasted as functions,
   867                 
   966             # programs cannot be pasted as functions or function blocks
   868             # we've found a name that does not already exist, use it
   967             if orig_type == 'functionBlock' and pou_type == 'function' or \
   869             new_pou.setname(new_name)
   968                orig_type == 'program' and pou_type in ['function', 'functionBlock']:
       
   969                 return _('''%s "%s" can't be pasted as a %s.''') % (orig_type, name, pou_type)
   870             
   970             
   871             if pou_type is not None:
   971             new_pou.setpouType(pou_type)
   872                 orig_type = new_pou.getpouType()
   972 
   873     
   973         self.Project.insertpou(-1, new_pou)
   874                 # prevent violations of POU content restrictions:
   974         self.BufferProject()
   875                 # function blocks cannot be pasted as functions,
   975         
   876                 # programs cannot be pasted as functions or function blocks
   976         return self.ComputePouName(new_name),
   877                 if orig_type == 'functionBlock' and pou_type == 'function' or \
       
   878                    orig_type == 'program' and pou_type in ['function', 'functionBlock']:
       
   879                     return _('''%s "%s" can't be pasted as a %s.''') % (orig_type, name, pou_type)
       
   880                 
       
   881                 new_pou.setpouType(pou_type)
       
   882 
       
   883             self.Project.insertpou(-1, new_pou)
       
   884             self.BufferProject()
       
   885             
       
   886             return self.ComputePouName(new_name),
       
   887         else:
       
   888             return _("Couldn't paste non-POU object.")
       
   889 
   977 
   890     # Remove a Pou from project
   978     # Remove a Pou from project
   891     def ProjectRemovePou(self, pou_name):
   979     def ProjectRemovePou(self, pou_name):
   892         if self.Project is not None:
   980         if self.Project is not None:
   893             self.Project.removepou(pou_name)
   981             self.Project.removepou(pou_name)
   978             # Found the pou corresponding to old name and change its name to new name
  1066             # Found the pou corresponding to old name and change its name to new name
   979             datatype = self.Project.getdataType(old_name)
  1067             datatype = self.Project.getdataType(old_name)
   980             if datatype is not None:
  1068             if datatype is not None:
   981                 datatype.setname(new_name)
  1069                 datatype.setname(new_name)
   982                 self.Project.updateElementName(old_name, new_name)
  1070                 self.Project.updateElementName(old_name, new_name)
   983                 self.Project.RefreshElementUsingTree()
       
   984                 self.Project.RefreshDataTypeHierarchy()
       
   985                 self.BufferProject()
  1071                 self.BufferProject()
   986     
  1072     
   987     # Change the name of a pou
  1073     # Change the name of a pou
   988     def ChangePouName(self, old_name, new_name):
  1074     def ChangePouName(self, old_name, new_name):
   989         if self.Project is not None:
  1075         if self.Project is not None:
   990             # Found the pou corresponding to old name and change its name to new name
  1076             # Found the pou corresponding to old name and change its name to new name
   991             pou = self.Project.getpou(old_name)
  1077             pou = self.Project.getpou(old_name)
   992             if pou is not None:
  1078             if pou is not None:
   993                 pou.setname(new_name)
  1079                 pou.setname(new_name)
   994                 self.Project.updateElementName(old_name, new_name)
  1080                 self.Project.updateElementName(old_name, new_name)
   995                 self.Project.RefreshElementUsingTree()
       
   996                 self.Project.RefreshCustomBlockTypes()
       
   997                 self.BufferProject()
  1081                 self.BufferProject()
   998     
  1082     
   999     # Change the name of a pou transition
  1083     # Change the name of a pou transition
  1000     def ChangePouTransitionName(self, pou_name, old_name, new_name):
  1084     def ChangePouTransitionName(self, pou_name, old_name, new_name):
  1001         if self.Project is not None:
  1085         if self.Project is not None:
  1028             if pou is not None:
  1112             if pou is not None:
  1029                 for type, varlist in pou.getvars():
  1113                 for type, varlist in pou.getvars():
  1030                     for var in varlist.getvariable():
  1114                     for var in varlist.getvariable():
  1031                         if var.getname() == old_name:
  1115                         if var.getname() == old_name:
  1032                             var.setname(new_name)
  1116                             var.setname(new_name)
  1033                 self.Project.RefreshCustomBlockTypes()
       
  1034                 self.BufferProject()
  1117                 self.BufferProject()
  1035         
  1118         
  1036     # Change the name of a configuration
  1119     # Change the name of a configuration
  1037     def ChangeConfigurationName(self, old_name, new_name):
  1120     def ChangeConfigurationName(self, old_name, new_name):
  1038         if self.Project is not None:
  1121         if self.Project is not None:
  1067         if project is not None:
  1150         if project is not None:
  1068             # Found the pou correponding to name and return its type
  1151             # Found the pou correponding to name and return its type
  1069             pou = project.getpou(name)
  1152             pou = project.getpou(name)
  1070             if pou is not None:
  1153             if pou is not None:
  1071                 pou.setdescription(description)
  1154                 pou.setdescription(description)
  1072                 project.RefreshCustomBlockTypes()
       
  1073                 self.BufferProject()
  1155                 self.BufferProject()
  1074     
  1156     
  1075     # Return the type of the pou given by its name
  1157     # Return the type of the pou given by its name
  1076     def GetPouType(self, name, debug = False):
  1158     def GetPouType(self, name, debug = False):
  1077         project = self.GetProject(debug)
  1159         project = self.GetProject(debug)
  1155     def ExtractVarLists(self, vars):
  1237     def ExtractVarLists(self, vars):
  1156         varlist_list = []
  1238         varlist_list = []
  1157         current_varlist = None
  1239         current_varlist = None
  1158         current_type = None
  1240         current_type = None
  1159         for var in vars:
  1241         for var in vars:
  1160             next_type = (var["Class"], 
  1242             next_type = (var.Class, 
  1161                          var["Option"], 
  1243                          var.Option, 
  1162                          var["Location"] in ["", None] or 
  1244                          var.Location in ["", None] or 
  1163                          # When declaring globals, located 
  1245                          # When declaring globals, located 
  1164                          # and not located variables are 
  1246                          # and not located variables are 
  1165                          # in the same declaration block
  1247                          # in the same declaration block
  1166                          var["Class"] == "Global")
  1248                          var.Class == "Global")
  1167             if current_type != next_type:
  1249             if current_type != next_type:
  1168                 current_type = next_type
  1250                 current_type = next_type
  1169                 infos = VAR_CLASS_INFOS.get(var["Class"], None)
  1251                 infos = VAR_CLASS_INFOS.get(var.Class, None)
  1170                 if infos is not None:
  1252                 if infos is not None:
  1171                     current_varlist = infos[0]()
  1253                     current_varlist = PLCOpenParser.CreateElement(infos[0], "interface")
  1172                 else:
  1254                 else:
  1173                     current_varlist = plcopen.varList()
  1255                     current_varlist = PLCOpenParser.CreateElement("varList")
  1174                 varlist_list.append((var["Class"], current_varlist))
  1256                 varlist_list.append((var.Class, current_varlist))
  1175                 if var["Option"] == "Constant":
  1257                 if var.Option == "Constant":
  1176                     current_varlist.setconstant(True)
  1258                     current_varlist.setconstant(True)
  1177                 elif var["Option"] == "Retain":
  1259                 elif var.Option == "Retain":
  1178                     current_varlist.setretain(True)
  1260                     current_varlist.setretain(True)
  1179                 elif var["Option"] == "Non-Retain":
  1261                 elif var.Option == "Non-Retain":
  1180                     current_varlist.setnonretain(True)
  1262                     current_varlist.setnonretain(True)
  1181             # Create variable and change its properties
  1263             # Create variable and change its properties
  1182             tempvar = plcopen.varListPlain_variable()
  1264             tempvar = PLCOpenParser.CreateElement("variable", "varListPlain")
  1183             tempvar.setname(var["Name"])
  1265             tempvar.setname(var.Name)
  1184             
  1266             
  1185             var_type = plcopen.dataType()
  1267             var_type = PLCOpenParser.CreateElement("type", "variable")
  1186             if isinstance(var["Type"], TupleType):
  1268             if isinstance(var.Type, TupleType):
  1187                 if var["Type"][0] == "array":
  1269                 if var.Type[0] == "array":
  1188                     array_type, base_type_name, dimensions = var["Type"]
  1270                     array_type, base_type_name, dimensions = var.Type
  1189                     array = plcopen.derivedTypes_array()
  1271                     array = PLCOpenParser.CreateElement("array", "dataType")
       
  1272                     baseType = PLCOpenParser.CreateElement("baseType", "array")
       
  1273                     array.setbaseType(baseType)
  1190                     for i, dimension in enumerate(dimensions):
  1274                     for i, dimension in enumerate(dimensions):
  1191                         dimension_range = plcopen.rangeSigned()
  1275                         dimension_range = PLCOpenParser.CreateElement("dimension", "array")
  1192                         dimension_range.setlower(dimension[0])
       
  1193                         dimension_range.setupper(dimension[1])
       
  1194                         if i == 0:
  1276                         if i == 0:
  1195                             array.setdimension([dimension_range])
  1277                             array.setdimension([dimension_range])
  1196                         else:
  1278                         else:
  1197                             array.appenddimension(dimension_range)
  1279                             array.appenddimension(dimension_range)
       
  1280                         dimension_range.setlower(dimension[0])
       
  1281                         dimension_range.setupper(dimension[1])
  1198                     if base_type_name in self.GetBaseTypes():
  1282                     if base_type_name in self.GetBaseTypes():
  1199                         if base_type_name == "STRING":
  1283                         baseType.setcontent(PLCOpenParser.CreateElement(
  1200                             array.baseType.setcontent({"name" : "string", "value" : plcopen.elementaryTypes_string()})
  1284                             base_type_name.lower()
  1201                         elif base_type_name == "WSTRING":
  1285                             if base_type_name in ["STRING", "WSTRING"]
  1202                             array.baseType.setcontent({"name" : "wstring", "value" : plcopen.wstring()})
  1286                             else base_type_name, "dataType"))
  1203                         else:
       
  1204                             array.baseType.setcontent({"name" : base_type_name, "value" : None})
       
  1205                     else:
  1287                     else:
  1206                         derived_datatype = plcopen.derivedTypes_derived()
  1288                         derived_datatype = PLCOpenParser.CreateElement("derived", "dataType")
  1207                         derived_datatype.setname(base_type_name)
  1289                         derived_datatype.setname(base_type_name)
  1208                         array.baseType.setcontent({"name" : "derived", "value" : derived_datatype})
  1290                         baseType.setcontent(derived_datatype)
  1209                     var_type.setcontent({"name" : "array", "value" : array})
  1291                     var_type.setcontent(array)
  1210             elif var["Type"] in self.GetBaseTypes():
  1292             elif var.Type in self.GetBaseTypes():
  1211                 if var["Type"] == "STRING":
  1293                 var_type.setcontent(PLCOpenParser.CreateElement(
  1212                     var_type.setcontent({"name" : "string", "value" : plcopen.elementaryTypes_string()})
  1294                     var.Type.lower()
  1213                 elif var["Type"] == "WSTRING":
  1295                     if var.Type in ["STRING", "WSTRING"]
  1214                     var_type.setcontent({"name" : "wstring", "value" : plcopen.elementaryTypes_wstring()})
  1296                     else var.Type, "dataType"))
  1215                 else:
       
  1216                     var_type.setcontent({"name" : var["Type"], "value" : None})
       
  1217             else:
  1297             else:
  1218                 derived_type = plcopen.derivedTypes_derived()
  1298                 derived_type = PLCOpenParser.CreateElement("derived", "dataType")
  1219                 derived_type.setname(var["Type"])
  1299                 derived_type.setname(var.Type)
  1220                 var_type.setcontent({"name" : "derived", "value" : derived_type})
  1300                 var_type.setcontent(derived_type)
  1221             tempvar.settype(var_type)
  1301             tempvar.settype(var_type)
  1222 
  1302 
  1223             if var["Initial Value"] != "":
  1303             if var.InitialValue != "":
  1224                 value = plcopen.value()
  1304                 value = PLCOpenParser.CreateElement("initialValue", "variable")
  1225                 value.setvalue(var["Initial Value"])
  1305                 value.setvalue(var.InitialValue)
  1226                 tempvar.setinitialValue(value)
  1306                 tempvar.setinitialValue(value)
  1227             if var["Location"] != "":
  1307             if var.Location != "":
  1228                 tempvar.setaddress(var["Location"])
  1308                 tempvar.setaddress(var.Location)
  1229             else:
  1309             else:
  1230                 tempvar.setaddress(None)
  1310                 tempvar.setaddress(None)
  1231             if var['Documentation'] != "":
  1311             if var.Documentation != "":
  1232                 ft = plcopen.formattedText()
  1312                 ft = PLCOpenParser.CreateElement("documentation", "variable")
  1233                 ft.settext(var['Documentation'])
  1313                 ft.setanyText(var.Documentation)
  1234                 tempvar.setdocumentation(ft)
  1314                 tempvar.setdocumentation(ft)
  1235 
  1315 
  1236             # Add variable to varList
  1316             # Add variable to varList
  1237             current_varlist.appendvariable(tempvar)
  1317             current_varlist.appendvariable(tempvar)
  1238         return varlist_list
  1318         return varlist_list
  1239     
  1319     
  1240     def GetVariableDictionary(self, varlist, var):
  1320     def GetVariableDictionary(self, object_with_vars, tree=False, debug=False):
  1241         '''
  1321         variables = []
  1242         convert a PLC variable to the dictionary representation
  1322         factory = VariablesInfosFactory(variables)
  1243         returned by Get*Vars)
  1323         
  1244         '''
  1324         parser = etree.XMLParser()
  1245 
  1325         parser.resolvers.add(LibraryResolver(self, debug))
  1246         tempvar = {"Name": var.getname()}
  1326         
  1247 
  1327         variables_infos_xslt_tree = etree.XSLT(
  1248         vartype_content = var.gettype().getcontent()
  1328             etree.parse(
  1249         if vartype_content["name"] == "derived":
  1329                 os.path.join(ScriptDirectory, "plcopen", "variables_infos.xslt"),
  1250             tempvar["Type"] = vartype_content["value"].getname()
  1330                 parser), 
  1251         elif vartype_content["name"] == "array":
  1331             extensions = {("var_infos_ns", name): getattr(factory, name)
  1252             dimensions = []
  1332                 for name in ["SetType", "AddDimension", "AddTree",
  1253             for dimension in vartype_content["value"].getdimension():
  1333                              "AddVarToTree", "AddVariable"]})
  1254                 dimensions.append((dimension.getlower(), dimension.getupper()))
  1334         variables_infos_xslt_tree(object_with_vars,
  1255             base_type = vartype_content["value"].baseType.getcontent()
  1335             tree=etree.XSLT.strparam(str(tree)))
  1256             if base_type["value"] is None or base_type["name"] in ["string", "wstring"]:
  1336         
  1257                 base_type_name = base_type["name"].upper()
  1337         return variables
  1258             else:
  1338             
  1259                 base_type_name = base_type["value"].getname()
       
  1260             tempvar["Type"] = ("array", base_type_name, dimensions)
       
  1261         elif vartype_content["name"] in ["string", "wstring"]:
       
  1262             tempvar["Type"] = vartype_content["name"].upper()
       
  1263         else:
       
  1264             tempvar["Type"] = vartype_content["name"]
       
  1265 
       
  1266         tempvar["Edit"] = True
       
  1267 
       
  1268         initial = var.getinitialValue()
       
  1269         if initial:
       
  1270             tempvar["Initial Value"] = initial.getvalue()
       
  1271         else:
       
  1272             tempvar["Initial Value"] = ""
       
  1273 
       
  1274         address = var.getaddress()
       
  1275         if address:
       
  1276             tempvar["Location"] = address
       
  1277         else:
       
  1278             tempvar["Location"] = ""
       
  1279 
       
  1280         if varlist.getconstant():
       
  1281             tempvar["Option"] = "Constant"
       
  1282         elif varlist.getretain():
       
  1283             tempvar["Option"] = "Retain"
       
  1284         elif varlist.getnonretain():
       
  1285             tempvar["Option"] = "Non-Retain"
       
  1286         else:
       
  1287             tempvar["Option"] = ""
       
  1288 
       
  1289         doc = var.getdocumentation()
       
  1290         if doc:
       
  1291             tempvar["Documentation"] = doc.gettext()
       
  1292         else:
       
  1293             tempvar["Documentation"] = ""
       
  1294 
       
  1295         return tempvar
       
  1296     
       
  1297     # Add a global var to configuration to configuration
  1339     # Add a global var to configuration to configuration
  1298     def AddConfigurationGlobalVar(self, config_name, type, var_name, 
  1340     def AddConfigurationGlobalVar(self, config_name, var_type, var_name, 
  1299                                            location="", description=""):
  1341                                            location="", description=""):
  1300         if self.Project is not None:
  1342         if self.Project is not None:
  1301             # Found the configuration corresponding to name
  1343             # Found the configuration corresponding to name
  1302             configuration = self.Project.getconfiguration(config_name)
  1344             configuration = self.Project.getconfiguration(config_name)
  1303             if configuration is not None:
  1345             if configuration is not None:
  1304                 # Set configuration global vars
  1346                 # Set configuration global vars
  1305                 configuration.addglobalVar(type, var_name, location, description)
  1347                 configuration.addglobalVar(
       
  1348                     self.GetVarTypeObject(var_type), 
       
  1349                     var_name, location, description)
  1306 
  1350 
  1307     # Replace the configuration globalvars by those given
  1351     # Replace the configuration globalvars by those given
  1308     def SetConfigurationGlobalVars(self, name, vars):
  1352     def SetConfigurationGlobalVars(self, name, vars):
  1309         if self.Project is not None:
  1353         if self.Project is not None:
  1310             # Found the configuration corresponding to name
  1354             # Found the configuration corresponding to name
  1311             configuration = self.Project.getconfiguration(name)
  1355             configuration = self.Project.getconfiguration(name)
  1312             if configuration is not None:
  1356             if configuration is not None:
  1313                 # Set configuration global vars
  1357                 # Set configuration global vars
  1314                 configuration.setglobalVars([])
  1358                 configuration.setglobalVars([
  1315                 for vartype, varlist in self.ExtractVarLists(vars):
  1359                     varlist for vartype, varlist
  1316                     configuration.globalVars.append(varlist)
  1360                     in self.ExtractVarLists(vars)])
  1317     
  1361     
  1318     # Return the configuration globalvars
  1362     # Return the configuration globalvars
  1319     def GetConfigurationGlobalVars(self, name, debug = False):
  1363     def GetConfigurationGlobalVars(self, name, debug = False):
  1320         vars = []
       
  1321         project = self.GetProject(debug)
  1364         project = self.GetProject(debug)
  1322         if project is not None:
  1365         if project is not None:
  1323             # Found the configuration corresponding to name
  1366             # Found the configuration corresponding to name
  1324             configuration = project.getconfiguration(name)
  1367             configuration = project.getconfiguration(name)
  1325             if configuration is not None:
  1368             if configuration is not None:
  1326                 # Extract variables from every varLists
  1369                 # Extract variables defined in configuration
  1327                 for varlist in configuration.getglobalVars():
  1370                 return self.GetVariableDictionary(configuration, debug)
  1328                     for var in varlist.getvariable():
  1371         
  1329                         tempvar = self.GetVariableDictionary(varlist, var)
  1372         return []
  1330                         tempvar["Class"] = "Global"
       
  1331                         vars.append(tempvar)
       
  1332         return vars
       
  1333 
  1373 
  1334     # Return configuration variable names
  1374     # Return configuration variable names
  1335     def GetConfigurationVariableNames(self, config_name = None, debug = False):
  1375     def GetConfigurationVariableNames(self, config_name = None, debug = False):
  1336         variables = []
  1376         variables = []
  1337         project = self.GetProject(debug)
  1377         project = self.GetProject(debug)
  1350         if self.Project is not None:
  1390         if self.Project is not None:
  1351             # Found the resource corresponding to name
  1391             # Found the resource corresponding to name
  1352             resource = self.Project.getconfigurationResource(config_name, name)
  1392             resource = self.Project.getconfigurationResource(config_name, name)
  1353             # Set resource global vars
  1393             # Set resource global vars
  1354             if resource is not None:
  1394             if resource is not None:
  1355                 resource.setglobalVars([])
  1395                 resource.setglobalVars([
  1356                 for vartype, varlist in self.ExtractVarLists(vars):
  1396                     varlist for vartype, varlist
  1357                     resource.globalVars.append(varlist)
  1397                     in self.ExtractVarLists(vars)])
  1358     
  1398     
  1359     # Return the resource globalvars
  1399     # Return the resource globalvars
  1360     def GetConfigurationResourceGlobalVars(self, config_name, name, debug = False):
  1400     def GetConfigurationResourceGlobalVars(self, config_name, name, debug = False):
  1361         vars = []
       
  1362         project = self.GetProject(debug)
  1401         project = self.GetProject(debug)
  1363         if project is not None:
  1402         if project is not None:
  1364             # Found the resource corresponding to name
  1403             # Found the resource corresponding to name
  1365             resource = project.getconfigurationResource(config_name, name)
  1404             resource = project.getconfigurationResource(config_name, name)
  1366             if resource:
  1405             if resource is not None:
  1367                 # Extract variables from every varLists
  1406                 # Extract variables defined in configuration
  1368                 for varlist in resource.getglobalVars():
  1407                 return self.GetVariableDictionary(resource, debug)
  1369                     for var in varlist.getvariable():
  1408         
  1370                         tempvar = self.GetVariableDictionary(varlist, var)
  1409         return []
  1371                         tempvar["Class"] = "Global"
       
  1372                         vars.append(tempvar)
       
  1373         return vars
       
  1374     
  1410     
  1375     # Return resource variable names
  1411     # Return resource variable names
  1376     def GetConfigurationResourceVariableNames(self, 
  1412     def GetConfigurationResourceVariableNames(self, 
  1377                 config_name = None, resource_name = None, debug = False):
  1413                 config_name = None, resource_name = None, debug = False):
  1378         variables = []
  1414         variables = []
  1386                                 [var.getname() for var in reduce(
  1422                                 [var.getname() for var in reduce(
  1387                                     lambda x, y: x + y, [varlist.getvariable() 
  1423                                     lambda x, y: x + y, [varlist.getvariable() 
  1388                                         for varlist in resource.globalVars],
  1424                                         for varlist in resource.globalVars],
  1389                                     [])])
  1425                                     [])])
  1390         return variables
  1426         return variables
  1391     
       
  1392     # Recursively generate element name tree for a structured variable
       
  1393     def GenerateVarTree(self, typename, debug = False):
       
  1394         project = self.GetProject(debug)
       
  1395         if project is not None:
       
  1396             blocktype = self.GetBlockType(typename, debug = debug)
       
  1397             if blocktype is not None:
       
  1398                 tree = []
       
  1399                 en = False
       
  1400                 eno = False
       
  1401                 for var_name, var_type, var_modifier in blocktype["inputs"] + blocktype["outputs"]:
       
  1402                     en |= var_name.upper() == "EN"
       
  1403                     eno |= var_name.upper() == "ENO"    
       
  1404                     tree.append((var_name, var_type, self.GenerateVarTree(var_type, debug)))
       
  1405                 if not eno:
       
  1406                     tree.insert(0, ("ENO", "BOOL", ([], [])))
       
  1407                 if not en:
       
  1408                     tree.insert(0, ("EN", "BOOL", ([], [])))
       
  1409                 return tree, []
       
  1410             datatype = project.getdataType(typename)
       
  1411             if datatype is None:
       
  1412                 datatype = self.GetConfNodeDataType(typename)
       
  1413             if datatype is not None:
       
  1414                 tree = []
       
  1415                 basetype_content = datatype.baseType.getcontent()
       
  1416                 if basetype_content["name"] == "derived":
       
  1417                     return self.GenerateVarTree(basetype_content["value"].getname())
       
  1418                 elif basetype_content["name"] == "array":
       
  1419                     dimensions = []
       
  1420                     base_type = basetype_content["value"].baseType.getcontent()
       
  1421                     if base_type["name"] == "derived":
       
  1422                         tree = self.GenerateVarTree(base_type["value"].getname())
       
  1423                         if len(tree[1]) == 0:
       
  1424                             tree = tree[0]
       
  1425                         for dimension in basetype_content["value"].getdimension():
       
  1426                             dimensions.append((dimension.getlower(), dimension.getupper()))
       
  1427                     return tree, dimensions
       
  1428                 elif basetype_content["name"] == "struct":
       
  1429                     for element in basetype_content["value"].getvariable():
       
  1430                         element_type = element.type.getcontent()
       
  1431                         if element_type["name"] == "derived":
       
  1432                             tree.append((element.getname(), element_type["value"].getname(), self.GenerateVarTree(element_type["value"].getname())))
       
  1433                         else:
       
  1434                             tree.append((element.getname(), element_type["name"], ([], [])))
       
  1435                     return tree, []
       
  1436         return [], []
       
  1437 
  1427 
  1438     # Return the interface for the given pou
  1428     # Return the interface for the given pou
  1439     def GetPouInterfaceVars(self, pou, debug = False):
  1429     def GetPouInterfaceVars(self, pou, tree=False, debug = False):
  1440         vars = []
  1430         interface = pou.interface
  1441         # Verify that the pou has an interface
  1431         # Verify that the pou has an interface
  1442         if pou.interface is not None:
  1432         if interface is not None:
  1443             # Extract variables from every varLists
  1433             # Extract variables defined in interface
  1444             for type, varlist in pou.getvars():
  1434             return self.GetVariableDictionary(interface, tree, debug)
  1445                 for var in varlist.getvariable():
  1435         return []
  1446                     tempvar = self.GetVariableDictionary(varlist, var)
       
  1447 
       
  1448                     tempvar["Class"] = type
       
  1449                     tempvar["Tree"] = ([], [])
       
  1450 
       
  1451                     vartype_content = var.gettype().getcontent()
       
  1452                     if vartype_content["name"] == "derived":
       
  1453                         tempvar["Edit"] = not pou.hasblock(tempvar["Name"])
       
  1454                         tempvar["Tree"] = self.GenerateVarTree(tempvar["Type"], debug)
       
  1455 
       
  1456                     vars.append(tempvar)
       
  1457         return vars
       
  1458 
  1436 
  1459     # Replace the Pou interface by the one given
  1437     # Replace the Pou interface by the one given
  1460     def SetPouInterfaceVars(self, name, vars):
  1438     def SetPouInterfaceVars(self, name, vars):
  1461         if self.Project is not None:
  1439         if self.Project is not None:
  1462             # Found the pou corresponding to name and add interface if there isn't one yet
  1440             # Found the pou corresponding to name and add interface if there isn't one yet
  1463             pou = self.Project.getpou(name)
  1441             pou = self.Project.getpou(name)
  1464             if pou is not None:
  1442             if pou is not None:
  1465                 if pou.interface is None:
  1443                 if pou.interface is None:
  1466                     pou.interface = plcopen.pou_interface()
  1444                     pou.interface = PLCOpenParser.CreateElement("interface", "pou")
  1467                 # Set Pou interface
  1445                 # Set Pou interface
  1468                 pou.setvars(self.ExtractVarLists(vars))
  1446                 pou.setvars([varlist for varlist_type, varlist in self.ExtractVarLists(vars)])
  1469                 self.Project.RefreshElementUsingTree()
  1447                 
  1470                 self.Project.RefreshCustomBlockTypes()
       
  1471     
       
  1472     # Replace the return type of the pou given by its name (only for functions)
  1448     # Replace the return type of the pou given by its name (only for functions)
  1473     def SetPouInterfaceReturnType(self, name, type):
  1449     def SetPouInterfaceReturnType(self, name, return_type):
  1474         if self.Project is not None:
  1450         if self.Project is not None:
  1475             pou = self.Project.getpou(name)
  1451             pou = self.Project.getpou(name)
  1476             if pou is not None:
  1452             if pou is not None:
  1477                 if pou.interface is None:
  1453                 if pou.interface is None:
  1478                     pou.interface = plcopen.pou_interface()
  1454                     pou.interface = PLCOpenParser.CreateElement("interface", "pou")
  1479                 # If there isn't any return type yet, add it
  1455                 # If there isn't any return type yet, add it
  1480                 return_type = pou.interface.getreturnType()
  1456                 return_type_obj = pou.interface.getreturnType()
  1481                 if not return_type:
  1457                 if return_type_obj is None:
  1482                     return_type = plcopen.dataType()
  1458                     return_type_obj = PLCOpenParser.CreateElement("returnType", "interface")
  1483                     pou.interface.setreturnType(return_type)
  1459                     pou.interface.setreturnType(return_type_obj)
  1484                 # Change return type
  1460                 # Change return type
  1485                 if type in self.GetBaseTypes():
  1461                 if return_type in self.GetBaseTypes():
  1486                     if type == "STRING":
  1462                     return_type_obj.setcontent(PLCOpenParser.CreateElement(
  1487                         return_type.setcontent({"name" : "string", "value" : plcopen.elementaryTypes_string()})
  1463                         return_type.lower()
  1488                     elif type == "WSTRING":
  1464                         if return_type in ["STRING", "WSTRING"]
  1489                         return_type.setcontent({"name" : "wstring", "value" : plcopen.elementaryTypes_wstring()})
  1465                         else return_type, "dataType"))
  1490                     else:
       
  1491                         return_type.setcontent({"name" : type, "value" : None})
       
  1492                 else:
  1466                 else:
  1493                     derived_type = plcopen.derivedTypes_derived()
  1467                     derived_type = PLCOpenParser.CreateElement("derived", "dataType")
  1494                     derived_type.setname(type)
  1468                     derived_type.setname(return_type)
  1495                     return_type.setcontent({"name" : "derived", "value" : derived_type})
  1469                     return_type.setcontent(derived_type)
  1496                 self.Project.RefreshElementUsingTree()
  1470                 
  1497                 self.Project.RefreshCustomBlockTypes()
       
  1498     
       
  1499     def UpdateProjectUsedPous(self, old_name, new_name):
  1471     def UpdateProjectUsedPous(self, old_name, new_name):
  1500         if self.Project:
  1472         if self.Project is not None:
  1501             self.Project.updateElementName(old_name, new_name)
  1473             self.Project.updateElementName(old_name, new_name)
  1502     
  1474     
  1503     def UpdateEditedElementUsedVariable(self, tagname, old_name, new_name):
  1475     def UpdateEditedElementUsedVariable(self, tagname, old_name, new_name):
  1504         pou = self.GetEditedElement(tagname)
  1476         pou = self.GetEditedElement(tagname)
  1505         if pou:
  1477         if pou is not None:
  1506             pou.updateElementName(old_name, new_name)
  1478             pou.updateElementName(old_name, new_name)
  1507     
  1479     
  1508     # Return the return type of the pou given by its name
       
  1509     def GetPouInterfaceReturnTypeByName(self, name):
       
  1510         project = self.GetProject(debug)
       
  1511         if project is not None:
       
  1512             # Found the pou correponding to name and return the return type
       
  1513             pou = project.getpou(name)
       
  1514             if pou is not None:
       
  1515                 return self.GetPouInterfaceReturnType(pou)
       
  1516         return False
       
  1517     
       
  1518     # Return the return type of the given pou
  1480     # Return the return type of the given pou
  1519     def GetPouInterfaceReturnType(self, pou):
  1481     def GetPouInterfaceReturnType(self, pou, tree=False, debug=False):
  1520         # Verify that the pou has an interface
  1482         # Verify that the pou has an interface
  1521         if pou.interface is not None:
  1483         if pou.interface is not None:
  1522             # Return the return type if there is one
  1484             # Return the return type if there is one
  1523             return_type = pou.interface.getreturnType()
  1485             return_type = pou.interface.getreturnType()
  1524             if return_type:
  1486             if return_type is not None:
  1525                 returntype_content = return_type.getcontent()
  1487                 factory = VariablesInfosFactory([])
  1526                 if returntype_content["name"] == "derived":
  1488         
  1527                     return returntype_content["value"].getname()
  1489                 parser = etree.XMLParser()
  1528                 elif returntype_content["name"] in ["string", "wstring"]:
  1490                 if tree:
  1529                     return returntype_content["name"].upper()
  1491                     parser.resolvers.add(LibraryResolver(self))
  1530                 else:
  1492                 
  1531                     return returntype_content["name"]
  1493                 return_type_infos_xslt_tree = etree.XSLT(
       
  1494                     etree.parse(
       
  1495                         os.path.join(ScriptDirectory, "plcopen", "variables_infos.xslt"),
       
  1496                         parser), 
       
  1497                     extensions = {("var_infos_ns", name): getattr(factory, name)
       
  1498                                   for name in ["SetType", "AddDimension", 
       
  1499                                                "AddTree", "AddVarToTree"]})
       
  1500                 return_type_infos_xslt_tree(return_type,
       
  1501                     tree=etree.XSLT.strparam(str(tree)))
       
  1502                 if tree:
       
  1503                     return [factory.GetType(), factory.GetTree()]
       
  1504                 return factory.GetType()
       
  1505         
       
  1506         if tree:
       
  1507             return [None, ([], [])]
  1532         return None
  1508         return None
  1533 
  1509 
  1534     # Function that add a new confnode to the confnode list
  1510     # Function that add a new confnode to the confnode list
  1535     def AddConfNodeTypesList(self, typeslist):
  1511     def AddConfNodeTypesList(self, typeslist):
  1536         self.ConfNodeTypes.extend(typeslist)
  1512         self.ConfNodeTypes.extend(typeslist)
       
  1513         addedcat = [{"name": _("%s POUs") % confnodetypes["name"],
       
  1514                      "list": [pou.getblockInfos()
       
  1515                               for pou in confnodetypes["types"].getpous()]}
       
  1516                      for confnodetypes in typeslist]
       
  1517         self.TotalTypes.extend(addedcat)
       
  1518         for cat in addedcat:
       
  1519             for desc in cat["list"]:
       
  1520                 BlkLst = self.TotalTypesDict.setdefault(desc["name"],[])
       
  1521                 BlkLst.append((section["name"], desc))
  1537         
  1522         
  1538     # Function that clear the confnode list
  1523     # Function that clear the confnode list
  1539     def ClearConfNodeTypes(self):
  1524     def ClearConfNodeTypes(self):
  1540         for i in xrange(len(self.ConfNodeTypes)):
  1525         self.ConfNodeTypes = []
  1541             self.ConfNodeTypes.pop(0)
  1526         self.TotalTypesDict = StdBlckDct.copy()
  1542 
  1527         self.TotalTypes = StdBlckLst[:]
  1543     def GetConfNodeBlockTypes(self):
  1528 
  1544         return [{"name": _("%s POUs") % confnodetypes["name"],
  1529     def GetConfNodeDataTypes(self, exclude = None, only_locatables = False):
  1545                  "list": confnodetypes["types"].GetCustomBlockTypes()}
  1530         return [{"name": _("%s Data Types") % confnodetypes["name"],
       
  1531                  "list": [
       
  1532                     datatype.getname() 
       
  1533                     for datatype in confnodetypes["types"].getdataTypes()
       
  1534                     if not only_locatables or self.IsLocatableDataType(datatype, debug)]}
  1546                 for confnodetypes in self.ConfNodeTypes]
  1535                 for confnodetypes in self.ConfNodeTypes]
  1547         
       
  1548     def GetConfNodeDataTypes(self, exclude = "", only_locatables = False):
       
  1549         return [{"name": _("%s Data Types") % confnodetypes["name"],
       
  1550                  "list": [datatype["name"] for datatype in confnodetypes["types"].GetCustomDataTypes(exclude, only_locatables)]}
       
  1551                 for confnodetypes in self.ConfNodeTypes]
       
  1552     
       
  1553     def GetConfNodeDataType(self, type):
       
  1554         for confnodetype in self.ConfNodeTypes:
       
  1555             datatype = confnodetype["types"].getdataType(type)
       
  1556             if datatype is not None:
       
  1557                 return datatype
       
  1558         return None
       
  1559     
  1536     
  1560     def GetVariableLocationTree(self):
  1537     def GetVariableLocationTree(self):
  1561         return []
  1538         return []
  1562 
  1539 
  1563     def GetConfNodeGlobalInstances(self):
  1540     def GetConfNodeGlobalInstances(self):
  1564         return []
  1541         return []
  1565 
  1542 
  1566     def GetConfigurationExtraVariables(self):
  1543     def GetConfigurationExtraVariables(self):
  1567         global_vars = []
  1544         global_vars = []
  1568         for var_name, var_type, var_initial in self.GetConfNodeGlobalInstances():
  1545         for var_name, var_type, var_initial in self.GetConfNodeGlobalInstances():
  1569             tempvar = plcopen.varListPlain_variable()
  1546             tempvar = PLCOpenParser.CreateElement("variable", "globalVars")
  1570             tempvar.setname(var_name)
  1547             tempvar.setname(var_name)
  1571             
  1548             
  1572             tempvartype = plcopen.dataType()
  1549             tempvartype = PLCOpenParser.CreateElement("type", "variable")
  1573             if var_type in self.GetBaseTypes():
  1550             if var_type in self.GetBaseTypes():
  1574                 if var_type == "STRING":
  1551                 tempvartype.setcontent(PLCOpenParser.CreateElement(
  1575                     tempvartype.setcontent({"name" : "string", "value" : plcopen.elementaryTypes_string()})
  1552                     var_type.lower()
  1576                 elif var_type == "WSTRING":
  1553                     if var_type in ["STRING", "WSTRING"]
  1577                     tempvartype.setcontent({"name" : "wstring", "value" : plcopen.elementaryTypes_wstring()})
  1554                     else var_type, "dataType"))
  1578                 else:
       
  1579                     tempvartype.setcontent({"name" : var_type, "value" : None})
       
  1580             else:
  1555             else:
  1581                 tempderivedtype = plcopen.derivedTypes_derived()
  1556                 tempderivedtype = PLCOpenParser.CreateElement("derived", "dataType")
  1582                 tempderivedtype.setname(var_type)
  1557                 tempderivedtype.setname(var_type)
  1583                 tempvartype.setcontent({"name" : "derived", "value" : tempderivedtype})
  1558                 tempvartype.setcontent(tempderivedtype)
  1584             tempvar.settype(tempvartype)
  1559             tempvar.settype(tempvartype)
  1585             
  1560             
  1586             if var_initial != "":
  1561             if var_initial != "":
  1587                 value = plcopen.value()
  1562                 value = PLCOpenParser.CreateElement("initialValue", "variable")
  1588                 value.setvalue(var_initial)
  1563                 value.setvalue(var_initial)
  1589                 tempvar.setinitialValue(value)
  1564                 tempvar.setinitialValue(value)
  1590             
  1565             
  1591             global_vars.append(tempvar)
  1566             global_vars.append(tempvar)
  1592         return global_vars
  1567         return global_vars
  1593 
  1568 
  1594     # Function that returns the block definition associated to the block type given
  1569     # Function that returns the block definition associated to the block type given
  1595     def GetBlockType(self, type, inputs = None, debug = False):
  1570     def GetBlockType(self, typename, inputs = None, debug = False):
  1596         result_blocktype = None
  1571         result_blocktype = None
  1597         for category in BlockTypes + self.GetConfNodeBlockTypes():
  1572         for sectioname, blocktype in self.TotalTypesDict.get(typename,[]):
  1598             for blocktype in category["list"]:
  1573             if inputs is not None and inputs != "undefined":
  1599                 if blocktype["name"] == type:
  1574                 block_inputs = tuple([var_type for name, var_type, modifier in blocktype["inputs"]])
  1600                     if inputs is not None and inputs != "undefined":
  1575                 if reduce(lambda x, y: x and y, map(lambda x: x[0] == "ANY" or self.IsOfType(*x), zip(inputs, block_inputs)), True):
  1601                         block_inputs = tuple([var_type for name, var_type, modifier in blocktype["inputs"]])
  1576                     return blocktype
  1602                         if reduce(lambda x, y: x and y, map(lambda x: x[0] == "ANY" or self.IsOfType(*x), zip(inputs, block_inputs)), True):
  1577             else:
  1603                             return blocktype
  1578                 if result_blocktype is not None:
       
  1579                     if inputs == "undefined":
       
  1580                         return None
  1604                     else:
  1581                     else:
  1605                         if result_blocktype is not None:
  1582                         result_blocktype["inputs"] = [(i[0], "ANY", i[2]) for i in result_blocktype["inputs"]]
  1606                             if inputs == "undefined":
  1583                         result_blocktype["outputs"] = [(o[0], "ANY", o[2]) for o in result_blocktype["outputs"]]
  1607                                 return None
  1584                         return result_blocktype
  1608                             else:
  1585                 result_blocktype = blocktype.copy()
  1609                                 result_blocktype["inputs"] = [(i[0], "ANY", i[2]) for i in result_blocktype["inputs"]]
       
  1610                                 result_blocktype["outputs"] = [(o[0], "ANY", o[2]) for o in result_blocktype["outputs"]]
       
  1611                                 return result_blocktype
       
  1612                         result_blocktype = blocktype.copy()
       
  1613         if result_blocktype is not None:
  1586         if result_blocktype is not None:
  1614             return result_blocktype
  1587             return result_blocktype
  1615         project = self.GetProject(debug)
  1588         project = self.GetProject(debug)
  1616         if project is not None:
  1589         if project is not None:
  1617             return project.GetCustomBlockType(type, inputs)
  1590             blocktype = project.getpou(typename)
       
  1591             if blocktype is not None:
       
  1592                 blocktype_infos = blocktype.getblockInfos()
       
  1593                 if inputs in [None, "undefined"]:
       
  1594                     return blocktype_infos
       
  1595             
       
  1596                 if inputs == tuple([var_type 
       
  1597                     for name, var_type, modifier in blocktype_infos["inputs"]]):
       
  1598                     return blocktype_infos
       
  1599         
  1618         return None
  1600         return None
  1619 
  1601 
  1620     # Return Block types checking for recursion
  1602     # Return Block types checking for recursion
  1621     def GetBlockTypes(self, tagname = "", debug = False):
  1603     def GetBlockTypes(self, tagname = "", debug = False):
  1622         type = None
  1604         typename = None
  1623         words = tagname.split("::")
  1605         words = tagname.split("::")
  1624         if self.Project:
  1606         name = None
  1625             name = ""
  1607         project = self.GetProject(debug)
       
  1608         if project is not None:
       
  1609             pou_type = None
  1626             if words[0] in ["P","T","A"]:
  1610             if words[0] in ["P","T","A"]:
  1627                 name = words[1]
  1611                 name = words[1]
  1628                 type = self.GetPouType(name, debug)
  1612                 pou_type = self.GetPouType(name, debug)
  1629         if type == "function":
  1613             filter = (["function"] 
  1630             blocktypes = []
  1614                       if pou_type == "function" or words[0] == "T" 
  1631             for category in BlockTypes + self.GetConfNodeBlockTypes():
  1615                       else ["functionBlock", "function"])
  1632                 cat = {"name" : category["name"], "list" : []}
  1616             blocktypes = [
  1633                 for block in category["list"]:
  1617                 {"name": category["name"],
  1634                     if block["type"] == "function":
  1618                  "list": [block for block in category["list"]
  1635                         cat["list"].append(block)
  1619                           if block["type"] in filter]}
  1636                 if len(cat["list"]) > 0:
  1620                 for category in self.TotalTypes]
  1637                     blocktypes.append(cat)
  1621             blocktypes.append({"name" : USER_DEFINED_POUS, 
  1638         else:
  1622                 "list": [pou.getblockInfos()
  1639             blocktypes = [category for category in BlockTypes + self.GetConfNodeBlockTypes()]
  1623                          for pou in project.getpous(name, filter)
  1640         project = self.GetProject(debug)
  1624                          if (name is None or 
  1641         if project is not None:
  1625                              len(self.GetInstanceList(pou, name, debug)) == 0)]})
  1642             blocktypes.append({"name" : USER_DEFINED_POUS, "list": project.GetCustomBlockTypes(name, type == "function" or words[0] == "T")})
  1626             return blocktypes
  1643         return blocktypes
  1627         return self.TotalTypes
  1644 
  1628 
  1645     # Return Function Block types checking for recursion
  1629     # Return Function Block types checking for recursion
  1646     def GetFunctionBlockTypes(self, tagname = "", debug = False):
  1630     def GetFunctionBlockTypes(self, tagname = "", debug = False):
       
  1631         project = self.GetProject(debug)
       
  1632         words = tagname.split("::")
       
  1633         name = None
       
  1634         if project is not None and words[0] in ["P","T","A"]:
       
  1635             name = words[1]
  1647         blocktypes = []
  1636         blocktypes = []
  1648         for category in BlockTypes + self.GetConfNodeBlockTypes():
  1637         for blocks in self.TotalTypesDict.itervalues():
  1649             for block in category["list"]:
  1638             for sectioname,block in blocks:
  1650                 if block["type"] == "functionBlock":
  1639                 if block["type"] == "functionBlock":
  1651                     blocktypes.append(block["name"])
  1640                     blocktypes.append(block["name"])
  1652         project = self.GetProject(debug)
  1641         if project is not None:
  1653         if project is not None:
  1642             blocktypes.extend([pou.getname()
  1654             name = ""
  1643                 for pou in project.getpous(name, ["functionBlock"])
  1655             words = tagname.split("::")
  1644                 if (name is None or 
  1656             if words[0] in ["P","T","A"]:
  1645                     len(self.GetInstanceList(pou, name, debug)) == 0)])
  1657                 name = words[1]
       
  1658             blocktypes.extend(project.GetCustomFunctionBlockTypes(name))
       
  1659         return blocktypes
  1646         return blocktypes
  1660 
  1647 
  1661     # Return Block types checking for recursion
  1648     # Return Block types checking for recursion
  1662     def GetBlockResource(self, debug = False):
  1649     def GetBlockResource(self, debug = False):
  1663         blocktypes = []
  1650         blocktypes = []
  1664         for category in BlockTypes[:-1]:
  1651         for category in StdBlckLst[:-1]:
  1665             for blocktype in category["list"]:
  1652             for blocktype in category["list"]:
  1666                 if blocktype["type"] == "program":
  1653                 if blocktype["type"] == "program":
  1667                     blocktypes.append(blocktype["name"])
  1654                     blocktypes.append(blocktype["name"])
  1668         project = self.GetProject(debug)
  1655         project = self.GetProject(debug)
  1669         if project is not None:
  1656         if project is not None:
  1670             blocktypes.extend(project.GetCustomBlockResource())
  1657             blocktypes.extend(
       
  1658                 [pou.getname()
       
  1659                  for pou in project.getpous(filter=["program"])])
  1671         return blocktypes
  1660         return blocktypes
  1672 
  1661 
  1673     # Return Data Types checking for recursion
  1662     # Return Data Types checking for recursion
  1674     def GetDataTypes(self, tagname = "", basetypes = True, confnodetypes = True, only_locatables = False, debug = False):
  1663     def GetDataTypes(self, tagname = "", basetypes = True, confnodetypes = True, only_locatables = False, debug = False):
  1675         if basetypes:
  1664         if basetypes:
  1676             datatypes = self.GetBaseTypes()
  1665             datatypes = self.GetBaseTypes()
  1677         else:
  1666         else:
  1678             datatypes = []
  1667             datatypes = []
  1679         project = self.GetProject(debug)
  1668         project = self.GetProject(debug)
  1680         if project is not None:
  1669         name = None
  1681             name = ""
  1670         if project is not None:
  1682             words = tagname.split("::")
  1671             words = tagname.split("::")
  1683             if words[0] in ["D"]:
  1672             if words[0] in ["D"]:
  1684                 name = words[1]
  1673                 name = words[1]
  1685             datatypes.extend([datatype["name"] for datatype in project.GetCustomDataTypes(name, only_locatables)])
  1674             datatypes.extend([
       
  1675                 datatype.getname() 
       
  1676                 for datatype in project.getdataTypes(name)
       
  1677                 if (not only_locatables or self.IsLocatableDataType(datatype, debug))
       
  1678                     and (name is None or 
       
  1679                          len(self.GetInstanceList(datatype, name, debug)) == 0)])
  1686         if confnodetypes:
  1680         if confnodetypes:
  1687             for category in self.GetConfNodeDataTypes(name, only_locatables):
  1681             for category in self.GetConfNodeDataTypes(name, only_locatables):
  1688                 datatypes.extend(category["list"])
  1682                 datatypes.extend(category["list"])
  1689         return datatypes
  1683         return datatypes
  1690 
  1684 
  1691     # Return Base Type of given possible derived type
  1685     # Return Data Type Object
  1692     def GetBaseType(self, type, debug = False):
  1686     def GetPou(self, typename, debug = False):
  1693         project = self.GetProject(debug)
  1687         project = self.GetProject(debug)
  1694         if project is not None:
  1688         if project is not None:
  1695             result = project.GetBaseType(type)
  1689             result = project.getpou(typename)
       
  1690             if result is not None:
       
  1691                 return result
       
  1692         for standardlibrary in [StdBlockLibrary, AddnlBlockLibrary]:
       
  1693             result = standardlibrary.getpou(typename)
  1696             if result is not None:
  1694             if result is not None:
  1697                 return result
  1695                 return result
  1698         for confnodetype in self.ConfNodeTypes:
  1696         for confnodetype in self.ConfNodeTypes:
  1699             result = confnodetype["types"].GetBaseType(type)
  1697             result = confnodetype["types"].getpou(typename)
  1700             if result is not None:
  1698             if result is not None:
  1701                 return result
  1699                 return result
       
  1700         return None
       
  1701 
       
  1702 
       
  1703     # Return Data Type Object
       
  1704     def GetDataType(self, typename, debug = False):
       
  1705         project = self.GetProject(debug)
       
  1706         if project is not None:
       
  1707             result = project.getdataType(typename)
       
  1708             if result is not None:
       
  1709                 return result
       
  1710         for confnodetype in self.ConfNodeTypes:
       
  1711             result = confnodetype["types"].getdataType(typename)
       
  1712             if result is not None:
       
  1713                 return result
       
  1714         return None
       
  1715 
       
  1716     # Return Data Type Object Base Type
       
  1717     def GetDataTypeBaseType(self, datatype):
       
  1718         basetype_content = datatype.baseType.getcontent()
       
  1719         basetype_content_type = basetype_content.getLocalTag()
       
  1720         if basetype_content_type in ["array", "subrangeSigned", "subrangeUnsigned"]:
       
  1721             basetype = basetype_content.baseType.getcontent()
       
  1722             basetype_type = basetype.getLocalTag()
       
  1723             return (basetype.getname() if basetype_type == "derived"
       
  1724                     else basetype_type.upper())
       
  1725         return (basetype_content.getname() if basetype_content_type == "derived"
       
  1726                 else basetype_content_type.upper())
       
  1727         return None
       
  1728 
       
  1729     # Return Base Type of given possible derived type
       
  1730     def GetBaseType(self, typename, debug = False):
       
  1731         if TypeHierarchy.has_key(typename):
       
  1732             return typename
       
  1733         
       
  1734         datatype = self.GetDataType(typename, debug)
       
  1735         if datatype is not None:
       
  1736             basetype = self.GetDataTypeBaseType(datatype)
       
  1737             if basetype is not None:
       
  1738                 return self.GetBaseType(basetype, debug)
       
  1739             return typename
       
  1740         
  1702         return None
  1741         return None
  1703 
  1742 
  1704     def GetBaseTypes(self):
  1743     def GetBaseTypes(self):
  1705         '''
  1744         '''
  1706         return the list of datatypes defined in IEC 61131-3.
  1745         return the list of datatypes defined in IEC 61131-3.
  1707         TypeHierarchy_list has a rough order to it (e.g. SINT, INT, DINT, ...),
  1746         TypeHierarchy_list has a rough order to it (e.g. SINT, INT, DINT, ...),
  1708         which makes it easy for a user to find a type in a menu.
  1747         which makes it easy for a user to find a type in a menu.
  1709         '''
  1748         '''
  1710         return [x for x,y in TypeHierarchy_list if not x.startswith("ANY")]
  1749         return [x for x,y in TypeHierarchy_list if not x.startswith("ANY")]
  1711 
  1750 
  1712     def IsOfType(self, type, reference, debug = False):
  1751     def IsOfType(self, typename, reference, debug = False):
  1713         if reference is None:
  1752         if reference is None or typename == reference:
  1714             return True
  1753             return True
  1715         elif type == reference:
  1754         
  1716             return True
  1755         basetype = TypeHierarchy.get(typename)
  1717         elif type in TypeHierarchy:
  1756         if basetype is not None:
  1718             return self.IsOfType(TypeHierarchy[type], reference)
  1757             return self.IsOfType(basetype, reference)
  1719         else:
  1758         
  1720             project = self.GetProject(debug)
  1759         datatype = self.GetDataType(typename, debug)
  1721             if project is not None and project.IsOfType(type, reference):
  1760         if datatype is not None:
  1722                 return True
  1761             basetype = self.GetDataTypeBaseType(datatype)
  1723             for confnodetype in self.ConfNodeTypes:
  1762             if basetype is not None:
  1724                 if confnodetype["types"].IsOfType(type, reference):
  1763                 return self.IsOfType(basetype, reference, debug)
  1725                     return True
  1764         
  1726         return False
  1765         return False
  1727     
  1766     
  1728     def IsEndType(self, type):
  1767     def IsEndType(self, typename):
  1729         if type is not None:
  1768         if typename is not None:
  1730             return not type.startswith("ANY")
  1769             return not typename.startswith("ANY")
  1731         return True
  1770         return True
  1732 
  1771 
  1733     def IsLocatableType(self, type, debug = False):
  1772     def IsLocatableDataType(self, datatype, debug = False):
  1734         if isinstance(type, TupleType):
  1773         basetype_content = datatype.baseType.getcontent()
  1735             return False 
  1774         basetype_content_type = basetype_content.getLocalTag()
  1736         if self.GetBlockType(type) is not None:
  1775         if basetype_content_type in ["enum", "struct"]:
  1737             return False
  1776             return False
  1738         project = self.GetProject(debug)
  1777         elif basetype_content_type == "derived":
  1739         if project is not None:
  1778             return self.IsLocatableType(basetype_content.getname())
  1740             datatype = project.getdataType(type)
  1779         elif basetype_content_type == "array":
  1741             if datatype is None:
  1780             array_base_type = basetype_content.baseType.getcontent()
  1742                 datatype = self.GetConfNodeDataType(type)
  1781             if array_base_type.getLocalTag() == "derived":
  1743             if datatype is not None:
  1782                 return self.IsLocatableType(array_base_type.getname(), debug)
  1744                 return project.IsLocatableType(datatype)
       
  1745         return True
  1783         return True
  1746     
  1784         
  1747     def IsEnumeratedType(self, type, debug = False):
  1785     def IsLocatableType(self, typename, debug = False):
  1748         project = self.GetProject(debug)
  1786         if isinstance(typename, TupleType) or self.GetBlockType(typename) is not None:
  1749         if project is not None:
  1787             return False
  1750             datatype = project.getdataType(type)
  1788         
  1751             if datatype is None:
  1789         datatype = self.GetDataType(typename, debug)
  1752                 datatype = self.GetConfNodeDataType(type)
  1790         if datatype is not None:
  1753             if datatype is not None:
  1791             return self.IsLocatableDataType(datatype)
  1754                 basetype_content = datatype.baseType.getcontent()
  1792         return True
  1755                 return basetype_content["name"] == "enum"
  1793     
       
  1794     def IsEnumeratedType(self, typename, debug = False):
       
  1795         if isinstance(typename, TupleType):
       
  1796             typename = typename[1]
       
  1797         datatype = self.GetDataType(typename, debug)
       
  1798         if datatype is not None:
       
  1799             basetype_content = datatype.baseType.getcontent()
       
  1800             basetype_content_type = basetype_content.getLocalTag()
       
  1801             if basetype_content_type == "derived":
       
  1802                 return self.IsEnumeratedType(basetype_content_type, debug)
       
  1803             return basetype_content_type == "enum"
  1756         return False
  1804         return False
  1757 
  1805 
  1758     def IsNumType(self, type, debug = False):
  1806     def IsSubrangeType(self, typename, exclude=None, debug = False):
  1759         return self.IsOfType(type, "ANY_NUM", debug) or\
  1807         if typename == exclude:
  1760                self.IsOfType(type, "ANY_BIT", debug)
  1808             return False
       
  1809         if isinstance(typename, TupleType):
       
  1810             typename = typename[1]
       
  1811         datatype = self.GetDataType(typename, debug)
       
  1812         if datatype is not None:
       
  1813             basetype_content = datatype.baseType.getcontent()
       
  1814             basetype_content_type = basetype_content.getLocalTag()
       
  1815             if basetype_content_type == "derived":
       
  1816                 return self.IsSubrangeType(basetype_content_type, exclude, debug)
       
  1817             elif basetype_content_type in ["subrangeSigned", "subrangeUnsigned"]:
       
  1818                 return not self.IsOfType(
       
  1819                     self.GetDataTypeBaseType(datatype), exclude)
       
  1820         return False
       
  1821 
       
  1822     def IsNumType(self, typename, debug = False):
       
  1823         return self.IsOfType(typename, "ANY_NUM", debug) or\
       
  1824                self.IsOfType(typename, "ANY_BIT", debug)
  1761             
  1825             
  1762     def GetDataTypeRange(self, type, debug = False):
  1826     def GetDataTypeRange(self, typename, debug = False):
  1763         if type in DataTypeRange:
  1827         range = DataTypeRange.get(typename)
  1764             return DataTypeRange[type]
  1828         if range is not None:
       
  1829             return range
       
  1830         datatype = self.GetDataType(typename, debug)
       
  1831         if datatype is not None:
       
  1832             basetype_content = datatype.baseType.getcontent()
       
  1833             basetype_content_type = basetype_content.getLocalTag()
       
  1834             if basetype_content_type in ["subrangeSigned", "subrangeUnsigned"]:
       
  1835                 return (basetype_content.range.getlower(),
       
  1836                         basetype_content.range.getupper())
       
  1837             elif basetype_content_type == "derived":
       
  1838                 return self.GetDataTypeRange(basetype_content.getname(), debug)
       
  1839         return None
       
  1840     
       
  1841     # Return Subrange types
       
  1842     def GetSubrangeBaseTypes(self, exclude, debug = False):
       
  1843         subrange_basetypes = DataTypeRange.keys()
       
  1844         project = self.GetProject(debug)
       
  1845         if project is not None:
       
  1846             subrange_basetypes.extend(
       
  1847                 [datatype.getname() for datatype in project.getdataTypes()
       
  1848                  if self.IsSubrangeType(datatype.getname(), exclude, debug)])
       
  1849         for confnodetype in self.ConfNodeTypes:
       
  1850             subrange_basetypes.extend(
       
  1851                 [datatype.getname() for datatype in confnodetype["types"].getdataTypes()
       
  1852                  if self.IsSubrangeType(datatype.getname(), exclude, debug)])
       
  1853         return subrange_basetypes
       
  1854     
       
  1855     # Return Enumerated Values
       
  1856     def GetEnumeratedDataValues(self, typename = None, debug = False):
       
  1857         values = []
       
  1858         if typename is not None:
       
  1859             datatype_obj = self.GetDataType(typename, debug)
       
  1860             if datatype_obj is not None:
       
  1861                 basetype_content = datatype_obj.baseType.getcontent()
       
  1862                 basetype_content_type = basetype_content.getLocalTag()
       
  1863                 if basetype_content_type == "enum":
       
  1864                     return [value.getname() 
       
  1865                             for value in basetype_content.xpath(
       
  1866                                 "ppx:values/ppx:value",
       
  1867                                 namespaces=PLCOpenParser.NSMAP)]
       
  1868                 elif basetype_content_type == "derived":
       
  1869                     return self.GetEnumeratedDataValues(basetype_content.getname(), debug)
  1765         else:
  1870         else:
  1766             project = self.GetProject(debug)
  1871             project = self.GetProject(debug)
  1767             if project is not None:
  1872             if project is not None:
  1768                 result = project.GetDataTypeRange(type)
  1873                 values.extend(project.GetEnumeratedDataTypeValues())
  1769                 if result is not None:
       
  1770                     return result
       
  1771             for confnodetype in self.ConfNodeTypes:
  1874             for confnodetype in self.ConfNodeTypes:
  1772                 result = confnodetype["types"].GetDataTypeRange(type)
  1875                 values.extend(confnodetype["types"].GetEnumeratedDataTypeValues())
  1773                 if result is not None:
       
  1774                     return result
       
  1775         return None
       
  1776     
       
  1777     # Return Subrange types
       
  1778     def GetSubrangeBaseTypes(self, exclude, debug = False):
       
  1779         subrange_basetypes = []
       
  1780         project = self.GetProject(debug)
       
  1781         if project is not None:
       
  1782             subrange_basetypes.extend(project.GetSubrangeBaseTypes(exclude))
       
  1783         for confnodetype in self.ConfNodeTypes:
       
  1784             subrange_basetypes.extend(confnodetype["types"].GetSubrangeBaseTypes(exclude))
       
  1785         return DataTypeRange.keys() + subrange_basetypes
       
  1786     
       
  1787     # Return Enumerated Values
       
  1788     def GetEnumeratedDataValues(self, type = None, debug = False):
       
  1789         values = []
       
  1790         project = self.GetProject(debug)
       
  1791         if project is not None:
       
  1792             values.extend(project.GetEnumeratedDataTypeValues(type))
       
  1793             if type is None and len(values) > 0:
       
  1794                 return values
       
  1795         for confnodetype in self.ConfNodeTypes:
       
  1796             values.extend(confnodetype["types"].GetEnumeratedDataTypeValues(type))
       
  1797             if type is None and len(values) > 0:
       
  1798                 return values
       
  1799         return values
  1876         return values
  1800 
  1877 
  1801 #-------------------------------------------------------------------------------
  1878 #-------------------------------------------------------------------------------
  1802 #                   Project Element tag name computation functions
  1879 #                   Project Element tag name computation functions
  1803 #-------------------------------------------------------------------------------
  1880 #-------------------------------------------------------------------------------
  1845                 infos = {}
  1922                 infos = {}
  1846                 datatype = project.getdataType(words[1])
  1923                 datatype = project.getdataType(words[1])
  1847                 if datatype is None:
  1924                 if datatype is None:
  1848                     return None
  1925                     return None
  1849                 basetype_content = datatype.baseType.getcontent()
  1926                 basetype_content = datatype.baseType.getcontent()
  1850                 if basetype_content["value"] is None or basetype_content["name"] in ["string", "wstring"]:
  1927                 basetype_content_type = basetype_content.getLocalTag()
  1851                     infos["type"] = "Directly"
  1928                 if basetype_content_type in ["subrangeSigned", "subrangeUnsigned"]:
  1852                     infos["base_type"] = basetype_content["name"].upper()
       
  1853                 elif basetype_content["name"] == "derived":
       
  1854                     infos["type"] = "Directly"
       
  1855                     infos["base_type"] = basetype_content["value"].getname()
       
  1856                 elif basetype_content["name"] in ["subrangeSigned", "subrangeUnsigned"]:
       
  1857                     infos["type"] = "Subrange"
  1929                     infos["type"] = "Subrange"
  1858                     infos["min"] = basetype_content["value"].range.getlower()
  1930                     infos["min"] = basetype_content.range.getlower()
  1859                     infos["max"] = basetype_content["value"].range.getupper()
  1931                     infos["max"] = basetype_content.range.getupper()
  1860                     base_type = basetype_content["value"].baseType.getcontent()
  1932                     base_type = basetype_content.baseType.getcontent()
  1861                     if base_type["value"] is None:
  1933                     base_type_type = base_type.getLocalTag()
  1862                         infos["base_type"] = base_type["name"]
  1934                     infos["base_type"] = (base_type.getname()
  1863                     else:
  1935                         if base_type_type == "derived"
  1864                         infos["base_type"] = base_type["value"].getname()
  1936                         else base_type_type)
  1865                 elif basetype_content["name"] == "enum":
  1937                 elif basetype_content_type == "enum":
  1866                     infos["type"] = "Enumerated"
  1938                     infos["type"] = "Enumerated"
  1867                     infos["values"] = []
  1939                     infos["values"] = []
  1868                     for value in basetype_content["value"].values.getvalue():
  1940                     for value in basetype_content.xpath("ppx:values/ppx:value", namespaces=PLCOpenParser.NSMAP):
  1869                         infos["values"].append(value.getname())
  1941                         infos["values"].append(value.getname())
  1870                 elif basetype_content["name"] == "array":
  1942                 elif basetype_content_type == "array":
  1871                     infos["type"] = "Array"
  1943                     infos["type"] = "Array"
  1872                     infos["dimensions"] = []
  1944                     infos["dimensions"] = []
  1873                     for dimension in basetype_content["value"].getdimension():
  1945                     for dimension in basetype_content.getdimension():
  1874                         infos["dimensions"].append((dimension.getlower(), dimension.getupper()))
  1946                         infos["dimensions"].append((dimension.getlower(), dimension.getupper()))
  1875                     base_type = basetype_content["value"].baseType.getcontent()
  1947                     base_type = basetype_content.baseType.getcontent()
  1876                     if base_type["value"] is None or base_type["name"] in ["string", "wstring"]:
  1948                     base_type_type = base_type.getLocalTag()
  1877                         infos["base_type"] = base_type["name"].upper()
  1949                     infos["base_type"] = (base_type.getname()
  1878                     else:
  1950                         if base_type_type == "derived"
  1879                         infos["base_type"] = base_type["value"].getname()
  1951                         else base_type_type.upper())
  1880                 elif basetype_content["name"] == "struct":
  1952                 elif basetype_content_type == "struct":
  1881                     infos["type"] = "Structure"
  1953                     infos["type"] = "Structure"
  1882                     infos["elements"] = []
  1954                     infos["elements"] = []
  1883                     for element in basetype_content["value"].getvariable():
  1955                     for element in basetype_content.getvariable():
  1884                         element_infos = {}
  1956                         element_infos = {}
  1885                         element_infos["Name"] = element.getname()
  1957                         element_infos["Name"] = element.getname()
  1886                         element_type = element.type.getcontent()
  1958                         element_type = element.type.getcontent()
  1887                         if element_type["value"] is None or element_type["name"] in ["string", "wstring"]:
  1959                         element_type_type = element_type.getLocalTag()
  1888                             element_infos["Type"] = element_type["name"].upper()
  1960                         if element_type_type == "array":
  1889                         elif element_type["name"] == "array":
       
  1890                             dimensions = []
  1961                             dimensions = []
  1891                             for dimension in element_type["value"].getdimension():
  1962                             for dimension in element_type.getdimension():
  1892                                 dimensions.append((dimension.getlower(), dimension.getupper()))
  1963                                 dimensions.append((dimension.getlower(), dimension.getupper()))
  1893                             base_type = element_type["value"].baseType.getcontent()
  1964                             base_type = element_type.baseType.getcontent()
  1894                             if base_type["value"] is None or base_type["name"] in ["string", "wstring"]:
  1965                             base_type_type = element_type.getLocalTag()
  1895                                 base_type_name = base_type["name"].upper()
  1966                             element_infos["Type"] = ("array", 
  1896                             else:
  1967                                 base_type.getname()
  1897                                 base_type_name = base_type["value"].getname()
  1968                                 if base_type_type == "derived"
  1898                             element_infos["Type"] = ("array", base_type_name, dimensions)
  1969                                 else base_type_type.upper(), dimensions)
       
  1970                         elif element_type_type == "derived":
       
  1971                             element_infos["Type"] = element_type.getname()
  1899                         else:
  1972                         else:
  1900                             element_infos["Type"] = element_type["value"].getname()
  1973                             element_infos["Type"] = element_type_type.upper()
  1901                         if element.initialValue is not None:
  1974                         if element.initialValue is not None:
  1902                             element_infos["Initial Value"] = str(element.initialValue.getvalue())
  1975                             element_infos["Initial Value"] = str(element.initialValue.getvalue())
  1903                         else:
  1976                         else:
  1904                             element_infos["Initial Value"] = ""
  1977                             element_infos["Initial Value"] = ""
  1905                         infos["elements"].append(element_infos)
  1978                         infos["elements"].append(element_infos)
       
  1979                 else:
       
  1980                     infos["type"] = "Directly"
       
  1981                     infos["base_type"] = (basetype_content.getname()
       
  1982                         if basetype_content_type == "derived"
       
  1983                         else basetype_content_type.upper())
       
  1984                 
  1906                 if datatype.initialValue is not None:
  1985                 if datatype.initialValue is not None:
  1907                     infos["initial"] = str(datatype.initialValue.getvalue())
  1986                     infos["initial"] = str(datatype.initialValue.getvalue())
  1908                 else:
  1987                 else:
  1909                     infos["initial"] = ""
  1988                     infos["initial"] = ""
  1910                 return infos
  1989                 return infos
  1915         words = tagname.split("::")
  1994         words = tagname.split("::")
  1916         if self.Project is not None and words[0] == "D":
  1995         if self.Project is not None and words[0] == "D":
  1917             datatype = self.Project.getdataType(words[1])
  1996             datatype = self.Project.getdataType(words[1])
  1918             if infos["type"] == "Directly":
  1997             if infos["type"] == "Directly":
  1919                 if infos["base_type"] in self.GetBaseTypes():
  1998                 if infos["base_type"] in self.GetBaseTypes():
  1920                     if infos["base_type"] == "STRING":
  1999                     datatype.baseType.setcontent(PLCOpenParser.CreateElement(
  1921                         datatype.baseType.setcontent({"name" : "string", "value" : plcopen.elementaryTypes_string()})
  2000                         infos["base_type"].lower()
  1922                     elif infos["base_type"] == "WSTRING":
  2001                         if infos["base_type"] in ["STRING", "WSTRING"]
  1923                         datatype.baseType.setcontent({"name" : "wstring", "value" : plcopen.elementaryTypes_wstring()})
  2002                         else infos["base_type"], "dataType"))
  1924                     else:
       
  1925                         datatype.baseType.setcontent({"name" : infos["base_type"], "value" : None})
       
  1926                 else:
  2003                 else:
  1927                     derived_datatype = plcopen.derivedTypes_derived()
  2004                     derived_datatype = PLCOpenParser.CreateElement("derived", "dataType")
  1928                     derived_datatype.setname(infos["base_type"])
  2005                     derived_datatype.setname(infos["base_type"])
  1929                     datatype.baseType.setcontent({"name" : "derived", "value" : derived_datatype})
  2006                     datatype.baseType.setcontent(derived_datatype)
  1930             elif infos["type"] == "Subrange":
  2007             elif infos["type"] == "Subrange":
  1931                 if infos["base_type"] in GetSubTypes("ANY_UINT"):
  2008                 subrange = PLCOpenParser.CreateElement(
  1932                     subrange = plcopen.derivedTypes_subrangeUnsigned()
  2009                     "subrangeUnsigned" 
  1933                     datatype.baseType.setcontent({"name" : "subrangeUnsigned", "value" : subrange})
  2010                     if infos["base_type"] in GetSubTypes("ANY_UINT")
  1934                 else:
  2011                     else "subrangeSigned", "dataType")
  1935                     subrange = plcopen.derivedTypes_subrangeSigned()
  2012                 datatype.baseType.setcontent(subrange)
  1936                     datatype.baseType.setcontent({"name" : "subrangeSigned", "value" : subrange})
       
  1937                 subrange.range.setlower(infos["min"])
  2013                 subrange.range.setlower(infos["min"])
  1938                 subrange.range.setupper(infos["max"])
  2014                 subrange.range.setupper(infos["max"])
  1939                 if infos["base_type"] in self.GetBaseTypes():
  2015                 if infos["base_type"] in self.GetBaseTypes():
  1940                     subrange.baseType.setcontent({"name" : infos["base_type"], "value" : None})
  2016                     subrange.baseType.setcontent(
       
  2017                         PLCOpenParser.CreateElement(infos["base_type"], "dataType"))
  1941                 else:
  2018                 else:
  1942                     derived_datatype = plcopen.derivedTypes_derived()
  2019                     derived_datatype = PLCOpenParser.CreateElement("derived", "dataType")
  1943                     derived_datatype.setname(infos["base_type"])
  2020                     derived_datatype.setname(infos["base_type"])
  1944                     subrange.baseType.setcontent({"name" : "derived", "value" : derived_datatype})
  2021                     subrange.baseType.setcontent(derived_datatype)
  1945             elif infos["type"] == "Enumerated":
  2022             elif infos["type"] == "Enumerated":
  1946                 enumerated = plcopen.derivedTypes_enum()
  2023                 enumerated = PLCOpenParser.CreateElement("enum", "dataType")
       
  2024                 datatype.baseType.setcontent(enumerated)
       
  2025                 values = PLCOpenParser.CreateElement("values", "enum")
       
  2026                 enumerated.setvalues(values)
  1947                 for i, enum_value in enumerate(infos["values"]):
  2027                 for i, enum_value in enumerate(infos["values"]):
  1948                     value = plcopen.values_value()
  2028                     value = PLCOpenParser.CreateElement("value", "values")
  1949                     value.setname(enum_value)
  2029                     value.setname(enum_value)
  1950                     if i == 0:
  2030                     if i == 0:
  1951                         enumerated.values.setvalue([value])
  2031                         values.setvalue([value])
  1952                     else:
  2032                     else:
  1953                         enumerated.values.appendvalue(value)
  2033                         values.appendvalue(value)
  1954                 datatype.baseType.setcontent({"name" : "enum", "value" : enumerated})
       
  1955             elif infos["type"] == "Array":
  2034             elif infos["type"] == "Array":
  1956                 array = plcopen.derivedTypes_array()
  2035                 array = PLCOpenParser.CreateElement("array", "dataType")
       
  2036                 datatype.baseType.setcontent(array)
  1957                 for i, dimension in enumerate(infos["dimensions"]):
  2037                 for i, dimension in enumerate(infos["dimensions"]):
  1958                     dimension_range = plcopen.rangeSigned()
  2038                     dimension_range = PLCOpenParser.CreateElement("dimension", "array")
  1959                     dimension_range.setlower(dimension[0])
  2039                     dimension_range.setlower(dimension[0])
  1960                     dimension_range.setupper(dimension[1])
  2040                     dimension_range.setupper(dimension[1])
  1961                     if i == 0:
  2041                     if i == 0:
  1962                         array.setdimension([dimension_range])
  2042                         array.setdimension([dimension_range])
  1963                     else:
  2043                     else:
  1964                         array.appenddimension(dimension_range)
  2044                         array.appenddimension(dimension_range)
  1965                 if infos["base_type"] in self.GetBaseTypes():
  2045                 if infos["base_type"] in self.GetBaseTypes():
  1966                     if infos["base_type"] == "STRING":
  2046                     array.baseType.setcontent(PLCOpenParser.CreateElement(
  1967                         array.baseType.setcontent({"name" : "string", "value" : plcopen.elementaryTypes_string()})
  2047                         infos["base_type"].lower()
  1968                     elif infos["base_type"] == "WSTRING":
  2048                         if infos["base_type"] in ["STRING", "WSTRING"]
  1969                         array.baseType.setcontent({"name" : "wstring", "value" : plcopen.wstring()})
  2049                         else infos["base_type"], "dataType"))
  1970                     else:
       
  1971                         array.baseType.setcontent({"name" : infos["base_type"], "value" : None})
       
  1972                 else:
  2050                 else:
  1973                     derived_datatype = plcopen.derivedTypes_derived()
  2051                     derived_datatype = PLCOpenParser.CreateElement("derived", "dataType")
  1974                     derived_datatype.setname(infos["base_type"])
  2052                     derived_datatype.setname(infos["base_type"])
  1975                     array.baseType.setcontent({"name" : "derived", "value" : derived_datatype})
  2053                     array.baseType.setcontent(derived_datatype)
  1976                 datatype.baseType.setcontent({"name" : "array", "value" : array})
       
  1977             elif infos["type"] == "Structure":
  2054             elif infos["type"] == "Structure":
  1978                 struct = plcopen.varListPlain()
  2055                 struct = PLCOpenParser.CreateElement("struct", "dataType")
       
  2056                 datatype.baseType.setcontent(struct)
  1979                 for i, element_infos in enumerate(infos["elements"]):
  2057                 for i, element_infos in enumerate(infos["elements"]):
  1980                     element = plcopen.varListPlain_variable()
  2058                     element = PLCOpenParser.CreateElement("variable", "struct")
  1981                     element.setname(element_infos["Name"])
  2059                     element.setname(element_infos["Name"])
       
  2060                     element_type = PLCOpenParser.CreateElement("type", "variable")
  1982                     if isinstance(element_infos["Type"], TupleType):
  2061                     if isinstance(element_infos["Type"], TupleType):
  1983                         if element_infos["Type"][0] == "array":
  2062                         if element_infos["Type"][0] == "array":
  1984                             array_type, base_type_name, dimensions = element_infos["Type"]
  2063                             array_type, base_type_name, dimensions = element_infos["Type"]
  1985                             array = plcopen.derivedTypes_array()
  2064                             array = PLCOpenParser.CreateElement("array", "dataType")
       
  2065                             element_type.setcontent(array)
  1986                             for j, dimension in enumerate(dimensions):
  2066                             for j, dimension in enumerate(dimensions):
  1987                                 dimension_range = plcopen.rangeSigned()
  2067                                 dimension_range = PLCOpenParser.CreateElement("dimension", "array")
  1988                                 dimension_range.setlower(dimension[0])
  2068                                 dimension_range.setlower(dimension[0])
  1989                                 dimension_range.setupper(dimension[1])
  2069                                 dimension_range.setupper(dimension[1])
  1990                                 if j == 0:
  2070                                 if j == 0:
  1991                                     array.setdimension([dimension_range])
  2071                                     array.setdimension([dimension_range])
  1992                                 else:
  2072                                 else:
  1993                                     array.appenddimension(dimension_range)
  2073                                     array.appenddimension(dimension_range)
  1994                             if base_type_name in self.GetBaseTypes():
  2074                             if base_type_name in self.GetBaseTypes():
  1995                                 if base_type_name == "STRING":
  2075                                 array.baseType.setcontent(PLCOpenParser.CreateElement(
  1996                                     array.baseType.setcontent({"name" : "string", "value" : plcopen.elementaryTypes_string()})
  2076                                     base_type_name.lower()
  1997                                 elif base_type_name == "WSTRING":
  2077                                     if base_type_name in ["STRING", "WSTRING"]
  1998                                     array.baseType.setcontent({"name" : "wstring", "value" : plcopen.wstring()})
  2078                                     else base_type_name, "dataType"))
  1999                                 else:
       
  2000                                     array.baseType.setcontent({"name" : base_type_name, "value" : None})
       
  2001                             else:
  2079                             else:
  2002                                 derived_datatype = plcopen.derivedTypes_derived()
  2080                                 derived_datatype = PLCOpenParser.CreateElement("derived", "dataType")
  2003                                 derived_datatype.setname(base_type_name)
  2081                                 derived_datatype.setname(base_type_name)
  2004                                 array.baseType.setcontent({"name" : "derived", "value" : derived_datatype})
  2082                                 array.baseType.setcontent(derived_datatype)
  2005                             element.type.setcontent({"name" : "array", "value" : array})
       
  2006                     elif element_infos["Type"] in self.GetBaseTypes():
  2083                     elif element_infos["Type"] in self.GetBaseTypes():
  2007                         if element_infos["Type"] == "STRING":
  2084                         element_type.setcontent(
  2008                             element.type.setcontent({"name" : "string", "value" : plcopen.elementaryTypes_string()})
  2085                             PLCOpenParser.CreateElement(
  2009                         elif element_infos["Type"] == "WSTRING":
  2086                                 element_infos["Type"].lower()
  2010                             element.type.setcontent({"name" : "wstring", "value" : plcopen.wstring()})
  2087                                 if element_infos["Type"] in ["STRING", "WSTRING"]
  2011                         else:
  2088                                 else element_infos["Type"], "dataType"))
  2012                             element.type.setcontent({"name" : element_infos["Type"], "value" : None})
       
  2013                     else:
  2089                     else:
  2014                         derived_datatype = plcopen.derivedTypes_derived()
  2090                         derived_datatype = PLCOpenParser.CreateElement("derived", "dataType")
  2015                         derived_datatype.setname(element_infos["Type"])
  2091                         derived_datatype.setname(element_infos["Type"])
  2016                         element.type.setcontent({"name" : "derived", "value" : derived_datatype})
  2092                         element_type.setcontent(derived_datatype)
       
  2093                     element.settype(element_type)
  2017                     if element_infos["Initial Value"] != "":
  2094                     if element_infos["Initial Value"] != "":
  2018                         value = plcopen.value()
  2095                         value = PLCOpenParser.CreateElement("initialValue", "variable")
  2019                         value.setvalue(element_infos["Initial Value"])
  2096                         value.setvalue(element_infos["Initial Value"])
  2020                         element.setinitialValue(value)
  2097                         element.setinitialValue(value)
  2021                     if i == 0:
  2098                     if i == 0:
  2022                         struct.setvariable([element])
  2099                         struct.setvariable([element])
  2023                     else:
  2100                     else:
  2024                         struct.appendvariable(element)
  2101                         struct.appendvariable(element)
  2025                 datatype.baseType.setcontent({"name" : "struct", "value" : struct})
       
  2026             if infos["initial"] != "":
  2102             if infos["initial"] != "":
  2027                 if datatype.initialValue is None:
  2103                 if datatype.initialValue is None:
  2028                     datatype.initialValue = plcopen.value()
  2104                     datatype.initialValue = PLCOpenParser.CreateElement("initialValue", "dataType")
  2029                 datatype.initialValue.setvalue(infos["initial"])
  2105                 datatype.initialValue.setvalue(infos["initial"])
  2030             else:
  2106             else:
  2031                 datatype.initialValue = None
  2107                 datatype.initialValue = None
  2032             self.Project.RefreshDataTypeHierarchy()
       
  2033             self.Project.RefreshElementUsingTree()
       
  2034             self.BufferProject()
  2108             self.BufferProject()
  2035     
  2109     
  2036 #-------------------------------------------------------------------------------
  2110 #-------------------------------------------------------------------------------
  2037 #                       Project opened Pous management functions
  2111 #                       Project opened Pous management functions
  2038 #-------------------------------------------------------------------------------
  2112 #-------------------------------------------------------------------------------
  2085         elif words[0] == 'A':
  2159         elif words[0] == 'A':
  2086             return self.GetActionBodyType(words[1], words[2], debug)
  2160             return self.GetActionBodyType(words[1], words[2], debug)
  2087         return None
  2161         return None
  2088 
  2162 
  2089     # Return the edited element variables
  2163     # Return the edited element variables
  2090     def GetEditedElementInterfaceVars(self, tagname, debug = False):
  2164     def GetEditedElementInterfaceVars(self, tagname, tree=False, debug = False):
  2091         words = tagname.split("::")
  2165         words = tagname.split("::")
  2092         if words[0] in ["P","T","A"]:
  2166         if words[0] in ["P","T","A"]:
  2093             project = self.GetProject(debug)
  2167             project = self.GetProject(debug)
  2094             if project is not None:
  2168             if project is not None:
  2095                 pou = project.getpou(words[1])
  2169                 pou = project.getpou(words[1])
  2096                 if pou is not None:
  2170                 if pou is not None:
  2097                     return self.GetPouInterfaceVars(pou, debug)
  2171                     return self.GetPouInterfaceVars(pou, tree, debug)
  2098         return []
  2172         return []
  2099 
  2173 
  2100     # Return the edited element return type
  2174     # Return the edited element return type
  2101     def GetEditedElementInterfaceReturnType(self, tagname, debug = False):
  2175     def GetEditedElementInterfaceReturnType(self, tagname, tree=False, debug = False):
  2102         words = tagname.split("::")
  2176         words = tagname.split("::")
  2103         if words[0] == "P":
  2177         if words[0] == "P":
  2104             project = self.GetProject(debug)
  2178             project = self.GetProject(debug)
  2105             if project is not None:
  2179             if project is not None:
  2106                 pou = self.Project.getpou(words[1])
  2180                 pou = self.Project.getpou(words[1])
  2107                 if pou is not None:
  2181                 if pou is not None:
  2108                     return self.GetPouInterfaceReturnType(pou)
  2182                     return self.GetPouInterfaceReturnType(pou, tree, debug)
  2109         elif words[0] == 'T':
  2183         elif words[0] == 'T':
  2110             return "BOOL"
  2184             return "BOOL"
  2111         return None
  2185         return None
  2112     
  2186     
  2113     # Change the edited element text
  2187     # Change the edited element text
  2114     def SetEditedElementText(self, tagname, text):
  2188     def SetEditedElementText(self, tagname, text):
  2115         if self.Project is not None:
  2189         if self.Project is not None:
  2116             element = self.GetEditedElement(tagname)
  2190             element = self.GetEditedElement(tagname)
  2117             if element is not None:
  2191             if element is not None:
  2118                 element.settext(text)
  2192                 element.settext(text)
  2119                 self.Project.RefreshElementUsingTree()
       
  2120     
  2193     
  2121     # Return the edited element text
  2194     # Return the edited element text
  2122     def GetEditedElementText(self, tagname, debug = False):
  2195     def GetEditedElementText(self, tagname, debug = False):
  2123         element = self.GetEditedElement(tagname, debug)
  2196         element = self.GetEditedElement(tagname, debug)
  2124         if element is not None:
  2197         if element is not None:
  2159         return []
  2232         return []
  2160 
  2233 
  2161     def GetEditedElementCopy(self, tagname, debug = False):
  2234     def GetEditedElementCopy(self, tagname, debug = False):
  2162         element = self.GetEditedElement(tagname, debug)
  2235         element = self.GetEditedElement(tagname, debug)
  2163         if element is not None:
  2236         if element is not None:
  2164             name = element.__class__.__name__
  2237             return element.tostring()
  2165             return element.generateXMLText(name.split("_")[-1], 0)
       
  2166         return ""
  2238         return ""
  2167         
  2239         
  2168     def GetEditedElementInstancesCopy(self, tagname, blocks_id = None, wires = None, debug = False):
  2240     def GetEditedElementInstancesCopy(self, tagname, blocks_id = None, wires = None, debug = False):
  2169         element = self.GetEditedElement(tagname, debug)
  2241         element = self.GetEditedElement(tagname, debug)
  2170         text = ""
  2242         text = ""
  2171         if element is not None:
  2243         if element is not None:
  2172             wires = dict([(wire, True) for wire in wires if wire[0] in blocks_id and wire[1] in blocks_id])
  2244             wires = dict([(wire, True) 
       
  2245                           for wire in wires 
       
  2246                           if wire[0] in blocks_id and wire[1] in blocks_id])
       
  2247             copy_body = PLCOpenParser.CreateElement("body", "pou")
       
  2248             element.append(copy_body)
       
  2249             copy_body.setcontent(
       
  2250                 PLCOpenParser.CreateElement(element.getbodyType(), "body"))
  2173             for id in blocks_id:
  2251             for id in blocks_id:
  2174                 instance = element.getinstance(id)
  2252                 instance = element.getinstance(id)
  2175                 if instance is not None:
  2253                 if instance is not None:
  2176                     instance_copy = self.Copy(instance)
  2254                     copy_body.appendcontentInstance(self.Copy(instance))
       
  2255                     instance_copy = copy_body.getcontentInstance(id)
  2177                     instance_copy.filterConnections(wires)
  2256                     instance_copy.filterConnections(wires)
  2178                     name = instance_copy.__class__.__name__
  2257                     text += instance_copy.tostring()
  2179                     text += instance_copy.generateXMLText(name.split("_")[-1], 0)
  2258             element.remove(copy_body)
  2180         return text
  2259         return text
  2181     
  2260     
  2182     def GenerateNewName(self, tagname, name, format, start_idx=0, exclude={}, debug=False):
  2261     def GenerateNewName(self, tagname, name, format, start_idx=0, exclude={}, debug=False):
  2183         names = exclude.copy()
  2262         names = exclude.copy()
  2184         if tagname is not None:
  2263         if tagname is not None:
  2187             words = tagname.split("::")
  2266             words = tagname.split("::")
  2188             if words[0] in ["P","T","A"]:
  2267             if words[0] in ["P","T","A"]:
  2189                 element = self.GetEditedElement(tagname, debug)
  2268                 element = self.GetEditedElement(tagname, debug)
  2190                 if element is not None and element.getbodyType() not in ["ST", "IL"]:
  2269                 if element is not None and element.getbodyType() not in ["ST", "IL"]:
  2191                     for instance in element.getinstances():
  2270                     for instance in element.getinstances():
  2192                         if isinstance(instance, (plcopen.sfcObjects_step, 
  2271                         if isinstance(instance, 
  2193                                                  plcopen.commonObjects_connector, 
  2272                             (PLCOpenParser.GetElementClass("step", "sfcObjects"), 
  2194                                                  plcopen.commonObjects_continuation)):
  2273                              PLCOpenParser.GetElementClass("connector", "commonObjects"), 
       
  2274                              PLCOpenParser.GetElementClass("continuation", "commonObjects"))):
  2195                             names[instance.getname().upper()] = True
  2275                             names[instance.getname().upper()] = True
  2196         else:
  2276         else:
  2197             project = self.GetProject(debug)
  2277             project = self.GetProject(debug)
  2198             if project is not None:
  2278             if project is not None:
  2199                 for datatype in project.getdataTypes():
  2279                 for datatype in project.getdataTypes():
  2200                     names[datatype.getname().upper()] = True
  2280                     names[datatype.getname().upper()] = True
  2201                 for pou in project.getpous():
  2281                 for pou in project.getpous():
  2202                     names[pou.getname().upper()] = True
  2282                     names[pou.getname().upper()] = True
  2203                     for var in self.GetPouInterfaceVars(pou, debug):
  2283                     for var in self.GetPouInterfaceVars(pou, debug=debug):
  2204                         names[var["Name"].upper()] = True
  2284                         names[var.Name.upper()] = True
  2205                     for transition in pou.gettransitionList():
  2285                     for transition in pou.gettransitionList():
  2206                         names[transition.getname().upper()] = True
  2286                         names[transition.getname().upper()] = True
  2207                     for action in pou.getactionList():
  2287                     for action in pou.getactionList():
  2208                         names[action.getname().upper()] = True
  2288                         names[action.getname().upper()] = True
  2209                 for config in project.getconfigurations():
  2289                 for config in project.getconfigurations():
  2214         i = start_idx
  2294         i = start_idx
  2215         while name is None or names.get(name.upper(), False):
  2295         while name is None or names.get(name.upper(), False):
  2216             name = (format%i)
  2296             name = (format%i)
  2217             i += 1
  2297             i += 1
  2218         return name
  2298         return name
  2219     
       
  2220     CheckPasteCompatibility = {"SFC": lambda name: True,
       
  2221                                "LD": lambda name: not name.startswith("sfcObjects"),
       
  2222                                "FBD": lambda name: name.startswith("fbdObjects") or name.startswith("commonObjects")}
       
  2223     
  2299     
  2224     def PasteEditedElementInstances(self, tagname, text, new_pos, middle=False, debug=False):
  2300     def PasteEditedElementInstances(self, tagname, text, new_pos, middle=False, debug=False):
  2225         element = self.GetEditedElement(tagname, debug)
  2301         element = self.GetEditedElement(tagname, debug)
  2226         element_name, element_type = self.GetEditedElementType(tagname, debug)
  2302         element_name, element_type = self.GetEditedElementType(tagname, debug)
  2227         if element is not None:
  2303         if element is not None:
  2236             
  2312             
  2237             # Get ids already by all the instances in edited element
  2313             # Get ids already by all the instances in edited element
  2238             used_id = dict([(instance.getlocalId(), True) for instance in element.getinstances()])
  2314             used_id = dict([(instance.getlocalId(), True) for instance in element.getinstances()])
  2239             new_id = {}
  2315             new_id = {}
  2240             
  2316             
  2241             text = "<paste>%s</paste>"%text
  2317             try:
       
  2318                 instances, error = LoadPouInstances(text.encode("utf-8"), bodytype)
       
  2319             except:
       
  2320                 instances, error = [], ""
       
  2321             if error is not None or len(instances) == 0:
       
  2322                 return _("Invalid plcopen element(s)!!!")
  2242             
  2323             
  2243             try:
       
  2244                 tree = minidom.parseString(text.encode("utf-8"))
       
  2245             except:
       
  2246                 return _("Invalid plcopen element(s)!!!")
       
  2247             instances = []
       
  2248             exclude = {}
  2324             exclude = {}
  2249             for root in tree.childNodes:
  2325             for instance in instances:
  2250                 if root.nodeType == tree.ELEMENT_NODE and root.nodeName == "paste":
  2326                 element.addinstance(instance)
  2251                     for child in root.childNodes:
  2327                 instance_type = instance.getLocalTag()
  2252                         if child.nodeType == tree.ELEMENT_NODE:
  2328                 if instance_type == "block":
  2253                             if not child.nodeName in plcopen.ElementNameToClass:
  2329                     blocktype = instance.gettypeName()
  2254                                 return _("\"%s\" element can't be pasted here!!!")%child.nodeName
  2330                     blocktype_infos = self.GetBlockType(blocktype)
  2255 
  2331                     blockname = instance.getinstanceName()
  2256                             classname = plcopen.ElementNameToClass[child.nodeName]
  2332                     if blocktype_infos["type"] != "function" and blockname is not None:
  2257                             if not self.CheckPasteCompatibility[bodytype](classname):
  2333                         if element_type == "function":
  2258                                 return _("\"%s\" element can't be pasted here!!!")%child.nodeName
  2334                             return _("FunctionBlock \"%s\" can't be pasted in a Function!!!")%blocktype
  2259 
  2335                         blockname = self.GenerateNewName(tagname, 
  2260                             classobj = getattr(plcopen, classname, None)
  2336                                                          blockname, 
  2261                             if classobj is not None:
  2337                                                          "%s%%d"%blocktype, 
  2262                                 instance = classobj()
  2338                                                          debug=debug)
  2263                                 instance.loadXMLTree(child)
  2339                         exclude[blockname] = True
  2264                                 if child.nodeName == "block":
  2340                         instance.setinstanceName(blockname)
  2265                                     blockname = instance.getinstanceName()
  2341                         self.AddEditedElementPouVar(tagname, blocktype, blockname)
  2266                                     if blockname is not None:
  2342                 elif instance_type == "step":
  2267                                         blocktype = instance.gettypeName()
  2343                     stepname = self.GenerateNewName(tagname, 
  2268                                         if element_type == "function":
  2344                                                     instance.getname(), 
  2269                                             return _("FunctionBlock \"%s\" can't be pasted in a Function!!!")%blocktype
  2345                                                     "Step%d", 
  2270                                         blockname = self.GenerateNewName(tagname, 
  2346                                                     exclude=exclude, 
  2271                                                                          blockname, 
  2347                                                     debug=debug)
  2272                                                                          "%s%%d"%blocktype, 
  2348                     exclude[stepname] = True
  2273                                                                          debug=debug)
  2349                     instance.setname(stepname)
  2274                                         exclude[blockname] = True
  2350                 localid = instance.getlocalId()
  2275                                         instance.setinstanceName(blockname)
  2351                 if not used_id.has_key(localid):
  2276                                         self.AddEditedElementPouVar(tagname, blocktype, blockname)
  2352                     new_id[localid] = True
  2277                                 elif child.nodeName == "step":
       
  2278                                     stepname = self.GenerateNewName(tagname, 
       
  2279                                                                     instance.getname(), 
       
  2280                                                                     "Step%d", 
       
  2281                                                                     exclude=exclude, 
       
  2282                                                                     debug=debug)
       
  2283                                     exclude[stepname] = True
       
  2284                                     instance.setname(stepname)
       
  2285                                 localid = instance.getlocalId()
       
  2286                                 if not used_id.has_key(localid):
       
  2287                                     new_id[localid] = True
       
  2288                                 instances.append((child.nodeName, instance))
       
  2289             
       
  2290             if len(instances) == 0:
       
  2291                 return _("Invalid plcopen element(s)!!!")
       
  2292             
  2353             
  2293             idx = 1
  2354             idx = 1
  2294             translate_id = {}
  2355             translate_id = {}
  2295             bbox = plcopen.rect()
  2356             bbox = rect()
  2296             for name, instance in instances:
  2357             for instance in instances:
  2297                 localId = instance.getlocalId()
  2358                 localId = instance.getlocalId()
  2298                 bbox.union(instance.getBoundingBox())
  2359                 bbox.union(instance.getBoundingBox())
  2299                 if used_id.has_key(localId):
  2360                 if used_id.has_key(localId):
  2300                     while used_id.has_key(idx) or new_id.has_key(idx):
  2361                     while used_id.has_key(idx) or new_id.has_key(idx):
  2301                         idx += 1
  2362                         idx += 1
  2321                 miny *= scaling[1]
  2382                 miny *= scaling[1]
  2322                 new_pos = (max(minx, round(new_pos[0] / scaling[0]) * scaling[0]),
  2383                 new_pos = (max(minx, round(new_pos[0] / scaling[0]) * scaling[0]),
  2323                            max(miny, round(new_pos[1] / scaling[1]) * scaling[1]))
  2384                            max(miny, round(new_pos[1] / scaling[1]) * scaling[1]))
  2324             else:
  2385             else:
  2325                 new_pos = (max(30, new_pos[0]), max(30, new_pos[1]))
  2386                 new_pos = (max(30, new_pos[0]), max(30, new_pos[1]))
  2326             diff = (new_pos[0] - x, new_pos[1] - y)
  2387             diff = (int(new_pos[0] - x), int(new_pos[1] - y))
  2327             
  2388             
  2328             connections = {}
  2389             connections = {}
  2329             for name, instance in instances:
  2390             for instance in instances:
  2330                 connections.update(instance.updateConnectionsId(translate_id))
  2391                 connections.update(instance.updateConnectionsId(translate_id))
  2331                 if getattr(instance, "setexecutionOrderId", None) is not None:
  2392                 if getattr(instance, "setexecutionOrderId", None) is not None:
  2332                     instance.setexecutionOrderId(0)
  2393                     instance.setexecutionOrderId(0)
  2333                 instance.translate(*diff)
  2394                 instance.translate(*diff)
  2334                 element.addinstance(name, instance)
       
  2335             
  2395             
  2336             return new_id, connections
  2396             return new_id, connections
  2337                 
  2397     
  2338     # Return the current pou editing informations
  2398     def GetEditedElementInstancesInfos(self, tagname, debug = False):
  2339     def GetEditedElementInstanceInfos(self, tagname, id = None, exclude = [], debug = False):
  2399         element_instances = OrderedDict()
  2340         infos = {}
       
  2341         instance = None
       
  2342         element = self.GetEditedElement(tagname, debug)
  2400         element = self.GetEditedElement(tagname, debug)
  2343         if element is not None:
  2401         if element is not None:
  2344             # if id is defined
  2402             factory = BlockInstanceFactory(element_instances)
  2345             if id is not None:
  2403             
  2346                 instance = element.getinstance(id)
  2404             pou_block_instances_xslt_tree = etree.XSLT(
  2347             else:
  2405                 pou_block_instances_xslt, 
  2348                 instance = element.getrandomInstance(exclude)
  2406                 extensions = {
  2349         if instance is not None:
  2407                     ("pou_block_instances_ns", name): getattr(factory, name)
  2350             infos = instance.getinfos()
  2408                     for name in ["AddBlockInstance", "SetSpecificValues",
  2351             if infos["type"] in ["input", "output", "inout"]:
  2409                                  "AddInstanceConnection", "AddConnectionLink",
  2352                 var_type = self.GetEditedElementVarValueType(tagname, infos["specific_values"]["name"], debug)
  2410                                  "AddLinkPoint", "AddAction"]})
  2353                 infos["specific_values"]["value_type"] = var_type
  2411         
  2354             return infos
  2412             pou_block_instances_xslt_tree(element)
  2355         return None
  2413         return element_instances
  2356     
  2414     
  2357     def ClearEditedElementExecutionOrder(self, tagname):
  2415     def ClearEditedElementExecutionOrder(self, tagname):
  2358         element = self.GetEditedElement(tagname)
  2416         element = self.GetEditedElement(tagname)
  2359         if element is not None:
  2417         if element is not None:
  2360             element.resetexecutionOrder()
  2418             element.resetexecutionOrder()
  2361     
  2419     
  2362     def ResetEditedElementExecutionOrder(self, tagname):
  2420     def ResetEditedElementExecutionOrder(self, tagname):
  2363         element = self.GetEditedElement(tagname)
  2421         element = self.GetEditedElement(tagname)
  2364         if element is not None:
  2422         if element is not None:
  2365             element.compileexecutionOrder()
  2423             element.compileexecutionOrder()
  2366     
       
  2367     # Return the variable type of the given pou
       
  2368     def GetEditedElementVarValueType(self, tagname, varname, debug = False):
       
  2369         project = self.GetProject(debug)
       
  2370         if project is not None:
       
  2371             words = tagname.split("::")
       
  2372             if words[0] in ["P","T","A"]:
       
  2373                 pou = self.Project.getpou(words[1])
       
  2374                 if pou is not None:
       
  2375                     if words[0] == "T" and varname == words[2]:
       
  2376                         return "BOOL"
       
  2377                     if words[1] == varname:
       
  2378                         return self.GetPouInterfaceReturnType(pou)
       
  2379                     for type, varlist in pou.getvars():
       
  2380                         for var in varlist.getvariable():
       
  2381                             if var.getname() == varname:
       
  2382                                 vartype_content = var.gettype().getcontent()
       
  2383                                 if vartype_content["name"] == "derived":
       
  2384                                     return vartype_content["value"].getname()
       
  2385                                 elif vartype_content["name"] in ["string", "wstring"]:
       
  2386                                     return vartype_content["name"].upper()
       
  2387                                 else:
       
  2388                                     return vartype_content["name"]
       
  2389         return None
       
  2390     
  2424     
  2391     def SetConnectionWires(self, connection, connector):
  2425     def SetConnectionWires(self, connection, connector):
  2392         wires = connector.GetWires()
  2426         wires = connector.GetWires()
  2393         idx = 0
  2427         idx = 0
  2394         for wire, handle in wires:
  2428         for wire, handle in wires:
  2408                     connection.setconnectionParameter(idx, formalParameter)
  2442                     connection.setconnectionParameter(idx, formalParameter)
  2409                 else:
  2443                 else:
  2410                     connection.setconnectionParameter(idx, None)
  2444                     connection.setconnectionParameter(idx, None)
  2411                 idx += 1
  2445                 idx += 1
  2412     
  2446     
  2413     def AddEditedElementPouVar(self, tagname, type, name, location="", description=""):
  2447     def GetVarTypeObject(self, var_type):
       
  2448         var_type_obj = PLCOpenParser.CreateElement("type", "variable")
       
  2449         if not var_type.startswith("ANY") and TypeHierarchy.get(var_type):
       
  2450             var_type_obj.setcontent(PLCOpenParser.CreateElement(
       
  2451                 var_type.lower() if var_type in ["STRING", "WSTRING"]
       
  2452                 else var_type, "dataType"))
       
  2453         else:
       
  2454             derived_type = PLCOpenParser.CreateElement("derived", "dataType")
       
  2455             derived_type.setname(var_type)
       
  2456             var_type_obj.setcontent(derived_type)
       
  2457         return var_type_obj
       
  2458     
       
  2459     def AddEditedElementPouVar(self, tagname, var_type, name, location="", description=""):
  2414         if self.Project is not None:
  2460         if self.Project is not None:
  2415             words = tagname.split("::")
  2461             words = tagname.split("::")
  2416             if words[0] in ['P', 'T', 'A']:
  2462             if words[0] in ['P', 'T', 'A']:
  2417                 pou = self.Project.getpou(words[1])
  2463                 pou = self.Project.getpou(words[1])
  2418                 if pou is not None:
  2464                 if pou is not None:
  2419                     pou.addpouLocalVar(type, name, location, description)
  2465                     pou.addpouLocalVar(
  2420     
  2466                         self.GetVarTypeObject(var_type), 
  2421     def AddEditedElementPouExternalVar(self, tagname, type, name):
  2467                         name, location, description)
       
  2468     
       
  2469     def AddEditedElementPouExternalVar(self, tagname, var_type, name):
  2422         if self.Project is not None:
  2470         if self.Project is not None:
  2423             words = tagname.split("::")
  2471             words = tagname.split("::")
  2424             if words[0] in ['P', 'T', 'A']:
  2472             if words[0] in ['P', 'T', 'A']:
  2425                 pou = self.Project.getpou(words[1])
  2473                 pou = self.Project.getpou(words[1])
  2426                 if pou is not None:
  2474                 if pou is not None:
  2427                     pou.addpouExternalVar(type, name)
  2475                     pou.addpouExternalVar(
       
  2476                         self.GetVarTypeObject(var_type), name)
  2428             
  2477             
  2429     def ChangeEditedElementPouVar(self, tagname, old_type, old_name, new_type, new_name):
  2478     def ChangeEditedElementPouVar(self, tagname, old_type, old_name, new_type, new_name):
  2430         if self.Project is not None:
  2479         if self.Project is not None:
  2431             words = tagname.split("::")
  2480             words = tagname.split("::")
  2432             if words[0] in ['P', 'T', 'A']:
  2481             if words[0] in ['P', 'T', 'A']:
  2443                     pou.removepouVar(type, name)
  2492                     pou.removepouVar(type, name)
  2444     
  2493     
  2445     def AddEditedElementBlock(self, tagname, id, blocktype, blockname = None):
  2494     def AddEditedElementBlock(self, tagname, id, blocktype, blockname = None):
  2446         element = self.GetEditedElement(tagname)
  2495         element = self.GetEditedElement(tagname)
  2447         if element is not None:
  2496         if element is not None:
  2448             block = plcopen.fbdObjects_block()
  2497             block = PLCOpenParser.CreateElement("block", "fbdObjects")
  2449             block.setlocalId(id)
  2498             block.setlocalId(id)
  2450             block.settypeName(blocktype)
  2499             block.settypeName(blocktype)
  2451             blocktype_infos = self.GetBlockType(blocktype)
  2500             blocktype_infos = self.GetBlockType(blocktype)
  2452             if blocktype_infos["type"] != "function" and blockname is not None:
  2501             if blocktype_infos["type"] != "function" and blockname is not None:
  2453                 block.setinstanceName(blockname)
  2502                 block.setinstanceName(blockname)
  2454                 self.AddEditedElementPouVar(tagname, blocktype, blockname)
  2503                 self.AddEditedElementPouVar(tagname, blocktype, blockname)
  2455             element.addinstance("block", block)
  2504             element.addinstance(block)
  2456             self.Project.RefreshElementUsingTree()
       
  2457     
  2505     
  2458     def SetEditedElementBlockInfos(self, tagname, id, infos):
  2506     def SetEditedElementBlockInfos(self, tagname, id, infos):
  2459         element = self.GetEditedElement(tagname)
  2507         element = self.GetEditedElement(tagname)
  2460         if element is not None:
  2508         if element is not None:
  2461             block = element.getinstance(id)
  2509             block = element.getinstance(id)
  2479                     self.ChangeEditedElementPouVar(tagname, old_type, old_name, new_type, new_name)
  2527                     self.ChangeEditedElementPouVar(tagname, old_type, old_name, new_type, new_name)
  2480             elif new_name != old_name:
  2528             elif new_name != old_name:
  2481                 self.ChangeEditedElementPouVar(tagname, old_type, old_name, new_type, new_name)
  2529                 self.ChangeEditedElementPouVar(tagname, old_type, old_name, new_type, new_name)
  2482             for param, value in infos.items():
  2530             for param, value in infos.items():
  2483                 if param == "name":
  2531                 if param == "name":
  2484                     block.setinstanceName(value)
  2532                     if value != "":
       
  2533                         block.setinstanceName(value)
       
  2534                     else:
       
  2535                         block.attrib.pop("instanceName", None)
  2485                 elif param == "type":
  2536                 elif param == "type":
  2486                     block.settypeName(value)
  2537                     block.settypeName(value)
  2487                 elif param == "executionOrder" and block.getexecutionOrderId() != value:
  2538                 elif param == "executionOrder" and block.getexecutionOrderId() != value:
  2488                     element.setelementExecutionOrder(block, value)
  2539                     element.setelementExecutionOrder(block, value)
  2489                 elif param == "height":
  2540                 elif param == "height":
  2496                     block.sety(value)
  2547                     block.sety(value)
  2497                 elif param == "connectors":
  2548                 elif param == "connectors":
  2498                     block.inputVariables.setvariable([])
  2549                     block.inputVariables.setvariable([])
  2499                     block.outputVariables.setvariable([])
  2550                     block.outputVariables.setvariable([])
  2500                     for connector in value["inputs"]:
  2551                     for connector in value["inputs"]:
  2501                         variable = plcopen.inputVariables_variable()
  2552                         variable = PLCOpenParser.CreateElement("variable", "inputVariables")
       
  2553                         block.inputVariables.appendvariable(variable)
  2502                         variable.setformalParameter(connector.GetName())
  2554                         variable.setformalParameter(connector.GetName())
  2503                         if connector.IsNegated():
  2555                         if connector.IsNegated():
  2504                             variable.setnegated(True)
  2556                             variable.setnegated(True)
  2505                         if connector.GetEdge() != "none":
  2557                         if connector.GetEdge() != "none":
  2506                             variable.setedge(connector.GetEdge())
  2558                             variable.setedge(connector.GetEdge())
  2507                         position = connector.GetRelPosition()
  2559                         position = connector.GetRelPosition()
  2508                         variable.connectionPointIn.setrelPositionXY(position.x, position.y)
  2560                         variable.connectionPointIn.setrelPositionXY(position.x, position.y)
  2509                         self.SetConnectionWires(variable.connectionPointIn, connector)
  2561                         self.SetConnectionWires(variable.connectionPointIn, connector)
  2510                         block.inputVariables.appendvariable(variable)
       
  2511                     for connector in value["outputs"]:
  2562                     for connector in value["outputs"]:
  2512                         variable = plcopen.outputVariables_variable()
  2563                         variable = PLCOpenParser.CreateElement("variable", "outputVariables")
       
  2564                         block.outputVariables.appendvariable(variable)
  2513                         variable.setformalParameter(connector.GetName())
  2565                         variable.setformalParameter(connector.GetName())
  2514                         if connector.IsNegated():
  2566                         if connector.IsNegated():
  2515                             variable.setnegated(True)
  2567                             variable.setnegated(True)
  2516                         if connector.GetEdge() != "none":
  2568                         if connector.GetEdge() != "none":
  2517                             variable.setedge(connector.GetEdge())
  2569                             variable.setedge(connector.GetEdge())
  2518                         position = connector.GetRelPosition()
  2570                         position = connector.GetRelPosition()
  2519                         variable.addconnectionPointOut()
  2571                         variable.addconnectionPointOut()
  2520                         variable.connectionPointOut.setrelPositionXY(position.x, position.y)
  2572                         variable.connectionPointOut.setrelPositionXY(position.x, position.y)
  2521                         block.outputVariables.appendvariable(variable)
  2573             block.tostring()
  2522             self.Project.RefreshElementUsingTree()
  2574         
  2523         
  2575     def AddEditedElementVariable(self, tagname, id, var_type):
  2524     def AddEditedElementVariable(self, tagname, id, type):
       
  2525         element = self.GetEditedElement(tagname)
  2576         element = self.GetEditedElement(tagname)
  2526         if element is not None:            
  2577         if element is not None:
  2527             if type == INPUT:
  2578             variable = PLCOpenParser.CreateElement(
  2528                 name = "inVariable"
  2579                 {INPUT: "inVariable",
  2529                 variable = plcopen.fbdObjects_inVariable()
  2580                  OUTPUT: "outVariable",
  2530             elif type == OUTPUT:
  2581                  INOUT: "inOutVariable"}[var_type], "fbdObjects")
  2531                 name = "outVariable"
       
  2532                 variable = plcopen.fbdObjects_outVariable()
       
  2533             elif type == INOUT:
       
  2534                 name = "inOutVariable"
       
  2535                 variable = plcopen.fbdObjects_inOutVariable()
       
  2536             variable.setlocalId(id)
  2582             variable.setlocalId(id)
  2537             element.addinstance(name, variable)
  2583             element.addinstance(variable)
  2538         
  2584         
  2539     def SetEditedElementVariableInfos(self, tagname, id, infos):
  2585     def SetEditedElementVariableInfos(self, tagname, id, infos):
  2540         element = self.GetEditedElement(tagname)
  2586         element = self.GetEditedElement(tagname)
  2541         if element is not None:
  2587         if element is not None:
  2542             variable = element.getinstance(id)
  2588             variable = element.getinstance(id)
  2543             if variable is None:
  2589             if variable is None:
  2544                 return 
  2590                 return 
  2545             for param, value in infos.items():
  2591             for param, value in infos.items():
  2546                 if param == "name":
  2592                 if param == "name":
  2547                     variable.setexpression(value)    
  2593                     variable.setexpression(value)
  2548                 elif param == "executionOrder" and variable.getexecutionOrderId() != value:
  2594                 elif param == "executionOrder" and variable.getexecutionOrderId() != value:
  2549                     element.setelementExecutionOrder(variable, value)
  2595                     element.setelementExecutionOrder(variable, value)
  2550                 elif param == "height":
  2596                 elif param == "height":
  2551                     variable.setheight(value)
  2597                     variable.setheight(value)
  2552                 elif param == "width":
  2598                 elif param == "width":
  2578                         position = input.GetRelPosition()
  2624                         position = input.GetRelPosition()
  2579                         variable.addconnectionPointIn()
  2625                         variable.addconnectionPointIn()
  2580                         variable.connectionPointIn.setrelPositionXY(position.x, position.y)
  2626                         variable.connectionPointIn.setrelPositionXY(position.x, position.y)
  2581                         self.SetConnectionWires(variable.connectionPointIn, input)
  2627                         self.SetConnectionWires(variable.connectionPointIn, input)
  2582 
  2628 
  2583     def AddEditedElementConnection(self, tagname, id, type):
  2629     def AddEditedElementConnection(self, tagname, id, connection_type):
  2584         element = self.GetEditedElement(tagname)
  2630         element = self.GetEditedElement(tagname)
  2585         if element is not None:
  2631         if element is not None:
  2586             if type == CONNECTOR:
  2632             connection = PLCOpenParser.CreateElement(
  2587                 name = "connector"
  2633                 {CONNECTOR: "connector",
  2588                 connection = plcopen.commonObjects_connector()
  2634                  CONTINUATION: "continuation"}[connection_type], "commonObjects")
  2589             elif type == CONTINUATION:
       
  2590                 name = "continuation"
       
  2591                 connection = plcopen.commonObjects_continuation()
       
  2592             connection.setlocalId(id)
  2635             connection.setlocalId(id)
  2593             element.addinstance(name, connection)
  2636             element.addinstance(connection)
  2594         
  2637         
  2595     def SetEditedElementConnectionInfos(self, tagname, id, infos):
  2638     def SetEditedElementConnectionInfos(self, tagname, id, infos):
  2596         element = self.GetEditedElement(tagname)
  2639         element = self.GetEditedElement(tagname)
  2597         if element is not None:
  2640         if element is not None:
  2598             connection = element.getinstance(id)
  2641             connection = element.getinstance(id)
  2609                     connection.setx(value)
  2652                     connection.setx(value)
  2610                 elif param == "y":
  2653                 elif param == "y":
  2611                     connection.sety(value)
  2654                     connection.sety(value)
  2612                 elif param == "connector":
  2655                 elif param == "connector":
  2613                     position = value.GetRelPosition()
  2656                     position = value.GetRelPosition()
  2614                     if isinstance(connection, plcopen.commonObjects_continuation):
  2657                     if isinstance(connection, PLCOpenParser.GetElementClass("continuation", "commonObjects")):
  2615                         connection.addconnectionPointOut()
  2658                         connection.addconnectionPointOut()
  2616                         connection.connectionPointOut.setrelPositionXY(position.x, position.y)
  2659                         connection.connectionPointOut.setrelPositionXY(position.x, position.y)
  2617                     elif isinstance(connection, plcopen.commonObjects_connector):
  2660                     elif isinstance(connection, PLCOpenParser.GetElementClass("connector", "commonObjects")):
  2618                         connection.addconnectionPointIn()
  2661                         connection.addconnectionPointIn()
  2619                         connection.connectionPointIn.setrelPositionXY(position.x, position.y)
  2662                         connection.connectionPointIn.setrelPositionXY(position.x, position.y)
  2620                         self.SetConnectionWires(connection.connectionPointIn, value)
  2663                         self.SetConnectionWires(connection.connectionPointIn, value)
  2621 
  2664 
  2622     def AddEditedElementComment(self, tagname, id):
  2665     def AddEditedElementComment(self, tagname, id):
  2623         element = self.GetEditedElement(tagname)
  2666         element = self.GetEditedElement(tagname)
  2624         if element is not None:
  2667         if element is not None:
  2625             comment = plcopen.commonObjects_comment()
  2668             comment = PLCOpenParser.CreateElement("comment", "commonObjects")
  2626             comment.setlocalId(id)
  2669             comment.setlocalId(id)
  2627             element.addinstance("comment", comment)
  2670             element.addinstance(comment)
  2628     
  2671     
  2629     def SetEditedElementCommentInfos(self, tagname, id, infos):
  2672     def SetEditedElementCommentInfos(self, tagname, id, infos):
  2630         element = self.GetEditedElement(tagname)
  2673         element = self.GetEditedElement(tagname)
  2631         if element is not None:
  2674         if element is not None:
  2632             comment = element.getinstance(id)
  2675             comment = element.getinstance(id)
  2640                 elif param == "x":
  2683                 elif param == "x":
  2641                     comment.setx(value)
  2684                     comment.setx(value)
  2642                 elif param == "y":
  2685                 elif param == "y":
  2643                     comment.sety(value)
  2686                     comment.sety(value)
  2644 
  2687 
  2645     def AddEditedElementPowerRail(self, tagname, id, type):
  2688     def AddEditedElementPowerRail(self, tagname, id, powerrail_type):
  2646         element = self.GetEditedElement(tagname)
  2689         element = self.GetEditedElement(tagname)
  2647         if element is not None:
  2690         if element is not None:
  2648             if type == LEFTRAIL:
  2691             powerrail = PLCOpenParser.CreateElement(
  2649                 name = "leftPowerRail"
  2692                 {LEFTRAIL: "leftPowerRail",
  2650                 powerrail = plcopen.ldObjects_leftPowerRail()
  2693                  RIGHTRAIL: "rightPowerRail"}[powerrail_type], "ldObjects")
  2651             elif type == RIGHTRAIL:
       
  2652                 name = "rightPowerRail"
       
  2653                 powerrail = plcopen.ldObjects_rightPowerRail()
       
  2654             powerrail.setlocalId(id)
  2694             powerrail.setlocalId(id)
  2655             element.addinstance(name, powerrail)
  2695             element.addinstance(powerrail)
  2656     
  2696     
  2657     def SetEditedElementPowerRailInfos(self, tagname, id, infos):
  2697     def SetEditedElementPowerRailInfos(self, tagname, id, infos):
  2658         element = self.GetEditedElement(tagname)
  2698         element = self.GetEditedElement(tagname)
  2659         if element is not None:
  2699         if element is not None:
  2660             powerrail = element.getinstance(id)
  2700             powerrail = element.getinstance(id)
  2668                 elif param == "x":
  2708                 elif param == "x":
  2669                     powerrail.setx(value)
  2709                     powerrail.setx(value)
  2670                 elif param == "y":
  2710                 elif param == "y":
  2671                     powerrail.sety(value)
  2711                     powerrail.sety(value)
  2672                 elif param == "connectors":
  2712                 elif param == "connectors":
  2673                     if isinstance(powerrail, plcopen.ldObjects_leftPowerRail):
  2713                     if isinstance(powerrail, PLCOpenParser.GetElementClass("leftPowerRail", "ldObjects")):
  2674                         powerrail.setconnectionPointOut([])
  2714                         powerrail.setconnectionPointOut([])
  2675                         for connector in value["outputs"]:
  2715                         for connector in value["outputs"]:
  2676                             position = connector.GetRelPosition()
  2716                             position = connector.GetRelPosition()
  2677                             connection = plcopen.leftPowerRail_connectionPointOut()
  2717                             connection = PLCOpenParser.CreateElement("connectionPointOut", "leftPowerRail")
       
  2718                             powerrail.appendconnectionPointOut(connection)
  2678                             connection.setrelPositionXY(position.x, position.y)
  2719                             connection.setrelPositionXY(position.x, position.y)
  2679                             powerrail.connectionPointOut.append(connection)
  2720                     elif isinstance(powerrail, PLCOpenParser.GetElementClass("rightPowerRail", "ldObjects")):
  2680                     elif isinstance(powerrail, plcopen.ldObjects_rightPowerRail):
       
  2681                         powerrail.setconnectionPointIn([])
  2721                         powerrail.setconnectionPointIn([])
  2682                         for connector in value["inputs"]:
  2722                         for connector in value["inputs"]:
  2683                             position = connector.GetRelPosition()
  2723                             position = connector.GetRelPosition()
  2684                             connection = plcopen.connectionPointIn()
  2724                             connection = PLCOpenParser.CreateElement("connectionPointIn", "rightPowerRail")
       
  2725                             powerrail.appendconnectionPointIn(connection)
  2685                             connection.setrelPositionXY(position.x, position.y)
  2726                             connection.setrelPositionXY(position.x, position.y)
  2686                             self.SetConnectionWires(connection, connector)
  2727                             self.SetConnectionWires(connection, connector)
  2687                             powerrail.connectionPointIn.append(connection)
  2728                             
  2688 
       
  2689     def AddEditedElementContact(self, tagname, id):
  2729     def AddEditedElementContact(self, tagname, id):
  2690         element = self.GetEditedElement(tagname)
  2730         element = self.GetEditedElement(tagname)
  2691         if element is not None:
  2731         if element is not None:
  2692             contact = plcopen.ldObjects_contact()
  2732             contact = PLCOpenParser.CreateElement("contact", "ldObjects")
  2693             contact.setlocalId(id)
  2733             contact.setlocalId(id)
  2694             element.addinstance("contact", contact)
  2734             element.addinstance(contact)
  2695 
  2735 
  2696     def SetEditedElementContactInfos(self, tagname, id, infos):
  2736     def SetEditedElementContactInfos(self, tagname, id, infos):
  2697         element = self.GetEditedElement(tagname)
  2737         element = self.GetEditedElement(tagname)
  2698         if element is not None:
  2738         if element is not None:
  2699             contact = element.getinstance(id)
  2739             contact = element.getinstance(id)
  2701                 return
  2741                 return
  2702             for param, value in infos.items():
  2742             for param, value in infos.items():
  2703                 if param == "name":
  2743                 if param == "name":
  2704                     contact.setvariable(value)
  2744                     contact.setvariable(value)
  2705                 elif param == "type":
  2745                 elif param == "type":
  2706                     if value == CONTACT_NORMAL:
  2746                     negated, edge = {
  2707                         contact.setnegated(False)
  2747                         CONTACT_NORMAL: (False, "none"),
  2708                         contact.setedge("none")
  2748                         CONTACT_REVERSE: (True, "none"),
  2709                     elif value == CONTACT_REVERSE:
  2749                         CONTACT_RISING: (False, "rising"),
  2710                         contact.setnegated(True)
  2750                         CONTACT_FALLING: (False, "falling")}[value]
  2711                         contact.setedge("none")
  2751                     contact.setnegated(negated)
  2712                     elif value == CONTACT_RISING:
  2752                     contact.setedge(edge)
  2713                         contact.setnegated(False)
       
  2714                         contact.setedge("rising")
       
  2715                     elif value == CONTACT_FALLING:
       
  2716                         contact.setnegated(False)
       
  2717                         contact.setedge("falling")
       
  2718                 elif param == "height":
  2753                 elif param == "height":
  2719                     contact.setheight(value)
  2754                     contact.setheight(value)
  2720                 elif param == "width":
  2755                 elif param == "width":
  2721                     contact.setwidth(value)
  2756                     contact.setwidth(value)
  2722                 elif param == "x":
  2757                 elif param == "x":
  2735                     contact.connectionPointOut.setrelPositionXY(position.x, position.y)
  2770                     contact.connectionPointOut.setrelPositionXY(position.x, position.y)
  2736 
  2771 
  2737     def AddEditedElementCoil(self, tagname, id):
  2772     def AddEditedElementCoil(self, tagname, id):
  2738         element = self.GetEditedElement(tagname)
  2773         element = self.GetEditedElement(tagname)
  2739         if element is not None:
  2774         if element is not None:
  2740             coil = plcopen.ldObjects_coil()
  2775             coil = PLCOpenParser.CreateElement("coil", "ldObjects")
  2741             coil.setlocalId(id)
  2776             coil.setlocalId(id)
  2742             element.addinstance("coil", coil)
  2777             element.addinstance(coil)
  2743 
  2778 
  2744     def SetEditedElementCoilInfos(self, tagname, id, infos):
  2779     def SetEditedElementCoilInfos(self, tagname, id, infos):
  2745         element = self.GetEditedElement(tagname)
  2780         element = self.GetEditedElement(tagname)
  2746         if element is not None:
  2781         if element is not None:
  2747             coil = element.getinstance(id)
  2782             coil = element.getinstance(id)
  2749                 return
  2784                 return
  2750             for param, value in infos.items():
  2785             for param, value in infos.items():
  2751                 if param == "name":
  2786                 if param == "name":
  2752                     coil.setvariable(value)
  2787                     coil.setvariable(value)
  2753                 elif param == "type":
  2788                 elif param == "type":
  2754                     if value == COIL_NORMAL:
  2789                     negated, storage, edge = {
  2755                         coil.setnegated(False)
  2790                         COIL_NORMAL: (False, "none", "none"),
  2756                         coil.setstorage("none")
  2791                         COIL_REVERSE: (True, "none", "none"),
  2757                         coil.setedge("none")
  2792                         COIL_SET: (False, "set", "none"),
  2758                     elif value == COIL_REVERSE:
  2793                         COIL_RESET: (False, "reset", "none"),
  2759                         coil.setnegated(True)
  2794                         COIL_RISING: (False, "none", "rising"),
  2760                         coil.setstorage("none")
  2795                         COIL_FALLING: (False, "none", "falling")}[value]
  2761                         coil.setedge("none")
  2796                     coil.setnegated(negated)
  2762                     elif value == COIL_SET:
  2797                     coil.setstorage(storage)
  2763                         coil.setnegated(False)
  2798                     coil.setedge(edge)
  2764                         coil.setstorage("set")
       
  2765                         coil.setedge("none")
       
  2766                     elif value == COIL_RESET:
       
  2767                         coil.setnegated(False)
       
  2768                         coil.setstorage("reset")
       
  2769                         coil.setedge("none")
       
  2770                     elif value == COIL_RISING:
       
  2771                         coil.setnegated(False)
       
  2772                         coil.setstorage("none")
       
  2773                         coil.setedge("rising")
       
  2774                     elif value == COIL_FALLING:
       
  2775                         coil.setnegated(False)
       
  2776                         coil.setstorage("none")
       
  2777                         coil.setedge("falling")
       
  2778                 elif param == "height":
  2799                 elif param == "height":
  2779                     coil.setheight(value)
  2800                     coil.setheight(value)
  2780                 elif param == "width":
  2801                 elif param == "width":
  2781                     coil.setwidth(value)
  2802                     coil.setwidth(value)
  2782                 elif param == "x":
  2803                 elif param == "x":
  2795                     coil.connectionPointOut.setrelPositionXY(position.x, position.y)
  2816                     coil.connectionPointOut.setrelPositionXY(position.x, position.y)
  2796 
  2817 
  2797     def AddEditedElementStep(self, tagname, id):
  2818     def AddEditedElementStep(self, tagname, id):
  2798         element = self.GetEditedElement(tagname)
  2819         element = self.GetEditedElement(tagname)
  2799         if element is not None:
  2820         if element is not None:
  2800             step = plcopen.sfcObjects_step()
  2821             step = PLCOpenParser.CreateElement("step", "sfcObjects")
  2801             step.setlocalId(id)
  2822             step.setlocalId(id)
  2802             element.addinstance("step", step)
  2823             element.addinstance(step)
  2803     
  2824     
  2804     def SetEditedElementStepInfos(self, tagname, id, infos):
  2825     def SetEditedElementStepInfos(self, tagname, id, infos):
  2805         element = self.GetEditedElement(tagname)
  2826         element = self.GetEditedElement(tagname)
  2806         if element is not None:
  2827         if element is not None:
  2807             step = element.getinstance(id)
  2828             step = element.getinstance(id)
  2845                         step.deleteconnectionPointOutAction()
  2866                         step.deleteconnectionPointOutAction()
  2846     
  2867     
  2847     def AddEditedElementTransition(self, tagname, id):
  2868     def AddEditedElementTransition(self, tagname, id):
  2848         element = self.GetEditedElement(tagname)
  2869         element = self.GetEditedElement(tagname)
  2849         if element is not None:
  2870         if element is not None:
  2850             transition = plcopen.sfcObjects_transition()
  2871             transition = PLCOpenParser.CreateElement("transition", "sfcObjects")
  2851             transition.setlocalId(id)
  2872             transition.setlocalId(id)
  2852             element.addinstance("transition", transition)
  2873             element.addinstance(transition)
  2853     
  2874     
  2854     def SetEditedElementTransitionInfos(self, tagname, id, infos):
  2875     def SetEditedElementTransitionInfos(self, tagname, id, infos):
  2855         element = self.GetEditedElement(tagname)
  2876         element = self.GetEditedElement(tagname)
  2856         if element is not None:
  2877         if element is not None:
  2857             transition = element.getinstance(id)
  2878             transition = element.getinstance(id)
  2883                     position = output_connector.GetRelPosition()
  2904                     position = output_connector.GetRelPosition()
  2884                     transition.addconnectionPointOut()
  2905                     transition.addconnectionPointOut()
  2885                     transition.connectionPointOut.setrelPositionXY(position.x, position.y)
  2906                     transition.connectionPointOut.setrelPositionXY(position.x, position.y)
  2886                 elif infos.get("type", None) == "connection" and param == "connection" and value:
  2907                 elif infos.get("type", None) == "connection" and param == "connection" and value:
  2887                     transition.setconditionContent("connection", None)
  2908                     transition.setconditionContent("connection", None)
  2888                     self.SetConnectionWires(transition.condition.content["value"], value)
  2909                     self.SetConnectionWires(transition.condition.content, value)
  2889     
  2910     
  2890     def AddEditedElementDivergence(self, tagname, id, type):
  2911     def AddEditedElementDivergence(self, tagname, id, divergence_type):
  2891         element = self.GetEditedElement(tagname)
  2912         element = self.GetEditedElement(tagname)
  2892         if element is not None:
  2913         if element is not None:
  2893             if type == SELECTION_DIVERGENCE:
  2914             divergence = PLCOpenParser.CreateElement(
  2894                 name = "selectionDivergence"
  2915                 {SELECTION_DIVERGENCE: "selectionDivergence",
  2895                 divergence = plcopen.sfcObjects_selectionDivergence()
  2916                  SELECTION_CONVERGENCE: "selectionConvergence",
  2896             elif type == SELECTION_CONVERGENCE:
  2917                  SIMULTANEOUS_DIVERGENCE: "simultaneousDivergence",
  2897                 name = "selectionConvergence"
  2918                  SIMULTANEOUS_CONVERGENCE: "simultaneousConvergence"}.get(
  2898                 divergence = plcopen.sfcObjects_selectionConvergence()
  2919                     divergence_type), "sfcObjects")
  2899             elif type == SIMULTANEOUS_DIVERGENCE:
       
  2900                 name = "simultaneousDivergence"
       
  2901                 divergence = plcopen.sfcObjects_simultaneousDivergence()
       
  2902             elif type == SIMULTANEOUS_CONVERGENCE:
       
  2903                 name = "simultaneousConvergence"
       
  2904                 divergence = plcopen.sfcObjects_simultaneousConvergence()
       
  2905             divergence.setlocalId(id)
  2920             divergence.setlocalId(id)
  2906             element.addinstance(name, divergence)
  2921             element.addinstance(divergence)
       
  2922     
       
  2923     DivergenceTypes = [
       
  2924         (divergence_type, 
       
  2925          PLCOpenParser.GetElementClass(divergence_type, "sfcObjects"))
       
  2926         for divergence_type in ["selectionDivergence", "simultaneousDivergence",
       
  2927                                 "selectionConvergence", "simultaneousConvergence"]]
       
  2928     
       
  2929     def GetDivergenceType(self, divergence):
       
  2930         for divergence_type, divergence_class in self.DivergenceTypes:
       
  2931             if isinstance(divergence, divergence_class):
       
  2932                 return divergence_type
       
  2933         return None
  2907     
  2934     
  2908     def SetEditedElementDivergenceInfos(self, tagname, id, infos):
  2935     def SetEditedElementDivergenceInfos(self, tagname, id, infos):
  2909         element = self.GetEditedElement(tagname)
  2936         element = self.GetEditedElement(tagname)
  2910         if element is not None:
  2937         if element is not None:
  2911             divergence = element.getinstance(id)
  2938             divergence = element.getinstance(id)
  2920                     divergence.setx(value)
  2947                     divergence.setx(value)
  2921                 elif param == "y":
  2948                 elif param == "y":
  2922                     divergence.sety(value)
  2949                     divergence.sety(value)
  2923                 elif param == "connectors":
  2950                 elif param == "connectors":
  2924                     input_connectors = value["inputs"]
  2951                     input_connectors = value["inputs"]
  2925                     if isinstance(divergence, (plcopen.sfcObjects_selectionDivergence, plcopen.sfcObjects_simultaneousDivergence)):
  2952                     divergence_type = self.GetDivergenceType(divergence)
       
  2953                     if divergence_type in ["selectionDivergence", "simultaneousDivergence"]:
  2926                         position = input_connectors[0].GetRelPosition()
  2954                         position = input_connectors[0].GetRelPosition()
  2927                         divergence.addconnectionPointIn()
  2955                         divergence.addconnectionPointIn()
  2928                         divergence.connectionPointIn.setrelPositionXY(position.x, position.y)
  2956                         divergence.connectionPointIn.setrelPositionXY(position.x, position.y)
  2929                         self.SetConnectionWires(divergence.connectionPointIn, input_connectors[0])
  2957                         self.SetConnectionWires(divergence.connectionPointIn, input_connectors[0])
  2930                     else:
  2958                     else:
  2931                         divergence.setconnectionPointIn([])
  2959                         divergence.setconnectionPointIn([])
  2932                         for input_connector in input_connectors:
  2960                         for input_connector in input_connectors:
  2933                             position = input_connector.GetRelPosition()
  2961                             position = input_connector.GetRelPosition()
  2934                             if isinstance(divergence, plcopen.sfcObjects_selectionConvergence):
  2962                             connection = PLCOpenParser.CreateElement("connectionPointIn", divergence_type)
  2935                                 connection = plcopen.selectionConvergence_connectionPointIn()
  2963                             divergence.appendconnectionPointIn(connection)
  2936                             else:
       
  2937                                 connection = plcopen.connectionPointIn()
       
  2938                             connection.setrelPositionXY(position.x, position.y)
  2964                             connection.setrelPositionXY(position.x, position.y)
  2939                             self.SetConnectionWires(connection, input_connector)
  2965                             self.SetConnectionWires(connection, input_connector)
  2940                             divergence.appendconnectionPointIn(connection)
       
  2941                     output_connectors = value["outputs"]
  2966                     output_connectors = value["outputs"]
  2942                     if isinstance(divergence, (plcopen.sfcObjects_selectionConvergence, plcopen.sfcObjects_simultaneousConvergence)):
  2967                     if divergence_type in ["selectionConvergence", "simultaneousConvergence"]:
  2943                         position = output_connectors[0].GetRelPosition()
  2968                         position = output_connectors[0].GetRelPosition()
  2944                         divergence.addconnectionPointOut()
  2969                         divergence.addconnectionPointOut()
  2945                         divergence.connectionPointOut.setrelPositionXY(position.x, position.y)
  2970                         divergence.connectionPointOut.setrelPositionXY(position.x, position.y)
  2946                     else:
  2971                     else:
  2947                         divergence.setconnectionPointOut([])
  2972                         divergence.setconnectionPointOut([])
  2948                         for output_connector in output_connectors:
  2973                         for output_connector in output_connectors:
  2949                             position = output_connector.GetRelPosition()
  2974                             position = output_connector.GetRelPosition()
  2950                             if isinstance(divergence, plcopen.sfcObjects_selectionDivergence):
  2975                             connection = PLCOpenParser.CreateElement("connectionPointOut", divergence_type)
  2951                                 connection = plcopen.selectionDivergence_connectionPointOut()
  2976                             divergence.appendconnectionPointOut(connection)
  2952                             else:
       
  2953                                 connection = plcopen.simultaneousDivergence_connectionPointOut()
       
  2954                             connection.setrelPositionXY(position.x, position.y)
  2977                             connection.setrelPositionXY(position.x, position.y)
  2955                             divergence.appendconnectionPointOut(connection)
  2978                             
  2956     
       
  2957     def AddEditedElementJump(self, tagname, id):
  2979     def AddEditedElementJump(self, tagname, id):
  2958         element = self.GetEditedElement(tagname)
  2980         element = self.GetEditedElement(tagname)
  2959         if element is not None:
  2981         if element is not None:
  2960             jump = plcopen.sfcObjects_jumpStep()
  2982             jump = PLCOpenParser.CreateElement("jumpStep", "sfcObjects")
  2961             jump.setlocalId(id)
  2983             jump.setlocalId(id)
  2962             element.addinstance("jumpStep", jump)
  2984             element.addinstance(jump)
  2963     
  2985     
  2964     def SetEditedElementJumpInfos(self, tagname, id, infos):
  2986     def SetEditedElementJumpInfos(self, tagname, id, infos):
  2965         element = self.GetEditedElement(tagname)
  2987         element = self.GetEditedElement(tagname)
  2966         if element is not None:
  2988         if element is not None:
  2967             jump = element.getinstance(id)
  2989             jump = element.getinstance(id)
  2985                     self.SetConnectionWires(jump.connectionPointIn, value)
  3007                     self.SetConnectionWires(jump.connectionPointIn, value)
  2986  
  3008  
  2987     def AddEditedElementActionBlock(self, tagname, id):
  3009     def AddEditedElementActionBlock(self, tagname, id):
  2988         element = self.GetEditedElement(tagname)
  3010         element = self.GetEditedElement(tagname)
  2989         if element is not None:
  3011         if element is not None:
  2990             actionBlock = plcopen.commonObjects_actionBlock()
  3012             actionBlock = PLCOpenParser.CreateElement("actionBlock", "commonObjects")
  2991             actionBlock.setlocalId(id)
  3013             actionBlock.setlocalId(id)
  2992             element.addinstance("actionBlock", actionBlock)
  3014             element.addinstance(actionBlock)
  2993     
  3015     
  2994     def SetEditedElementActionBlockInfos(self, tagname, id, infos):
  3016     def SetEditedElementActionBlockInfos(self, tagname, id, infos):
  2995         element = self.GetEditedElement(tagname)
  3017         element = self.GetEditedElement(tagname)
  2996         if element is not None:
  3018         if element is not None:
  2997             actionBlock = element.getinstance(id)
  3019             actionBlock = element.getinstance(id)
  3016     
  3038     
  3017     def RemoveEditedElementInstance(self, tagname, id):
  3039     def RemoveEditedElementInstance(self, tagname, id):
  3018         element = self.GetEditedElement(tagname)
  3040         element = self.GetEditedElement(tagname)
  3019         if element is not None:
  3041         if element is not None:
  3020             instance = element.getinstance(id)
  3042             instance = element.getinstance(id)
  3021             if isinstance(instance, plcopen.fbdObjects_block):
  3043             if isinstance(instance, PLCOpenParser.GetElementClass("block", "fbdObjects")):
  3022                 self.RemoveEditedElementPouVar(tagname, instance.gettypeName(), instance.getinstanceName())
  3044                 self.RemoveEditedElementPouVar(tagname, instance.gettypeName(), instance.getinstanceName())
  3023             element.removeinstance(id)
  3045             element.removeinstance(id)
  3024             self.Project.RefreshElementUsingTree()
       
  3025 
  3046 
  3026     def GetEditedResourceVariables(self, tagname, debug = False):
  3047     def GetEditedResourceVariables(self, tagname, debug = False):
  3027         varlist = []
  3048         varlist = []
  3028         words = tagname.split("::")
  3049         words = tagname.split("::")
  3029         for var in self.GetConfigurationGlobalVars(words[1], debug):
  3050         for var in self.GetConfigurationGlobalVars(words[1], debug):
  3030             if var["Type"] == "BOOL":
  3051             if var.Type == "BOOL":
  3031                 varlist.append(var["Name"])
  3052                 varlist.append(var.Name)
  3032         for var in self.GetConfigurationResourceGlobalVars(words[1], words[2], debug):
  3053         for var in self.GetConfigurationResourceGlobalVars(words[1], words[2], debug):
  3033             if var["Type"] == "BOOL":
  3054             if var.Type == "BOOL":
  3034                 varlist.append(var["Name"])
  3055                 varlist.append(var.Name)
  3035         return varlist
  3056         return varlist
  3036 
  3057 
  3037     def SetEditedResourceInfos(self, tagname, tasks, instances):
  3058     def SetEditedResourceInfos(self, tagname, tasks, instances):
  3038         resource = self.GetEditedElement(tagname)
  3059         resource = self.GetEditedElement(tagname)
  3039         if resource is not None:
  3060         if resource is not None:
  3040             resource.settask([])
  3061             resource.settask([])
  3041             resource.setpouInstance([])
  3062             resource.setpouInstance([])
  3042             task_list = {}
  3063             task_list = {}
  3043             for task in tasks:
  3064             for task in tasks:
  3044                 new_task = plcopen.resource_task()
  3065                 new_task = PLCOpenParser.CreateElement("task", "resource")
       
  3066                 resource.appendtask(new_task)
  3045                 new_task.setname(task["Name"])
  3067                 new_task.setname(task["Name"])
  3046                 if task["Triggering"] == "Interrupt":
  3068                 if task["Triggering"] == "Interrupt":
  3047                     new_task.setsingle(task["Single"])
  3069                     new_task.setsingle(task["Single"])
  3048 ##                result = duration_model.match(task["Interval"]).groups()
  3070 ##                result = duration_model.match(task["Interval"]).groups()
  3049 ##                if reduce(lambda x, y: x or y != None, result):
  3071 ##                if reduce(lambda x, y: x or y != None, result):
  3059                 if task["Triggering"] == "Cyclic":
  3081                 if task["Triggering"] == "Cyclic":
  3060                     new_task.setinterval(task["Interval"])
  3082                     new_task.setinterval(task["Interval"])
  3061                 new_task.setpriority(int(task["Priority"]))
  3083                 new_task.setpriority(int(task["Priority"]))
  3062                 if task["Name"] != "":
  3084                 if task["Name"] != "":
  3063                     task_list[task["Name"]] = new_task
  3085                     task_list[task["Name"]] = new_task
  3064                 resource.appendtask(new_task)
       
  3065             for instance in instances:
  3086             for instance in instances:
  3066                 new_instance = plcopen.pouInstance()
  3087                 task = task_list.get(instance["Task"])
       
  3088                 if task is not None:
       
  3089                     new_instance = PLCOpenParser.CreateElement("pouInstance", "task")
       
  3090                     task.appendpouInstance(new_instance)
       
  3091                 else:
       
  3092                     new_instance = PLCOpenParser.CreateElement("pouInstance", "resource")
       
  3093                     resource.appendpouInstance(new_instance)
  3067                 new_instance.setname(instance["Name"])
  3094                 new_instance.setname(instance["Name"])
  3068                 new_instance.settypeName(instance["Type"])
  3095                 new_instance.settypeName(instance["Type"])
  3069                 task_list.get(instance["Task"], resource).appendpouInstance(new_instance)
       
  3070 
  3096 
  3071     def GetEditedResourceInfos(self, tagname, debug = False):
  3097     def GetEditedResourceInfos(self, tagname, debug = False):
  3072         resource = self.GetEditedElement(tagname, debug)
  3098         resource = self.GetEditedElement(tagname, debug)
  3073         if resource is not None:
  3099         if resource is not None:
  3074             tasks = resource.gettask()
  3100             tasks = resource.gettask()
  3122                 new_instance["Task"] = ""
  3148                 new_instance["Task"] = ""
  3123                 instances_data.append(new_instance)
  3149                 instances_data.append(new_instance)
  3124             return tasks_data, instances_data
  3150             return tasks_data, instances_data
  3125 
  3151 
  3126     def OpenXMLFile(self, filepath):
  3152     def OpenXMLFile(self, filepath):
  3127         xmlfile = open(filepath, 'r')
  3153         self.Project, error = LoadProject(filepath)
  3128         tree = minidom.parse(xmlfile)
  3154         if self.Project is None:
  3129         xmlfile.close()
  3155             return _("Project file syntax error:\n\n") + error
  3130         
  3156         self.SetFilePath(filepath)
  3131         self.Project = plcopen.project()
  3157         self.CreateProjectBuffer(True)
  3132         for child in tree.childNodes:
  3158         self.ProgramChunks = []
  3133             if child.nodeType == tree.ELEMENT_NODE and child.nodeName == "project":
  3159         self.ProgramOffset = 0
  3134                 try:
  3160         self.NextCompiledProject = self.Copy(self.Project)
  3135                     result = self.Project.loadXMLTree(child)
  3161         self.CurrentCompiledProject = None
  3136                 except ValueError, e:
  3162         self.Buffering = False
  3137                     return _("Project file syntax error:\n\n") + str(e)
  3163         self.CurrentElementEditing = None
  3138                 self.SetFilePath(filepath)
  3164         return error
  3139                 self.Project.RefreshElementUsingTree()
  3165         
  3140                 self.Project.RefreshDataTypeHierarchy()
       
  3141                 self.Project.RefreshCustomBlockTypes()
       
  3142                 self.CreateProjectBuffer(True)
       
  3143                 self.ProgramChunks = []
       
  3144                 self.ProgramOffset = 0
       
  3145                 self.NextCompiledProject = self.Copy(self.Project)
       
  3146                 self.CurrentCompiledProject = None
       
  3147                 self.Buffering = False
       
  3148                 self.CurrentElementEditing = None
       
  3149                 return None
       
  3150         return _("No PLC project found")
       
  3151 
       
  3152     def SaveXMLFile(self, filepath = None):
  3166     def SaveXMLFile(self, filepath = None):
  3153         if not filepath and self.FilePath == "":
  3167         if not filepath and self.FilePath == "":
  3154             return False
  3168             return False
  3155         else:
  3169         else:
  3156             contentheader = {"modificationDateTime": datetime.datetime(*localtime()[:6])}
  3170             contentheader = {"modificationDateTime": datetime.datetime(*localtime()[:6])}
  3157             self.Project.setcontentHeader(contentheader)
  3171             self.Project.setcontentHeader(contentheader)
  3158             
  3172             
  3159             text = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"
  3173             if filepath:
  3160             extras = {"xmlns" : "http://www.plcopen.org/xml/tc6.xsd",
  3174                 SaveProject(self.Project, filepath)
  3161                       "xmlns:xhtml" : "http://www.w3.org/1999/xhtml",
  3175             else:
  3162                       "xmlns:xsi" : "http://www.w3.org/2001/XMLSchema-instance",
  3176                 SaveProject(self.Project, self.FilePath)
  3163                       "xsi:schemaLocation" : "http://www.plcopen.org/xml/tc6.xsd"}
       
  3164             text += self.Project.generateXMLText("project", 0, extras)
       
  3165             
  3177             
  3166             if filepath:
       
  3167                 xmlfile = open(filepath,"w")
       
  3168             else:
       
  3169                 xmlfile = open(self.FilePath,"w")
       
  3170             xmlfile.write(text.encode("utf-8"))
       
  3171             xmlfile.close()
       
  3172             self.MarkProjectAsSaved()
  3178             self.MarkProjectAsSaved()
  3173             if filepath:
  3179             if filepath:
  3174                 self.SetFilePath(filepath)
  3180                 self.SetFilePath(filepath)
  3175             return True
  3181             return True
  3176 
  3182 
  3193 
  3199 
  3194     """
  3200     """
  3195     Return a copy of the project
  3201     Return a copy of the project
  3196     """
  3202     """
  3197     def Copy(self, model):
  3203     def Copy(self, model):
  3198         return cPickle.loads(cPickle.dumps(model))
  3204         return deepcopy(model)
  3199 
  3205 
  3200     def CreateProjectBuffer(self, saved):
  3206     def CreateProjectBuffer(self, saved):
  3201         if self.ProjectBufferEnabled:
  3207         if self.ProjectBufferEnabled:
  3202             self.ProjectBuffer = UndoBuffer(cPickle.dumps(self.Project), saved)
  3208             self.ProjectBuffer = UndoBuffer(PLCOpenParser.Dumps(self.Project), saved)
  3203         else:
  3209         else:
  3204             self.ProjectBuffer = None
  3210             self.ProjectBuffer = None
  3205             self.ProjectSaved = saved
  3211             self.ProjectSaved = saved
  3206 
  3212 
  3207     def IsProjectBufferEnabled(self):
  3213     def IsProjectBufferEnabled(self):
  3216                 current_saved = self.ProjectBuffer.IsCurrentSaved()
  3222                 current_saved = self.ProjectBuffer.IsCurrentSaved()
  3217             self.CreateProjectBuffer(current_saved)
  3223             self.CreateProjectBuffer(current_saved)
  3218 
  3224 
  3219     def BufferProject(self):
  3225     def BufferProject(self):
  3220         if self.ProjectBuffer is not None:
  3226         if self.ProjectBuffer is not None:
  3221             self.ProjectBuffer.Buffering(cPickle.dumps(self.Project))
  3227             self.ProjectBuffer.Buffering(PLCOpenParser.Dumps(self.Project))
  3222         else:
  3228         else:
  3223             self.ProjectSaved = False
  3229             self.ProjectSaved = False
  3224 
  3230 
  3225     def StartBuffering(self):
  3231     def StartBuffering(self):
  3226         if self.ProjectBuffer is not None:
  3232         if self.ProjectBuffer is not None:
  3228         else:
  3234         else:
  3229             self.ProjectSaved = False
  3235             self.ProjectSaved = False
  3230         
  3236         
  3231     def EndBuffering(self):
  3237     def EndBuffering(self):
  3232         if self.ProjectBuffer is not None and self.Buffering:
  3238         if self.ProjectBuffer is not None and self.Buffering:
  3233             self.ProjectBuffer.Buffering(cPickle.dumps(self.Project))
  3239             self.ProjectBuffer.Buffering(PLCOpenParser.Dumps(self.Project))
  3234             self.Buffering = False
  3240             self.Buffering = False
  3235 
  3241 
  3236     def MarkProjectAsSaved(self):
  3242     def MarkProjectAsSaved(self):
  3237         self.EndBuffering()
  3243         self.EndBuffering()
  3238         if self.ProjectBuffer is not None:
  3244         if self.ProjectBuffer is not None:
  3248             return self.ProjectSaved
  3254             return self.ProjectSaved
  3249 
  3255 
  3250     def LoadPrevious(self):
  3256     def LoadPrevious(self):
  3251         self.EndBuffering()
  3257         self.EndBuffering()
  3252         if self.ProjectBuffer is not None:
  3258         if self.ProjectBuffer is not None:
  3253             self.Project = cPickle.loads(self.ProjectBuffer.Previous())
  3259             self.Project = PLCOpenParser.Loads(self.ProjectBuffer.Previous())
  3254     
  3260     
  3255     def LoadNext(self):
  3261     def LoadNext(self):
  3256         if self.ProjectBuffer is not None:
  3262         if self.ProjectBuffer is not None:
  3257             self.Project = cPickle.loads(self.ProjectBuffer.Next())
  3263             self.Project = PLCOpenParser.Loads(self.ProjectBuffer.Next())
  3258     
  3264     
  3259     def GetBufferState(self):
  3265     def GetBufferState(self):
  3260         if self.ProjectBuffer is not None:
  3266         if self.ProjectBuffer is not None:
  3261             first = self.ProjectBuffer.IsFirst() and not self.Buffering
  3267             first = self.ProjectBuffer.IsFirst() and not self.Buffering
  3262             last = self.ProjectBuffer.IsLast()
  3268             last = self.ProjectBuffer.IsLast()