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