diff -r 31e63e25b4cc -r 64beb9e9c749 PLCControler.py --- a/PLCControler.py Mon Aug 21 20:17:19 2017 +0000 +++ b/PLCControler.py Mon Aug 21 23:22:58 2017 +0300 @@ -27,47 +27,52 @@ from types import StringType, UnicodeType, TupleType from lxml import etree from copy import deepcopy -import os,sys,re +import os +import sys +import re import datetime import util.paths as paths from time import localtime from collections import OrderedDict, namedtuple - +from util.TranslationCatalogs import NoTranslate from plcopen import * from graphics.GraphicCommons import * from PLCGenerator import * 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)?") -ITEMS_EDITABLE = [ITEM_PROJECT, - ITEM_POU, - ITEM_VARIABLE, - ITEM_TRANSITION, - ITEM_ACTION, - ITEM_CONFIGURATION, - ITEM_RESOURCE, - ITEM_DATATYPE - ] = range(8) - -ITEMS_UNEDITABLE = [ITEM_DATATYPES, - ITEM_FUNCTION, - ITEM_FUNCTIONBLOCK, - ITEM_PROGRAM, - ITEM_TRANSITIONS, - ITEM_ACTIONS, - ITEM_CONFIGURATIONS, - ITEM_RESOURCES, - ITEM_PROPERTIES - ] = range(8, 17) - -ITEMS_VARIABLE = [ITEM_VAR_LOCAL, - ITEM_VAR_GLOBAL, - ITEM_VAR_EXTERNAL, - ITEM_VAR_TEMP, - ITEM_VAR_INPUT, - ITEM_VAR_OUTPUT, - ITEM_VAR_INOUT - ] = range(17, 24) +ITEMS_EDITABLE = [ + ITEM_PROJECT, + ITEM_POU, + ITEM_VARIABLE, + ITEM_TRANSITION, + ITEM_ACTION, + ITEM_CONFIGURATION, + ITEM_RESOURCE, + ITEM_DATATYPE +] = range(8) + +ITEMS_UNEDITABLE = [ + ITEM_DATATYPES, + ITEM_FUNCTION, + ITEM_FUNCTIONBLOCK, + ITEM_PROGRAM, + ITEM_TRANSITIONS, + ITEM_ACTIONS, + ITEM_CONFIGURATIONS, + ITEM_RESOURCES, + ITEM_PROPERTIES +] = range(8, 17) + +ITEMS_VARIABLE = [ + ITEM_VAR_LOCAL, + ITEM_VAR_GLOBAL, + ITEM_VAR_EXTERNAL, + ITEM_VAR_TEMP, + ITEM_VAR_INPUT, + ITEM_VAR_OUTPUT, + ITEM_VAR_INOUT +] = range(17, 24) VAR_CLASS_INFOS = { "Local": ("localVars", ITEM_VAR_LOCAL), @@ -78,10 +83,11 @@ "Output": ("outputVars", ITEM_VAR_OUTPUT), "InOut": ("inOutVars", ITEM_VAR_INOUT)} -POU_TYPES = {"program": ITEM_PROGRAM, - "functionBlock": ITEM_FUNCTIONBLOCK, - "function": ITEM_FUNCTION, - } +POU_TYPES = { + "program": ITEM_PROGRAM, + "functionBlock": ITEM_FUNCTIONBLOCK, + "function": ITEM_FUNCTION, +} LOCATIONS_ITEMS = [LOCATION_CONFNODE, LOCATION_MODULE, @@ -92,21 +98,22 @@ ScriptDirectory = paths.AbsDir(__file__) + def GetUneditableNames(): - _ = lambda x:x + _ = NoTranslate return [_("User-defined POUs"), _("Functions"), _("Function Blocks"), _("Programs"), _("Data Types"), _("Transitions"), _("Actions"), _("Configurations"), _("Resources"), _("Properties")] + + UNEDITABLE_NAMES = GetUneditableNames() [USER_DEFINED_POUS, FUNCTIONS, FUNCTION_BLOCKS, PROGRAMS, DATA_TYPES, TRANSITIONS, ACTIONS, CONFIGURATIONS, RESOURCES, PROPERTIES] = UNEDITABLE_NAMES -#------------------------------------------------------------------------------- -# Helper object for loading library in xslt stylesheets -#------------------------------------------------------------------------------- class LibraryResolver(etree.Resolver): + """Helper object for loading library in xslt stylesheets""" def __init__(self, controller, debug=False): self.Controller = controller @@ -126,32 +133,42 @@ lib_el.append(deepcopy(ctn["types"])) return self.resolve_string(etree.tostring(lib_el), context) -#------------------------------------------------------------------------------- +# ------------------------------------------------------------------------------- # Helpers functions for translating list of arguments # from xslt to valid arguments -#------------------------------------------------------------------------------- - -_StringValue = lambda x: x -_BoolValue = lambda x: x in ["true", "0"] +# ------------------------------------------------------------------------------- + + +def _StringValue(x): + return x + + +def _BoolValue(x): + return x in ["true", "0"] + def _translate_args(translations, args): return [translate(arg[0]) if len(arg) > 0 else None for translate, arg in zip(translations, args)] -#------------------------------------------------------------------------------- +# ------------------------------------------------------------------------------- # Helpers object for generating pou var list -#------------------------------------------------------------------------------- +# ------------------------------------------------------------------------------- + class _VariableInfos(object): __slots__ = ["Name", "Class", "Option", "Location", "InitialValue", "Edit", "Documentation", "Type", "Tree", "Number"] + def __init__(self, *args): for attr, value in zip(self.__slots__, args): setattr(self, attr, value if value is not None else "") + def copy(self): return _VariableInfos(*[getattr(self, attr) for attr in self.__slots__]) + class VariablesInfosFactory: def __init__(self, variables): @@ -188,9 +205,10 @@ [_StringValue] * 5 + [_BoolValue] + [_StringValue], args) + [self.GetType(), self.GetTree()]))) -#------------------------------------------------------------------------------- +# ------------------------------------------------------------------------------- # Helpers object for generating pou variable instance list -#------------------------------------------------------------------------------- +# ------------------------------------------------------------------------------- + def class_extraction(value): class_type = { @@ -212,14 +230,18 @@ return None + class _VariablesTreeItemInfos(object): __slots__ = ["name", "var_class", "type", "edit", "debug", "variables"] + def __init__(self, *args): for attr, value in zip(self.__slots__, args): setattr(self, attr, value if value is not None else "") + def copy(self): return _VariableTreeItem(*[getattr(self, attr) for attr in self.__slots__]) + class VariablesTreeInfosFactory: def __init__(self): @@ -241,23 +263,18 @@ [_StringValue, class_extraction, _StringValue] + [_BoolValue] * 2, args) + [[]]))) -#------------------------------------------------------------------------------- -# Helpers object for generating instances path list -#------------------------------------------------------------------------------- class InstancesPathFactory: - + """Helpers object for generating instances path list""" def __init__(self, instances): self.Instances = instances def AddInstance(self, context, *args): self.Instances.append(args[0][0]) -#------------------------------------------------------------------------------- -# Helpers object for generating instance tagname -#------------------------------------------------------------------------------- class InstanceTagName: + """Helpers object for generating instance tagname""" def __init__(self, controller): self.Controller = controller @@ -281,13 +298,16 @@ def TransitionTagName(self, context, *args): self.TagName = self.Controller.ComputePouTransitionName(args[0][0], args[0][1]) -#------------------------------------------------------------------------------- + +# ------------------------------------------------------------------------------- # Helpers object for generating pou block instances list -#------------------------------------------------------------------------------- +# ------------------------------------------------------------------------------- + _Point = namedtuple("Point", ["x", "y"]) -_BlockInstanceInfos = namedtuple("BlockInstanceInfos", +_BlockInstanceInfos = namedtuple( + "BlockInstanceInfos", ["type", "id", "x", "y", "width", "height", "specific_values", "inputs", "outputs"]) _BlockSpecificValues = ( @@ -347,20 +367,26 @@ [lambda x: x]), } -_InstanceConnectionInfos = namedtuple("InstanceConnectionInfos", +_InstanceConnectionInfos = namedtuple( + "InstanceConnectionInfos", ["name", "negated", "edge", "position", "links"]) -_ConnectionLinkInfos = namedtuple("ConnectionLinkInfos", +_ConnectionLinkInfos = namedtuple( + "ConnectionLinkInfos", ["refLocalId", "formalParameter", "points"]) + class _ActionInfos(object): __slots__ = ["qualifier", "type", "value", "duration", "indicator"] + def __init__(self, *args): for attr, value in zip(self.__slots__, args): setattr(self, attr, value if value is not None else "") + def copy(self): return _ActionInfos(*[getattr(self, attr) for attr in self.__slots__]) + class BlockInstanceFactory: def __init__(self, block_instances): @@ -380,8 +406,8 @@ specific_values_tuple, specific_values_translation = \ _SpecificValuesTuples.get(args[0][0], _BlockSpecificValues) - if (args[0][0] == "step" and len(self.SpecificValues) < 3 or - args[0][0] == "transition" and len(self.SpecificValues) < 4): + if args[0][0] == "step" and len(self.SpecificValues) < 3 or \ + args[0][0] == "transition" and len(self.SpecificValues) < 4: self.SpecificValues.append([None]) elif args[0][0] == "actionBlock" and len(self.SpecificValues) < 1: self.SpecificValues.append([[]]) @@ -426,23 +452,25 @@ translated_args = _translate_args([_StringValue] * 5, args) self.SpecificValues[0][0].append(_ActionInfos(*translated_args)) + pou_block_instances_xslt = etree.parse( os.path.join(ScriptDirectory, "plcopen", "pou_block_instances.xslt")) -#------------------------------------------------------------------------------- -# Undo Buffer for PLCOpenEditor -#------------------------------------------------------------------------------- # Length of the buffer UNDO_BUFFER_LENGTH = 20 -""" -Class implementing a buffer of changes made on the current editing model -""" + class UndoBuffer: - - # Constructor initialising buffer - def __init__(self, currentstate, issaved = False): + """ + Undo Buffer for PLCOpenEditor + Class implementing a buffer of changes made on the current editing model + """ + + def __init__(self, currentstate, issaved=False): + """ + Constructor initialising buffer + """ self.Buffer = [] self.CurrentIndex = -1 self.MinIndex = -1 @@ -464,8 +492,10 @@ else: self.LastSave = -1 - # Add a new state in buffer def Buffering(self, currentstate): + """ + Add a new state in buffer + """ self.CurrentIndex = (self.CurrentIndex + 1) % UNDO_BUFFER_LENGTH self.Buffer[self.CurrentIndex] = currentstate # Actualising buffer limits @@ -477,8 +507,10 @@ self.MinIndex = (self.MinIndex + 1) % UNDO_BUFFER_LENGTH self.MinIndex = max(self.MinIndex, 0) - # Return current state of buffer def Current(self): + """ + Return current state of buffer + """ return self.Buffer[self.CurrentIndex] # Change current state to previous in buffer and return new current state @@ -512,14 +544,11 @@ return self.LastSave == self.CurrentIndex -#------------------------------------------------------------------------------- -# Controler for PLCOpenEditor -#------------------------------------------------------------------------------- - -""" -Class which controls the operations made on the plcopen model and answers to view requests -""" class PLCControler: + """ + Controler for PLCOpenEditor + Class which controls the operations made on the plcopen model and answers to view requests + """ # Create a new PLCControler def __init__(self): @@ -547,15 +576,15 @@ def GetQualifierTypes(self): return QualifierList - def GetProject(self, debug = False): + def GetProject(self, debug=False): if debug and self.CurrentCompiledProject is not None: return self.CurrentCompiledProject else: return self.Project -#------------------------------------------------------------------------------- -# Project management functions -#------------------------------------------------------------------------------- + # ------------------------------------------------------------------------------- + # Project management functions + # ------------------------------------------------------------------------------- # Return if a project is opened def HasOpenedProject(self): @@ -579,28 +608,28 @@ self.Buffering = False # Return project data type names - def GetProjectDataTypeNames(self, debug = False): + def GetProjectDataTypeNames(self, debug=False): project = self.GetProject(debug) if project is not None: return [datatype.getname() for datatype in project.getdataTypes()] return [] # Return project pou names - def GetProjectPouNames(self, debug = False): + def GetProjectPouNames(self, debug=False): project = self.GetProject(debug) if project is not None: return [pou.getname() for pou in project.getpous()] return [] # Return project pou names - def GetProjectConfigNames(self, debug = False): + def GetProjectConfigNames(self, debug=False): project = self.GetProject(debug) if project is not None: return [config.getname() for config in project.getconfigurations()] return [] # Return project pou variable names - def GetProjectPouVariableNames(self, pou_name = None, debug = False): + def GetProjectPouVariableNames(self, pou_name=None, debug=False): variables = [] project = self.GetProject(debug) if project is not None: @@ -627,7 +656,7 @@ if self.ProjectIsSaved(): return self.FileName else: - return "~%s~"%self.FileName + return "~%s~" % self.FileName return "" # Change file path and save file name or create a default one if file path not defined @@ -635,12 +664,12 @@ self.FilePath = filepath if filepath == "": self.LastNewIndex += 1 - self.FileName = _("Unnamed%d")%self.LastNewIndex + self.FileName = _("Unnamed%d") % self.LastNewIndex else: self.FileName = os.path.splitext(os.path.basename(filepath))[0] # Change project properties - def SetProjectProperties(self, name = None, properties = None, buffer = True): + def SetProjectProperties(self, name=None, properties=None, buffer=True): if self.Project is not None: if name is not None: self.Project.setname(name) @@ -658,7 +687,7 @@ return None # Return project properties - def GetProjectProperties(self, debug = False): + def GetProjectProperties(self, debug=False): project = self.GetProject(debug) if project is not None: properties = project.getfileHeader() @@ -667,17 +696,34 @@ return None # Return project informations - def GetProjectInfos(self, debug = False): + def GetProjectInfos(self, debug=False): project = self.GetProject(debug) if project is not None: infos = {"name": project.getname(), "type": ITEM_PROJECT} - datatypes = {"name": DATA_TYPES, "type": ITEM_DATATYPES, "values":[]} + datatypes = {"name": DATA_TYPES, "type": ITEM_DATATYPES, "values": []} for datatype in project.getdataTypes(): - datatypes["values"].append({"name": datatype.getname(), "type": ITEM_DATATYPE, - "tagname": self.ComputeDataTypeName(datatype.getname()), "values": []}) - pou_types = {"function": {"name": FUNCTIONS, "type": ITEM_FUNCTION, "values":[]}, - "functionBlock": {"name": FUNCTION_BLOCKS, "type": ITEM_FUNCTIONBLOCK, "values":[]}, - "program": {"name": PROGRAMS, "type": ITEM_PROGRAM, "values":[]}} + datatypes["values"].append({ + "name": datatype.getname(), + "type": ITEM_DATATYPE, + "tagname": self.ComputeDataTypeName(datatype.getname()), + "values": []}) + pou_types = { + "function": { + "name": FUNCTIONS, + "type": ITEM_FUNCTION, + "values": [] + }, + "functionBlock": { + "name": FUNCTION_BLOCKS, + "type": ITEM_FUNCTIONBLOCK, + "values": [] + }, + "program": { + "name": PROGRAMS, + "type": ITEM_PROGRAM, + "values": [] + } + } for pou in project.getpous(): pou_type = pou.getpouType() pou_infos = {"name": pou.getname(), "type": ITEM_POU, @@ -686,13 +732,17 @@ if pou.getbodyType() == "SFC": transitions = [] for transition in pou.gettransitionList(): - transitions.append({"name": transition.getname(), "type": ITEM_TRANSITION, + transitions.append({ + "name": transition.getname(), + "type": ITEM_TRANSITION, "tagname": self.ComputePouTransitionName(pou.getname(), transition.getname()), "values": []}) pou_values.append({"name": TRANSITIONS, "type": ITEM_TRANSITIONS, "values": transitions}) actions = [] for action in pou.getactionList(): - actions.append({"name": action.getname(), "type": ITEM_ACTION, + actions.append({ + "name": action.getname(), + "type": ITEM_ACTION, "tagname": self.ComputePouActionName(pou.getname(), action.getname()), "values": []}) pou_values.append({"name": ACTIONS, "type": ITEM_ACTIONS, "values": actions}) @@ -702,13 +752,17 @@ configurations = {"name": CONFIGURATIONS, "type": ITEM_CONFIGURATIONS, "values": []} for config in project.getconfigurations(): config_name = config.getname() - config_infos = {"name": config_name, "type": ITEM_CONFIGURATION, + config_infos = { + "name": config_name, + "type": ITEM_CONFIGURATION, "tagname": self.ComputeConfigurationName(config.getname()), "values": []} resources = {"name": RESOURCES, "type": ITEM_RESOURCES, "values": []} for resource in config.getresource(): resource_name = resource.getname() - resource_infos = {"name": resource_name, "type": ITEM_RESOURCE, + resource_infos = { + "name": resource_name, + "type": ITEM_RESOURCE, "tagname": self.ComputeConfigurationResourceName(config.getname(), resource.getname()), "values": []} resources["values"].append(resource_infos) @@ -719,7 +773,7 @@ return infos return None - def GetPouVariables(self, tagname, debug = False): + def GetPouVariables(self, tagname, debug=False): pou_type = None project = self.GetProject(debug) if project is not None: @@ -732,8 +786,8 @@ etree.parse( os.path.join(ScriptDirectory, "plcopen", "pou_variables.xslt"), parser), - extensions = {("pou_vars_ns", name): getattr(factory, name) - for name in ["SetRoot", "AddVariable"]}) + extensions={("pou_vars_ns", name): getattr(factory, name) + for name in ["SetRoot", "AddVariable"]}) obj = None words = tagname.split("::") @@ -747,7 +801,7 @@ return None - def GetInstanceList(self, root, name, debug = False): + def GetInstanceList(self, root, name, debug=False): instances = [] project = self.GetProject(debug) if project is not None: @@ -760,15 +814,15 @@ etree.parse( os.path.join(ScriptDirectory, "plcopen", "instances_path.xslt"), parser), - extensions = { + extensions={ ("instances_ns", "AddInstance"): factory.AddInstance}) - instances_path_xslt_tree(root, - instance_type=etree.XSLT.strparam(name)) + instances_path_xslt_tree( + root, instance_type=etree.XSLT.strparam(name)) return instances - def SearchPouInstances(self, tagname, debug = False): + def SearchPouInstances(self, tagname, debug=False): project = self.GetProject(debug) if project is not None: words = tagname.split("::") @@ -784,7 +838,7 @@ self.ComputePouName(words[1]), debug)] return [] - def GetPouInstanceTagName(self, instance_path, debug = False): + def GetPouInstanceTagName(self, instance_path, debug=False): project = self.GetProject(debug) factory = InstanceTagName(self) @@ -795,17 +849,19 @@ etree.parse( os.path.join(ScriptDirectory, "plcopen", "instance_tagname.xslt"), parser), - extensions = {("instance_tagname_ns", name): getattr(factory, name) - for name in ["ConfigTagName", "ResourceTagName", - "PouTagName", "ActionTagName", - "TransitionTagName"]}) - - instance_tagname_xslt_tree(project, - instance_path=etree.XSLT.strparam(instance_path)) + extensions={("instance_tagname_ns", name): getattr(factory, name) + for name in ["ConfigTagName", + "ResourceTagName", + "PouTagName", + "ActionTagName", + "TransitionTagName"]}) + + instance_tagname_xslt_tree( + project, instance_path=etree.XSLT.strparam(instance_path)) return factory.GetTagName() - def GetInstanceInfos(self, instance_path, debug = False): + def GetInstanceInfos(self, instance_path, debug=False): tagname = self.GetPouInstanceTagName(instance_path) if tagname is not None: infos = self.GetPouVariables(tagname, debug) @@ -822,21 +878,21 @@ return None # Return if data type given by name is used by another data type or pou - def DataTypeIsUsed(self, name, debug = False): + def DataTypeIsUsed(self, name, debug=False): project = self.GetProject(debug) if project is not None: return len(self.GetInstanceList(project, name, debug)) > 0 return False # Return if pou given by name is used by another pou - def PouIsUsed(self, name, debug = False): + def PouIsUsed(self, name, debug=False): project = self.GetProject(debug) if project is not None: return len(self.GetInstanceList(project, name, debug)) > 0 return False # Return if pou given by name is directly or undirectly used by the reference pou - def PouIsUsedBy(self, name, reference, debug = False): + def PouIsUsedBy(self, name, reference, debug=False): pou_infos = self.GetPou(reference, debug) if pou_infos is not None: return len(self.GetInstanceList(pou_infos, name, debug)) > 0 @@ -890,9 +946,9 @@ row, col = next_row, next_col return infos -#------------------------------------------------------------------------------- -# Project Pous management functions -#------------------------------------------------------------------------------- + # ------------------------------------------------------------------------------- + # Project Pous management functions + # ------------------------------------------------------------------------------- # Add a Data Type to Project def ProjectAddDataType(self, datatype_name=None): @@ -942,7 +998,7 @@ ''' try: new_pou, error = LoadPou(pou_xml) - except: + except Exception: error = "" if error is not None: return _("Couldn't paste non-POU object.") @@ -969,7 +1025,7 @@ # programs cannot be pasted as functions or function blocks if orig_type == 'functionBlock' and pou_type == 'function' or \ orig_type == 'program' and pou_type in ['function', 'functionBlock']: - msg = _('''{a1} "{a2}" can't be pasted as a {a3}.''').format(a1 = orig_type, a2 = name, a3 = pou_type) + msg = _('''{a1} "{a2}" can't be pasted as a {a3}.''').format(a1=orig_type, a2=name, a3=pou_type) return msg new_pou.setpouType(pou_type) @@ -1139,7 +1195,7 @@ self.BufferProject() # Return the description of the pou given by its name - def GetPouDescription(self, name, debug = False): + def GetPouDescription(self, name, debug=False): project = self.GetProject(debug) if project is not None: # Found the pou correponding to name and return its type @@ -1149,7 +1205,7 @@ return "" # Return the description of the pou given by its name - def SetPouDescription(self, name, description, debug = False): + def SetPouDescription(self, name, description, debug=False): project = self.GetProject(debug) if project is not None: # Found the pou correponding to name and return its type @@ -1159,7 +1215,7 @@ self.BufferProject() # Return the type of the pou given by its name - def GetPouType(self, name, debug = False): + def GetPouType(self, name, debug=False): project = self.GetProject(debug) if project is not None: # Found the pou correponding to name and return its type @@ -1169,7 +1225,7 @@ return None # Return pous with SFC language - def GetSFCPous(self, debug = False): + def GetSFCPous(self, debug=False): list = [] project = self.GetProject(debug) if project is not None: @@ -1179,7 +1235,7 @@ return list # Return the body language of the pou given by its name - def GetPouBodyType(self, name, debug = False): + def GetPouBodyType(self, name, debug=False): project = self.GetProject(debug) if project is not None: # Found the pou correponding to name and return its body language @@ -1189,7 +1245,7 @@ return None # Return the actions of a pou - def GetPouTransitions(self, pou_name, debug = False): + def GetPouTransitions(self, pou_name, debug=False): transitions = [] project = self.GetProject(debug) if project is not None: @@ -1201,7 +1257,7 @@ return transitions # Return the body language of the transition given by its name - def GetTransitionBodyType(self, pou_name, pou_transition, debug = False): + def GetTransitionBodyType(self, pou_name, pou_transition, debug=False): project = self.GetProject(debug) if project is not None: # Found the pou correponding to name @@ -1214,7 +1270,7 @@ return None # Return the actions of a pou - def GetPouActions(self, pou_name, debug = False): + def GetPouActions(self, pou_name, debug=False): actions = [] project = self.GetProject(debug) if project is not None: @@ -1226,7 +1282,7 @@ return actions # Return the body language of the pou given by its name - def GetActionBodyType(self, pou_name, pou_action, debug = False): + def GetActionBodyType(self, pou_name, pou_action, debug=False): project = self.GetProject(debug) if project is not None: # Found the pou correponding to name and return its body language @@ -1332,17 +1388,17 @@ etree.parse( os.path.join(ScriptDirectory, "plcopen", "variables_infos.xslt"), parser), - extensions = {("var_infos_ns", name): getattr(factory, name) - for name in ["SetType", "AddDimension", "AddTree", - "AddVarToTree", "AddVariable"]}) - variables_infos_xslt_tree(object_with_vars, - tree=etree.XSLT.strparam(str(tree))) + extensions={("var_infos_ns", name): getattr(factory, name) + for name in ["SetType", "AddDimension", "AddTree", + "AddVarToTree", "AddVariable"]}) + variables_infos_xslt_tree( + object_with_vars, tree=etree.XSLT.strparam(str(tree))) return variables # Add a global var to configuration to configuration def AddConfigurationGlobalVar(self, config_name, var_type, var_name, - location="", description=""): + location="", description=""): if self.Project is not None: # Found the configuration corresponding to name configuration = self.Project.getconfiguration(config_name) @@ -1364,7 +1420,7 @@ in self.ExtractVarLists(vars)]) # Return the configuration globalvars - def GetConfigurationGlobalVars(self, name, debug = False): + def GetConfigurationGlobalVars(self, name, debug=False): project = self.GetProject(debug) if project is not None: # Found the configuration corresponding to name @@ -1376,7 +1432,7 @@ return [] # Return configuration variable names - def GetConfigurationVariableNames(self, config_name = None, debug = False): + def GetConfigurationVariableNames(self, config_name=None, debug=False): variables = [] project = self.GetProject(debug) if project is not None: @@ -1384,7 +1440,8 @@ if config_name is None or config_name == configuration.getname(): variables.extend( [var.getname() for var in reduce( - lambda x, y: x + y, [varlist.getvariable() + lambda x, y: x + y, [ + varlist.getvariable() for varlist in configuration.globalVars], [])]) return variables @@ -1401,7 +1458,7 @@ in self.ExtractVarLists(vars)]) # Return the resource globalvars - def GetConfigurationResourceGlobalVars(self, config_name, name, debug = False): + def GetConfigurationResourceGlobalVars(self, config_name, name, debug=False): project = self.GetProject(debug) if project is not None: # Found the resource corresponding to name @@ -1413,8 +1470,8 @@ return [] # Return resource variable names - def GetConfigurationResourceVariableNames(self, - config_name = None, resource_name = None, debug = False): + def GetConfigurationResourceVariableNames( + self, config_name=None, resource_name=None, debug=False): variables = [] project = self.GetProject(debug) if project is not None: @@ -1424,13 +1481,14 @@ if resource_name is None or resource.getname() == resource_name: variables.extend( [var.getname() for var in reduce( - lambda x, y: x + y, [varlist.getvariable() + lambda x, y: x + y, [ + varlist.getvariable() for varlist in resource.globalVars], [])]) return variables # Return the interface for the given pou - def GetPouInterfaceVars(self, pou, tree=False, debug = False): + def GetPouInterfaceVars(self, pou, tree=False, debug=False): interface = pou.interface # Verify that the pou has an interface if interface is not None: @@ -1497,11 +1555,11 @@ etree.parse( os.path.join(ScriptDirectory, "plcopen", "variables_infos.xslt"), parser), - extensions = {("var_infos_ns", name): getattr(factory, name) - for name in ["SetType", "AddDimension", - "AddTree", "AddVarToTree"]}) - return_type_infos_xslt_tree(return_type, - tree=etree.XSLT.strparam(str(tree))) + extensions={("var_infos_ns", name): getattr(factory, name) + for name in ["SetType", "AddDimension", + "AddTree", "AddVarToTree"]}) + return_type_infos_xslt_tree( + return_type, tree=etree.XSLT.strparam(str(tree))) if tree: return [factory.GetType(), factory.GetTree()] return factory.GetType() @@ -1516,11 +1574,11 @@ addedcat = [{"name": _("%s POUs") % confnodetypes["name"], "list": [pou.getblockInfos() for pou in confnodetypes["types"].getpous()]} - for confnodetypes in typeslist] + for confnodetypes in typeslist] self.TotalTypes.extend(addedcat) for cat in addedcat: for desc in cat["list"]: - BlkLst = self.TotalTypesDict.setdefault(desc["name"],[]) + BlkLst = self.TotalTypesDict.setdefault(desc["name"], []) BlkLst.append((section["name"], desc)) # Function that clear the confnode list @@ -1529,7 +1587,7 @@ self.TotalTypesDict = StdBlckDct.copy() self.TotalTypes = StdBlckLst[:] - def GetConfNodeDataTypes(self, exclude = None, only_locatables = False): + def GetConfNodeDataTypes(self, exclude=None, only_locatables=False): return [{"name": _("%s Data Types") % confnodetypes["name"], "list": [ datatype.getname() @@ -1570,9 +1628,9 @@ return global_vars # Function that returns the block definition associated to the block type given - def GetBlockType(self, typename, inputs = None, debug = False): + def GetBlockType(self, typename, inputs=None, debug=False): result_blocktype = None - for sectioname, blocktype in self.TotalTypesDict.get(typename,[]): + for sectioname, blocktype in self.TotalTypesDict.get(typename, []): if inputs is not None and inputs != "undefined": block_inputs = tuple([var_type for name, var_type, modifier in blocktype["inputs"]]) if reduce(lambda x, y: x and y, map(lambda x: x[0] == "ANY" or self.IsOfType(*x), zip(inputs, block_inputs)), True): @@ -1597,20 +1655,20 @@ return blocktype_infos if inputs == tuple([var_type - for name, var_type, modifier in blocktype_infos["inputs"]]): + for name, var_type, modifier in blocktype_infos["inputs"]]): return blocktype_infos return None # Return Block types checking for recursion - def GetBlockTypes(self, tagname = "", debug = False): + def GetBlockTypes(self, tagname="", debug=False): typename = None words = tagname.split("::") name = None project = self.GetProject(debug) if project is not None: pou_type = None - if words[0] in ["P","T","A"]: + if words[0] in ["P", "T", "A"]: name = words[1] pou_type = self.GetPouType(name, debug) filter = (["function"] @@ -1621,35 +1679,38 @@ "list": [block for block in category["list"] if block["type"] in filter]} for category in self.TotalTypes] - blocktypes.append({"name" : USER_DEFINED_POUS, + blocktypes.append({ + "name": USER_DEFINED_POUS, "list": [pou.getblockInfos() for pou in project.getpous(name, filter) if (name is None or - len(self.GetInstanceList(pou, name, debug)) == 0)]}) + len(self.GetInstanceList(pou, name, debug)) == 0)] + }) return blocktypes return self.TotalTypes # Return Function Block types checking for recursion - def GetFunctionBlockTypes(self, tagname = "", debug = False): + def GetFunctionBlockTypes(self, tagname="", debug=False): project = self.GetProject(debug) words = tagname.split("::") name = None - if project is not None and words[0] in ["P","T","A"]: + if project is not None and words[0] in ["P", "T", "A"]: name = words[1] blocktypes = [] for blocks in self.TotalTypesDict.itervalues(): - for sectioname,block in blocks: + for sectioname, block in blocks: if block["type"] == "functionBlock": blocktypes.append(block["name"]) if project is not None: - blocktypes.extend([pou.getname() + blocktypes.extend([ + pou.getname() for pou in project.getpous(name, ["functionBlock"]) if (name is None or len(self.GetInstanceList(pou, name, debug)) == 0)]) return blocktypes # Return Block types checking for recursion - def GetBlockResource(self, debug = False): + def GetBlockResource(self, debug=False): blocktypes = [] for category in StdBlckLst[:-1]: for blocktype in category["list"]: @@ -1663,7 +1724,7 @@ return blocktypes # Return Data Types checking for recursion - def GetDataTypes(self, tagname = "", basetypes = True, confnodetypes = True, only_locatables = False, debug = False): + def GetDataTypes(self, tagname="", basetypes=True, confnodetypes=True, only_locatables=False, debug=False): if basetypes: datatypes = self.GetBaseTypes() else: @@ -1677,16 +1738,16 @@ datatypes.extend([ datatype.getname() for datatype in project.getdataTypes(name) - if (not only_locatables or self.IsLocatableDataType(datatype, debug)) + if ((not only_locatables or self.IsLocatableDataType(datatype, debug)) and (name is None or - len(self.GetInstanceList(datatype, name, debug)) == 0)]) + len(self.GetInstanceList(datatype, name, debug)) == 0))]) if confnodetypes: for category in self.GetConfNodeDataTypes(name, only_locatables): datatypes.extend(category["list"]) return datatypes # Return Data Type Object - def GetPou(self, typename, debug = False): + def GetPou(self, typename, debug=False): project = self.GetProject(debug) if project is not None: result = project.getpou(typename) @@ -1702,9 +1763,8 @@ return result return None - # Return Data Type Object - def GetDataType(self, typename, debug = False): + def GetDataType(self, typename, debug=False): project = self.GetProject(debug) if project is not None: result = project.getdataType(typename) @@ -1730,8 +1790,8 @@ return None # Return Base Type of given possible derived type - def GetBaseType(self, typename, debug = False): - if TypeHierarchy.has_key(typename): + def GetBaseType(self, typename, debug=False): + if typename in TypeHierarchy: return typename datatype = self.GetDataType(typename, debug) @@ -1749,9 +1809,9 @@ TypeHierarchy_list has a rough order to it (e.g. SINT, INT, DINT, ...), which makes it easy for a user to find a type in a menu. ''' - return [x for x,y in TypeHierarchy_list if not x.startswith("ANY")] - - def IsOfType(self, typename, reference, debug = False): + return [x for x, y in TypeHierarchy_list if not x.startswith("ANY")] + + def IsOfType(self, typename, reference, debug=False): if reference is None or typename == reference: return True @@ -1772,7 +1832,7 @@ return not typename.startswith("ANY") return True - def IsLocatableDataType(self, datatype, debug = False): + def IsLocatableDataType(self, datatype, debug=False): basetype_content = datatype.baseType.getcontent() basetype_content_type = basetype_content.getLocalTag() if basetype_content_type in ["enum", "struct"]: @@ -1785,20 +1845,20 @@ return self.IsLocatableType(array_base_type.getname(), debug) return True - def IsLocatableType(self, typename, debug = False): + def IsLocatableType(self, typename, debug=False): if isinstance(typename, TupleType) or self.GetBlockType(typename) is not None: return False # the size of these types is implementation dependend if typename in ["TIME", "DATE", "DT", "TOD"]: return False - + datatype = self.GetDataType(typename, debug) if datatype is not None: return self.IsLocatableDataType(datatype) return True - def IsEnumeratedType(self, typename, debug = False): + def IsEnumeratedType(self, typename, debug=False): if isinstance(typename, TupleType): typename = typename[1] datatype = self.GetDataType(typename, debug) @@ -1810,7 +1870,7 @@ return basetype_content_type == "enum" return False - def IsSubrangeType(self, typename, exclude=None, debug = False): + def IsSubrangeType(self, typename, exclude=None, debug=False): if typename == exclude: return False if isinstance(typename, TupleType): @@ -1826,11 +1886,11 @@ self.GetDataTypeBaseType(datatype), exclude) return False - def IsNumType(self, typename, debug = False): + def IsNumType(self, typename, debug=False): return self.IsOfType(typename, "ANY_NUM", debug) or\ self.IsOfType(typename, "ANY_BIT", debug) - def GetDataTypeRange(self, typename, debug = False): + def GetDataTypeRange(self, typename, debug=False): range = DataTypeRange.get(typename) if range is not None: return range @@ -1846,7 +1906,7 @@ return None # Return Subrange types - def GetSubrangeBaseTypes(self, exclude, debug = False): + def GetSubrangeBaseTypes(self, exclude, debug=False): subrange_basetypes = DataTypeRange.keys() project = self.GetProject(debug) if project is not None: @@ -1860,7 +1920,7 @@ return subrange_basetypes # Return Enumerated Values - def GetEnumeratedDataValues(self, typename = None, debug = False): + def GetEnumeratedDataValues(self, typename=None, debug=False): values = [] if typename is not None: datatype_obj = self.GetDataType(typename, debug) @@ -1882,9 +1942,9 @@ values.extend(confnodetype["types"].GetEnumeratedDataTypeValues()) return values -#------------------------------------------------------------------------------- -# Project Element tag name computation functions -#------------------------------------------------------------------------------- + # ------------------------------------------------------------------------------- + # Project Element tag name computation functions + # ------------------------------------------------------------------------------- # Compute a data type name def ComputeDataTypeName(self, datatype): @@ -1912,16 +1972,21 @@ def GetElementType(self, tagname): words = tagname.split("::") - return {"D" : ITEM_DATATYPE, "P" : ITEM_POU, - "T" : ITEM_TRANSITION, "A" : ITEM_ACTION, - "C" : ITEM_CONFIGURATION, "R" : ITEM_RESOURCE}[words[0]] - -#------------------------------------------------------------------------------- -# Project opened Data types management functions -#------------------------------------------------------------------------------- + return { + "D": ITEM_DATATYPE, + "P": ITEM_POU, + "T": ITEM_TRANSITION, + "A": ITEM_ACTION, + "C": ITEM_CONFIGURATION, + "R": ITEM_RESOURCE + }[words[0]] + + # ------------------------------------------------------------------------------- + # Project opened Data types management functions + # ------------------------------------------------------------------------------- # Return the data type informations - def GetDataTypeInfos(self, tagname, debug = False): + def GetDataTypeInfos(self, tagname, debug=False): project = self.GetProject(debug) if project is not None: words = tagname.split("::") @@ -1939,8 +2004,8 @@ base_type = basetype_content.baseType.getcontent() base_type_type = base_type.getLocalTag() infos["base_type"] = (base_type.getname() - if base_type_type == "derived" - else base_type_type) + if base_type_type == "derived" + else base_type_type) elif basetype_content_type == "enum": infos["type"] = "Enumerated" infos["values"] = [] @@ -1954,8 +2019,8 @@ base_type = basetype_content.baseType.getcontent() base_type_type = base_type.getLocalTag() infos["base_type"] = (base_type.getname() - if base_type_type == "derived" - else base_type_type.upper()) + if base_type_type == "derived" + else base_type_type.upper()) elif basetype_content_type == "struct": infos["type"] = "Structure" infos["elements"] = [] @@ -1971,9 +2036,10 @@ base_type = element_type.baseType.getcontent() base_type_type = base_type.getLocalTag() element_infos["Type"] = ("array", - base_type.getname() - if base_type_type == "derived" - else base_type_type.upper(), dimensions) + base_type.getname() + if base_type_type == "derived" + else base_type_type.upper(), + dimensions) elif element_type_type == "derived": element_infos["Type"] = element_type.getname() else: @@ -1986,8 +2052,8 @@ else: infos["type"] = "Directly" infos["base_type"] = (basetype_content.getname() - if basetype_content_type == "derived" - else basetype_content_type.upper()) + if basetype_content_type == "derived" + else basetype_content_type.upper()) if datatype.initialValue is not None: infos["initial"] = datatype.initialValue.getvalue() @@ -2116,12 +2182,12 @@ datatype.initialValue = None self.BufferProject() -#------------------------------------------------------------------------------- -# Project opened Pous management functions -#------------------------------------------------------------------------------- + # ------------------------------------------------------------------------------- + # Project opened Pous management functions + # ------------------------------------------------------------------------------- # Return edited element - def GetEditedElement(self, tagname, debug = False): + def GetEditedElement(self, tagname, debug=False): project = self.GetProject(debug) if project is not None: words = tagname.split("::") @@ -2145,21 +2211,21 @@ # Return edited element name def GetEditedElementName(self, tagname): words = tagname.split("::") - if words[0] in ["P","C","D"]: + if words[0] in ["P", "C", "D"]: return words[1] else: return words[2] return None # Return edited element name and type - def GetEditedElementType(self, tagname, debug = False): + def GetEditedElementType(self, tagname, debug=False): words = tagname.split("::") - if words[0] in ["P","T","A"]: + if words[0] in ["P", "T", "A"]: return words[1], self.GetPouType(words[1], debug) return None, None # Return language in which edited element is written - def GetEditedElementBodyType(self, tagname, debug = False): + def GetEditedElementBodyType(self, tagname, debug=False): words = tagname.split("::") if words[0] == "P": return self.GetPouBodyType(words[1], debug) @@ -2170,9 +2236,9 @@ return None # Return the edited element variables - def GetEditedElementInterfaceVars(self, tagname, tree=False, debug = False): + def GetEditedElementInterfaceVars(self, tagname, tree=False, debug=False): words = tagname.split("::") - if words[0] in ["P","T","A"]: + if words[0] in ["P", "T", "A"]: project = self.GetProject(debug) if project is not None: pou = project.getpou(words[1]) @@ -2181,7 +2247,7 @@ return [] # Return the edited element return type - def GetEditedElementInterfaceReturnType(self, tagname, tree=False, debug = False): + def GetEditedElementInterfaceReturnType(self, tagname, tree=False, debug=False): words = tagname.split("::") if words[0] == "P": project = self.GetProject(debug) @@ -2201,14 +2267,14 @@ element.settext(text) # Return the edited element text - def GetEditedElementText(self, tagname, debug = False): + def GetEditedElementText(self, tagname, debug=False): element = self.GetEditedElement(tagname, debug) if element is not None: return element.gettext() return "" # Return the edited element transitions - def GetEditedElementTransitions(self, tagname, debug = False): + def GetEditedElementTransitions(self, tagname, debug=False): pou = self.GetEditedElement(tagname, debug) if pou is not None and pou.getbodyType() == "SFC": transitions = [] @@ -2218,7 +2284,7 @@ return [] # Return edited element transitions - def GetEditedElementActions(self, tagname, debug = False): + def GetEditedElementActions(self, tagname, debug=False): pou = self.GetEditedElement(tagname, debug) if pou is not None and pou.getbodyType() == "SFC": actions = [] @@ -2228,9 +2294,9 @@ return [] # Return the names of the pou elements - def GetEditedElementVariables(self, tagname, debug = False): + def GetEditedElementVariables(self, tagname, debug=False): words = tagname.split("::") - if words[0] in ["P","T","A"]: + if words[0] in ["P", "T", "A"]: return self.GetProjectPouVariableNames(words[1], debug) elif words[0] in ["C", "R"]: names = self.GetConfigurationVariableNames(words[1], debug) @@ -2240,13 +2306,13 @@ return names return [] - def GetEditedElementCopy(self, tagname, debug = False): + def GetEditedElementCopy(self, tagname, debug=False): element = self.GetEditedElement(tagname, debug) if element is not None: return element.tostring() return "" - def GetEditedElementInstancesCopy(self, tagname, blocks_id = None, wires = None, debug = False): + def GetEditedElementInstancesCopy(self, tagname, blocks_id=None, wires=None, debug=False): element = self.GetEditedElement(tagname, debug) text = "" if element is not None: @@ -2273,14 +2339,15 @@ names.update(dict([(varname.upper(), True) for varname in self.GetEditedElementVariables(tagname, debug)])) words = tagname.split("::") - if words[0] in ["P","T","A"]: + if words[0] in ["P", "T", "A"]: element = self.GetEditedElement(tagname, debug) if element is not None and element.getbodyType() not in ["ST", "IL"]: for instance in element.getinstances(): - if isinstance(instance, - (PLCOpenParser.GetElementClass("step", "sfcObjects"), - PLCOpenParser.GetElementClass("connector", "commonObjects"), - PLCOpenParser.GetElementClass("continuation", "commonObjects"))): + if isinstance( + instance, + (PLCOpenParser.GetElementClass("step", "sfcObjects"), + PLCOpenParser.GetElementClass("connector", "commonObjects"), + PLCOpenParser.GetElementClass("continuation", "commonObjects"))): names[instance.getname().upper()] = True else: project = self.GetProject(debug) @@ -2302,7 +2369,7 @@ i = start_idx while name is None or names.get(name.upper(), False): - name = (format%i) + name = (format % i) i += 1 return name @@ -2325,7 +2392,7 @@ try: instances, error = LoadPouInstances(text, bodytype) - except: + except Exception: instances, error = [], "" if error is not None or len(instances) == 0: return _("Invalid plcopen element(s)!!!") @@ -2340,10 +2407,10 @@ blockname = instance.getinstanceName() if blocktype_infos["type"] != "function" and blockname is not None: if element_type == "function": - return _("FunctionBlock \"%s\" can't be pasted in a Function!!!")%blocktype + return _("FunctionBlock \"%s\" can't be pasted in a Function!!!") % blocktype blockname = self.GenerateNewName(tagname, blockname, - "%s%%d"%blocktype, + "%s%%d" % blocktype, debug=debug) exclude[blockname] = True instance.setinstanceName(blockname) @@ -2357,7 +2424,7 @@ exclude[stepname] = True instance.setname(stepname) localid = instance.getlocalId() - if not used_id.has_key(localid): + if localid not in used_id: new_id[localid] = True idx = 1 @@ -2366,8 +2433,8 @@ for instance in instances: localId = instance.getlocalId() bbox.union(instance.getBoundingBox()) - if used_id.has_key(localId): - while used_id.has_key(idx) or new_id.has_key(idx): + if localId in used_id: + while (idx in used_id) or (idx in new_id): idx += 1 new_id[idx] = True instance.setlocalId(idx) @@ -2404,7 +2471,7 @@ return new_id, connections - def GetEditedElementInstancesInfos(self, tagname, debug = False): + def GetEditedElementInstancesInfos(self, tagname, debug=False): element_instances = OrderedDict() element = self.GetEditedElement(tagname, debug) if element is not None: @@ -2412,7 +2479,7 @@ pou_block_instances_xslt_tree = etree.XSLT( pou_block_instances_xslt, - extensions = { + extensions={ ("pou_block_instances_ns", name): getattr(factory, name) for name in ["AddBlockInstance", "SetSpecificValues", "AddInstanceConnection", "AddConnectionLink", @@ -2440,7 +2507,7 @@ result = wire.GetConnectedInfos(-1) else: result = wire.GetConnectedInfos(0) - if result != None: + if result is not None: refLocalId, formalParameter = result connections = connection.getconnections() if connections is None or len(connection.getconnections()) <= idx: @@ -2465,7 +2532,7 @@ var_type_obj.setcontent(derived_type) return var_type_obj - def AddEditedElementPouVar(self, tagname, var_type, name,**args): + def AddEditedElementPouVar(self, tagname, var_type, name, **args): if self.Project is not None: words = tagname.split("::") if words[0] in ['P', 'T', 'A']: @@ -2500,7 +2567,7 @@ if pou is not None: pou.removepouVar(type, name) - def AddEditedElementBlock(self, tagname, id, blocktype, blockname = None): + def AddEditedElementBlock(self, tagname, id, blocktype, blockname=None): element = self.GetEditedElement(tagname) if element is not None: block = PLCOpenParser.CreateElement("block", "fbdObjects") @@ -3053,7 +3120,7 @@ self.RemoveEditedElementPouVar(tagname, instance.gettypeName(), instance.getinstanceName()) element.removeinstance(id) - def GetEditedResourceVariables(self, tagname, debug = False): + def GetEditedResourceVariables(self, tagname, debug=False): varlist = [] words = tagname.split("::") for var in self.GetConfigurationGlobalVars(words[1], debug): @@ -3076,17 +3143,17 @@ new_task.setname(task["Name"]) if task["Triggering"] == "Interrupt": new_task.setsingle(task["Single"]) -## result = duration_model.match(task["Interval"]).groups() -## if reduce(lambda x, y: x or y != None, result): -## values = [] -## for value in result[:-1]: -## if value != None: -## values.append(int(value)) -## else: -## values.append(0) -## if result[-1] is not None: -## values.append(int(float(result[-1]) * 1000)) -## new_task.setinterval(datetime.time(*values)) +# result = duration_model.match(task["Interval"]).groups() +# if reduce(lambda x, y: x or y != None, result): +# values = [] +# for value in result[:-1]: +# if value != None: +# values.append(int(value)) +# else: +# values.append(0) +# if result[-1] is not None: +# values.append(int(float(result[-1]) * 1000)) +# new_task.setinterval(datetime.time(*values)) if task["Triggering"] == "Cyclic": new_task.setinterval(task["Interval"]) new_task.setpriority(int(task["Priority"])) @@ -3103,7 +3170,7 @@ new_instance.setname(instance["Name"]) new_instance.settypeName(instance["Type"]) - def GetEditedResourceInfos(self, tagname, debug = False): + def GetEditedResourceInfos(self, tagname, debug=False): resource = self.GetEditedElement(tagname, debug) if resource is not None: tasks = resource.gettask() @@ -3120,19 +3187,19 @@ new_task["Single"] = "" interval = task.getinterval() if interval is not None: -## text = "" -## if interval.hour != 0: -## text += "%dh"%interval.hour -## if interval.minute != 0: -## text += "%dm"%interval.minute -## if interval.second != 0: -## text += "%ds"%interval.second -## if interval.microsecond != 0: -## if interval.microsecond % 1000 != 0: -## text += "%.3fms"%(float(interval.microsecond) / 1000) -## else: -## text += "%dms"%(interval.microsecond / 1000) -## new_task["Interval"] = text + # text = "" + # if interval.hour != 0: + # text += "%dh"%interval.hour + # if interval.minute != 0: + # text += "%dm"%interval.minute + # if interval.second != 0: + # text += "%ds"%interval.second + # if interval.microsecond != 0: + # if interval.microsecond % 1000 != 0: + # text += "%.3fms"%(float(interval.microsecond) / 1000) + # else: + # text += "%dms"%(interval.microsecond / 1000) + # new_task["Interval"] = text new_task["Interval"] = interval else: new_task["Interval"] = "" @@ -3172,7 +3239,7 @@ self.CurrentElementEditing = None return error - def SaveXMLFile(self, filepath = None): + def SaveXMLFile(self, filepath=None): if not filepath and self.FilePath == "": return False else: @@ -3189,9 +3256,9 @@ self.SetFilePath(filepath) return True -#------------------------------------------------------------------------------- -# Search in Current Project Functions -#------------------------------------------------------------------------------- + # ------------------------------------------------------------------------------- + # Search in Current Project Functions + # ------------------------------------------------------------------------------- def SearchInProject(self, criteria): return self.Project.Search(criteria) @@ -3209,14 +3276,12 @@ return search_results return [] -#------------------------------------------------------------------------------- -# Current Buffering Management Functions -#------------------------------------------------------------------------------- - - """ - Return a copy of the project - """ + # ------------------------------------------------------------------------------- + # Current Buffering Management Functions + # ------------------------------------------------------------------------------- + def Copy(self, model): + """Return a copy of the project""" return deepcopy(model) def CreateProjectBuffer(self, saved):