Laurent@814: #!/usr/bin/env python Laurent@814: # -*- coding: utf-8 -*- Laurent@814: Laurent@814: #This file is part of PLCOpenEditor, a library implementing an IEC 61131-3 editor Laurent@814: #based on the plcopen standard. Laurent@814: # Laurent@814: #Copyright (C) 2007: Edouard TISSERANT and Laurent BESSARD Laurent@814: # Laurent@814: #See COPYING file for copyrights details. Laurent@814: # Laurent@814: #This library is free software; you can redistribute it and/or Laurent@814: #modify it under the terms of the GNU General Public Laurent@814: #License as published by the Free Software Foundation; either Laurent@814: #version 2.1 of the License, or (at your option) any later version. Laurent@814: # Laurent@814: #This library is distributed in the hope that it will be useful, Laurent@814: #but WITHOUT ANY WARRANTY; without even the implied warranty of Laurent@814: #MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Laurent@814: #General Public License for more details. Laurent@814: # Laurent@814: #You should have received a copy of the GNU General Public Laurent@814: #License along with this library; if not, write to the Free Software Laurent@814: #Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA Laurent@814: Laurent@814: from xml.dom import minidom Laurent@814: from types import StringType, UnicodeType, TupleType Laurent@814: import cPickle Laurent@814: import os,sys,re Laurent@814: import datetime Laurent@814: from time import localtime Laurent@814: Laurent@814: from plcopen import plcopen Laurent@814: from plcopen.structures import * Laurent@814: from graphics.GraphicCommons import * Laurent@814: from PLCGenerator import * Laurent@814: Laurent@814: 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)?") Laurent@814: Laurent@814: ITEMS_EDITABLE = [ITEM_PROJECT, Laurent@814: ITEM_POU, Laurent@814: ITEM_VARIABLE, Laurent@814: ITEM_TRANSITION, Laurent@814: ITEM_ACTION, Laurent@814: ITEM_CONFIGURATION, Laurent@814: ITEM_RESOURCE, Laurent@814: ITEM_DATATYPE Laurent@814: ] = range(8) Laurent@814: Laurent@814: ITEMS_UNEDITABLE = [ITEM_DATATYPES, Laurent@814: ITEM_FUNCTION, Laurent@814: ITEM_FUNCTIONBLOCK, Laurent@814: ITEM_PROGRAM, Laurent@814: ITEM_TRANSITIONS, Laurent@814: ITEM_ACTIONS, Laurent@814: ITEM_CONFIGURATIONS, Laurent@814: ITEM_RESOURCES, Laurent@814: ITEM_PROPERTIES Laurent@814: ] = range(8, 17) Laurent@814: Laurent@814: ITEMS_VARIABLE = [ITEM_VAR_LOCAL, Laurent@814: ITEM_VAR_GLOBAL, Laurent@814: ITEM_VAR_EXTERNAL, Laurent@814: ITEM_VAR_TEMP, Laurent@814: ITEM_VAR_INPUT, Laurent@814: ITEM_VAR_OUTPUT, Laurent@814: ITEM_VAR_INOUT Laurent@814: ] = range(17, 24) Laurent@814: Laurent@814: VAR_CLASS_INFOS = {"Local" : (plcopen.interface_localVars, ITEM_VAR_LOCAL), Laurent@814: "Global" : (plcopen.interface_globalVars, ITEM_VAR_GLOBAL), Laurent@814: "External" : (plcopen.interface_externalVars, ITEM_VAR_EXTERNAL), Laurent@814: "Temp" : (plcopen.interface_tempVars, ITEM_VAR_TEMP), Laurent@814: "Input" : (plcopen.interface_inputVars, ITEM_VAR_INPUT), Laurent@814: "Output" : (plcopen.interface_outputVars, ITEM_VAR_OUTPUT), Laurent@814: "InOut" : (plcopen.interface_inOutVars, ITEM_VAR_INOUT) Laurent@814: } Laurent@814: Laurent@814: POU_TYPES = {"program": ITEM_PROGRAM, Laurent@814: "functionBlock": ITEM_FUNCTIONBLOCK, Laurent@814: "function": ITEM_FUNCTION, Laurent@814: } Laurent@814: Laurent@814: LOCATIONS_ITEMS = [LOCATION_CONFNODE, Laurent@814: LOCATION_MODULE, Laurent@814: LOCATION_GROUP, Laurent@814: LOCATION_VAR_INPUT, Laurent@814: LOCATION_VAR_OUTPUT, Laurent@814: LOCATION_VAR_MEMORY] = range(6) Laurent@814: Laurent@814: ScriptDirectory = os.path.split(os.path.realpath(__file__))[0] Laurent@814: Laurent@814: def GetUneditableNames(): Laurent@814: _ = lambda x:x Laurent@814: return [_("User-defined POUs"), _("Functions"), _("Function Blocks"), Laurent@814: _("Programs"), _("Data Types"), _("Transitions"), _("Actions"), Laurent@814: _("Configurations"), _("Resources"), _("Properties")] Laurent@814: UNEDITABLE_NAMES = GetUneditableNames() Laurent@814: [USER_DEFINED_POUS, FUNCTIONS, FUNCTION_BLOCKS, PROGRAMS, Laurent@814: DATA_TYPES, TRANSITIONS, ACTIONS, CONFIGURATIONS, Laurent@814: RESOURCES, PROPERTIES] = UNEDITABLE_NAMES Laurent@814: Laurent@814: #------------------------------------------------------------------------------- Laurent@814: # Undo Buffer for PLCOpenEditor Laurent@814: #------------------------------------------------------------------------------- Laurent@814: Laurent@814: # Length of the buffer Laurent@814: UNDO_BUFFER_LENGTH = 20 Laurent@814: Laurent@814: """ Laurent@814: Class implementing a buffer of changes made on the current editing model Laurent@814: """ Laurent@814: class UndoBuffer: Laurent@814: Laurent@814: # Constructor initialising buffer Laurent@814: def __init__(self, currentstate, issaved = False): Laurent@814: self.Buffer = [] Laurent@814: self.CurrentIndex = -1 Laurent@814: self.MinIndex = -1 Laurent@814: self.MaxIndex = -1 Laurent@814: # if current state is defined Laurent@814: if currentstate: Laurent@814: self.CurrentIndex = 0 Laurent@814: self.MinIndex = 0 Laurent@814: self.MaxIndex = 0 Laurent@814: # Initialising buffer with currentstate at the first place Laurent@814: for i in xrange(UNDO_BUFFER_LENGTH): Laurent@814: if i == 0: Laurent@814: self.Buffer.append(currentstate) Laurent@814: else: Laurent@814: self.Buffer.append(None) Laurent@814: # Initialising index of state saved Laurent@814: if issaved: Laurent@814: self.LastSave = 0 Laurent@814: else: Laurent@814: self.LastSave = -1 Laurent@814: Laurent@814: # Add a new state in buffer Laurent@814: def Buffering(self, currentstate): Laurent@814: self.CurrentIndex = (self.CurrentIndex + 1) % UNDO_BUFFER_LENGTH Laurent@814: self.Buffer[self.CurrentIndex] = currentstate Laurent@814: # Actualising buffer limits Laurent@814: self.MaxIndex = self.CurrentIndex Laurent@814: if self.MinIndex == self.CurrentIndex: Laurent@814: # If the removed state was the state saved, there is no state saved in the buffer Laurent@814: if self.LastSave == self.MinIndex: Laurent@814: self.LastSave = -1 Laurent@814: self.MinIndex = (self.MinIndex + 1) % UNDO_BUFFER_LENGTH Laurent@814: self.MinIndex = max(self.MinIndex, 0) Laurent@814: Laurent@814: # Return current state of buffer Laurent@814: def Current(self): Laurent@814: return self.Buffer[self.CurrentIndex] Laurent@814: Laurent@814: # Change current state to previous in buffer and return new current state Laurent@814: def Previous(self): Laurent@814: if self.CurrentIndex != self.MinIndex: Laurent@814: self.CurrentIndex = (self.CurrentIndex - 1) % UNDO_BUFFER_LENGTH Laurent@814: return self.Buffer[self.CurrentIndex] Laurent@814: return None Laurent@814: Laurent@814: # Change current state to next in buffer and return new current state Laurent@814: def Next(self): Laurent@814: if self.CurrentIndex != self.MaxIndex: Laurent@814: self.CurrentIndex = (self.CurrentIndex + 1) % UNDO_BUFFER_LENGTH Laurent@814: return self.Buffer[self.CurrentIndex] Laurent@814: return None Laurent@814: Laurent@814: # Return True if current state is the first in buffer Laurent@814: def IsFirst(self): Laurent@814: return self.CurrentIndex == self.MinIndex Laurent@814: Laurent@814: # Return True if current state is the last in buffer Laurent@814: def IsLast(self): Laurent@814: return self.CurrentIndex == self.MaxIndex Laurent@814: Laurent@814: # Note that current state is saved Laurent@814: def CurrentSaved(self): Laurent@814: self.LastSave = self.CurrentIndex Laurent@814: Laurent@814: # Return True if current state is saved Laurent@814: def IsCurrentSaved(self): Laurent@814: return self.LastSave == self.CurrentIndex Laurent@814: Laurent@814: Laurent@814: #------------------------------------------------------------------------------- Laurent@814: # Controler for PLCOpenEditor Laurent@814: #------------------------------------------------------------------------------- Laurent@814: Laurent@814: """ Laurent@814: Class which controls the operations made on the plcopen model and answers to view requests Laurent@814: """ Laurent@814: class PLCControler: Laurent@814: Laurent@814: # Create a new PLCControler Laurent@814: def __init__(self): Laurent@814: self.LastNewIndex = 0 Laurent@814: self.Reset() Laurent@814: Laurent@814: # Reset PLCControler internal variables Laurent@814: def Reset(self): Laurent@814: self.Project = None Laurent@814: self.ProjectBufferEnabled = True Laurent@814: self.ProjectBuffer = None Laurent@814: self.ProjectSaved = True Laurent@814: self.Buffering = False Laurent@814: self.FilePath = "" Laurent@814: self.FileName = "" Laurent@814: self.ProgramChunks = [] Laurent@814: self.ProgramOffset = 0 Laurent@814: self.NextCompiledProject = None Laurent@814: self.CurrentCompiledProject = None Laurent@814: self.ConfNodeTypes = [] Laurent@814: self.ProgramFilePath = "" Laurent@814: Laurent@814: def GetQualifierTypes(self): Laurent@814: return plcopen.QualifierList Laurent@814: Laurent@814: def GetProject(self, debug = False): Laurent@814: if debug and self.CurrentCompiledProject is not None: Laurent@814: return self.CurrentCompiledProject Laurent@814: else: Laurent@814: return self.Project Laurent@814: Laurent@814: #------------------------------------------------------------------------------- Laurent@814: # Project management functions Laurent@814: #------------------------------------------------------------------------------- Laurent@814: Laurent@814: # Return if a project is opened Laurent@814: def HasOpenedProject(self): Laurent@814: return self.Project is not None Laurent@814: Laurent@814: # Create a new project by replacing the current one Laurent@814: def CreateNewProject(self, properties): Laurent@814: # Create the project Laurent@814: self.Project = plcopen.project() Laurent@814: properties["creationDateTime"] = datetime.datetime(*localtime()[:6]) Laurent@814: self.Project.setfileHeader(properties) Laurent@814: self.Project.setcontentHeader(properties) Laurent@814: self.SetFilePath("") Laurent@814: # Initialize the project buffer Laurent@814: self.CreateProjectBuffer(False) Laurent@814: self.ProgramChunks = [] Laurent@814: self.ProgramOffset = 0 Laurent@814: self.NextCompiledProject = self.Copy(self.Project) Laurent@814: self.CurrentCompiledProject = None Laurent@814: self.Buffering = False Laurent@814: Laurent@814: # Return project data type names Laurent@814: def GetProjectDataTypeNames(self, debug = False): Laurent@814: project = self.GetProject(debug) Laurent@814: if project is not None: Laurent@814: return [datatype.getname() for datatype in project.getdataTypes()] Laurent@814: return [] Laurent@814: Laurent@814: # Return project pou names Laurent@814: def GetProjectPouNames(self, debug = False): Laurent@814: project = self.GetProject(debug) Laurent@814: if project is not None: Laurent@814: return [pou.getname() for pou in project.getpous()] Laurent@814: return [] Laurent@814: Laurent@814: # Return project pou names Laurent@814: def GetProjectConfigNames(self, debug = False): Laurent@814: project = self.GetProject(debug) Laurent@814: if project is not None: Laurent@814: return [config.getname() for config in project.getconfigurations()] Laurent@814: return [] Laurent@814: Laurent@814: # Return project pou variables Laurent@814: def GetProjectPouVariables(self, pou_name = None, debug = False): Laurent@814: variables = [] Laurent@814: project = self.GetProject(debug) Laurent@814: if project is not None: Laurent@814: for pou in project.getpous(): Laurent@814: if pou_name is None or pou_name == pou.getname(): Laurent@814: variables.extend([var["Name"] for var in self.GetPouInterfaceVars(pou, debug)]) Laurent@814: for transition in pou.gettransitionList(): Laurent@814: variables.append(transition.getname()) Laurent@814: for action in pou.getactionList(): Laurent@814: variables.append(action.getname()) Laurent@814: return variables Laurent@814: Laurent@814: # Return file path if project is an open file Laurent@814: def GetFilePath(self): Laurent@814: return self.FilePath Laurent@814: Laurent@814: # Return file path if project is an open file Laurent@814: def GetProgramFilePath(self): Laurent@814: return self.ProgramFilePath Laurent@814: Laurent@814: # Return file name and point out if file is up to date Laurent@814: def GetFilename(self): Laurent@814: if self.Project is not None: Laurent@814: if self.ProjectIsSaved(): Laurent@814: return self.FileName Laurent@814: else: Laurent@814: return "~%s~"%self.FileName Laurent@814: return "" Laurent@814: Laurent@814: # Change file path and save file name or create a default one if file path not defined Laurent@814: def SetFilePath(self, filepath): Laurent@814: self.FilePath = filepath Laurent@814: if filepath == "": Laurent@814: self.LastNewIndex += 1 Laurent@814: self.FileName = _("Unnamed%d")%self.LastNewIndex Laurent@814: else: Laurent@814: self.FileName = os.path.splitext(os.path.basename(filepath))[0] Laurent@814: Laurent@814: # Change project properties Laurent@814: def SetProjectProperties(self, name = None, properties = None, buffer = True): Laurent@814: if self.Project is not None: Laurent@814: if name is not None: Laurent@814: self.Project.setname(name) Laurent@814: if properties is not None: Laurent@814: self.Project.setfileHeader(properties) Laurent@814: self.Project.setcontentHeader(properties) Laurent@814: if buffer and (name is not None or properties is not None): Laurent@814: self.BufferProject() Laurent@814: Laurent@814: # Return project name Laurent@814: def GetProjectName(self, debug=False): Laurent@814: project = self.GetProject(debug) Laurent@814: if project is not None: Laurent@814: return project.getname() Laurent@814: return None Laurent@814: Laurent@814: # Return project properties Laurent@814: def GetProjectProperties(self, debug = False): Laurent@814: project = self.GetProject(debug) Laurent@814: if project is not None: Laurent@814: properties = project.getfileHeader() Laurent@814: properties.update(project.getcontentHeader()) Laurent@814: return properties Laurent@814: return None Laurent@814: Laurent@814: # Return project informations Laurent@814: def GetProjectInfos(self, debug = False): Laurent@814: project = self.GetProject(debug) Laurent@814: if project is not None: Laurent@814: infos = {"name": project.getname(), "type": ITEM_PROJECT} Laurent@814: datatypes = {"name": DATA_TYPES, "type": ITEM_DATATYPES, "values":[]} Laurent@814: for datatype in project.getdataTypes(): Laurent@814: datatypes["values"].append({"name": datatype.getname(), "type": ITEM_DATATYPE, Laurent@814: "tagname": self.ComputeDataTypeName(datatype.getname()), "values": []}) Laurent@814: pou_types = {"function": {"name": FUNCTIONS, "type": ITEM_FUNCTION, "values":[]}, Laurent@814: "functionBlock": {"name": FUNCTION_BLOCKS, "type": ITEM_FUNCTIONBLOCK, "values":[]}, Laurent@814: "program": {"name": PROGRAMS, "type": ITEM_PROGRAM, "values":[]}} Laurent@814: for pou in project.getpous(): Laurent@814: pou_type = pou.getpouType() Laurent@814: pou_infos = {"name": pou.getname(), "type": ITEM_POU, Laurent@814: "tagname": self.ComputePouName(pou.getname())} Laurent@814: pou_values = [] Laurent@814: if pou.getbodyType() == "SFC": Laurent@814: transitions = [] Laurent@814: for transition in pou.gettransitionList(): Laurent@814: transitions.append({"name": transition.getname(), "type": ITEM_TRANSITION, Laurent@814: "tagname": self.ComputePouTransitionName(pou.getname(), transition.getname()), Laurent@814: "values": []}) Laurent@814: pou_values.append({"name": TRANSITIONS, "type": ITEM_TRANSITIONS, "values": transitions}) Laurent@814: actions = [] Laurent@814: for action in pou.getactionList(): Laurent@814: actions.append({"name": action.getname(), "type": ITEM_ACTION, Laurent@814: "tagname": self.ComputePouActionName(pou.getname(), action.getname()), Laurent@814: "values": []}) Laurent@814: pou_values.append({"name": ACTIONS, "type": ITEM_ACTIONS, "values": actions}) Laurent@814: if pou_type in pou_types: Laurent@814: pou_infos["values"] = pou_values Laurent@814: pou_types[pou_type]["values"].append(pou_infos) Laurent@814: configurations = {"name": CONFIGURATIONS, "type": ITEM_CONFIGURATIONS, "values": []} Laurent@814: for config in project.getconfigurations(): Laurent@814: config_name = config.getname() Laurent@814: config_infos = {"name": config_name, "type": ITEM_CONFIGURATION, Laurent@814: "tagname": self.ComputeConfigurationName(config.getname()), Laurent@814: "values": []} Laurent@814: resources = {"name": RESOURCES, "type": ITEM_RESOURCES, "values": []} Laurent@814: for resource in config.getresource(): Laurent@814: resource_name = resource.getname() Laurent@814: resource_infos = {"name": resource_name, "type": ITEM_RESOURCE, Laurent@814: "tagname": self.ComputeConfigurationResourceName(config.getname(), resource.getname()), Laurent@814: "values": []} Laurent@814: resources["values"].append(resource_infos) Laurent@814: config_infos["values"] = [resources] Laurent@814: configurations["values"].append(config_infos) Laurent@814: infos["values"] = [datatypes, pou_types["function"], pou_types["functionBlock"], Laurent@814: pou_types["program"], configurations] Laurent@814: return infos Laurent@814: return None Laurent@814: Laurent@814: def GetPouVariableInfos(self, project, variable, var_class, debug=False): Laurent@814: vartype_content = variable.gettype().getcontent() Laurent@814: if vartype_content["name"] == "derived": Laurent@814: var_type = vartype_content["value"].getname() Laurent@814: pou_type = None Laurent@814: pou = project.getpou(var_type) Laurent@814: if pou is not None: Laurent@814: pou_type = pou.getpouType() Laurent@814: edit = debug = pou_type is not None Laurent@814: if pou_type is None: Laurent@814: block_infos = self.GetBlockType(var_type, debug = debug) Laurent@814: if block_infos is not None: Laurent@814: pou_type = block_infos["type"] Laurent@814: if pou_type is not None: Laurent@814: var_class = None Laurent@814: if pou_type == "program": Laurent@814: var_class = ITEM_PROGRAM Laurent@814: elif pou_type != "function": Laurent@814: var_class = ITEM_FUNCTIONBLOCK Laurent@814: if var_class is not None: Laurent@814: return {"name": variable.getname(), Laurent@814: "type": var_type, Laurent@814: "class": var_class, Laurent@814: "edit": edit, Laurent@814: "debug": debug} Laurent@814: elif var_type in self.GetDataTypes(debug = debug): Laurent@814: return {"name": variable.getname(), Laurent@814: "type": var_type, Laurent@814: "class": var_class, Laurent@814: "edit": False, Laurent@814: "debug": False} Laurent@814: elif vartype_content["name"] in ["string", "wstring"]: Laurent@814: return {"name": variable.getname(), Laurent@814: "type": vartype_content["name"].upper(), Laurent@814: "class": var_class, Laurent@814: "edit": False, Laurent@814: "debug": True} Laurent@814: else: Laurent@814: return {"name": variable.getname(), Laurent@814: "type": vartype_content["name"], Laurent@814: "class": var_class, Laurent@814: "edit": False, Laurent@814: "debug": True} Laurent@814: return None Laurent@814: Laurent@814: def GetPouVariables(self, tagname, debug = False): Laurent@814: vars = [] Laurent@814: pou_type = None Laurent@814: project = self.GetProject(debug) Laurent@814: if project is not None: Laurent@814: words = tagname.split("::") Laurent@814: if words[0] == "P": Laurent@814: pou = project.getpou(words[1]) Laurent@814: if pou is not None: Laurent@814: pou_type = pou.getpouType() Laurent@814: if (pou_type in ["program", "functionBlock"] and Laurent@814: pou.interface is not None): Laurent@814: # Extract variables from every varLists Laurent@814: for varlist_type, varlist in pou.getvars(): Laurent@814: var_infos = VAR_CLASS_INFOS.get(varlist_type, None) Laurent@814: if var_infos is not None: Laurent@814: var_class = var_infos[1] Laurent@814: else: Laurent@814: var_class = ITEM_VAR_LOCAL Laurent@814: for variable in varlist.getvariable(): Laurent@814: var_infos = self.GetPouVariableInfos(project, variable, var_class, debug) Laurent@814: if var_infos is not None: Laurent@814: vars.append(var_infos) laurent@826: if pou.getbodyType() == "SFC": laurent@826: for transition in pou.gettransitionList(): laurent@826: vars.append({ laurent@826: "name": transition.getname(), laurent@826: "type": None, laurent@826: "class": ITEM_TRANSITION, laurent@826: "edit": True, laurent@826: "debug": True}) laurent@826: for action in pou.getactionList(): laurent@826: vars.append({ laurent@826: "name": action.getname(), laurent@826: "type": None, laurent@826: "class": ITEM_ACTION, laurent@826: "edit": True, laurent@826: "debug": True}) Laurent@814: return {"class": POU_TYPES[pou_type], Laurent@814: "type": words[1], Laurent@814: "variables": vars, Laurent@814: "edit": True, Laurent@814: "debug": True} Laurent@814: else: Laurent@814: block_infos = self.GetBlockType(words[1], debug = debug) Laurent@814: if (block_infos is not None and Laurent@814: block_infos["type"] in ["program", "functionBlock"]): Laurent@814: for varname, vartype, varmodifier in block_infos["inputs"]: Laurent@814: vars.append({"name" : varname, Laurent@814: "type" : vartype, Laurent@814: "class" : ITEM_VAR_INPUT, Laurent@814: "edit": False, Laurent@814: "debug": True}) Laurent@814: for varname, vartype, varmodifier in block_infos["outputs"]: Laurent@814: vars.append({"name" : varname, Laurent@814: "type" : vartype, Laurent@814: "class" : ITEM_VAR_OUTPUT, Laurent@814: "edit": False, Laurent@814: "debug": True}) Laurent@814: return {"class": POU_TYPES[block_infos["type"]], Laurent@814: "type": None, Laurent@814: "variables": vars, Laurent@814: "edit": False, Laurent@814: "debug": False} laurent@826: elif words[0] in ['A', 'T']: laurent@826: pou_vars = self.GetPouVariables(self.ComputePouName(words[1]), debug) laurent@826: if pou_vars is not None: laurent@826: if words[0] == 'A': laurent@826: element_type = ITEM_ACTION laurent@826: elif words[0] == 'T': laurent@826: element_type = ITEM_TRANSITION laurent@826: return {"class": element_type, laurent@826: "type": None, laurent@826: "variables": [var for var in pou_vars["variables"] laurent@826: if var["class"] not in [ITEM_ACTION, ITEM_TRANSITION]], laurent@826: "edit": True, laurent@826: "debug": True} Laurent@814: elif words[0] in ['C', 'R']: Laurent@814: if words[0] == 'C': Laurent@814: element_type = ITEM_CONFIGURATION Laurent@814: element = project.getconfiguration(words[1]) Laurent@814: if element is not None: Laurent@814: for resource in element.getresource(): Laurent@814: vars.append({"name": resource.getname(), Laurent@814: "type": None, Laurent@814: "class": ITEM_RESOURCE, Laurent@814: "edit": True, Laurent@814: "debug": False}) Laurent@814: elif words[0] == 'R': Laurent@814: element_type = ITEM_RESOURCE Laurent@814: element = project.getconfigurationResource(words[1], words[2]) Laurent@814: if element is not None: Laurent@814: for task in element.gettask(): Laurent@814: for pou in task.getpouInstance(): Laurent@814: vars.append({"name": pou.getname(), Laurent@814: "type": pou.gettypeName(), Laurent@814: "class": ITEM_PROGRAM, Laurent@814: "edit": True, Laurent@814: "debug": True}) Laurent@814: for pou in element.getpouInstance(): Laurent@814: vars.append({"name": pou.getname(), Laurent@814: "type": pou.gettypeName(), Laurent@814: "class": ITEM_PROGRAM, Laurent@814: "edit": True, Laurent@814: "debug": True}) Laurent@814: if element is not None: Laurent@814: for varlist in element.getglobalVars(): Laurent@814: for variable in varlist.getvariable(): Laurent@814: var_infos = self.GetPouVariableInfos(project, variable, ITEM_VAR_GLOBAL, debug) Laurent@814: if var_infos is not None: Laurent@814: vars.append(var_infos) Laurent@814: return {"class": element_type, Laurent@814: "type": None, Laurent@814: "variables": vars, Laurent@814: "edit": True, Laurent@814: "debug": False} Laurent@814: return None Laurent@814: Laurent@814: def RecursiveSearchPouInstances(self, project, pou_type, parent_path, varlists, debug = False): Laurent@814: instances = [] Laurent@814: for varlist in varlists: Laurent@814: for variable in varlist.getvariable(): Laurent@814: vartype_content = variable.gettype().getcontent() Laurent@814: if vartype_content["name"] == "derived": Laurent@814: var_path = "%s.%s" % (parent_path, variable.getname()) Laurent@814: var_type = vartype_content["value"].getname() Laurent@814: if var_type == pou_type: Laurent@814: instances.append(var_path) Laurent@814: else: Laurent@814: pou = project.getpou(var_type) Laurent@814: if pou is not None: Laurent@814: instances.extend( Laurent@814: self.RecursiveSearchPouInstances( Laurent@814: project, pou_type, var_path, Laurent@814: [varlist for type, varlist in pou.getvars()], Laurent@814: debug)) Laurent@814: return instances Laurent@814: Laurent@814: def SearchPouInstances(self, tagname, debug = False): Laurent@814: project = self.GetProject(debug) Laurent@814: if project is not None: Laurent@814: words = tagname.split("::") Laurent@814: if words[0] == "P": Laurent@814: instances = [] Laurent@814: for config in project.getconfigurations(): Laurent@814: config_name = config.getname() Laurent@814: instances.extend( Laurent@814: self.RecursiveSearchPouInstances( Laurent@814: project, words[1], config_name, Laurent@814: config.getglobalVars(), debug)) Laurent@814: for resource in config.getresource(): Laurent@814: res_path = "%s.%s" % (config_name, resource.getname()) Laurent@814: instances.extend( Laurent@814: self.RecursiveSearchPouInstances( Laurent@814: project, words[1], res_path, Laurent@814: resource.getglobalVars(), debug)) Laurent@814: pou_instances = resource.getpouInstance()[:] Laurent@814: for task in resource.gettask(): Laurent@814: pou_instances.extend(task.getpouInstance()) Laurent@814: for pou_instance in pou_instances: Laurent@814: pou_path = "%s.%s" % (res_path, pou_instance.getname()) Laurent@814: pou_type = pou_instance.gettypeName() Laurent@814: if pou_type == words[1]: Laurent@814: instances.append(pou_path) Laurent@814: pou = project.getpou(pou_type) Laurent@814: if pou is not None: Laurent@814: instances.extend( Laurent@814: self.RecursiveSearchPouInstances( Laurent@814: project, words[1], pou_path, Laurent@814: [varlist for type, varlist in pou.getvars()], Laurent@814: debug)) Laurent@814: return instances Laurent@814: elif words[0] == 'C': Laurent@814: return [words[1]] Laurent@814: elif words[0] == 'R': Laurent@814: return ["%s.%s" % (words[1], words[2])] laurent@826: elif words[0] in ['T', 'A']: laurent@826: return ["%s.%s" % (instance, words[2]) laurent@826: for instance in self.SearchPouInstances( laurent@826: self.ComputePouName(words[1]), debug)] Laurent@814: return [] Laurent@814: Laurent@886: def RecursiveGetPouInstanceTagName(self, project, pou_type, parts, debug = False): Laurent@814: pou = project.getpou(pou_type) Laurent@814: if pou is not None: Laurent@814: if len(parts) == 0: Laurent@814: return self.ComputePouName(pou_type) Laurent@814: Laurent@814: for varlist_type, varlist in pou.getvars(): Laurent@814: for variable in varlist.getvariable(): laurent@827: if variable.getname() == parts[0]: laurent@827: vartype_content = variable.gettype().getcontent() laurent@827: if vartype_content["name"] == "derived": laurent@827: return self.RecursiveGetPouInstanceTagName( laurent@827: project, laurent@827: vartype_content["value"].getname(), Laurent@886: parts[1:], debug) laurent@827: laurent@827: if pou.getbodyType() == "SFC" and len(parts) == 1: laurent@827: for action in pou.getactionList(): laurent@827: if action.getname() == parts[0]: laurent@827: return self.ComputePouActionName(pou_type, parts[0]) laurent@827: for transition in pou.gettransitionList(): laurent@827: if transition.getname() == parts[0]: laurent@827: return self.ComputePouTransitionName(pou_type, parts[0]) Laurent@886: else: Laurent@886: block_infos = self.GetBlockType(pou_type, debug=debug) Laurent@886: if (block_infos is not None and Laurent@886: block_infos["type"] in ["program", "functionBlock"]): Laurent@886: Laurent@886: if len(parts) == 0: Laurent@886: return self.ComputePouName(pou_type) Laurent@886: Laurent@886: for varname, vartype, varmodifier in block_infos["inputs"] + block_infos["outputs"]: Laurent@886: if varname == parts[0]: Laurent@886: return self.RecursiveGetPouInstanceTagName(project, vartype, parts[1:], debug) Laurent@814: return None Laurent@814: Laurent@814: def GetPouInstanceTagName(self, instance_path, debug = False): Laurent@814: parts = instance_path.split(".") Laurent@814: if len(parts) == 1: Laurent@814: return self.ComputeConfigurationName(parts[0]) Laurent@814: elif len(parts) == 2: Laurent@814: return self.ComputeConfigurationResourceName(parts[0], parts[1]) Laurent@814: else: Laurent@814: project = self.GetProject(debug) Laurent@814: for config in project.getconfigurations(): Laurent@814: if config.getname() == parts[0]: Laurent@814: for resource in config.getresource(): Laurent@814: if resource.getname() == parts[1]: Laurent@814: pou_instances = resource.getpouInstance()[:] Laurent@814: for task in resource.gettask(): Laurent@814: pou_instances.extend(task.getpouInstance()) Laurent@814: for pou_instance in pou_instances: Laurent@814: if pou_instance.getname() == parts[2]: Laurent@814: if len(parts) == 3: Laurent@814: return self.ComputePouName( Laurent@814: pou_instance.gettypeName()) Laurent@814: else: Laurent@814: return self.RecursiveGetPouInstanceTagName( Laurent@814: project, Laurent@814: pou_instance.gettypeName(), Laurent@886: parts[3:], debug) Laurent@814: return None Laurent@814: Laurent@814: def GetInstanceInfos(self, instance_path, debug = False): Laurent@814: tagname = self.GetPouInstanceTagName(instance_path) Laurent@814: if tagname is not None: laurent@827: infos = self.GetPouVariables(tagname, debug) laurent@827: infos["type"] = tagname laurent@827: return infos Laurent@814: else: Laurent@814: pou_path, var_name = instance_path.rsplit(".", 1) Laurent@814: tagname = self.GetPouInstanceTagName(pou_path) Laurent@814: if tagname is not None: Laurent@814: pou_infos = self.GetPouVariables(tagname, debug) Laurent@814: for var_infos in pou_infos["variables"]: Laurent@814: if var_infos["name"] == var_name: Laurent@814: return var_infos Laurent@814: return None Laurent@814: Laurent@814: # Return if data type given by name is used by another data type or pou Laurent@814: def DataTypeIsUsed(self, name, debug = False): Laurent@814: project = self.GetProject(debug) Laurent@814: if project is not None: Laurent@814: return project.ElementIsUsed(name) or project.DataTypeIsDerived(name) Laurent@814: return False Laurent@814: Laurent@814: # Return if pou given by name is used by another pou Laurent@814: def PouIsUsed(self, name, debug = False): Laurent@814: project = self.GetProject(debug) Laurent@814: if project is not None: Laurent@814: return project.ElementIsUsed(name) Laurent@814: return False Laurent@814: Laurent@814: # Return if pou given by name is directly or undirectly used by the reference pou Laurent@814: def PouIsUsedBy(self, name, reference, debug = False): Laurent@814: project = self.GetProject(debug) Laurent@814: if project is not None: Laurent@814: return project.ElementIsUsedBy(name, reference) Laurent@814: return False Laurent@814: Laurent@814: def GenerateProgram(self, filepath=None): Laurent@814: errors = [] Laurent@814: warnings = [] Laurent@814: if self.Project is not None: Laurent@814: try: Laurent@814: self.ProgramChunks = GenerateCurrentProgram(self, self.Project, errors, warnings) Laurent@814: self.NextCompiledProject = self.Copy(self.Project) Laurent@901: program_text = "".join([item[0] for item in self.ProgramChunks]) Laurent@814: if filepath is not None: Laurent@814: programfile = open(filepath, "w") Laurent@814: programfile.write(program_text.encode("utf-8")) Laurent@814: programfile.close() Laurent@814: self.ProgramFilePath = filepath Laurent@814: return program_text, errors, warnings Laurent@814: except PLCGenException, e: Laurent@814: errors.append(e.message) Laurent@814: else: Laurent@814: errors.append("No project opened") Laurent@814: return "", errors, warnings Laurent@814: Laurent@814: def DebugAvailable(self): Laurent@814: return self.CurrentCompiledProject is not None Laurent@814: Laurent@814: def ProgramTransferred(self): Laurent@814: if self.NextCompiledProject is None: Laurent@814: self.CurrentCompiledProject = self.NextCompiledProject Laurent@814: else: Laurent@814: self.CurrentCompiledProject = self.Copy(self.Project) Laurent@814: Laurent@814: def GetChunkInfos(self, from_location, to_location): Laurent@814: row = self.ProgramOffset + 1 Laurent@814: col = 1 Laurent@814: infos = [] Laurent@814: for chunk, chunk_infos in self.ProgramChunks: Laurent@814: lines = chunk.split("\n") Laurent@814: if len(lines) > 1: Laurent@814: next_row = row + len(lines) - 1 Laurent@814: next_col = len(lines[-1]) + 1 Laurent@814: else: Laurent@814: next_row = row Laurent@814: next_col = col + len(chunk) Laurent@814: if (next_row > from_location[0] or next_row == from_location[0] and next_col >= from_location[1]) and len(chunk_infos) > 0: Laurent@814: infos.append((chunk_infos, (row, col))) Laurent@814: if next_row == to_location[0] and next_col > to_location[1] or next_row > to_location[0]: Laurent@814: return infos Laurent@814: row, col = next_row, next_col Laurent@814: return infos Laurent@814: Laurent@814: #------------------------------------------------------------------------------- Laurent@814: # Project Pous management functions Laurent@814: #------------------------------------------------------------------------------- Laurent@814: Laurent@814: # Add a Data Type to Project Laurent@814: def ProjectAddDataType(self, datatype_name=None): Laurent@814: if self.Project is not None: Laurent@814: if datatype_name is None: Laurent@814: datatype_name = self.GenerateNewName(None, None, "datatype%d") Laurent@814: # Add the datatype to project Laurent@814: self.Project.appenddataType(datatype_name) Laurent@814: self.BufferProject() Laurent@814: return self.ComputeDataTypeName(datatype_name) Laurent@814: return None Laurent@814: Laurent@814: # Remove a Data Type from project Laurent@814: def ProjectRemoveDataType(self, datatype_name): Laurent@814: if self.Project is not None: Laurent@814: self.Project.removedataType(datatype_name) Laurent@814: self.BufferProject() Laurent@814: Laurent@814: # Add a Pou to Project Laurent@814: def ProjectAddPou(self, pou_name, pou_type, body_type): Laurent@814: if self.Project is not None: Laurent@814: # Add the pou to project Laurent@814: self.Project.appendpou(pou_name, pou_type, body_type) Laurent@814: if pou_type == "function": Laurent@814: self.SetPouInterfaceReturnType(pou_name, "BOOL") Laurent@814: self.BufferProject() Laurent@814: return self.ComputePouName(pou_name) Laurent@814: return None Laurent@814: Laurent@814: def ProjectChangePouType(self, name, pou_type): Laurent@814: if self.Project is not None: Laurent@814: pou = self.Project.getpou(name) Laurent@814: if pou is not None: Laurent@814: pou.setpouType(pou_type) Laurent@814: self.Project.RefreshCustomBlockTypes() Laurent@814: self.BufferProject() Laurent@814: Laurent@814: def GetPouXml(self, pou_name): Laurent@814: if self.Project is not None: Laurent@814: pou = self.Project.getpou(pou_name) Laurent@814: if pou is not None: Laurent@814: return pou.generateXMLText('pou', 0) Laurent@814: return None Laurent@814: Laurent@814: def PastePou(self, pou_type, pou_xml): Laurent@814: ''' Laurent@814: Adds the POU defined by 'pou_xml' to the current project with type 'pou_type' Laurent@814: ''' Laurent@814: try: Laurent@814: tree = minidom.parseString(pou_xml.encode("utf-8")) Laurent@814: root = tree.childNodes[0] Laurent@814: except: Laurent@814: return _("Couldn't paste non-POU object.") Laurent@814: Laurent@814: if root.nodeName == "pou": Laurent@814: new_pou = plcopen.pous_pou() Laurent@814: new_pou.loadXMLTree(root) Laurent@814: Laurent@814: name = new_pou.getname() Laurent@814: Laurent@814: idx = 0 Laurent@814: new_name = name Laurent@814: while self.Project.getpou(new_name): Laurent@814: # a POU with that name already exists. Laurent@814: # make a new name and test if a POU with that name exists. Laurent@814: # append an incrementing numeric suffix to the POU name. Laurent@814: idx += 1 Laurent@814: new_name = "%s%d" % (name, idx) Laurent@814: Laurent@814: # we've found a name that does not already exist, use it Laurent@814: new_pou.setname(new_name) Laurent@814: Laurent@814: if pou_type is not None: Laurent@814: orig_type = new_pou.getpouType() Laurent@814: Laurent@814: # prevent violations of POU content restrictions: Laurent@814: # function blocks cannot be pasted as functions, Laurent@814: # programs cannot be pasted as functions or function blocks Laurent@814: if orig_type == 'functionBlock' and pou_type == 'function' or \ Laurent@814: orig_type == 'program' and pou_type in ['function', 'functionBlock']: Laurent@814: return _('''%s "%s" can't be pasted as a %s.''') % (orig_type, name, pou_type) Laurent@814: Laurent@814: new_pou.setpouType(pou_type) Laurent@814: Laurent@814: self.Project.insertpou(-1, new_pou) Laurent@814: self.BufferProject() Laurent@814: Laurent@814: return self.ComputePouName(new_name), Laurent@814: else: Laurent@814: return _("Couldn't paste non-POU object.") Laurent@814: Laurent@814: # Remove a Pou from project Laurent@814: def ProjectRemovePou(self, pou_name): Laurent@814: if self.Project is not None: Laurent@814: self.Project.removepou(pou_name) Laurent@814: self.BufferProject() Laurent@814: Laurent@814: # Return the name of the configuration if only one exist Laurent@814: def GetProjectMainConfigurationName(self): Laurent@814: if self.Project is not None: Laurent@814: # Found the configuration corresponding to old name and change its name to new name Laurent@814: configurations = self.Project.getconfigurations() Laurent@814: if len(configurations) == 1: Laurent@814: return configurations[0].getname() Laurent@814: return None Laurent@814: Laurent@814: # Add a configuration to Project Laurent@814: def ProjectAddConfiguration(self, config_name=None): Laurent@814: if self.Project is not None: Laurent@814: if config_name is None: Laurent@814: config_name = self.GenerateNewName(None, None, "configuration%d") Laurent@814: self.Project.addconfiguration(config_name) Laurent@814: self.BufferProject() Laurent@814: return self.ComputeConfigurationName(config_name) Laurent@814: return None Laurent@814: Laurent@814: # Remove a configuration from project Laurent@814: def ProjectRemoveConfiguration(self, config_name): Laurent@814: if self.Project is not None: Laurent@814: self.Project.removeconfiguration(config_name) Laurent@814: self.BufferProject() Laurent@814: Laurent@814: # Add a resource to a configuration of the Project Laurent@814: def ProjectAddConfigurationResource(self, config_name, resource_name=None): Laurent@814: if self.Project is not None: Laurent@814: if resource_name is None: Laurent@814: resource_name = self.GenerateNewName(None, None, "resource%d") Laurent@814: self.Project.addconfigurationResource(config_name, resource_name) Laurent@814: self.BufferProject() Laurent@814: return self.ComputeConfigurationResourceName(config_name, resource_name) Laurent@814: return None Laurent@814: Laurent@814: # Remove a resource from a configuration of the project Laurent@814: def ProjectRemoveConfigurationResource(self, config_name, resource_name): Laurent@814: if self.Project is not None: Laurent@814: self.Project.removeconfigurationResource(config_name, resource_name) Laurent@814: self.BufferProject() Laurent@814: Laurent@814: # Add a Transition to a Project Pou Laurent@814: def ProjectAddPouTransition(self, pou_name, transition_name, transition_type): Laurent@814: if self.Project is not None: Laurent@814: pou = self.Project.getpou(pou_name) Laurent@814: if pou is not None: Laurent@814: pou.addtransition(transition_name, transition_type) Laurent@814: self.BufferProject() Laurent@814: return self.ComputePouTransitionName(pou_name, transition_name) Laurent@814: return None Laurent@814: Laurent@814: # Remove a Transition from a Project Pou Laurent@814: def ProjectRemovePouTransition(self, pou_name, transition_name): Laurent@814: # Search if the pou removed is currently opened Laurent@814: if self.Project is not None: Laurent@814: pou = self.Project.getpou(pou_name) Laurent@814: if pou is not None: Laurent@814: pou.removetransition(transition_name) Laurent@814: self.BufferProject() Laurent@814: Laurent@814: # Add an Action to a Project Pou Laurent@814: def ProjectAddPouAction(self, pou_name, action_name, action_type): Laurent@814: if self.Project is not None: Laurent@814: pou = self.Project.getpou(pou_name) Laurent@814: if pou is not None: Laurent@814: pou.addaction(action_name, action_type) Laurent@814: self.BufferProject() Laurent@814: return self.ComputePouActionName(pou_name, action_name) Laurent@814: return None Laurent@814: Laurent@814: # Remove an Action from a Project Pou Laurent@814: def ProjectRemovePouAction(self, pou_name, action_name): Laurent@814: # Search if the pou removed is currently opened Laurent@814: if self.Project is not None: Laurent@814: pou = self.Project.getpou(pou_name) Laurent@814: if pou is not None: Laurent@814: pou.removeaction(action_name) Laurent@814: self.BufferProject() Laurent@814: Laurent@814: # Change the name of a pou Laurent@814: def ChangeDataTypeName(self, old_name, new_name): Laurent@814: if self.Project is not None: Laurent@814: # Found the pou corresponding to old name and change its name to new name Laurent@814: datatype = self.Project.getdataType(old_name) Laurent@814: if datatype is not None: Laurent@814: datatype.setname(new_name) Laurent@814: self.Project.updateElementName(old_name, new_name) Laurent@814: self.Project.RefreshElementUsingTree() Laurent@814: self.Project.RefreshDataTypeHierarchy() Laurent@814: self.BufferProject() Laurent@814: Laurent@814: # Change the name of a pou Laurent@814: def ChangePouName(self, old_name, new_name): Laurent@814: if self.Project is not None: Laurent@814: # Found the pou corresponding to old name and change its name to new name Laurent@814: pou = self.Project.getpou(old_name) Laurent@814: if pou is not None: Laurent@814: pou.setname(new_name) Laurent@814: self.Project.updateElementName(old_name, new_name) Laurent@814: self.Project.RefreshElementUsingTree() Laurent@814: self.Project.RefreshCustomBlockTypes() Laurent@814: self.BufferProject() Laurent@814: Laurent@814: # Change the name of a pou transition Laurent@814: def ChangePouTransitionName(self, pou_name, old_name, new_name): Laurent@814: if self.Project is not None: Laurent@814: # Found the pou transition corresponding to old name and change its name to new name Laurent@814: pou = self.Project.getpou(pou_name) Laurent@814: if pou is not None: Laurent@814: transition = pou.gettransition(old_name) Laurent@814: if transition is not None: Laurent@814: transition.setname(new_name) Laurent@814: pou.updateElementName(old_name, new_name) Laurent@814: self.BufferProject() Laurent@814: Laurent@814: # Change the name of a pou action Laurent@814: def ChangePouActionName(self, pou_name, old_name, new_name): Laurent@814: if self.Project is not None: Laurent@814: # Found the pou action corresponding to old name and change its name to new name Laurent@814: pou = self.Project.getpou(pou_name) Laurent@814: if pou is not None: Laurent@814: action = pou.getaction(old_name) Laurent@814: if action is not None: Laurent@814: action.setname(new_name) Laurent@814: pou.updateElementName(old_name, new_name) Laurent@814: self.BufferProject() Laurent@814: Laurent@814: # Change the name of a pou variable Laurent@814: def ChangePouVariableName(self, pou_name, old_name, new_name): Laurent@814: if self.Project is not None: Laurent@814: # Found the pou action corresponding to old name and change its name to new name Laurent@814: pou = self.Project.getpou(pou_name) Laurent@814: if pou is not None: Laurent@814: for type, varlist in pou.getvars(): Laurent@814: for var in varlist.getvariable(): Laurent@814: if var.getname() == old_name: Laurent@814: var.setname(new_name) Laurent@814: self.Project.RefreshCustomBlockTypes() Laurent@814: self.BufferProject() Laurent@814: Laurent@814: # Change the name of a configuration Laurent@814: def ChangeConfigurationName(self, old_name, new_name): Laurent@814: if self.Project is not None: Laurent@814: # Found the configuration corresponding to old name and change its name to new name Laurent@814: configuration = self.Project.getconfiguration(old_name) Laurent@814: if configuration is not None: Laurent@814: configuration.setname(new_name) Laurent@814: self.BufferProject() Laurent@814: Laurent@814: # Change the name of a configuration resource Laurent@814: def ChangeConfigurationResourceName(self, config_name, old_name, new_name): Laurent@814: if self.Project is not None: Laurent@814: # Found the resource corresponding to old name and change its name to new name Laurent@814: resource = self.Project.getconfigurationResource(config_name, old_name) Laurent@814: if resource is not None: Laurent@814: resource.setname(new_name) Laurent@814: self.BufferProject() Laurent@814: Laurent@814: # Return the description of the pou given by its name Laurent@814: def GetPouDescription(self, name, debug = False): Laurent@814: project = self.GetProject(debug) Laurent@814: if project is not None: Laurent@814: # Found the pou correponding to name and return its type Laurent@814: pou = project.getpou(name) Laurent@814: if pou is not None: Laurent@814: return pou.getdescription() Laurent@814: return "" Laurent@814: Laurent@814: # Return the description of the pou given by its name Laurent@814: def SetPouDescription(self, name, description, debug = False): Laurent@814: project = self.GetProject(debug) Laurent@814: if project is not None: Laurent@814: # Found the pou correponding to name and return its type Laurent@814: pou = project.getpou(name) Laurent@814: if pou is not None: Laurent@814: pou.setdescription(description) Laurent@814: project.RefreshCustomBlockTypes() Laurent@814: self.BufferProject() Laurent@814: Laurent@814: # Return the type of the pou given by its name Laurent@814: def GetPouType(self, name, debug = False): Laurent@814: project = self.GetProject(debug) Laurent@814: if project is not None: Laurent@814: # Found the pou correponding to name and return its type Laurent@814: pou = project.getpou(name) Laurent@814: if pou is not None: Laurent@814: return pou.getpouType() Laurent@814: return None Laurent@814: Laurent@814: # Return pous with SFC language Laurent@814: def GetSFCPous(self, debug = False): Laurent@814: list = [] Laurent@814: project = self.GetProject(debug) Laurent@814: if project is not None: Laurent@814: for pou in project.getpous(): Laurent@814: if pou.getBodyType() == "SFC": Laurent@814: list.append(pou.getname()) Laurent@814: return list Laurent@814: Laurent@814: # Return the body language of the pou given by its name Laurent@814: def GetPouBodyType(self, name, debug = False): Laurent@814: project = self.GetProject(debug) Laurent@814: if project is not None: Laurent@814: # Found the pou correponding to name and return its body language Laurent@814: pou = project.getpou(name) Laurent@814: if pou is not None: Laurent@814: return pou.getbodyType() Laurent@814: return None Laurent@814: Laurent@814: # Return the actions of a pou Laurent@814: def GetPouTransitions(self, pou_name, debug = False): Laurent@814: transitions = [] Laurent@814: project = self.GetProject(debug) Laurent@814: if project is not None: Laurent@814: # Found the pou correponding to name and return its transitions if SFC Laurent@814: pou = project.getpou(pou_name) Laurent@814: if pou is not None and pou.getbodyType() == "SFC": Laurent@814: for transition in pou.gettransitionList(): Laurent@814: transitions.append(transition.getname()) Laurent@814: return transitions Laurent@814: Laurent@814: # Return the body language of the transition given by its name Laurent@814: def GetTransitionBodyType(self, pou_name, pou_transition, debug = False): Laurent@814: project = self.GetProject(debug) Laurent@814: if project is not None: Laurent@814: # Found the pou correponding to name Laurent@814: pou = project.getpou(pou_name) Laurent@814: if pou is not None: Laurent@814: # Found the pou transition correponding to name and return its body language Laurent@814: transition = pou.gettransition(pou_transition) Laurent@814: if transition is not None: Laurent@814: return transition.getbodyType() Laurent@814: return None Laurent@814: Laurent@814: # Return the actions of a pou Laurent@814: def GetPouActions(self, pou_name, debug = False): Laurent@814: actions = [] Laurent@814: project = self.GetProject(debug) Laurent@814: if project is not None: Laurent@814: # Found the pou correponding to name and return its actions if SFC Laurent@814: pou = project.getpou(pou_name) Laurent@814: if pou.getbodyType() == "SFC": Laurent@814: for action in pou.getactionList(): Laurent@814: actions.append(action.getname()) Laurent@814: return actions Laurent@814: Laurent@814: # Return the body language of the pou given by its name Laurent@814: def GetActionBodyType(self, pou_name, pou_action, debug = False): Laurent@814: project = self.GetProject(debug) Laurent@814: if project is not None: Laurent@814: # Found the pou correponding to name and return its body language Laurent@814: pou = project.getpou(pou_name) Laurent@814: if pou is not None: Laurent@814: action = pou.getaction(pou_action) Laurent@814: if action is not None: Laurent@814: return action.getbodyType() Laurent@814: return None Laurent@814: Laurent@814: # Extract varlists from a list of vars Laurent@814: def ExtractVarLists(self, vars): Laurent@814: varlist_list = [] Laurent@814: current_varlist = None Laurent@814: current_type = None Laurent@814: for var in vars: Laurent@814: next_type = (var["Class"], Laurent@814: var["Option"], Laurent@814: var["Location"] in ["", None] or Laurent@814: # When declaring globals, located Laurent@814: # and not located variables are Laurent@814: # in the same declaration block Laurent@814: var["Class"] == "Global") Laurent@814: if current_type != next_type: Laurent@814: current_type = next_type Laurent@814: infos = VAR_CLASS_INFOS.get(var["Class"], None) Laurent@814: if infos is not None: Laurent@814: current_varlist = infos[0]() Laurent@814: else: Laurent@814: current_varlist = plcopen.varList() Laurent@814: varlist_list.append((var["Class"], current_varlist)) Laurent@814: if var["Option"] == "Constant": Laurent@814: current_varlist.setconstant(True) Laurent@814: elif var["Option"] == "Retain": Laurent@814: current_varlist.setretain(True) Laurent@814: elif var["Option"] == "Non-Retain": Laurent@814: current_varlist.setnonretain(True) Laurent@814: # Create variable and change its properties Laurent@814: tempvar = plcopen.varListPlain_variable() Laurent@814: tempvar.setname(var["Name"]) Laurent@814: Laurent@814: var_type = plcopen.dataType() Laurent@814: if isinstance(var["Type"], TupleType): Laurent@814: if var["Type"][0] == "array": Laurent@814: array_type, base_type_name, dimensions = var["Type"] Laurent@814: array = plcopen.derivedTypes_array() Laurent@814: for i, dimension in enumerate(dimensions): Laurent@814: dimension_range = plcopen.rangeSigned() Laurent@814: dimension_range.setlower(dimension[0]) Laurent@814: dimension_range.setupper(dimension[1]) Laurent@814: if i == 0: Laurent@814: array.setdimension([dimension_range]) Laurent@814: else: Laurent@814: array.appenddimension(dimension_range) Laurent@814: if base_type_name in self.GetBaseTypes(): Laurent@814: if base_type_name == "STRING": Laurent@814: array.baseType.setcontent({"name" : "string", "value" : plcopen.elementaryTypes_string()}) Laurent@814: elif base_type_name == "WSTRING": Laurent@814: array.baseType.setcontent({"name" : "wstring", "value" : plcopen.wstring()}) Laurent@814: else: Laurent@814: array.baseType.setcontent({"name" : base_type_name, "value" : None}) Laurent@814: else: Laurent@814: derived_datatype = plcopen.derivedTypes_derived() Laurent@814: derived_datatype.setname(base_type_name) Laurent@814: array.baseType.setcontent({"name" : "derived", "value" : derived_datatype}) Laurent@814: var_type.setcontent({"name" : "array", "value" : array}) Laurent@814: elif var["Type"] in self.GetBaseTypes(): Laurent@814: if var["Type"] == "STRING": Laurent@814: var_type.setcontent({"name" : "string", "value" : plcopen.elementaryTypes_string()}) Laurent@814: elif var["Type"] == "WSTRING": Laurent@814: var_type.setcontent({"name" : "wstring", "value" : plcopen.elementaryTypes_wstring()}) Laurent@814: else: Laurent@814: var_type.setcontent({"name" : var["Type"], "value" : None}) Laurent@814: else: Laurent@814: derived_type = plcopen.derivedTypes_derived() Laurent@814: derived_type.setname(var["Type"]) Laurent@814: var_type.setcontent({"name" : "derived", "value" : derived_type}) Laurent@814: tempvar.settype(var_type) Laurent@814: Laurent@814: if var["Initial Value"] != "": Laurent@814: value = plcopen.value() Laurent@814: value.setvalue(var["Initial Value"]) Laurent@814: tempvar.setinitialValue(value) Laurent@814: if var["Location"] != "": Laurent@814: tempvar.setaddress(var["Location"]) Laurent@814: else: Laurent@814: tempvar.setaddress(None) Laurent@814: if var['Documentation'] != "": Laurent@814: ft = plcopen.formattedText() Laurent@814: ft.settext(var['Documentation']) Laurent@814: tempvar.setdocumentation(ft) Laurent@814: Laurent@814: # Add variable to varList Laurent@814: current_varlist.appendvariable(tempvar) Laurent@814: return varlist_list Laurent@814: Laurent@814: def GetVariableDictionary(self, varlist, var): Laurent@814: ''' Laurent@814: convert a PLC variable to the dictionary representation Laurent@814: returned by Get*Vars) Laurent@814: ''' Laurent@814: Laurent@814: tempvar = {"Name": var.getname()} Laurent@814: Laurent@814: vartype_content = var.gettype().getcontent() Laurent@814: if vartype_content["name"] == "derived": Laurent@814: tempvar["Type"] = vartype_content["value"].getname() Laurent@814: elif vartype_content["name"] == "array": Laurent@814: dimensions = [] Laurent@814: for dimension in vartype_content["value"].getdimension(): Laurent@814: dimensions.append((dimension.getlower(), dimension.getupper())) Laurent@814: base_type = vartype_content["value"].baseType.getcontent() Laurent@864: if base_type["value"] is None or base_type["name"] in ["string", "wstring"]: Laurent@864: base_type_name = base_type["name"].upper() Laurent@814: else: Laurent@814: base_type_name = base_type["value"].getname() Laurent@814: tempvar["Type"] = ("array", base_type_name, dimensions) Laurent@814: elif vartype_content["name"] in ["string", "wstring"]: Laurent@814: tempvar["Type"] = vartype_content["name"].upper() Laurent@814: else: Laurent@814: tempvar["Type"] = vartype_content["name"] Laurent@814: Laurent@814: tempvar["Edit"] = True Laurent@814: Laurent@814: initial = var.getinitialValue() Laurent@814: if initial: Laurent@814: tempvar["Initial Value"] = initial.getvalue() Laurent@814: else: Laurent@814: tempvar["Initial Value"] = "" Laurent@814: Laurent@814: address = var.getaddress() Laurent@814: if address: Laurent@814: tempvar["Location"] = address Laurent@814: else: Laurent@814: tempvar["Location"] = "" Laurent@814: Laurent@814: if varlist.getconstant(): Laurent@814: tempvar["Option"] = "Constant" Laurent@814: elif varlist.getretain(): Laurent@814: tempvar["Option"] = "Retain" Laurent@814: elif varlist.getnonretain(): Laurent@814: tempvar["Option"] = "Non-Retain" Laurent@814: else: Laurent@814: tempvar["Option"] = "" Laurent@814: Laurent@814: doc = var.getdocumentation() Laurent@814: if doc: Laurent@814: tempvar["Documentation"] = doc.gettext() Laurent@814: else: Laurent@814: tempvar["Documentation"] = "" Laurent@814: Laurent@814: return tempvar Laurent@814: Laurent@814: # Replace the configuration globalvars by those given Laurent@814: def SetConfigurationGlobalVars(self, name, vars): Laurent@814: if self.Project is not None: Laurent@814: # Found the configuration corresponding to name Laurent@814: configuration = self.Project.getconfiguration(name) Laurent@814: if configuration is not None: Laurent@814: # Set configuration global vars Laurent@814: configuration.setglobalVars([]) Laurent@814: for vartype, varlist in self.ExtractVarLists(vars): Laurent@814: configuration.globalVars.append(varlist) Laurent@814: Laurent@814: # Return the configuration globalvars Laurent@814: def GetConfigurationGlobalVars(self, name, debug = False): Laurent@814: vars = [] Laurent@814: project = self.GetProject(debug) Laurent@814: if project is not None: Laurent@814: # Found the configuration corresponding to name Laurent@814: configuration = project.getconfiguration(name) Laurent@814: if configuration is not None: Laurent@814: # Extract variables from every varLists Laurent@814: for varlist in configuration.getglobalVars(): Laurent@814: for var in varlist.getvariable(): Laurent@814: tempvar = self.GetVariableDictionary(varlist, var) Laurent@814: tempvar["Class"] = "Global" Laurent@814: vars.append(tempvar) Laurent@814: return vars Laurent@814: Laurent@814: # Replace the resource globalvars by those given Laurent@814: def SetConfigurationResourceGlobalVars(self, config_name, name, vars): Laurent@814: if self.Project is not None: Laurent@814: # Found the resource corresponding to name Laurent@814: resource = self.Project.getconfigurationResource(config_name, name) Laurent@814: # Set resource global vars Laurent@814: if resource is not None: Laurent@814: resource.setglobalVars([]) Laurent@814: for vartype, varlist in self.ExtractVarLists(vars): Laurent@814: resource.globalVars.append(varlist) Laurent@814: Laurent@814: # Return the resource globalvars Laurent@814: def GetConfigurationResourceGlobalVars(self, config_name, name, debug = False): Laurent@814: vars = [] Laurent@814: project = self.GetProject(debug) Laurent@814: if project is not None: Laurent@814: # Found the resource corresponding to name Laurent@814: resource = project.getconfigurationResource(config_name, name) Laurent@814: if resource: Laurent@814: # Extract variables from every varLists Laurent@814: for varlist in resource.getglobalVars(): Laurent@814: for var in varlist.getvariable(): Laurent@814: tempvar = self.GetVariableDictionary(varlist, var) Laurent@814: tempvar["Class"] = "Global" Laurent@814: vars.append(tempvar) Laurent@814: return vars Laurent@814: Laurent@814: # Recursively generate element name tree for a structured variable Laurent@814: def GenerateVarTree(self, typename, debug = False): Laurent@814: project = self.GetProject(debug) Laurent@814: if project is not None: Laurent@814: blocktype = self.GetBlockType(typename, debug = debug) Laurent@814: if blocktype is not None: Laurent@814: tree = [] Laurent@814: en = False Laurent@814: eno = False Laurent@814: for var_name, var_type, var_modifier in blocktype["inputs"] + blocktype["outputs"]: Laurent@814: en |= var_name.upper() == "EN" Laurent@814: eno |= var_name.upper() == "ENO" Laurent@814: tree.append((var_name, var_type, self.GenerateVarTree(var_type, debug))) Laurent@814: if not eno: Laurent@814: tree.insert(0, ("ENO", "BOOL", ([], []))) Laurent@814: if not en: Laurent@814: tree.insert(0, ("EN", "BOOL", ([], []))) Laurent@814: return tree, [] Laurent@814: datatype = project.getdataType(typename) Laurent@814: if datatype is None: Laurent@814: datatype = self.GetConfNodeDataType(typename) Laurent@814: if datatype is not None: Laurent@814: tree = [] Laurent@814: basetype_content = datatype.baseType.getcontent() Laurent@814: if basetype_content["name"] == "derived": Laurent@814: return self.GenerateVarTree(basetype_content["value"].getname()) Laurent@814: elif basetype_content["name"] == "array": Laurent@814: dimensions = [] Laurent@814: base_type = basetype_content["value"].baseType.getcontent() Laurent@814: if base_type["name"] == "derived": Laurent@814: tree = self.GenerateVarTree(base_type["value"].getname()) Laurent@814: if len(tree[1]) == 0: Laurent@814: tree = tree[0] Laurent@814: for dimension in basetype_content["value"].getdimension(): Laurent@814: dimensions.append((dimension.getlower(), dimension.getupper())) Laurent@814: return tree, dimensions Laurent@814: elif basetype_content["name"] == "struct": Laurent@814: for element in basetype_content["value"].getvariable(): Laurent@814: element_type = element.type.getcontent() Laurent@814: if element_type["name"] == "derived": Laurent@814: tree.append((element.getname(), element_type["value"].getname(), self.GenerateVarTree(element_type["value"].getname()))) Laurent@814: else: Laurent@814: tree.append((element.getname(), element_type["name"], ([], []))) Laurent@814: return tree, [] Laurent@814: return [], [] Laurent@814: Laurent@814: # Return the interface for the given pou Laurent@814: def GetPouInterfaceVars(self, pou, debug = False): Laurent@814: vars = [] Laurent@814: # Verify that the pou has an interface Laurent@814: if pou.interface is not None: Laurent@814: # Extract variables from every varLists Laurent@814: for type, varlist in pou.getvars(): Laurent@814: for var in varlist.getvariable(): Laurent@814: tempvar = self.GetVariableDictionary(varlist, var) Laurent@814: Laurent@814: tempvar["Class"] = type Laurent@814: tempvar["Tree"] = ([], []) Laurent@814: Laurent@814: vartype_content = var.gettype().getcontent() Laurent@814: if vartype_content["name"] == "derived": Laurent@814: tempvar["Edit"] = not pou.hasblock(tempvar["Name"]) Laurent@814: tempvar["Tree"] = self.GenerateVarTree(tempvar["Type"], debug) Laurent@814: Laurent@814: vars.append(tempvar) Laurent@814: return vars Laurent@814: Laurent@814: # Replace the Pou interface by the one given Laurent@814: def SetPouInterfaceVars(self, name, vars): Laurent@814: if self.Project is not None: Laurent@814: # Found the pou corresponding to name and add interface if there isn't one yet Laurent@814: pou = self.Project.getpou(name) Laurent@814: if pou is not None: Laurent@814: if pou.interface is None: Laurent@814: pou.interface = plcopen.pou_interface() Laurent@814: # Set Pou interface Laurent@814: pou.setvars(self.ExtractVarLists(vars)) Laurent@814: self.Project.RefreshElementUsingTree() Laurent@814: self.Project.RefreshCustomBlockTypes() Laurent@814: Laurent@814: # Replace the return type of the pou given by its name (only for functions) Laurent@814: def SetPouInterfaceReturnType(self, name, type): Laurent@814: if self.Project is not None: Laurent@814: pou = self.Project.getpou(name) Laurent@814: if pou is not None: Laurent@814: if pou.interface is None: Laurent@814: pou.interface = plcopen.pou_interface() Laurent@814: # If there isn't any return type yet, add it Laurent@814: return_type = pou.interface.getreturnType() Laurent@814: if not return_type: Laurent@814: return_type = plcopen.dataType() Laurent@814: pou.interface.setreturnType(return_type) Laurent@814: # Change return type Laurent@814: if type in self.GetBaseTypes(): Laurent@814: if type == "STRING": Laurent@814: return_type.setcontent({"name" : "string", "value" : plcopen.elementaryTypes_string()}) Laurent@814: elif type == "WSTRING": Laurent@814: return_type.setcontent({"name" : "wstring", "value" : plcopen.elementaryTypes_wstring()}) Laurent@814: else: Laurent@814: return_type.setcontent({"name" : type, "value" : None}) Laurent@814: else: Laurent@814: derived_type = plcopen.derivedTypes_derived() Laurent@814: derived_type.setname(type) Laurent@814: return_type.setcontent({"name" : "derived", "value" : derived_type}) Laurent@814: self.Project.RefreshElementUsingTree() Laurent@814: self.Project.RefreshCustomBlockTypes() Laurent@814: Laurent@814: def UpdateProjectUsedPous(self, old_name, new_name): Laurent@814: if self.Project: Laurent@814: self.Project.updateElementName(old_name, new_name) Laurent@814: Laurent@814: def UpdateEditedElementUsedVariable(self, tagname, old_name, new_name): Laurent@814: pou = self.GetEditedElement(tagname) Laurent@814: if pou: Laurent@814: pou.updateElementName(old_name, new_name) Laurent@814: Laurent@814: # Return the return type of the pou given by its name Laurent@814: def GetPouInterfaceReturnTypeByName(self, name): Laurent@814: project = self.GetProject(debug) Laurent@814: if project is not None: Laurent@814: # Found the pou correponding to name and return the return type Laurent@814: pou = project.getpou(name) Laurent@814: if pou is not None: Laurent@814: return self.GetPouInterfaceReturnType(pou) Laurent@814: return False Laurent@814: Laurent@814: # Return the return type of the given pou Laurent@814: def GetPouInterfaceReturnType(self, pou): Laurent@814: # Verify that the pou has an interface Laurent@814: if pou.interface is not None: Laurent@814: # Return the return type if there is one Laurent@814: return_type = pou.interface.getreturnType() Laurent@814: if return_type: Laurent@814: returntype_content = return_type.getcontent() Laurent@814: if returntype_content["name"] == "derived": Laurent@814: return returntype_content["value"].getname() Laurent@814: elif returntype_content["name"] in ["string", "wstring"]: Laurent@814: return returntype_content["name"].upper() Laurent@814: else: Laurent@814: return returntype_content["name"] Laurent@814: return None Laurent@814: Laurent@814: # Function that add a new confnode to the confnode list Laurent@814: def AddConfNodeTypesList(self, typeslist): Laurent@814: self.ConfNodeTypes.extend(typeslist) Laurent@814: Laurent@814: # Function that clear the confnode list Laurent@814: def ClearConfNodeTypes(self): Laurent@814: for i in xrange(len(self.ConfNodeTypes)): Laurent@814: self.ConfNodeTypes.pop(0) Laurent@814: Laurent@814: def GetConfNodeBlockTypes(self): Laurent@814: return [{"name": _("%s POUs") % confnodetypes["name"], Laurent@814: "list": confnodetypes["types"].GetCustomBlockTypes()} Laurent@814: for confnodetypes in self.ConfNodeTypes] Laurent@814: Laurent@863: def GetConfNodeDataTypes(self, exclude = "", only_locatables = False): Laurent@814: return [{"name": _("%s Data Types") % confnodetypes["name"], Laurent@863: "list": [datatype["name"] for datatype in confnodetypes["types"].GetCustomDataTypes(exclude, only_locatables)]} Laurent@814: for confnodetypes in self.ConfNodeTypes] Laurent@814: Laurent@814: def GetConfNodeDataType(self, type): Laurent@814: for confnodetype in self.ConfNodeTypes: Laurent@814: datatype = confnodetype["types"].getdataType(type) Laurent@814: if datatype is not None: Laurent@814: return datatype Laurent@814: return None Laurent@814: Laurent@814: def GetVariableLocationTree(self): Laurent@814: return [] Laurent@814: Laurent@883: def GetConfNodeGlobalInstances(self): Laurent@883: return [] Laurent@883: Laurent@883: def GetConfigurationExtraVariables(self): Laurent@883: global_vars = [] Laurent@883: for var_name, var_type in self.GetConfNodeGlobalInstances(): Laurent@883: tempvar = plcopen.varListPlain_variable() Laurent@883: tempvar.setname(var_name) Laurent@883: Laurent@883: tempvartype = plcopen.dataType() Laurent@883: if var_type in self.GetBaseTypes(): Laurent@883: if var_type == "STRING": Laurent@883: var_type.setcontent({"name" : "string", "value" : plcopen.elementaryTypes_string()}) Laurent@883: elif var_type == "WSTRING": Laurent@883: var_type.setcontent({"name" : "wstring", "value" : plcopen.elementaryTypes_wstring()}) Laurent@883: else: Laurent@883: var_type.setcontent({"name" : var_type, "value" : None}) Laurent@883: else: Laurent@883: tempderivedtype = plcopen.derivedTypes_derived() Laurent@883: tempderivedtype.setname(var_type) Laurent@883: tempvartype.setcontent({"name" : "derived", "value" : tempderivedtype}) Laurent@883: tempvar.settype(tempvartype) Laurent@883: Laurent@883: global_vars.append(tempvar) Laurent@883: return global_vars Laurent@883: Laurent@814: # Function that returns the block definition associated to the block type given Laurent@814: def GetBlockType(self, type, inputs = None, debug = False): Laurent@814: result_blocktype = None Laurent@814: for category in BlockTypes + self.GetConfNodeBlockTypes(): Laurent@814: for blocktype in category["list"]: Laurent@814: if blocktype["name"] == type: Laurent@814: if inputs is not None and inputs != "undefined": Laurent@814: block_inputs = tuple([var_type for name, var_type, modifier in blocktype["inputs"]]) Laurent@814: if reduce(lambda x, y: x and y, map(lambda x: x[0] == "ANY" or self.IsOfType(*x), zip(inputs, block_inputs)), True): Laurent@814: return blocktype Laurent@814: else: Laurent@814: if result_blocktype is not None: Laurent@814: if inputs == "undefined": Laurent@814: return None Laurent@814: else: Laurent@814: result_blocktype["inputs"] = [(i[0], "ANY", i[2]) for i in result_blocktype["inputs"]] Laurent@814: result_blocktype["outputs"] = [(o[0], "ANY", o[2]) for o in result_blocktype["outputs"]] Laurent@814: return result_blocktype Laurent@814: result_blocktype = blocktype Laurent@814: if result_blocktype is not None: Laurent@814: return result_blocktype Laurent@814: project = self.GetProject(debug) Laurent@814: if project is not None: Laurent@814: return project.GetCustomBlockType(type, inputs) Laurent@814: return None Laurent@814: Laurent@814: # Return Block types checking for recursion Laurent@814: def GetBlockTypes(self, tagname = "", debug = False): Laurent@814: type = None Laurent@814: words = tagname.split("::") Laurent@814: if self.Project: Laurent@814: name = "" Laurent@814: if words[0] in ["P","T","A"]: Laurent@814: name = words[1] Laurent@814: type = self.GetPouType(name, debug) laurent@823: if type == "function": Laurent@814: blocktypes = [] Laurent@814: for category in BlockTypes + self.GetConfNodeBlockTypes(): Laurent@814: cat = {"name" : category["name"], "list" : []} Laurent@814: for block in category["list"]: Laurent@814: if block["type"] == "function": Laurent@814: cat["list"].append(block) Laurent@814: if len(cat["list"]) > 0: Laurent@814: blocktypes.append(cat) Laurent@814: else: Laurent@814: blocktypes = [category for category in BlockTypes + self.GetConfNodeBlockTypes()] Laurent@814: project = self.GetProject(debug) Laurent@814: if project is not None: Laurent@814: blocktypes.append({"name" : USER_DEFINED_POUS, "list": project.GetCustomBlockTypes(name, type == "function" or words[0] == "T")}) Laurent@814: return blocktypes Laurent@814: Laurent@814: # Return Function Block types checking for recursion Laurent@814: def GetFunctionBlockTypes(self, tagname = "", debug = False): Laurent@814: blocktypes = [] Laurent@814: for category in BlockTypes + self.GetConfNodeBlockTypes(): Laurent@814: for block in category["list"]: Laurent@814: if block["type"] == "functionBlock": Laurent@814: blocktypes.append(block["name"]) Laurent@814: project = self.GetProject(debug) Laurent@814: if project is not None: Laurent@814: name = "" Laurent@814: words = tagname.split("::") Laurent@814: if words[0] in ["P","T","A"]: Laurent@814: name = words[1] Laurent@814: blocktypes.extend(project.GetCustomFunctionBlockTypes(name)) Laurent@814: return blocktypes Laurent@814: Laurent@814: # Return Block types checking for recursion Laurent@814: def GetBlockResource(self, debug = False): Laurent@814: blocktypes = [] Laurent@814: for category in BlockTypes[:-1]: Laurent@814: for blocktype in category["list"]: Laurent@814: if blocktype["type"] == "program": Laurent@814: blocktypes.append(blocktype["name"]) Laurent@814: project = self.GetProject(debug) Laurent@814: if project is not None: Laurent@814: blocktypes.extend(project.GetCustomBlockResource()) Laurent@814: return blocktypes Laurent@814: Laurent@814: # Return Data Types checking for recursion Laurent@863: def GetDataTypes(self, tagname = "", basetypes = True, confnodetypes = True, only_locatables = False, debug = False): Laurent@814: if basetypes: Laurent@814: datatypes = self.GetBaseTypes() Laurent@814: else: Laurent@814: datatypes = [] Laurent@814: project = self.GetProject(debug) Laurent@814: if project is not None: Laurent@814: name = "" Laurent@814: words = tagname.split("::") Laurent@814: if words[0] in ["D"]: Laurent@814: name = words[1] Laurent@814: datatypes.extend([datatype["name"] for datatype in project.GetCustomDataTypes(name, only_locatables)]) Laurent@863: if confnodetypes: Laurent@863: for category in self.GetConfNodeDataTypes(name, only_locatables): Laurent@863: datatypes.extend(category["list"]) Laurent@814: return datatypes Laurent@814: Laurent@814: # Return Base Type of given possible derived type Laurent@814: def GetBaseType(self, type, debug = False): Laurent@814: project = self.GetProject(debug) Laurent@814: if project is not None: Laurent@814: result = project.GetBaseType(type) Laurent@814: if result is not None: Laurent@814: return result Laurent@814: for confnodetype in self.ConfNodeTypes: Laurent@814: result = confnodetype["types"].GetBaseType(type) Laurent@814: if result is not None: Laurent@814: return result Laurent@814: return None Laurent@814: Laurent@814: def GetBaseTypes(self): Laurent@814: ''' Laurent@814: return the list of datatypes defined in IEC 61131-3. Laurent@814: TypeHierarchy_list has a rough order to it (e.g. SINT, INT, DINT, ...), Laurent@814: which makes it easy for a user to find a type in a menu. Laurent@814: ''' Laurent@814: return [x for x,y in TypeHierarchy_list if not x.startswith("ANY")] Laurent@814: Laurent@814: def IsOfType(self, type, reference, debug = False): Laurent@814: if reference is None: Laurent@814: return True Laurent@814: elif type == reference: Laurent@814: return True Laurent@814: elif type in TypeHierarchy: Laurent@814: return self.IsOfType(TypeHierarchy[type], reference) Laurent@814: else: Laurent@814: project = self.GetProject(debug) Laurent@814: if project is not None and project.IsOfType(type, reference): Laurent@814: return True Laurent@814: for confnodetype in self.ConfNodeTypes: Laurent@814: if confnodetype["types"].IsOfType(type, reference): Laurent@814: return True Laurent@814: return False Laurent@814: Laurent@814: def IsEndType(self, type): Laurent@814: if type is not None: Laurent@814: return not type.startswith("ANY") Laurent@814: return True Laurent@814: Laurent@814: def IsLocatableType(self, type, debug = False): Laurent@814: if isinstance(type, TupleType): Laurent@814: return False Laurent@884: if self.GetBlockType(type) is not None: Laurent@884: return False Laurent@814: project = self.GetProject(debug) Laurent@814: if project is not None: Laurent@814: datatype = project.getdataType(type) Laurent@814: if datatype is None: Laurent@814: datatype = self.GetConfNodeDataType(type) Laurent@814: if datatype is not None: Laurent@814: return project.IsLocatableType(datatype) Laurent@814: return True Laurent@814: Laurent@814: def IsEnumeratedType(self, type, debug = False): Laurent@814: project = self.GetProject(debug) Laurent@814: if project is not None: Laurent@814: datatype = project.getdataType(type) Laurent@814: if datatype is None: Laurent@814: datatype = self.GetConfNodeDataType(type) Laurent@814: if datatype is not None: Laurent@814: basetype_content = datatype.baseType.getcontent() Laurent@814: return basetype_content["name"] == "enum" Laurent@814: return False Laurent@814: Laurent@887: def IsNumType(self, type, debug = False): Laurent@887: return self.IsOfType(type, "ANY_NUM", debug) or\ Laurent@887: self.IsOfType(type, "ANY_BIT", debug) Laurent@887: Laurent@814: def GetDataTypeRange(self, type, debug = False): Laurent@814: if type in DataTypeRange: Laurent@814: return DataTypeRange[type] Laurent@814: else: Laurent@814: project = self.GetProject(debug) Laurent@814: if project is not None: Laurent@814: result = project.GetDataTypeRange(type) Laurent@814: if result is not None: Laurent@814: return result Laurent@814: for confnodetype in self.ConfNodeTypes: Laurent@814: result = confnodetype["types"].GetDataTypeRange(type) Laurent@814: if result is not None: Laurent@814: return result Laurent@814: return None Laurent@814: Laurent@814: # Return Subrange types Laurent@814: def GetSubrangeBaseTypes(self, exclude, debug = False): Laurent@814: subrange_basetypes = [] Laurent@814: project = self.GetProject(debug) Laurent@814: if project is not None: Laurent@814: subrange_basetypes.extend(project.GetSubrangeBaseTypes(exclude)) Laurent@814: for confnodetype in self.ConfNodeTypes: Laurent@814: subrange_basetypes.extend(confnodetype["types"].GetSubrangeBaseTypes(exclude)) Laurent@814: return DataTypeRange.keys() + subrange_basetypes Laurent@814: Laurent@814: # Return Enumerated Values Laurent@814: def GetEnumeratedDataValues(self, type = None, debug = False): Laurent@814: values = [] Laurent@814: project = self.GetProject(debug) Laurent@814: if project is not None: Laurent@814: values.extend(project.GetEnumeratedDataTypeValues(type)) Laurent@814: if type is None and len(values) > 0: Laurent@814: return values Laurent@814: for confnodetype in self.ConfNodeTypes: Laurent@814: values.extend(confnodetype["types"].GetEnumeratedDataTypeValues(type)) Laurent@814: if type is None and len(values) > 0: Laurent@814: return values Laurent@814: return values Laurent@814: Laurent@814: #------------------------------------------------------------------------------- Laurent@814: # Project Element tag name computation functions Laurent@814: #------------------------------------------------------------------------------- Laurent@814: Laurent@814: # Compute a data type name Laurent@814: def ComputeDataTypeName(self, datatype): Laurent@814: return "D::%s" % datatype Laurent@814: Laurent@814: # Compute a pou name Laurent@814: def ComputePouName(self, pou): Laurent@814: return "P::%s" % pou Laurent@814: Laurent@814: # Compute a pou transition name Laurent@814: def ComputePouTransitionName(self, pou, transition): Laurent@814: return "T::%s::%s" % (pou, transition) Laurent@814: Laurent@814: # Compute a pou action name Laurent@814: def ComputePouActionName(self, pou, action): Laurent@814: return "A::%s::%s" % (pou, action) Laurent@814: Laurent@814: # Compute a pou name Laurent@814: def ComputeConfigurationName(self, config): Laurent@814: return "C::%s" % config Laurent@814: Laurent@814: # Compute a pou name Laurent@814: def ComputeConfigurationResourceName(self, config, resource): Laurent@814: return "R::%s::%s" % (config, resource) Laurent@814: Laurent@814: def GetElementType(self, tagname): Laurent@814: words = tagname.split("::") Laurent@814: return {"D" : ITEM_DATATYPE, "P" : ITEM_POU, Laurent@814: "T" : ITEM_TRANSITION, "A" : ITEM_ACTION, Laurent@814: "C" : ITEM_CONFIGURATION, "R" : ITEM_RESOURCE}[words[0]] Laurent@814: Laurent@814: #------------------------------------------------------------------------------- Laurent@814: # Project opened Data types management functions Laurent@814: #------------------------------------------------------------------------------- Laurent@814: Laurent@814: # Return the data type informations Laurent@814: def GetDataTypeInfos(self, tagname, debug = False): Laurent@814: project = self.GetProject(debug) Laurent@814: if project is not None: Laurent@814: words = tagname.split("::") Laurent@814: if words[0] == "D": Laurent@814: infos = {} Laurent@814: datatype = project.getdataType(words[1]) Laurent@883: if datatype is None: Laurent@883: return None Laurent@814: basetype_content = datatype.baseType.getcontent() Laurent@814: if basetype_content["value"] is None or basetype_content["name"] in ["string", "wstring"]: Laurent@814: infos["type"] = "Directly" Laurent@814: infos["base_type"] = basetype_content["name"].upper() Laurent@814: elif basetype_content["name"] == "derived": Laurent@814: infos["type"] = "Directly" Laurent@814: infos["base_type"] = basetype_content["value"].getname() Laurent@814: elif basetype_content["name"] in ["subrangeSigned", "subrangeUnsigned"]: Laurent@814: infos["type"] = "Subrange" Laurent@814: infos["min"] = basetype_content["value"].range.getlower() Laurent@814: infos["max"] = basetype_content["value"].range.getupper() Laurent@814: base_type = basetype_content["value"].baseType.getcontent() Laurent@814: if base_type["value"] is None: Laurent@814: infos["base_type"] = base_type["name"] Laurent@814: else: Laurent@814: infos["base_type"] = base_type["value"].getname() Laurent@814: elif basetype_content["name"] == "enum": Laurent@814: infos["type"] = "Enumerated" Laurent@814: infos["values"] = [] Laurent@814: for value in basetype_content["value"].values.getvalue(): Laurent@814: infos["values"].append(value.getname()) Laurent@814: elif basetype_content["name"] == "array": Laurent@814: infos["type"] = "Array" Laurent@814: infos["dimensions"] = [] Laurent@814: for dimension in basetype_content["value"].getdimension(): Laurent@814: infos["dimensions"].append((dimension.getlower(), dimension.getupper())) Laurent@814: base_type = basetype_content["value"].baseType.getcontent() Laurent@814: if base_type["value"] is None or base_type["name"] in ["string", "wstring"]: Laurent@814: infos["base_type"] = base_type["name"].upper() Laurent@814: else: Laurent@814: infos["base_type"] = base_type["value"].getname() Laurent@814: elif basetype_content["name"] == "struct": Laurent@814: infos["type"] = "Structure" Laurent@814: infos["elements"] = [] Laurent@814: for element in basetype_content["value"].getvariable(): Laurent@814: element_infos = {} Laurent@814: element_infos["Name"] = element.getname() Laurent@814: element_type = element.type.getcontent() Laurent@814: if element_type["value"] is None or element_type["name"] in ["string", "wstring"]: Laurent@814: element_infos["Type"] = element_type["name"].upper() Laurent@864: elif element_type["name"] == "array": Laurent@864: dimensions = [] Laurent@864: for dimension in element_type["value"].getdimension(): Laurent@864: dimensions.append((dimension.getlower(), dimension.getupper())) Laurent@864: base_type = element_type["value"].baseType.getcontent() Laurent@864: if base_type["value"] is None or base_type["name"] in ["string", "wstring"]: Laurent@864: base_type_name = base_type["name"].upper() Laurent@864: else: Laurent@864: base_type_name = base_type["value"].getname() Laurent@864: element_infos["Type"] = ("array", base_type_name, dimensions) Laurent@814: else: Laurent@814: element_infos["Type"] = element_type["value"].getname() Laurent@814: if element.initialValue is not None: Laurent@814: element_infos["Initial Value"] = str(element.initialValue.getvalue()) Laurent@814: else: Laurent@814: element_infos["Initial Value"] = "" Laurent@814: infos["elements"].append(element_infos) Laurent@814: if datatype.initialValue is not None: Laurent@814: infos["initial"] = str(datatype.initialValue.getvalue()) Laurent@814: else: Laurent@814: infos["initial"] = "" Laurent@814: return infos Laurent@814: return None Laurent@814: Laurent@814: # Change the data type informations Laurent@814: def SetDataTypeInfos(self, tagname, infos): Laurent@814: words = tagname.split("::") Laurent@814: if self.Project is not None and words[0] == "D": Laurent@814: datatype = self.Project.getdataType(words[1]) Laurent@814: if infos["type"] == "Directly": Laurent@814: if infos["base_type"] in self.GetBaseTypes(): Laurent@814: if infos["base_type"] == "STRING": Laurent@814: datatype.baseType.setcontent({"name" : "string", "value" : plcopen.elementaryTypes_string()}) Laurent@814: elif infos["base_type"] == "WSTRING": Laurent@814: datatype.baseType.setcontent({"name" : "wstring", "value" : plcopen.elementaryTypes_wstring()}) Laurent@814: else: Laurent@814: datatype.baseType.setcontent({"name" : infos["base_type"], "value" : None}) Laurent@814: else: Laurent@814: derived_datatype = plcopen.derivedTypes_derived() Laurent@814: derived_datatype.setname(infos["base_type"]) Laurent@814: datatype.baseType.setcontent({"name" : "derived", "value" : derived_datatype}) Laurent@814: elif infos["type"] == "Subrange": Laurent@814: if infos["base_type"] in GetSubTypes("ANY_UINT"): Laurent@814: subrange = plcopen.derivedTypes_subrangeUnsigned() Laurent@814: datatype.baseType.setcontent({"name" : "subrangeUnsigned", "value" : subrange}) Laurent@814: else: Laurent@814: subrange = plcopen.derivedTypes_subrangeSigned() Laurent@814: datatype.baseType.setcontent({"name" : "subrangeSigned", "value" : subrange}) Laurent@814: subrange.range.setlower(infos["min"]) Laurent@814: subrange.range.setupper(infos["max"]) Laurent@814: if infos["base_type"] in self.GetBaseTypes(): Laurent@814: subrange.baseType.setcontent({"name" : infos["base_type"], "value" : None}) Laurent@814: else: Laurent@814: derived_datatype = plcopen.derivedTypes_derived() Laurent@814: derived_datatype.setname(infos["base_type"]) Laurent@814: subrange.baseType.setcontent({"name" : "derived", "value" : derived_datatype}) Laurent@814: elif infos["type"] == "Enumerated": Laurent@814: enumerated = plcopen.derivedTypes_enum() Laurent@814: for i, enum_value in enumerate(infos["values"]): Laurent@814: value = plcopen.values_value() Laurent@814: value.setname(enum_value) Laurent@814: if i == 0: Laurent@814: enumerated.values.setvalue([value]) Laurent@814: else: Laurent@814: enumerated.values.appendvalue(value) Laurent@814: datatype.baseType.setcontent({"name" : "enum", "value" : enumerated}) Laurent@814: elif infos["type"] == "Array": Laurent@814: array = plcopen.derivedTypes_array() Laurent@814: for i, dimension in enumerate(infos["dimensions"]): Laurent@814: dimension_range = plcopen.rangeSigned() Laurent@814: dimension_range.setlower(dimension[0]) Laurent@814: dimension_range.setupper(dimension[1]) Laurent@814: if i == 0: Laurent@814: array.setdimension([dimension_range]) Laurent@814: else: Laurent@814: array.appenddimension(dimension_range) Laurent@814: if infos["base_type"] in self.GetBaseTypes(): Laurent@814: if infos["base_type"] == "STRING": Laurent@814: array.baseType.setcontent({"name" : "string", "value" : plcopen.elementaryTypes_string()}) Laurent@814: elif infos["base_type"] == "WSTRING": Laurent@814: array.baseType.setcontent({"name" : "wstring", "value" : plcopen.wstring()}) Laurent@814: else: Laurent@814: array.baseType.setcontent({"name" : infos["base_type"], "value" : None}) Laurent@814: else: Laurent@814: derived_datatype = plcopen.derivedTypes_derived() Laurent@814: derived_datatype.setname(infos["base_type"]) Laurent@814: array.baseType.setcontent({"name" : "derived", "value" : derived_datatype}) Laurent@814: datatype.baseType.setcontent({"name" : "array", "value" : array}) Laurent@814: elif infos["type"] == "Structure": Laurent@814: struct = plcopen.varListPlain() Laurent@814: for i, element_infos in enumerate(infos["elements"]): Laurent@814: element = plcopen.varListPlain_variable() Laurent@814: element.setname(element_infos["Name"]) Laurent@864: if isinstance(element_infos["Type"], TupleType): Laurent@864: if element_infos["Type"][0] == "array": Laurent@864: array_type, base_type_name, dimensions = element_infos["Type"] Laurent@864: array = plcopen.derivedTypes_array() Laurent@864: for j, dimension in enumerate(dimensions): Laurent@864: dimension_range = plcopen.rangeSigned() Laurent@864: dimension_range.setlower(dimension[0]) Laurent@864: dimension_range.setupper(dimension[1]) Laurent@864: if j == 0: Laurent@864: array.setdimension([dimension_range]) Laurent@864: else: Laurent@864: array.appenddimension(dimension_range) Laurent@864: if base_type_name in self.GetBaseTypes(): Laurent@864: if base_type_name == "STRING": Laurent@864: array.baseType.setcontent({"name" : "string", "value" : plcopen.elementaryTypes_string()}) Laurent@864: elif base_type_name == "WSTRING": Laurent@864: array.baseType.setcontent({"name" : "wstring", "value" : plcopen.wstring()}) Laurent@864: else: Laurent@864: array.baseType.setcontent({"name" : base_type_name, "value" : None}) Laurent@864: else: Laurent@864: derived_datatype = plcopen.derivedTypes_derived() Laurent@864: derived_datatype.setname(base_type_name) Laurent@864: array.baseType.setcontent({"name" : "derived", "value" : derived_datatype}) Laurent@864: element.type.setcontent({"name" : "array", "value" : array}) Laurent@864: elif element_infos["Type"] in self.GetBaseTypes(): Laurent@814: if element_infos["Type"] == "STRING": Laurent@814: element.type.setcontent({"name" : "string", "value" : plcopen.elementaryTypes_string()}) Laurent@814: elif element_infos["Type"] == "WSTRING": Laurent@814: element.type.setcontent({"name" : "wstring", "value" : plcopen.wstring()}) Laurent@814: else: Laurent@814: element.type.setcontent({"name" : element_infos["Type"], "value" : None}) Laurent@814: else: Laurent@814: derived_datatype = plcopen.derivedTypes_derived() Laurent@814: derived_datatype.setname(element_infos["Type"]) Laurent@814: element.type.setcontent({"name" : "derived", "value" : derived_datatype}) Laurent@814: if element_infos["Initial Value"] != "": Laurent@814: value = plcopen.value() Laurent@814: value.setvalue(element_infos["Initial Value"]) Laurent@814: element.setinitialValue(value) Laurent@814: if i == 0: Laurent@814: struct.setvariable([element]) Laurent@814: else: Laurent@814: struct.appendvariable(element) Laurent@814: datatype.baseType.setcontent({"name" : "struct", "value" : struct}) Laurent@814: if infos["initial"] != "": Laurent@814: if datatype.initialValue is None: Laurent@814: datatype.initialValue = plcopen.value() Laurent@814: datatype.initialValue.setvalue(infos["initial"]) Laurent@814: else: Laurent@814: datatype.initialValue = None Laurent@814: self.Project.RefreshDataTypeHierarchy() Laurent@814: self.Project.RefreshElementUsingTree() Laurent@814: self.BufferProject() Laurent@814: Laurent@814: #------------------------------------------------------------------------------- Laurent@814: # Project opened Pous management functions Laurent@814: #------------------------------------------------------------------------------- Laurent@814: Laurent@814: # Return edited element Laurent@814: def GetEditedElement(self, tagname, debug = False): Laurent@814: project = self.GetProject(debug) Laurent@814: if project is not None: Laurent@814: words = tagname.split("::") Laurent@814: if words[0] == "D": Laurent@814: return project.getdataType(words[1]) Laurent@814: elif words[0] == "P": Laurent@814: return project.getpou(words[1]) Laurent@814: elif words[0] in ['T', 'A']: Laurent@814: pou = project.getpou(words[1]) Laurent@814: if pou is not None: Laurent@814: if words[0] == 'T': Laurent@814: return pou.gettransition(words[2]) Laurent@814: elif words[0] == 'A': Laurent@814: return pou.getaction(words[2]) Laurent@814: elif words[0] == 'C': Laurent@814: return project.getconfiguration(words[1]) Laurent@814: elif words[0] == 'R': Laurent@814: return project.getconfigurationResource(words[1], words[2]) Laurent@814: return None Laurent@814: Laurent@814: # Return edited element name Laurent@814: def GetEditedElementName(self, tagname): Laurent@814: words = tagname.split("::") Laurent@814: if words[0] in ["P","C","D"]: Laurent@814: return words[1] Laurent@814: else: Laurent@814: return words[2] Laurent@814: return None Laurent@814: Laurent@814: # Return edited element name and type Laurent@814: def GetEditedElementType(self, tagname, debug = False): Laurent@814: words = tagname.split("::") Laurent@814: if words[0] in ["P","T","A"]: Laurent@814: return words[1], self.GetPouType(words[1], debug) Laurent@814: return None, None Laurent@814: Laurent@814: # Return language in which edited element is written Laurent@814: def GetEditedElementBodyType(self, tagname, debug = False): Laurent@814: words = tagname.split("::") Laurent@814: if words[0] == "P": Laurent@814: return self.GetPouBodyType(words[1], debug) Laurent@814: elif words[0] == 'T': Laurent@814: return self.GetTransitionBodyType(words[1], words[2], debug) Laurent@814: elif words[0] == 'A': Laurent@814: return self.GetActionBodyType(words[1], words[2], debug) Laurent@814: return None Laurent@814: Laurent@814: # Return the edited element variables Laurent@814: def GetEditedElementInterfaceVars(self, tagname, debug = False): Laurent@814: words = tagname.split("::") Laurent@814: if words[0] in ["P","T","A"]: Laurent@814: project = self.GetProject(debug) Laurent@814: if project is not None: Laurent@814: pou = project.getpou(words[1]) Laurent@814: if pou is not None: Laurent@814: return self.GetPouInterfaceVars(pou, debug) Laurent@814: return [] Laurent@814: Laurent@814: # Return the edited element return type Laurent@814: def GetEditedElementInterfaceReturnType(self, tagname, debug = False): Laurent@814: words = tagname.split("::") Laurent@814: if words[0] == "P": Laurent@814: project = self.GetProject(debug) Laurent@814: if project is not None: Laurent@814: pou = self.Project.getpou(words[1]) Laurent@814: if pou is not None: Laurent@814: return self.GetPouInterfaceReturnType(pou) Laurent@814: elif words[0] == 'T': Laurent@814: return "BOOL" Laurent@814: return None Laurent@814: Laurent@814: # Change the edited element text Laurent@814: def SetEditedElementText(self, tagname, text): Laurent@814: if self.Project is not None: Laurent@814: element = self.GetEditedElement(tagname) Laurent@814: if element is not None: Laurent@814: element.settext(text) Laurent@814: self.Project.RefreshElementUsingTree() Laurent@814: Laurent@814: # Return the edited element text Laurent@814: def GetEditedElementText(self, tagname, debug = False): Laurent@814: element = self.GetEditedElement(tagname, debug) Laurent@814: if element is not None: Laurent@814: return element.gettext() Laurent@814: return "" Laurent@814: Laurent@814: # Return the edited element transitions Laurent@814: def GetEditedElementTransitions(self, tagname, debug = False): Laurent@814: pou = self.GetEditedElement(tagname, debug) Laurent@814: if pou is not None and pou.getbodyType() == "SFC": Laurent@814: transitions = [] Laurent@814: for transition in pou.gettransitionList(): Laurent@814: transitions.append(transition.getname()) Laurent@814: return transitions Laurent@814: return [] Laurent@814: Laurent@814: # Return edited element transitions Laurent@814: def GetEditedElementActions(self, tagname, debug = False): Laurent@814: pou = self.GetEditedElement(tagname, debug) Laurent@814: if pou is not None and pou.getbodyType() == "SFC": Laurent@814: actions = [] Laurent@814: for action in pou.getactionList(): Laurent@814: actions.append(action.getname()) Laurent@814: return actions Laurent@814: return [] Laurent@814: Laurent@814: # Return the names of the pou elements Laurent@814: def GetEditedElementVariables(self, tagname, debug = False): Laurent@814: words = tagname.split("::") Laurent@814: if words[0] in ["P","T","A"]: Laurent@814: return self.GetProjectPouVariables(words[1], debug) Laurent@814: return [] Laurent@814: Laurent@814: def GetEditedElementCopy(self, tagname, debug = False): Laurent@814: element = self.GetEditedElement(tagname, debug) Laurent@814: if element is not None: Laurent@814: name = element.__class__.__name__ Laurent@814: return element.generateXMLText(name.split("_")[-1], 0) Laurent@814: return "" Laurent@814: Laurent@814: def GetEditedElementInstancesCopy(self, tagname, blocks_id = None, wires = None, debug = False): Laurent@814: element = self.GetEditedElement(tagname, debug) Laurent@814: text = "" Laurent@814: if element is not None: Laurent@814: wires = dict([(wire, True) for wire in wires if wire[0] in blocks_id and wire[1] in blocks_id]) Laurent@814: for id in blocks_id: Laurent@814: instance = element.getinstance(id) Laurent@814: if instance is not None: Laurent@814: instance_copy = self.Copy(instance) Laurent@814: instance_copy.filterConnections(wires) Laurent@814: name = instance_copy.__class__.__name__ Laurent@814: text += instance_copy.generateXMLText(name.split("_")[-1], 0) Laurent@814: return text Laurent@814: Laurent@814: def GenerateNewName(self, tagname, name, format, exclude={}, debug=False): Laurent@814: names = exclude.copy() Laurent@814: if tagname is not None: Laurent@814: names.update(dict([(varname.upper(), True) for varname in self.GetEditedElementVariables(tagname, debug)])) Laurent@814: element = self.GetEditedElement(tagname, debug) Laurent@814: if element is not None: Laurent@814: for instance in element.getinstances(): Laurent@814: if isinstance(instance, (plcopen.sfcObjects_step, plcopen.commonObjects_connector, plcopen.commonObjects_continuation)): Laurent@814: names[instance.getname().upper()] = True Laurent@814: else: Laurent@814: project = self.GetProject(debug) Laurent@814: if project is not None: Laurent@814: for datatype in project.getdataTypes(): Laurent@814: names[datatype.getname().upper()] = True Laurent@814: for pou in project.getpous(): Laurent@814: names[pou.getname().upper()] = True Laurent@814: for var in self.GetPouInterfaceVars(pou, debug): Laurent@814: names[var["Name"].upper()] = True Laurent@814: for transition in pou.gettransitionList(): Laurent@814: names[transition.getname().upper()] = True Laurent@814: for action in pou.getactionList(): Laurent@814: names[action.getname().upper()] = True Laurent@814: for config in project.getconfigurations(): Laurent@814: names[config.getname().upper()] = True Laurent@814: for resource in config.getresource(): Laurent@814: names[resource.getname().upper()] = True Laurent@814: Laurent@814: i = 0 Laurent@814: while name is None or names.get(name.upper(), False): Laurent@814: name = (format%i) Laurent@814: i += 1 Laurent@814: return name Laurent@814: Laurent@814: CheckPasteCompatibility = {"SFC": lambda name: True, Laurent@814: "LD": lambda name: not name.startswith("sfcObjects"), Laurent@814: "FBD": lambda name: name.startswith("fbdObjects") or name.startswith("commonObjects")} Laurent@814: Laurent@814: def PasteEditedElementInstances(self, tagname, text, new_pos, middle=False, debug=False): Laurent@814: element = self.GetEditedElement(tagname, debug) Laurent@814: element_name, element_type = self.GetEditedElementType(tagname, debug) Laurent@814: if element is not None: Laurent@814: bodytype = element.getbodyType() Laurent@814: Laurent@814: # Get edited element type scaling Laurent@814: scaling = None Laurent@814: project = self.GetProject(debug) Laurent@814: if project is not None: Laurent@814: properties = project.getcontentHeader() Laurent@814: scaling = properties["scaling"][bodytype] Laurent@814: Laurent@814: # Get ids already by all the instances in edited element Laurent@814: used_id = dict([(instance.getlocalId(), True) for instance in element.getinstances()]) Laurent@814: new_id = {} Laurent@814: Laurent@814: text = "%s"%text Laurent@814: Laurent@814: try: Laurent@814: tree = minidom.parseString(text) Laurent@814: except: Laurent@814: return _("Invalid plcopen element(s)!!!") Laurent@814: instances = [] Laurent@814: exclude = {} Laurent@814: for root in tree.childNodes: Laurent@814: if root.nodeType == tree.ELEMENT_NODE and root.nodeName == "paste": Laurent@814: for child in root.childNodes: Laurent@814: if child.nodeType == tree.ELEMENT_NODE: Laurent@814: if not child.nodeName in plcopen.ElementNameToClass: Laurent@814: return _("\"%s\" element can't be pasted here!!!")%child.nodeName Laurent@814: Laurent@814: classname = plcopen.ElementNameToClass[child.nodeName] Laurent@814: if not self.CheckPasteCompatibility[bodytype](classname): Laurent@814: return _("\"%s\" element can't be pasted here!!!")%child.nodeName Laurent@814: Laurent@814: classobj = getattr(plcopen, classname, None) Laurent@814: if classobj is not None: Laurent@814: instance = classobj() Laurent@814: instance.loadXMLTree(child) Laurent@814: if child.nodeName == "block": Laurent@814: blockname = instance.getinstanceName() Laurent@814: if blockname is not None: Laurent@814: blocktype = instance.gettypeName() Laurent@814: if element_type == "function": Laurent@814: return _("FunctionBlock \"%s\" can't be pasted in a Function!!!")%blocktype Laurent@814: blockname = self.GenerateNewName(tagname, blockname, "%s%%d"%blocktype, debug=debug) Laurent@814: exclude[blockname] = True Laurent@814: instance.setinstanceName(blockname) Laurent@814: self.AddEditedElementPouVar(tagname, blocktype, blockname) Laurent@814: elif child.nodeName == "step": Laurent@814: stepname = self.GenerateNewName(tagname, instance.getname(), "Step%d", exclude, debug) Laurent@814: exclude[stepname] = True Laurent@814: instance.setname(stepname) Laurent@814: localid = instance.getlocalId() Laurent@814: if not used_id.has_key(localid): Laurent@814: new_id[localid] = True Laurent@814: instances.append((child.nodeName, instance)) Laurent@814: Laurent@814: if len(instances) == 0: Laurent@814: return _("Invalid plcopen element(s)!!!") Laurent@814: Laurent@814: idx = 1 Laurent@814: translate_id = {} Laurent@814: bbox = plcopen.rect() Laurent@814: for name, instance in instances: Laurent@814: localId = instance.getlocalId() Laurent@814: bbox.union(instance.getBoundingBox()) Laurent@814: if used_id.has_key(localId): Laurent@814: while used_id.has_key(idx) or new_id.has_key(idx): Laurent@814: idx += 1 Laurent@814: new_id[idx] = True Laurent@814: instance.setlocalId(idx) Laurent@814: translate_id[localId] = idx Laurent@814: Laurent@814: x, y, width, height = bbox.bounding_box() Laurent@814: if middle: Laurent@814: new_pos[0] -= width / 2 Laurent@814: new_pos[1] -= height / 2 Laurent@814: else: Laurent@814: new_pos = map(lambda x: x + 30, new_pos) Laurent@814: if scaling[0] != 0 and scaling[1] != 0: Laurent@814: min_pos = map(lambda x: 30 / x, scaling) Laurent@814: minx = round(min_pos[0]) Laurent@814: if int(min_pos[0]) == round(min_pos[0]): Laurent@814: minx += 1 Laurent@814: miny = round(min_pos[1]) Laurent@814: if int(min_pos[1]) == round(min_pos[1]): Laurent@814: miny += 1 Laurent@814: minx *= scaling[0] Laurent@814: miny *= scaling[1] Laurent@814: new_pos = (max(minx, round(new_pos[0] / scaling[0]) * scaling[0]), Laurent@814: max(miny, round(new_pos[1] / scaling[1]) * scaling[1])) Laurent@814: else: Laurent@814: new_pos = (max(30, new_pos[0]), max(30, new_pos[1])) Laurent@814: diff = (new_pos[0] - x, new_pos[1] - y) Laurent@814: Laurent@814: connections = {} Laurent@814: for name, instance in instances: Laurent@814: connections.update(instance.updateConnectionsId(translate_id)) Laurent@814: if getattr(instance, "setexecutionOrderId", None) is not None: Laurent@814: instance.setexecutionOrderId(0) Laurent@814: instance.translate(*diff) Laurent@814: element.addinstance(name, instance) Laurent@814: Laurent@814: return new_id, connections Laurent@814: Laurent@814: # Return the current pou editing informations Laurent@814: def GetEditedElementInstanceInfos(self, tagname, id = None, exclude = [], debug = False): Laurent@814: infos = {} Laurent@814: instance = None Laurent@814: element = self.GetEditedElement(tagname, debug) Laurent@814: if element is not None: Laurent@814: # if id is defined Laurent@814: if id is not None: Laurent@814: instance = element.getinstance(id) Laurent@814: else: Laurent@814: instance = element.getrandomInstance(exclude) Laurent@814: if instance is not None: Laurent@814: infos = instance.getinfos() Laurent@814: if infos["type"] in ["input", "output", "inout"]: Laurent@814: var_type = self.GetEditedElementVarValueType(tagname, infos["specific_values"]["name"], debug) Laurent@814: infos["specific_values"]["value_type"] = var_type Laurent@814: return infos Laurent@814: return None Laurent@814: Laurent@814: def ClearEditedElementExecutionOrder(self, tagname): Laurent@814: element = self.GetEditedElement(tagname) Laurent@814: if element is not None: Laurent@814: element.resetexecutionOrder() Laurent@814: Laurent@814: def ResetEditedElementExecutionOrder(self, tagname): Laurent@814: element = self.GetEditedElement(tagname) Laurent@814: if element is not None: Laurent@814: element.compileexecutionOrder() Laurent@814: Laurent@814: # Return the variable type of the given pou Laurent@814: def GetEditedElementVarValueType(self, tagname, varname, debug = False): Laurent@814: project = self.GetProject(debug) Laurent@814: if project is not None: Laurent@814: words = tagname.split("::") Laurent@814: if words[0] in ["P","T","A"]: Laurent@814: pou = self.Project.getpou(words[1]) Laurent@814: if pou is not None: Laurent@814: if words[0] == "T" and varname == words[2]: Laurent@814: return "BOOL" Laurent@814: if words[1] == varname: Laurent@814: return self.GetPouInterfaceReturnType(pou) Laurent@814: for type, varlist in pou.getvars(): Laurent@814: for var in varlist.getvariable(): Laurent@814: if var.getname() == varname: Laurent@814: vartype_content = var.gettype().getcontent() Laurent@814: if vartype_content["name"] == "derived": Laurent@814: return vartype_content["value"].getname() Laurent@814: elif vartype_content["name"] in ["string", "wstring"]: Laurent@814: return vartype_content["name"].upper() Laurent@814: else: Laurent@814: return vartype_content["name"] Laurent@814: return None Laurent@814: Laurent@814: def SetConnectionWires(self, connection, connector): Laurent@814: wires = connector.GetWires() Laurent@814: idx = 0 Laurent@814: for wire, handle in wires: Laurent@814: points = wire.GetPoints(handle != 0) Laurent@814: if handle == 0: Laurent@814: result = wire.GetConnectedInfos(-1) Laurent@814: else: Laurent@814: result = wire.GetConnectedInfos(0) Laurent@814: if result != None: Laurent@814: refLocalId, formalParameter = result Laurent@814: connections = connection.getconnections() Laurent@814: if connections is None or len(connection.getconnections()) <= idx: Laurent@814: connection.addconnection() Laurent@814: connection.setconnectionId(idx, refLocalId) Laurent@814: connection.setconnectionPoints(idx, points) Laurent@814: if formalParameter != "": Laurent@814: connection.setconnectionParameter(idx, formalParameter) Laurent@814: else: Laurent@814: connection.setconnectionParameter(idx, None) Laurent@814: idx += 1 Laurent@814: Laurent@814: def AddEditedElementPouVar(self, tagname, type, name, location="", description=""): Laurent@814: if self.Project is not None: Laurent@814: words = tagname.split("::") Laurent@814: if words[0] in ['P', 'T', 'A']: Laurent@814: pou = self.Project.getpou(words[1]) Laurent@814: if pou is not None: Laurent@814: pou.addpouLocalVar(type, name, location, description) Laurent@814: Laurent@814: def AddEditedElementPouExternalVar(self, tagname, type, name): Laurent@814: if self.Project is not None: Laurent@814: words = tagname.split("::") Laurent@814: if words[0] in ['P', 'T', 'A']: Laurent@814: pou = self.Project.getpou(words[1]) Laurent@814: if pou is not None: Laurent@814: pou.addpouExternalVar(type, name) Laurent@814: Laurent@814: def ChangeEditedElementPouVar(self, tagname, old_type, old_name, new_type, new_name): Laurent@814: if self.Project is not None: Laurent@814: words = tagname.split("::") Laurent@814: if words[0] in ['P', 'T', 'A']: Laurent@814: pou = self.Project.getpou(words[1]) Laurent@814: if pou is not None: Laurent@814: pou.changepouVar(old_type, old_name, new_type, new_name) Laurent@814: Laurent@814: def RemoveEditedElementPouVar(self, tagname, type, name): Laurent@814: if self.Project is not None: Laurent@814: words = tagname.split("::") Laurent@814: if words[0] in ['P', 'T', 'A']: Laurent@814: pou = self.Project.getpou(words[1]) Laurent@814: if pou is not None: Laurent@814: pou.removepouVar(type, name) Laurent@814: Laurent@814: def AddEditedElementBlock(self, tagname, id, blocktype, blockname = None): Laurent@814: element = self.GetEditedElement(tagname) Laurent@814: if element is not None: Laurent@814: block = plcopen.fbdObjects_block() Laurent@814: block.setlocalId(id) Laurent@814: block.settypeName(blocktype) Laurent@814: blocktype_infos = self.GetBlockType(blocktype) Laurent@814: if blocktype_infos["type"] != "function" and blockname is not None: Laurent@814: block.setinstanceName(blockname) Laurent@814: self.AddEditedElementPouVar(tagname, blocktype, blockname) Laurent@814: element.addinstance("block", block) Laurent@814: self.Project.RefreshElementUsingTree() Laurent@814: Laurent@814: def SetEditedElementBlockInfos(self, tagname, id, infos): Laurent@814: element = self.GetEditedElement(tagname) Laurent@814: if element is not None: Laurent@814: block = element.getinstance(id) Laurent@814: if block is None: Laurent@814: return Laurent@814: old_name = block.getinstanceName() Laurent@814: old_type = block.gettypeName() Laurent@814: new_name = infos.get("name", old_name) Laurent@814: new_type = infos.get("type", old_type) Laurent@814: if new_type != old_type: Laurent@814: old_typeinfos = self.GetBlockType(old_type) Laurent@814: new_typeinfos = self.GetBlockType(new_type) Laurent@814: if old_typeinfos is None or new_typeinfos is None: Laurent@814: self.ChangeEditedElementPouVar(tagname, old_type, old_name, new_type, new_name) Laurent@814: elif new_typeinfos["type"] != old_typeinfos["type"]: Laurent@814: if new_typeinfos["type"] == "function": Laurent@814: self.RemoveEditedElementPouVar(tagname, old_type, old_name) Laurent@814: else: Laurent@814: self.AddEditedElementPouVar(tagname, new_type, new_name) Laurent@814: elif new_typeinfos["type"] != "function": Laurent@814: self.ChangeEditedElementPouVar(tagname, old_type, old_name, new_type, new_name) Laurent@814: elif new_name != old_name: Laurent@814: self.ChangeEditedElementPouVar(tagname, old_type, old_name, new_type, new_name) Laurent@814: for param, value in infos.items(): Laurent@814: if param == "name": Laurent@814: block.setinstanceName(value) Laurent@814: elif param == "type": Laurent@814: block.settypeName(value) Laurent@814: elif param == "executionOrder" and block.getexecutionOrderId() != value: Laurent@814: element.setelementExecutionOrder(block, value) Laurent@814: elif param == "height": Laurent@814: block.setheight(value) Laurent@814: elif param == "width": Laurent@814: block.setwidth(value) Laurent@814: elif param == "x": Laurent@814: block.setx(value) Laurent@814: elif param == "y": Laurent@814: block.sety(value) Laurent@814: elif param == "connectors": Laurent@814: block.inputVariables.setvariable([]) Laurent@814: block.outputVariables.setvariable([]) Laurent@814: for connector in value["inputs"]: Laurent@814: variable = plcopen.inputVariables_variable() Laurent@814: variable.setformalParameter(connector.GetName()) Laurent@814: if connector.IsNegated(): Laurent@814: variable.setnegated(True) Laurent@814: if connector.GetEdge() != "none": Laurent@814: variable.setedge(connector.GetEdge()) Laurent@814: position = connector.GetRelPosition() Laurent@814: variable.connectionPointIn.setrelPositionXY(position.x, position.y) Laurent@814: self.SetConnectionWires(variable.connectionPointIn, connector) Laurent@814: block.inputVariables.appendvariable(variable) Laurent@814: for connector in value["outputs"]: Laurent@814: variable = plcopen.outputVariables_variable() Laurent@814: variable.setformalParameter(connector.GetName()) Laurent@814: if connector.IsNegated(): Laurent@814: variable.setnegated(True) Laurent@814: if connector.GetEdge() != "none": Laurent@814: variable.setedge(connector.GetEdge()) Laurent@814: position = connector.GetRelPosition() Laurent@814: variable.addconnectionPointOut() Laurent@814: variable.connectionPointOut.setrelPositionXY(position.x, position.y) Laurent@814: block.outputVariables.appendvariable(variable) Laurent@814: self.Project.RefreshElementUsingTree() Laurent@814: Laurent@814: def AddEditedElementVariable(self, tagname, id, type): Laurent@814: element = self.GetEditedElement(tagname) Laurent@814: if element is not None: Laurent@814: if type == INPUT: Laurent@814: name = "inVariable" Laurent@814: variable = plcopen.fbdObjects_inVariable() Laurent@814: elif type == OUTPUT: Laurent@814: name = "outVariable" Laurent@814: variable = plcopen.fbdObjects_outVariable() Laurent@814: elif type == INOUT: Laurent@814: name = "inOutVariable" Laurent@814: variable = plcopen.fbdObjects_inOutVariable() Laurent@814: variable.setlocalId(id) Laurent@814: element.addinstance(name, variable) Laurent@814: Laurent@814: def SetEditedElementVariableInfos(self, tagname, id, infos): Laurent@814: element = self.GetEditedElement(tagname) Laurent@814: if element is not None: Laurent@814: variable = element.getinstance(id) Laurent@814: if variable is None: Laurent@814: return Laurent@814: for param, value in infos.items(): Laurent@814: if param == "name": Laurent@814: variable.setexpression(value) Laurent@814: elif param == "executionOrder" and variable.getexecutionOrderId() != value: Laurent@814: element.setelementExecutionOrder(variable, value) Laurent@814: elif param == "height": Laurent@814: variable.setheight(value) Laurent@814: elif param == "width": Laurent@814: variable.setwidth(value) Laurent@814: elif param == "x": Laurent@814: variable.setx(value) Laurent@814: elif param == "y": Laurent@814: variable.sety(value) Laurent@814: elif param == "connectors": Laurent@814: if len(value["outputs"]) > 0: Laurent@814: output = value["outputs"][0] Laurent@814: if len(value["inputs"]) > 0: Laurent@814: variable.setnegatedOut(output.IsNegated()) Laurent@814: variable.setedgeOut(output.GetEdge()) Laurent@814: else: Laurent@814: variable.setnegated(output.IsNegated()) Laurent@814: variable.setedge(output.GetEdge()) Laurent@814: position = output.GetRelPosition() Laurent@814: variable.addconnectionPointOut() Laurent@814: variable.connectionPointOut.setrelPositionXY(position.x, position.y) Laurent@814: if len(value["inputs"]) > 0: Laurent@814: input = value["inputs"][0] Laurent@814: if len(value["outputs"]) > 0: Laurent@814: variable.setnegatedIn(input.IsNegated()) Laurent@814: variable.setedgeIn(input.GetEdge()) Laurent@814: else: Laurent@814: variable.setnegated(input.IsNegated()) Laurent@814: variable.setedge(input.GetEdge()) Laurent@814: position = input.GetRelPosition() Laurent@814: variable.addconnectionPointIn() Laurent@814: variable.connectionPointIn.setrelPositionXY(position.x, position.y) Laurent@814: self.SetConnectionWires(variable.connectionPointIn, input) Laurent@814: Laurent@814: def AddEditedElementConnection(self, tagname, id, type): Laurent@814: element = self.GetEditedElement(tagname) Laurent@814: if element is not None: Laurent@814: if type == CONNECTOR: Laurent@814: name = "connector" Laurent@814: connection = plcopen.commonObjects_connector() Laurent@814: elif type == CONTINUATION: Laurent@814: name = "continuation" Laurent@814: connection = plcopen.commonObjects_continuation() Laurent@814: connection.setlocalId(id) Laurent@814: element.addinstance(name, connection) Laurent@814: Laurent@814: def SetEditedElementConnectionInfos(self, tagname, id, infos): Laurent@814: element = self.GetEditedElement(tagname) Laurent@814: if element is not None: Laurent@814: connection = element.getinstance(id) Laurent@814: if connection is None: Laurent@814: return Laurent@814: for param, value in infos.items(): Laurent@814: if param == "name": Laurent@814: connection.setname(value) Laurent@814: elif param == "height": Laurent@814: connection.setheight(value) Laurent@814: elif param == "width": Laurent@814: connection.setwidth(value) Laurent@814: elif param == "x": Laurent@814: connection.setx(value) Laurent@814: elif param == "y": Laurent@814: connection.sety(value) Laurent@814: elif param == "connector": Laurent@814: position = value.GetRelPosition() Laurent@814: if isinstance(connection, plcopen.commonObjects_continuation): Laurent@814: connection.addconnectionPointOut() Laurent@814: connection.connectionPointOut.setrelPositionXY(position.x, position.y) Laurent@814: elif isinstance(connection, plcopen.commonObjects_connector): Laurent@814: connection.addconnectionPointIn() Laurent@814: connection.connectionPointIn.setrelPositionXY(position.x, position.y) Laurent@814: self.SetConnectionWires(connection.connectionPointIn, value) Laurent@814: Laurent@814: def AddEditedElementComment(self, tagname, id): Laurent@814: element = self.GetEditedElement(tagname) Laurent@814: if element is not None: Laurent@814: comment = plcopen.commonObjects_comment() Laurent@814: comment.setlocalId(id) Laurent@814: element.addinstance("comment", comment) Laurent@814: Laurent@814: def SetEditedElementCommentInfos(self, tagname, id, infos): Laurent@814: element = self.GetEditedElement(tagname) Laurent@814: if element is not None: Laurent@814: comment = element.getinstance(id) Laurent@814: for param, value in infos.items(): Laurent@814: if param == "content": Laurent@814: comment.setcontentText(value) Laurent@814: elif param == "height": Laurent@814: comment.setheight(value) Laurent@814: elif param == "width": Laurent@814: comment.setwidth(value) Laurent@814: elif param == "x": Laurent@814: comment.setx(value) Laurent@814: elif param == "y": Laurent@814: comment.sety(value) Laurent@814: Laurent@814: def AddEditedElementPowerRail(self, tagname, id, type): Laurent@814: element = self.GetEditedElement(tagname) Laurent@814: if element is not None: Laurent@814: if type == LEFTRAIL: Laurent@814: name = "leftPowerRail" Laurent@814: powerrail = plcopen.ldObjects_leftPowerRail() Laurent@814: elif type == RIGHTRAIL: Laurent@814: name = "rightPowerRail" Laurent@814: powerrail = plcopen.ldObjects_rightPowerRail() Laurent@814: powerrail.setlocalId(id) Laurent@814: element.addinstance(name, powerrail) Laurent@814: Laurent@814: def SetEditedElementPowerRailInfos(self, tagname, id, infos): Laurent@814: element = self.GetEditedElement(tagname) Laurent@814: if element is not None: Laurent@814: powerrail = element.getinstance(id) Laurent@814: if powerrail is None: Laurent@814: return Laurent@814: for param, value in infos.items(): Laurent@814: if param == "height": Laurent@814: powerrail.setheight(value) Laurent@814: elif param == "width": Laurent@814: powerrail.setwidth(value) Laurent@814: elif param == "x": Laurent@814: powerrail.setx(value) Laurent@814: elif param == "y": Laurent@814: powerrail.sety(value) Laurent@814: elif param == "connectors": Laurent@814: if isinstance(powerrail, plcopen.ldObjects_leftPowerRail): Laurent@814: powerrail.setconnectionPointOut([]) Laurent@814: for connector in value["outputs"]: Laurent@814: position = connector.GetRelPosition() Laurent@814: connection = plcopen.leftPowerRail_connectionPointOut() Laurent@814: connection.setrelPositionXY(position.x, position.y) Laurent@814: powerrail.connectionPointOut.append(connection) Laurent@814: elif isinstance(powerrail, plcopen.ldObjects_rightPowerRail): Laurent@814: powerrail.setconnectionPointIn([]) Laurent@814: for connector in value["inputs"]: Laurent@814: position = connector.GetRelPosition() Laurent@814: connection = plcopen.connectionPointIn() Laurent@814: connection.setrelPositionXY(position.x, position.y) Laurent@814: self.SetConnectionWires(connection, connector) Laurent@814: powerrail.connectionPointIn.append(connection) Laurent@814: Laurent@814: def AddEditedElementContact(self, tagname, id): Laurent@814: element = self.GetEditedElement(tagname) Laurent@814: if element is not None: Laurent@814: contact = plcopen.ldObjects_contact() Laurent@814: contact.setlocalId(id) Laurent@814: element.addinstance("contact", contact) Laurent@814: Laurent@814: def SetEditedElementContactInfos(self, tagname, id, infos): Laurent@814: element = self.GetEditedElement(tagname) Laurent@814: if element is not None: Laurent@814: contact = element.getinstance(id) Laurent@814: if contact is None: Laurent@814: return Laurent@814: for param, value in infos.items(): Laurent@814: if param == "name": Laurent@814: contact.setvariable(value) Laurent@814: elif param == "type": Laurent@814: if value == CONTACT_NORMAL: Laurent@814: contact.setnegated(False) Laurent@814: contact.setedge("none") Laurent@814: elif value == CONTACT_REVERSE: Laurent@814: contact.setnegated(True) Laurent@814: contact.setedge("none") Laurent@814: elif value == CONTACT_RISING: Laurent@814: contact.setnegated(False) Laurent@814: contact.setedge("rising") Laurent@814: elif value == CONTACT_FALLING: Laurent@814: contact.setnegated(False) Laurent@814: contact.setedge("falling") Laurent@814: elif param == "height": Laurent@814: contact.setheight(value) Laurent@814: elif param == "width": Laurent@814: contact.setwidth(value) Laurent@814: elif param == "x": Laurent@814: contact.setx(value) Laurent@814: elif param == "y": Laurent@814: contact.sety(value) Laurent@814: elif param == "connectors": Laurent@814: input_connector = value["inputs"][0] Laurent@814: position = input_connector.GetRelPosition() Laurent@814: contact.addconnectionPointIn() Laurent@814: contact.connectionPointIn.setrelPositionXY(position.x, position.y) Laurent@814: self.SetConnectionWires(contact.connectionPointIn, input_connector) Laurent@814: output_connector = value["outputs"][0] Laurent@814: position = output_connector.GetRelPosition() Laurent@814: contact.addconnectionPointOut() Laurent@814: contact.connectionPointOut.setrelPositionXY(position.x, position.y) Laurent@814: Laurent@814: def AddEditedElementCoil(self, tagname, id): Laurent@814: element = self.GetEditedElement(tagname) Laurent@814: if element is not None: Laurent@814: coil = plcopen.ldObjects_coil() Laurent@814: coil.setlocalId(id) Laurent@814: element.addinstance("coil", coil) Laurent@814: Laurent@814: def SetEditedElementCoilInfos(self, tagname, id, infos): Laurent@814: element = self.GetEditedElement(tagname) Laurent@814: if element is not None: Laurent@814: coil = element.getinstance(id) Laurent@814: if coil is None: Laurent@814: return Laurent@814: for param, value in infos.items(): Laurent@814: if param == "name": Laurent@814: coil.setvariable(value) Laurent@814: elif param == "type": Laurent@814: if value == COIL_NORMAL: Laurent@814: coil.setnegated(False) Laurent@814: coil.setstorage("none") Laurent@814: coil.setedge("none") Laurent@814: elif value == COIL_REVERSE: Laurent@814: coil.setnegated(True) Laurent@814: coil.setstorage("none") Laurent@814: coil.setedge("none") Laurent@814: elif value == COIL_SET: Laurent@814: coil.setnegated(False) Laurent@814: coil.setstorage("set") Laurent@814: coil.setedge("none") Laurent@814: elif value == COIL_RESET: Laurent@814: coil.setnegated(False) Laurent@814: coil.setstorage("reset") Laurent@814: coil.setedge("none") Laurent@814: elif value == COIL_RISING: Laurent@814: coil.setnegated(False) Laurent@814: coil.setstorage("none") Laurent@814: coil.setedge("rising") Laurent@814: elif value == COIL_FALLING: Laurent@814: coil.setnegated(False) Laurent@814: coil.setstorage("none") Laurent@814: coil.setedge("falling") Laurent@814: elif param == "height": Laurent@814: coil.setheight(value) Laurent@814: elif param == "width": Laurent@814: coil.setwidth(value) Laurent@814: elif param == "x": Laurent@814: coil.setx(value) Laurent@814: elif param == "y": Laurent@814: coil.sety(value) Laurent@814: elif param == "connectors": Laurent@814: input_connector = value["inputs"][0] Laurent@814: position = input_connector.GetRelPosition() Laurent@814: coil.addconnectionPointIn() Laurent@814: coil.connectionPointIn.setrelPositionXY(position.x, position.y) Laurent@814: self.SetConnectionWires(coil.connectionPointIn, input_connector) Laurent@814: output_connector = value["outputs"][0] Laurent@814: position = output_connector.GetRelPosition() Laurent@814: coil.addconnectionPointOut() Laurent@814: coil.connectionPointOut.setrelPositionXY(position.x, position.y) Laurent@814: Laurent@814: def AddEditedElementStep(self, tagname, id): Laurent@814: element = self.GetEditedElement(tagname) Laurent@814: if element is not None: Laurent@814: step = plcopen.sfcObjects_step() Laurent@814: step.setlocalId(id) Laurent@814: element.addinstance("step", step) Laurent@814: Laurent@814: def SetEditedElementStepInfos(self, tagname, id, infos): Laurent@814: element = self.GetEditedElement(tagname) Laurent@814: if element is not None: Laurent@814: step = element.getinstance(id) Laurent@814: if step is None: Laurent@814: return Laurent@814: for param, value in infos.items(): Laurent@814: if param == "name": Laurent@814: step.setname(value) Laurent@814: elif param == "initial": Laurent@814: step.setinitialStep(value) Laurent@814: elif param == "height": Laurent@814: step.setheight(value) Laurent@814: elif param == "width": Laurent@814: step.setwidth(value) Laurent@814: elif param == "x": Laurent@814: step.setx(value) Laurent@814: elif param == "y": Laurent@814: step.sety(value) Laurent@814: elif param == "connectors": Laurent@814: if len(value["inputs"]) > 0: Laurent@814: input_connector = value["inputs"][0] Laurent@814: position = input_connector.GetRelPosition() Laurent@814: step.addconnectionPointIn() Laurent@814: step.connectionPointIn.setrelPositionXY(position.x, position.y) Laurent@814: self.SetConnectionWires(step.connectionPointIn, input_connector) Laurent@814: else: Laurent@814: step.deleteconnectionPointIn() Laurent@814: if len(value["outputs"]) > 0: Laurent@814: output_connector = value["outputs"][0] Laurent@814: position = output_connector.GetRelPosition() Laurent@814: step.addconnectionPointOut() Laurent@814: step.connectionPointOut.setrelPositionXY(position.x, position.y) Laurent@814: else: Laurent@814: step.deleteconnectionPointOut() Laurent@814: elif param == "action": Laurent@814: if value: Laurent@814: position = value.GetRelPosition() Laurent@814: step.addconnectionPointOutAction() Laurent@814: step.connectionPointOutAction.setrelPositionXY(position.x, position.y) Laurent@814: else: Laurent@814: step.deleteconnectionPointOutAction() Laurent@814: Laurent@814: def AddEditedElementTransition(self, tagname, id): Laurent@814: element = self.GetEditedElement(tagname) Laurent@814: if element is not None: Laurent@814: transition = plcopen.sfcObjects_transition() Laurent@814: transition.setlocalId(id) Laurent@814: element.addinstance("transition", transition) Laurent@814: Laurent@814: def SetEditedElementTransitionInfos(self, tagname, id, infos): Laurent@814: element = self.GetEditedElement(tagname) Laurent@814: if element is not None: Laurent@814: transition = element.getinstance(id) Laurent@814: if transition is None: Laurent@814: return Laurent@814: for param, value in infos.items(): Laurent@814: if param == "type" and value != "connection": Laurent@814: transition.setconditionContent(value, infos["condition"]) Laurent@814: elif param == "height": Laurent@814: transition.setheight(value) Laurent@814: elif param == "width": Laurent@814: transition.setwidth(value) Laurent@814: elif param == "x": Laurent@814: transition.setx(value) Laurent@814: elif param == "y": Laurent@814: transition.sety(value) Laurent@814: elif param == "priority": Laurent@814: if value != 0: Laurent@814: transition.setpriority(value) Laurent@814: else: Laurent@814: transition.setpriority(None) Laurent@814: elif param == "connectors": Laurent@814: input_connector = value["inputs"][0] Laurent@814: position = input_connector.GetRelPosition() Laurent@814: transition.addconnectionPointIn() Laurent@814: transition.connectionPointIn.setrelPositionXY(position.x, position.y) Laurent@814: self.SetConnectionWires(transition.connectionPointIn, input_connector) Laurent@814: output_connector = value["outputs"][0] Laurent@814: position = output_connector.GetRelPosition() Laurent@814: transition.addconnectionPointOut() Laurent@814: transition.connectionPointOut.setrelPositionXY(position.x, position.y) Laurent@814: elif infos.get("type", None) == "connection" and param == "connection" and value: Laurent@814: transition.setconditionContent("connection", None) Laurent@814: self.SetConnectionWires(transition.condition.content["value"], value) Laurent@814: Laurent@814: def AddEditedElementDivergence(self, tagname, id, type): Laurent@814: element = self.GetEditedElement(tagname) Laurent@814: if element is not None: Laurent@814: if type == SELECTION_DIVERGENCE: Laurent@814: name = "selectionDivergence" Laurent@814: divergence = plcopen.sfcObjects_selectionDivergence() Laurent@814: elif type == SELECTION_CONVERGENCE: Laurent@814: name = "selectionConvergence" Laurent@814: divergence = plcopen.sfcObjects_selectionConvergence() Laurent@814: elif type == SIMULTANEOUS_DIVERGENCE: Laurent@814: name = "simultaneousDivergence" Laurent@814: divergence = plcopen.sfcObjects_simultaneousDivergence() Laurent@814: elif type == SIMULTANEOUS_CONVERGENCE: Laurent@814: name = "simultaneousConvergence" Laurent@814: divergence = plcopen.sfcObjects_simultaneousConvergence() Laurent@814: divergence.setlocalId(id) Laurent@814: element.addinstance(name, divergence) Laurent@814: Laurent@814: def SetEditedElementDivergenceInfos(self, tagname, id, infos): Laurent@814: element = self.GetEditedElement(tagname) Laurent@814: if element is not None: Laurent@814: divergence = element.getinstance(id) Laurent@814: if divergence is None: Laurent@814: return Laurent@814: for param, value in infos.items(): Laurent@814: if param == "height": Laurent@814: divergence.setheight(value) Laurent@814: elif param == "width": Laurent@814: divergence.setwidth(value) Laurent@814: elif param == "x": Laurent@814: divergence.setx(value) Laurent@814: elif param == "y": Laurent@814: divergence.sety(value) Laurent@814: elif param == "connectors": Laurent@814: input_connectors = value["inputs"] Laurent@814: if isinstance(divergence, (plcopen.sfcObjects_selectionDivergence, plcopen.sfcObjects_simultaneousDivergence)): Laurent@814: position = input_connectors[0].GetRelPosition() Laurent@814: divergence.addconnectionPointIn() Laurent@814: divergence.connectionPointIn.setrelPositionXY(position.x, position.y) Laurent@814: self.SetConnectionWires(divergence.connectionPointIn, input_connectors[0]) Laurent@814: else: Laurent@814: divergence.setconnectionPointIn([]) Laurent@814: for input_connector in input_connectors: Laurent@814: position = input_connector.GetRelPosition() Laurent@814: if isinstance(divergence, plcopen.sfcObjects_selectionConvergence): Laurent@814: connection = plcopen.selectionConvergence_connectionPointIn() Laurent@814: else: Laurent@814: connection = plcopen.connectionPointIn() Laurent@814: connection.setrelPositionXY(position.x, position.y) Laurent@814: self.SetConnectionWires(connection, input_connector) Laurent@814: divergence.appendconnectionPointIn(connection) Laurent@814: output_connectors = value["outputs"] Laurent@814: if isinstance(divergence, (plcopen.sfcObjects_selectionConvergence, plcopen.sfcObjects_simultaneousConvergence)): Laurent@814: position = output_connectors[0].GetRelPosition() Laurent@814: divergence.addconnectionPointOut() Laurent@814: divergence.connectionPointOut.setrelPositionXY(position.x, position.y) Laurent@814: else: Laurent@814: divergence.setconnectionPointOut([]) Laurent@814: for output_connector in output_connectors: Laurent@814: position = output_connector.GetRelPosition() Laurent@814: if isinstance(divergence, plcopen.sfcObjects_selectionDivergence): Laurent@814: connection = plcopen.selectionDivergence_connectionPointOut() Laurent@814: else: Laurent@814: connection = plcopen.simultaneousDivergence_connectionPointOut() Laurent@814: connection.setrelPositionXY(position.x, position.y) Laurent@814: divergence.appendconnectionPointOut(connection) Laurent@814: Laurent@814: def AddEditedElementJump(self, tagname, id): Laurent@814: element = self.GetEditedElement(tagname) Laurent@814: if element is not None: Laurent@814: jump = plcopen.sfcObjects_jumpStep() Laurent@814: jump.setlocalId(id) Laurent@814: element.addinstance("jumpStep", jump) Laurent@814: Laurent@814: def SetEditedElementJumpInfos(self, tagname, id, infos): Laurent@814: element = self.GetEditedElement(tagname) Laurent@814: if element is not None: Laurent@814: jump = element.getinstance(id) Laurent@814: if jump is None: Laurent@814: return Laurent@814: for param, value in infos.items(): Laurent@814: if param == "target": Laurent@814: jump.settargetName(value) Laurent@814: elif param == "height": Laurent@814: jump.setheight(value) Laurent@814: elif param == "width": Laurent@814: jump.setwidth(value) Laurent@814: elif param == "x": Laurent@814: jump.setx(value) Laurent@814: elif param == "y": Laurent@814: jump.sety(value) Laurent@814: elif param == "connector": Laurent@814: position = value.GetRelPosition() Laurent@814: jump.addconnectionPointIn() Laurent@814: jump.connectionPointIn.setrelPositionXY(position.x, position.y) Laurent@814: self.SetConnectionWires(jump.connectionPointIn, value) Laurent@814: Laurent@814: def AddEditedElementActionBlock(self, tagname, id): Laurent@814: element = self.GetEditedElement(tagname) Laurent@814: if element is not None: Laurent@814: actionBlock = plcopen.commonObjects_actionBlock() Laurent@814: actionBlock.setlocalId(id) Laurent@814: element.addinstance("actionBlock", actionBlock) Laurent@814: Laurent@814: def SetEditedElementActionBlockInfos(self, tagname, id, infos): Laurent@814: element = self.GetEditedElement(tagname) Laurent@814: if element is not None: Laurent@814: actionBlock = element.getinstance(id) Laurent@814: if actionBlock is None: Laurent@814: return Laurent@814: for param, value in infos.items(): Laurent@814: if param == "actions": Laurent@814: actionBlock.setactions(value) Laurent@814: elif param == "height": Laurent@814: actionBlock.setheight(value) Laurent@814: elif param == "width": Laurent@814: actionBlock.setwidth(value) Laurent@814: elif param == "x": Laurent@814: actionBlock.setx(value) Laurent@814: elif param == "y": Laurent@814: actionBlock.sety(value) Laurent@814: elif param == "connector": Laurent@814: position = value.GetRelPosition() Laurent@814: actionBlock.addconnectionPointIn() Laurent@814: actionBlock.connectionPointIn.setrelPositionXY(position.x, position.y) Laurent@814: self.SetConnectionWires(actionBlock.connectionPointIn, value) Laurent@814: Laurent@814: def RemoveEditedElementInstance(self, tagname, id): Laurent@814: element = self.GetEditedElement(tagname) Laurent@814: if element is not None: Laurent@814: instance = element.getinstance(id) Laurent@814: if isinstance(instance, plcopen.fbdObjects_block): Laurent@814: self.RemoveEditedElementPouVar(tagname, instance.gettypeName(), instance.getinstanceName()) Laurent@814: element.removeinstance(id) Laurent@814: self.Project.RefreshElementUsingTree() Laurent@814: Laurent@814: def GetEditedResourceVariables(self, tagname, debug = False): Laurent@814: varlist = [] Laurent@814: words = tagname.split("::") Laurent@814: for var in self.GetConfigurationGlobalVars(words[1], debug): Laurent@814: if var["Type"] == "BOOL": Laurent@814: varlist.append(var["Name"]) Laurent@814: for var in self.GetConfigurationResourceGlobalVars(words[1], words[2], debug): Laurent@814: if var["Type"] == "BOOL": Laurent@814: varlist.append(var["Name"]) Laurent@814: return varlist Laurent@814: Laurent@814: def SetEditedResourceInfos(self, tagname, tasks, instances): Laurent@814: resource = self.GetEditedElement(tagname) Laurent@814: if resource is not None: Laurent@814: resource.settask([]) Laurent@814: resource.setpouInstance([]) Laurent@814: task_list = {} Laurent@814: for task in tasks: Laurent@814: new_task = plcopen.resource_task() Laurent@814: new_task.setname(task["Name"]) Laurent@814: if task["Triggering"] == "Interrupt": Laurent@814: new_task.setsingle(task["Single"]) Laurent@814: ## result = duration_model.match(task["Interval"]).groups() Laurent@814: ## if reduce(lambda x, y: x or y != None, result): Laurent@814: ## values = [] Laurent@814: ## for value in result[:-1]: Laurent@814: ## if value != None: Laurent@814: ## values.append(int(value)) Laurent@814: ## else: Laurent@814: ## values.append(0) Laurent@814: ## if result[-1] is not None: Laurent@814: ## values.append(int(float(result[-1]) * 1000)) Laurent@814: ## new_task.setinterval(datetime.time(*values)) Laurent@814: if task["Triggering"] == "Cyclic": Laurent@814: new_task.setinterval(task["Interval"]) Laurent@814: new_task.setpriority(int(task["Priority"])) Laurent@814: if task["Name"] != "": Laurent@814: task_list[task["Name"]] = new_task Laurent@814: resource.appendtask(new_task) Laurent@814: for instance in instances: Laurent@814: new_instance = plcopen.pouInstance() Laurent@814: new_instance.setname(instance["Name"]) Laurent@814: new_instance.settypeName(instance["Type"]) Laurent@814: task_list.get(instance["Task"], resource).appendpouInstance(new_instance) Laurent@814: Laurent@814: def GetEditedResourceInfos(self, tagname, debug = False): Laurent@814: resource = self.GetEditedElement(tagname, debug) Laurent@814: if resource is not None: Laurent@814: tasks = resource.gettask() Laurent@814: instances = resource.getpouInstance() Laurent@814: tasks_data = [] Laurent@814: instances_data = [] Laurent@814: for task in tasks: Laurent@814: new_task = {} Laurent@814: new_task["Name"] = task.getname() Laurent@814: single = task.getsingle() Laurent@814: if single is not None: Laurent@814: new_task["Single"] = single Laurent@814: else: Laurent@814: new_task["Single"] = "" Laurent@814: interval = task.getinterval() Laurent@814: if interval is not None: Laurent@814: ## text = "" Laurent@814: ## if interval.hour != 0: Laurent@814: ## text += "%dh"%interval.hour Laurent@814: ## if interval.minute != 0: Laurent@814: ## text += "%dm"%interval.minute Laurent@814: ## if interval.second != 0: Laurent@814: ## text += "%ds"%interval.second Laurent@814: ## if interval.microsecond != 0: Laurent@814: ## if interval.microsecond % 1000 != 0: Laurent@814: ## text += "%.3fms"%(float(interval.microsecond) / 1000) Laurent@814: ## else: Laurent@814: ## text += "%dms"%(interval.microsecond / 1000) Laurent@814: ## new_task["Interval"] = text Laurent@814: new_task["Interval"] = interval Laurent@814: else: Laurent@814: new_task["Interval"] = "" Laurent@814: if single is not None and interval is None: Laurent@814: new_task["Triggering"] = "Interrupt" Laurent@814: elif interval is not None and single is None: Laurent@814: new_task["Triggering"] = "Cyclic" Laurent@814: else: Laurent@814: new_task["Triggering"] = "" Laurent@814: new_task["Priority"] = str(task.getpriority()) Laurent@814: tasks_data.append(new_task) Laurent@814: for instance in task.getpouInstance(): Laurent@814: new_instance = {} Laurent@814: new_instance["Name"] = instance.getname() Laurent@814: new_instance["Type"] = instance.gettypeName() Laurent@814: new_instance["Task"] = task.getname() Laurent@814: instances_data.append(new_instance) Laurent@814: for instance in instances: Laurent@814: new_instance = {} Laurent@814: new_instance["Name"] = instance.getname() Laurent@814: new_instance["Type"] = instance.gettypeName() Laurent@814: new_instance["Task"] = "" Laurent@814: instances_data.append(new_instance) Laurent@814: return tasks_data, instances_data Laurent@814: Laurent@814: def OpenXMLFile(self, filepath): Laurent@814: xmlfile = open(filepath, 'r') Laurent@814: tree = minidom.parse(xmlfile) Laurent@814: xmlfile.close() Laurent@814: Laurent@814: self.Project = plcopen.project() Laurent@814: for child in tree.childNodes: Laurent@814: if child.nodeType == tree.ELEMENT_NODE and child.nodeName == "project": Laurent@814: try: Laurent@814: result = self.Project.loadXMLTree(child) Laurent@814: except ValueError, e: Laurent@814: return _("Project file syntax error:\n\n") + str(e) Laurent@814: self.SetFilePath(filepath) Laurent@814: self.Project.RefreshElementUsingTree() Laurent@814: self.Project.RefreshDataTypeHierarchy() Laurent@814: self.Project.RefreshCustomBlockTypes() Laurent@814: self.CreateProjectBuffer(True) Laurent@814: self.ProgramChunks = [] Laurent@814: self.ProgramOffset = 0 Laurent@814: self.NextCompiledProject = self.Copy(self.Project) Laurent@814: self.CurrentCompiledProject = None Laurent@814: self.Buffering = False Laurent@814: self.CurrentElementEditing = None Laurent@814: return None Laurent@814: return _("No PLC project found") Laurent@814: Laurent@814: def SaveXMLFile(self, filepath = None): Laurent@814: if not filepath and self.FilePath == "": Laurent@814: return False Laurent@814: else: Laurent@814: contentheader = {"modificationDateTime": datetime.datetime(*localtime()[:6])} Laurent@814: self.Project.setcontentHeader(contentheader) Laurent@814: Laurent@814: text = "\n" Laurent@814: extras = {"xmlns" : "http://www.plcopen.org/xml/tc6.xsd", Laurent@814: "xmlns:xhtml" : "http://www.w3.org/1999/xhtml", Laurent@814: "xmlns:xsi" : "http://www.w3.org/2001/XMLSchema-instance", Laurent@814: "xsi:schemaLocation" : "http://www.plcopen.org/xml/tc6.xsd"} Laurent@814: text += self.Project.generateXMLText("project", 0, extras) Laurent@814: Laurent@814: if filepath: Laurent@814: xmlfile = open(filepath,"w") Laurent@814: else: Laurent@814: xmlfile = open(self.FilePath,"w") Laurent@814: xmlfile.write(text.encode("utf-8")) Laurent@814: xmlfile.close() Laurent@814: self.MarkProjectAsSaved() Laurent@814: if filepath: Laurent@814: self.SetFilePath(filepath) Laurent@814: return True Laurent@814: Laurent@814: #------------------------------------------------------------------------------- Laurent@814: # Search in Current Project Functions Laurent@814: #------------------------------------------------------------------------------- Laurent@814: Laurent@814: def SearchInProject(self, criteria): Laurent@814: return self.Project.Search(criteria) Laurent@814: Laurent@814: def SearchInPou(self, tagname, criteria, debug=False): Laurent@814: pou = self.GetEditedElement(tagname, debug) Laurent@814: if pou is not None: Laurent@814: return pou.Search(criteria) Laurent@814: return [] Laurent@814: Laurent@814: #------------------------------------------------------------------------------- Laurent@814: # Current Buffering Management Functions Laurent@814: #------------------------------------------------------------------------------- Laurent@814: Laurent@814: """ Laurent@814: Return a copy of the project Laurent@814: """ Laurent@814: def Copy(self, model): Laurent@814: return cPickle.loads(cPickle.dumps(model)) Laurent@814: Laurent@814: def CreateProjectBuffer(self, saved): Laurent@814: if self.ProjectBufferEnabled: Laurent@814: self.ProjectBuffer = UndoBuffer(cPickle.dumps(self.Project), saved) Laurent@814: else: Laurent@814: self.ProjectBuffer = None Laurent@814: self.ProjectSaved = saved Laurent@814: Laurent@814: def IsProjectBufferEnabled(self): Laurent@814: return self.ProjectBufferEnabled Laurent@814: Laurent@814: def EnableProjectBuffer(self, enable): Laurent@814: self.ProjectBufferEnabled = enable Laurent@814: if self.Project is not None: Laurent@814: if enable: Laurent@814: current_saved = self.ProjectSaved Laurent@814: else: Laurent@814: current_saved = self.ProjectBuffer.IsCurrentSaved() Laurent@814: self.CreateProjectBuffer(current_saved) Laurent@814: Laurent@814: def BufferProject(self): Laurent@814: if self.ProjectBuffer is not None: Laurent@814: self.ProjectBuffer.Buffering(cPickle.dumps(self.Project)) Laurent@814: else: Laurent@814: self.ProjectSaved = False Laurent@814: Laurent@814: def StartBuffering(self): Laurent@814: if self.ProjectBuffer is not None: Laurent@814: self.Buffering = True Laurent@814: else: Laurent@814: self.ProjectSaved = False Laurent@814: Laurent@814: def EndBuffering(self): Laurent@814: if self.ProjectBuffer is not None and self.Buffering: Laurent@814: self.ProjectBuffer.Buffering(cPickle.dumps(self.Project)) Laurent@814: self.Buffering = False Laurent@814: Laurent@814: def MarkProjectAsSaved(self): Laurent@814: self.EndBuffering() Laurent@814: if self.ProjectBuffer is not None: Laurent@814: self.ProjectBuffer.CurrentSaved() Laurent@814: else: Laurent@814: self.ProjectSaved = True Laurent@814: Laurent@814: # Return if project is saved Laurent@814: def ProjectIsSaved(self): Laurent@814: if self.ProjectBuffer is not None: Laurent@814: return self.ProjectBuffer.IsCurrentSaved() and not self.Buffering Laurent@814: else: Laurent@814: return self.ProjectSaved Laurent@814: Laurent@814: def LoadPrevious(self): Laurent@814: self.EndBuffering() Laurent@814: if self.ProjectBuffer is not None: Laurent@814: self.Project = cPickle.loads(self.ProjectBuffer.Previous()) Laurent@814: Laurent@814: def LoadNext(self): Laurent@814: if self.ProjectBuffer is not None: Laurent@814: self.Project = cPickle.loads(self.ProjectBuffer.Next()) Laurent@814: Laurent@814: def GetBufferState(self): Laurent@814: if self.ProjectBuffer is not None: Laurent@814: first = self.ProjectBuffer.IsFirst() and not self.Buffering Laurent@814: last = self.ProjectBuffer.IsLast() Laurent@814: return not first, not last Laurent@814: return False, False