PLCControler.py
changeset 249 d8425712acef
parent 236 9f594b90bb1a
child 252 166ee9d2e233
equal deleted inserted replaced
248:f7df265edd54 249:d8425712acef
    35 from PLCGenerator import *
    35 from PLCGenerator import *
    36 
    36 
    37 duration_model = re.compile("(?:([0-9]{1,2})h)?(?:([0-9]{1,2})m(?!s))?(?:([0-9]{1,2})s)?(?:([0-9]{1,3}(?:\.[0-9]*)?)ms)?")
    37 duration_model = re.compile("(?:([0-9]{1,2})h)?(?:([0-9]{1,2})m(?!s))?(?:([0-9]{1,2})s)?(?:([0-9]{1,3}(?:\.[0-9]*)?)ms)?")
    38 
    38 
    39 ITEMS_EDITABLE = [ITEM_PROJECT,
    39 ITEMS_EDITABLE = [ITEM_PROJECT,
    40                     ITEM_POU,
    40                   ITEM_POU,
    41                     ITEM_VARIABLE,
    41                   ITEM_VARIABLE,
    42                     ITEM_TRANSITION,
    42                   ITEM_TRANSITION,
    43                     ITEM_ACTION,
    43                   ITEM_ACTION,
    44                     ITEM_CONFIGURATION,
    44                   ITEM_CONFIGURATION,
    45                     ITEM_RESOURCE,
    45                   ITEM_RESOURCE,
    46                     ITEM_DATATYPE] = range(8)
    46                   ITEM_DATATYPE
    47 
    47                  ] = range(8)
    48 ITEMS_UNEDITABLE=[ITEM_DATATYPES,
    48 
    49                   ITEM_FUNCTION,
    49 ITEMS_UNEDITABLE = [ITEM_DATATYPES,
    50                   ITEM_FUNCTIONBLOCK,
    50                     ITEM_FUNCTION,
    51                   ITEM_PROGRAM,
    51                     ITEM_FUNCTIONBLOCK,
    52                   ITEM_VAR_LOCAL,
    52                     ITEM_PROGRAM,
       
    53                     ITEM_TRANSITIONS,
       
    54                     ITEM_ACTIONS,
       
    55                     ITEM_CONFIGURATIONS,
       
    56                     ITEM_RESOURCES,
       
    57                     ITEM_PROPERTIES
       
    58                    ] = range(8, 17)
       
    59  
       
    60 ITEMS_VARIABLE = [ITEM_VAR_LOCAL,
    53                   ITEM_VAR_GLOBAL,
    61                   ITEM_VAR_GLOBAL,
    54                   ITEM_VAR_EXTERNAL,
    62                   ITEM_VAR_EXTERNAL,
    55                   ITEM_VAR_TEMP,
    63                   ITEM_VAR_TEMP,
    56                   ITEM_VAR_INPUT,
    64                   ITEM_VAR_INPUT,
    57                   ITEM_VAR_OUTPUT,
    65                   ITEM_VAR_OUTPUT,
    58                   ITEM_VAR_INOUT,
    66                   ITEM_VAR_INOUT
    59                   ITEM_TRANSITIONS,
    67                  ] = range(17, 24)
    60                   ITEM_ACTIONS,
       
    61                   ITEM_CONFIGURATIONS,
       
    62                   ITEM_RESOURCES,
       
    63                   ITEM_PROPERTIES,
       
    64                   ]=range(9,25)
       
    65 
    68 
    66 VAR_CLASS_INFOS = {"Local" :    (plcopen.interface_localVars,    ITEM_VAR_LOCAL),
    69 VAR_CLASS_INFOS = {"Local" :    (plcopen.interface_localVars,    ITEM_VAR_LOCAL),
    67                    "Global" :   (plcopen.interface_globalVars,   ITEM_VAR_GLOBAL),
    70                    "Global" :   (plcopen.interface_globalVars,   ITEM_VAR_GLOBAL),
    68                    "External" : (plcopen.interface_externalVars, ITEM_VAR_EXTERNAL),
    71                    "External" : (plcopen.interface_externalVars, ITEM_VAR_EXTERNAL),
    69                    "Temp" :     (plcopen.interface_tempVars,     ITEM_VAR_TEMP),
    72                    "Temp" :     (plcopen.interface_tempVars,     ITEM_VAR_TEMP),
   177         self.ProjectBuffer = None
   180         self.ProjectBuffer = None
   178         self.Buffering = False
   181         self.Buffering = False
   179         self.FilePath = ""
   182         self.FilePath = ""
   180         self.FileName = ""
   183         self.FileName = ""
   181         self.ProgramChunks = []
   184         self.ProgramChunks = []
       
   185         self.CurrentCompiledProject = None
   182         self.PluginTypes = []
   186         self.PluginTypes = []
   183         self.ProgramFilePath = ""
   187         self.ProgramFilePath = ""
   184         
   188         
   185     def GetQualifierTypes(self):
   189     def GetQualifierTypes(self):
   186         return plcopen.QualifierList
   190         return plcopen.QualifierList
   187 
   191 
       
   192     def GetProject(self, debug = False):
       
   193         if debug and self.CurrentCompiledProject is not None:
       
   194             return self.CurrentCompiledProject
       
   195         else:
       
   196             return self.Project
       
   197 
   188 #-------------------------------------------------------------------------------
   198 #-------------------------------------------------------------------------------
   189 #                         Project management functions
   199 #                         Project management functions
   190 #-------------------------------------------------------------------------------
   200 #-------------------------------------------------------------------------------
   191 
   201 
   192     # Return if a project is opened
   202     # Return if a project is opened
   193     def HasOpenedProject(self):
   203     def HasOpenedProject(self):
   194         return self.Project != None
   204         return self.Project is not None
   195 
   205 
   196     # Create a new project by replacing the current one
   206     # Create a new project by replacing the current one
   197     def CreateNewProject(self, properties):
   207     def CreateNewProject(self, properties):
   198         # Create the project
   208         # Create the project
   199         self.Project = plcopen.project()
   209         self.Project = plcopen.project()
   201         self.Project.setfileHeader(properties)
   211         self.Project.setfileHeader(properties)
   202         self.Project.setcontentHeader(properties)
   212         self.Project.setcontentHeader(properties)
   203         self.SetFilePath("")
   213         self.SetFilePath("")
   204         # Initialize the project buffer
   214         # Initialize the project buffer
   205         self.ProjectBuffer = UndoBuffer(self.Copy(self.Project), False)
   215         self.ProjectBuffer = UndoBuffer(self.Copy(self.Project), False)
       
   216         self.ProgramChunks = []
       
   217         self.CurrentCompiledProject = None
   206         self.Buffering = False
   218         self.Buffering = False
   207     
   219     
   208     # Return project data type names
   220     # Return project data type names
   209     def GetProjectDataTypeNames(self):
   221     def GetProjectDataTypeNames(self, debug = False):
   210         if self.Project:
   222         project = self.GetProject(debug)
   211             return [datatype.getname() for datatype in self.Project.getdataTypes()]
   223         if project is not None:
       
   224             return [datatype.getname() for datatype in project.getdataTypes()]
   212         return []
   225         return []
   213     
   226     
   214     # Return project pou names
   227     # Return project pou names
   215     def GetProjectPouNames(self):
   228     def GetProjectPouNames(self, debug = False):
   216         if self.Project:
   229         project = self.GetProject(debug)
   217             return [pou.getname() for pou in self.Project.getpous()]
   230         if project is not None:
       
   231             return [pou.getname() for pou in project.getpous()]
   218         return []
   232         return []
   219     
   233     
   220     # Return project pou names
   234     # Return project pou names
   221     def GetProjectConfigNames(self):
   235     def GetProjectConfigNames(self, debug = False):
   222         if self.Project:
   236         project = self.GetProject(debug)
   223             return [config.getName() for config in self.Project.getconfigurations()]
   237         if project is not None:
       
   238             return [config.getName() for config in project.getconfigurations()]
   224         return []
   239         return []
   225     
   240     
   226     # Return project pou variables
   241     # Return project pou variables
   227     def GetProjectPouVariables(self, pou_name=None):
   242     def GetProjectPouVariables(self, pou_name = None, debug = False):
   228         variables = []
   243         variables = []
   229         for pou in self.Project.getpous():
   244         project = self.GetProject(debug)
   230             if not pou_name or pou_name == pou.getname():
   245         if project is not None:
   231                 variables.extend([var["Name"] for var in self.GetPouInterfaceVars(pou)])
   246             for pou in project.getpous():
   232                 for transition in pou.gettransitionList():
   247                 if pou_name is None or pou_name == pou.getname():
   233                     variables.append(transition.getname())
   248                     variables.extend([var["Name"] for var in self.GetPouInterfaceVars(pou)])
   234                 for action in pou.getactionList():
   249                     for transition in pou.gettransitionList():
   235                     variables.append(action.getname())
   250                         variables.append(transition.getname())
       
   251                     for action in pou.getactionList():
       
   252                         variables.append(action.getname())
   236         return variables
   253         return variables
   237     
       
   238     # Return if project is saved
       
   239     def ProjectIsSaved(self):
       
   240         return self.ProjectBuffer.IsCurrentSaved()
       
   241     
   254     
   242     # Return file path if project is an open file
   255     # Return file path if project is an open file
   243     def GetFilePath(self):
   256     def GetFilePath(self):
   244         return self.FilePath
   257         return self.FilePath
   245     
   258     
   247     def GetProgramFilePath(self):
   260     def GetProgramFilePath(self):
   248         return self.ProgramFilePath
   261         return self.ProgramFilePath
   249     
   262     
   250     # Return file name and point out if file is up to date
   263     # Return file name and point out if file is up to date
   251     def GetFilename(self):
   264     def GetFilename(self):
   252         if self.ProjectBuffer.IsCurrentSaved():
   265         if self.Project is not None:
   253             return self.FileName
   266             if self.ProjectBuffer.IsCurrentSaved():
   254         else:
   267                 return self.FileName
   255             return "~%s~"%self.FileName
   268             else:
       
   269                 return "~%s~"%self.FileName
       
   270         return ""
   256     
   271     
   257     # Change file path and save file name or create a default one if file path not defined
   272     # Change file path and save file name or create a default one if file path not defined
   258     def SetFilePath(self, filepath):
   273     def SetFilePath(self, filepath):
   259         self.FilePath = filepath
   274         self.FilePath = filepath
   260         if filepath == "":
   275         if filepath == "":
   263         else:
   278         else:
   264             self.FileName = os.path.splitext(os.path.basename(filepath))[0]
   279             self.FileName = os.path.splitext(os.path.basename(filepath))[0]
   265     
   280     
   266     # Change project properties
   281     # Change project properties
   267     def SetProjectProperties(self, name = None, properties = None):
   282     def SetProjectProperties(self, name = None, properties = None):
   268         if name != None:
   283         if self.Project is not None:
   269             self.Project.setname(name)
   284             if name is not None:
   270         if properties != None:
   285                 self.Project.setname(name)
   271             self.Project.setfileHeader(properties)
   286             if properties is not None:
   272             self.Project.setcontentHeader(properties)
   287                 self.Project.setfileHeader(properties)
   273         if name != None or properties != None:
   288                 self.Project.setcontentHeader(properties)
   274             self.BufferProject()
   289             if name is not None or properties is not None:
       
   290                 self.BufferProject()
   275             
   291             
   276     # Return project properties
   292     # Return project properties
   277     def GetProjectProperties(self):
   293     def GetProjectProperties(self, debug = False):
   278         properties = self.Project.getfileHeader()
   294         project = self.GetProject(debug)
   279         properties.update(self.Project.getcontentHeader())
   295         if project is not None:
   280         return properties
   296             properties = project.getfileHeader()
       
   297             properties.update(project.getcontentHeader())
       
   298             return properties
       
   299         return None
   281     
   300     
   282     # Return project informations
   301     # Return project informations
   283     def GetProjectInfos(self):
   302     def GetProjectInfos(self, debug = False):
   284         if self.Project:
   303         project = self.GetProject(debug)
   285             infos = {"name": self.Project.getname(), "type": ITEM_PROJECT}
   304         if project is not None:
       
   305             infos = {"name": project.getname(), "type": ITEM_PROJECT}
   286             datatypes = {"name": "Data Types", "type": ITEM_DATATYPES, "values":[]}
   306             datatypes = {"name": "Data Types", "type": ITEM_DATATYPES, "values":[]}
   287             for datatype in self.Project.getdataTypes():
   307             for datatype in project.getdataTypes():
   288                 datatypes["values"].append({"name": datatype.getname(), "type": ITEM_DATATYPE, 
   308                 datatypes["values"].append({"name": datatype.getname(), "type": ITEM_DATATYPE, 
   289                     "tagname": self.ComputeDataTypeName(datatype.getname()), "values": []})
   309                     "tagname": self.ComputeDataTypeName(datatype.getname()), "values": []})
   290             pou_types = {"function": {"name": "Functions", "type": ITEM_FUNCTION, "values":[]},
   310             pou_types = {"function": {"name": "Functions", "type": ITEM_FUNCTION, "values":[]},
   291                          "functionBlock": {"name": "Function Blocks", "type": ITEM_FUNCTIONBLOCK, "values":[]},
   311                          "functionBlock": {"name": "Function Blocks", "type": ITEM_FUNCTIONBLOCK, "values":[]},
   292                          "program": {"name": "Programs", "type": ITEM_PROGRAM, "values":[]}}
   312                          "program": {"name": "Programs", "type": ITEM_PROGRAM, "values":[]}}
   293             for pou in self.Project.getpous():
   313             for pou in project.getpous():
   294                 pou_type = pou.getpouType()
   314                 pou_type = pou.getpouType()
   295                 pou_infos = {"name": pou.getname(), "type": ITEM_POU,
   315                 pou_infos = {"name": pou.getname(), "type": ITEM_POU,
   296                              "tagname": self.ComputePouName(pou.getname())}
   316                              "tagname": self.ComputePouName(pou.getname())}
   297                 pou_values = []
   317                 pou_values = []
   298                 if pou.getbodyType() == "SFC":
   318                 if pou.getbodyType() == "SFC":
   310                     pou_values.append({"name": "Actions", "type": ITEM_ACTIONS, "values": actions})
   330                     pou_values.append({"name": "Actions", "type": ITEM_ACTIONS, "values": actions})
   311                 if pou_type in pou_types:
   331                 if pou_type in pou_types:
   312                     pou_infos["values"] = pou_values
   332                     pou_infos["values"] = pou_values
   313                     pou_types[pou_type]["values"].append(pou_infos)
   333                     pou_types[pou_type]["values"].append(pou_infos)
   314             configurations = {"name": "Configurations", "type": ITEM_CONFIGURATIONS, "values": []}
   334             configurations = {"name": "Configurations", "type": ITEM_CONFIGURATIONS, "values": []}
   315             for config in self.Project.getconfigurations():
   335             for config in project.getconfigurations():
   316                 config_name = config.getname()
   336                 config_name = config.getname()
   317                 config_infos = {"name": config_name, "type": ITEM_CONFIGURATION, 
   337                 config_infos = {"name": config_name, "type": ITEM_CONFIGURATION, 
   318                     "tagname": self.ComputeConfigurationName(config.getname()), 
   338                     "tagname": self.ComputeConfigurationName(config.getname()), 
   319                     "values": []}
   339                     "values": []}
   320                 resources = {"name": "Resources", "type": ITEM_RESOURCES, "values": []}
   340                 resources = {"name": "Resources", "type": ITEM_RESOURCES, "values": []}
   331                                pou_types["program"], configurations]
   351                                pou_types["program"], configurations]
   332             return infos
   352             return infos
   333         return None
   353         return None
   334 
   354 
   335     # Return project topology informations
   355     # Return project topology informations
   336     def GetProjectTopology(self):
   356     def GetProjectTopology(self, debug = False):
   337         if self.Project:
   357         project = self.GetProject(debug)
   338             infos = {"name": self.Project.getname(), "type": ITEM_PROJECT, "values" : []}
   358         if project is not None:
   339             for config in self.Project.getconfigurations():
   359             infos = {"name": project.getname(), "type": ITEM_PROJECT, "values" : []}
       
   360             for config in project.getconfigurations():
   340                 config_infos = {"name" : config.getname(), "type": ITEM_CONFIGURATION, "values" : []}
   361                 config_infos = {"name" : config.getname(), "type": ITEM_CONFIGURATION, "values" : []}
   341                 for resource in config.getresource():
   362                 for resource in config.getresource():
   342                     resource_infos = {"name" : resource.getname(), "type": ITEM_RESOURCE, "values": []}
   363                     resource_infos = {"name" : resource.getname(), "type": ITEM_RESOURCE, "values": []}
   343                     for task in resource.gettask():
   364                     for task in resource.gettask():
   344                         for pou in task.getpouInstance():
   365                         for pou in task.getpouInstance():
   345                             instance_infos = self.GetPouTopology(pou.getname(), pou.gettype())
   366                             instance_infos = self.GetPouTopology(pou.getname(), pou.gettype(), debug=debug)
   346                             if instance_infos is not None:
   367                             if instance_infos is not None:
   347                                 resource_infos["values"].append(instance_infos)
   368                                 resource_infos["values"].append(instance_infos)
   348                     for pou in resource.getpouInstance():
   369                     for pou in resource.getpouInstance():
   349                         instance_infos = self.GetPouTopology(pou.getname(), pou.gettype())
   370                         instance_infos = self.GetPouTopology(pou.getname(), pou.gettype(), debug=debug)
   350                         if instance_infos is not None:
   371                         if instance_infos is not None:
   351                             resource_infos["values"].append(instance_infos)
   372                             resource_infos["values"].append(instance_infos)
   352                     for varlist in resource.getglobalVars():
   373                     for varlist in resource.getglobalVars():
   353                         for variable in varlist.getvariable():
   374                         for variable in varlist.getvariable():
   354                             vartype_content = variable.gettype().getcontent()
   375                             vartype_content = variable.gettype().getcontent()
   355                             if vartype_content["name"] == "derived":
   376                             if vartype_content["name"] == "derived":
   356                                 var_infos = self.GetPouTopology(variable.getname(), vartype_content["value"].getname(), True)
   377                                 var_infos = self.GetPouTopology(variable.getname(), vartype_content["value"].getname(), True, debug)
   357                                 if var_infos is not None:
   378                                 if var_infos is not None:
   358                                     resource_infos["values"].append(var_infos)
   379                                     resource_infos["values"].append(var_infos)
   359                             elif vartype_content["name"] in ["string", "wstring"]:
   380                             elif vartype_content["name"] in ["string", "wstring"]:
   360                                 resource_infos["values"].append({"name" : variable.getname(), 
   381                                 resource_infos["values"].append({"name" : variable.getname(), 
   361                                                                  "elmt_type" : vartype_content["name"].upper(),
   382                                                                  "elmt_type" : vartype_content["name"].upper(),
   367                     config_infos["values"].append(resource_infos)
   388                     config_infos["values"].append(resource_infos)
   368                 for varlist in config.getglobalVars():
   389                 for varlist in config.getglobalVars():
   369                     for variable in varlist.getvariable():
   390                     for variable in varlist.getvariable():
   370                         vartype_content = variable.gettype().getcontent()
   391                         vartype_content = variable.gettype().getcontent()
   371                         if vartype_content["name"] == "derived":
   392                         if vartype_content["name"] == "derived":
   372                             var_infos = self.GetPouTopology(variable.getname(), vartype_content["value"].getname(), True)
   393                             var_infos = self.GetPouTopology(variable.getname(), vartype_content["value"].getname(), True, debug)
   373                             if var_infos is not None:
   394                             if var_infos is not None:
   374                                 config_infos["values"].append(var_infos)
   395                                 config_infos["values"].append(var_infos)
   375                         elif vartype_content["name"] in ["string", "wstring"]:
   396                         elif vartype_content["name"] in ["string", "wstring"]:
   376                             config_infos["values"].append({"name" : variable.getname(), 
   397                             config_infos["values"].append({"name" : variable.getname(), 
   377                                                            "elmt_type" : vartype_content["name"].upper(), 
   398                                                            "elmt_type" : vartype_content["name"].upper(), 
   383                 infos["values"].append(config_infos)
   404                 infos["values"].append(config_infos)
   384             return infos
   405             return infos
   385         return None
   406         return None
   386     
   407     
   387     # Return pou topology informations
   408     # Return pou topology informations
   388     def GetPouTopology(self, name, type, global_var=False):
   409     def GetPouTopology(self, name, type, global_var = False, debug = False):
   389         if self.Project:
   410         project = self.GetProject(debug)
   390             pou = self.Project.getpou(type)
   411         if project is not None:
       
   412             pou = project.getpou(type)
   391             if pou is not None:
   413             if pou is not None:
   392                 pou_type = pou.getpouType()
   414                 pou_type = pou.getpouType()
   393                 if pou_type == "function":
   415                 if pou_type == "function":
   394                     return None
   416                     return None
   395                 elif pou_type == "program":
   417                 elif pou_type == "program":
   396                     pou_infos = {"name" : name, "elmt_type" : type, "type" : ITEM_PROGRAM, "values" : []}
   418                     pou_infos = {"name" : name, "elmt_type" : type, "type" : ITEM_PROGRAM, 
       
   419                                  "tagname" : self.ComputePouName(pou.getname()), "values" : []}
   397                 else:
   420                 else:
   398                     pou_infos = {"name" : name, "elmt_type" : type, "type" : ITEM_FUNCTIONBLOCK, "values" : []}
   421                     pou_infos = {"name" : name, "elmt_type" : type, "type" : ITEM_FUNCTIONBLOCK, 
       
   422                                  "tagname" : self.ComputePouName(pou.getname()), "values" : []}
       
   423                 if pou.getbodyType() == "SFC":
       
   424                     for transition in pou.gettransitionList():
       
   425                         pou_infos["values"].append({"name" : transition.getname(), 
       
   426                             "elmt_type" : "TRANSITION", "type" : ITEM_TRANSITION, 
       
   427                             "tagname" : self.ComputePouActionName(pou.getname(), transition.getname()),
       
   428                             "values" : []})
       
   429                     for action in pou.getactionList():
       
   430                         pou_infos["values"].append({"name": action.getname(), 
       
   431                             "elmt_type" : "ACTION", "type": ITEM_ACTION, 
       
   432                             "tagname" : self.ComputePouActionName(pou.getname(), action.getname()),
       
   433                             "values" : []})
   399                 if pou.interface:
   434                 if pou.interface:
   400                     # Extract variables from every varLists
   435                     # Extract variables from every varLists
   401                     for type, varlist in pou.getvars():
   436                     for type, varlist in pou.getvars():
   402                         infos = VAR_CLASS_INFOS.get(type, None)
   437                         infos = VAR_CLASS_INFOS.get(type, None)
   403                         if infos is not None:
   438                         if infos is not None:
   417                             else:
   452                             else:
   418                                 pou_infos["values"].append({"name" : variable.getname(), 
   453                                 pou_infos["values"].append({"name" : variable.getname(), 
   419                                                             "elmt_type" : vartype_content["name"], 
   454                                                             "elmt_type" : vartype_content["name"], 
   420                                                             "type" : current_var_class, "values" : []})
   455                                                             "type" : current_var_class, "values" : []})
   421                 return pou_infos
   456                 return pou_infos
   422             block_infos = self.GetBlockType(type)
   457             block_infos = self.GetBlockType(type, debug = debug)
   423             if block_infos is not None:
   458             if block_infos is not None:
   424                 if block_infos["type"] == "function":
   459                 if block_infos["type"] == "function":
   425                     return None
   460                     return None
   426                 elif block_infos["type"] == "program":
   461                 elif block_infos["type"] == "program":
   427                     pou_infos = {"name" : name, "elmt_type" : type, "type" : ITEM_PROGRAM, "values" : []}
   462                     pou_infos = {"name" : name, "elmt_type" : type, "type" : ITEM_PROGRAM, "values" : []}
   431                     pou_infos["values"].append({"name" : varname, "elmt_type" : vartype, "type" : ITEM_VAR_INPUT, "values" : []})
   466                     pou_infos["values"].append({"name" : varname, "elmt_type" : vartype, "type" : ITEM_VAR_INPUT, "values" : []})
   432                 for varname, vartype, varmodifier in block_infos["outputs"]:
   467                 for varname, vartype, varmodifier in block_infos["outputs"]:
   433                     pou_infos["values"].append({"name" : varname, "elmt_type" : vartype, "type" : ITEM_VAR_INPUT, "values" : []})
   468                     pou_infos["values"].append({"name" : varname, "elmt_type" : vartype, "type" : ITEM_VAR_INPUT, "values" : []})
   434                 return pou_infos
   469                 return pou_infos
   435             
   470             
   436             if type in self.GetDataTypes():
   471             if type in self.GetDataTypes(debug = debug):
   437                 if global_var:
   472                 if global_var:
   438                     return {"name" : name, "elmt_type" : type, "type" : ITEM_VAR_GLOBAL, "values" : []}
   473                     return {"name" : name, "elmt_type" : type, "type" : ITEM_VAR_GLOBAL, "values" : []}
   439                 else:
   474                 else:
   440                     return {"name" : name, "elmt_type" : type, "type" : ITEM_VAR_LOCAL, "values" : []}
   475                     return {"name" : name, "elmt_type" : type, "type" : ITEM_VAR_LOCAL, "values" : []}
   441         return None
   476         return None
   442 
   477 
   443     # Return if data type given by name is used by another data type or pou
   478     # Return if data type given by name is used by another data type or pou
   444     def DataTypeIsUsed(self, name):
   479     def DataTypeIsUsed(self, name, debug = False):
   445         return self.Project.ElementIsUsed(name) or self.Project.DataTypeIsDerived(name)
   480         project = self.GetProject(debug)
       
   481         if project is not None:
       
   482             return project.ElementIsUsed(name) or project.DataTypeIsDerived(name)
       
   483         return False
   446 
   484 
   447     # Return if pou given by name is used by another pou
   485     # Return if pou given by name is used by another pou
   448     def PouIsUsed(self, name):
   486     def PouIsUsed(self, name, debug = False):
   449         return self.Project.ElementIsUsed(name)
   487         project = self.GetProject(debug)
       
   488         if project is not None:
       
   489             return project.ElementIsUsed(name)
       
   490         return False
   450 
   491 
   451     # Return if pou given by name is directly or undirectly used by the reference pou
   492     # Return if pou given by name is directly or undirectly used by the reference pou
   452     def PouIsUsedBy(self, name, reference):
   493     def PouIsUsedBy(self, name, reference, debug = False):
   453         return self.Project.ElementIsUsedBy(name, reference)
   494         project = self.GetProject(debug)
       
   495         if project is not None:
       
   496             return project.ElementIsUsedBy(name, reference)
       
   497         return False
   454 
   498 
   455     def GenerateProgram(self, filepath):
   499     def GenerateProgram(self, filepath):
   456         if self.Project:
   500         if self.Project is not None:
   457             try:
   501             try:
   458                 self.ProgramChunks = GenerateCurrentProgram(self, self.Project)
   502                 self.ProgramChunks = GenerateCurrentProgram(self, self.Project)
       
   503                 self.CurrentCompiledProject = self.Copy(self.Project)
   459                 program_text = "".join([item[0] for item in self.ProgramChunks])
   504                 program_text = "".join([item[0] for item in self.ProgramChunks])
   460                 programfile = open(filepath, "w")
   505                 programfile = open(filepath, "w")
   461                 programfile.write(program_text)
   506                 programfile.write(program_text)
   462                 programfile.close()
   507                 programfile.close()
   463                 self.ProgramFilePath = filepath
   508                 self.ProgramFilePath = filepath
   488 #                        Project Pous management functions
   533 #                        Project Pous management functions
   489 #-------------------------------------------------------------------------------
   534 #-------------------------------------------------------------------------------
   490     
   535     
   491     # Add a Data Type to Project
   536     # Add a Data Type to Project
   492     def ProjectAddDataType(self, datatype_name):
   537     def ProjectAddDataType(self, datatype_name):
   493         # Add the pou to project
   538         if self.Project is not None:
   494         self.Project.appenddataType(datatype_name)
   539             # Add the datatype to project
   495         self.BufferProject()
   540             self.Project.appenddataType(datatype_name)
   496     
   541             self.BufferProject()
       
   542         
   497     # Remove a Data Type from project
   543     # Remove a Data Type from project
   498     def ProjectRemoveDataType(self, datatype_name):
   544     def ProjectRemoveDataType(self, datatype_name):
   499         self.Project.removedataType(datatype_name)
   545         if self.Project is not None:
   500         self.BufferProject()
   546             self.Project.removedataType(datatype_name)
       
   547             self.BufferProject()
   501     
   548     
   502     # Add a Pou to Project
   549     # Add a Pou to Project
   503     def ProjectAddPou(self, pou_name, pou_type, body_type):
   550     def ProjectAddPou(self, pou_name, pou_type, body_type):
   504         # Add the pou to project
   551         if self.Project is not None:
   505         self.Project.appendpou(pou_name, pou_type, body_type)
   552             # Add the pou to project
   506         if pou_type == "function":
   553             self.Project.appendpou(pou_name, pou_type, body_type)
   507             self.SetPouInterfaceReturnType(pou_name, "BOOL")
   554             if pou_type == "function":
   508         self.BufferProject()
   555                 self.SetPouInterfaceReturnType(pou_name, "BOOL")
       
   556             self.BufferProject()
   509     
   557     
   510     # Remove a Pou from project
   558     # Remove a Pou from project
   511     def ProjectRemovePou(self, pou_name):
   559     def ProjectRemovePou(self, pou_name):
   512         self.Project.removepou(pou_name)
   560         if self.Project is not None:
   513         self.BufferProject()
   561             self.Project.removepou(pou_name)
       
   562             self.BufferProject()
   514     
   563     
   515     # Add a configuration to Project
   564     # Add a configuration to Project
   516     def ProjectAddConfiguration(self, config_name):
   565     def ProjectAddConfiguration(self, config_name):
   517         self.Project.addconfiguration(config_name)
   566         if self.Project is not None:
   518         self.BufferProject()
   567             self.Project.addconfiguration(config_name)
       
   568             self.BufferProject()
   519     
   569     
   520     # Remove a configuration from project
   570     # Remove a configuration from project
   521     def ProjectRemoveConfiguration(self, config_name):
   571     def ProjectRemoveConfiguration(self, config_name):
   522         self.Project.removeconfiguration(config_name)
   572         if self.Project is not None:
   523         self.BufferProject()
   573             self.Project.removeconfiguration(config_name)
       
   574             self.BufferProject()
   524     
   575     
   525     # Add a resource to a configuration of the Project
   576     # Add a resource to a configuration of the Project
   526     def ProjectAddConfigurationResource(self, config_name, resource_name):
   577     def ProjectAddConfigurationResource(self, config_name, resource_name):
   527         self.Project.addconfigurationResource(config_name, resource_name)
   578         if self.Project is not None:
   528         self.BufferProject()
   579             self.Project.addconfigurationResource(config_name, resource_name)
       
   580             self.BufferProject()
   529     
   581     
   530     # Remove a resource from a configuration of the project
   582     # Remove a resource from a configuration of the project
   531     def ProjectRemoveConfigurationResource(self, config_name, resource_name):
   583     def ProjectRemoveConfigurationResource(self, config_name, resource_name):
   532         self.Project.removeconfigurationResource(config_name, resource_name)
   584         if self.Project is not None:
   533         self.BufferProject()
   585             self.Project.removeconfigurationResource(config_name, resource_name)
       
   586             self.BufferProject()
   534     
   587     
   535     # Add a Transition to a Project Pou
   588     # Add a Transition to a Project Pou
   536     def ProjectAddPouTransition(self, pou_name, transition_name, transition_type):
   589     def ProjectAddPouTransition(self, pou_name, transition_name, transition_type):
   537         pou = self.Project.getpou(pou_name)
   590         if self.Project is not None:
   538         pou.addtransition(transition_name, transition_type)
   591             pou = self.Project.getpou(pou_name)
   539         self.BufferProject()
   592             if pou is not None:
       
   593                 pou.addtransition(transition_name, transition_type)
       
   594                 self.BufferProject()
   540     
   595     
   541     # Remove a Transition from a Project Pou
   596     # Remove a Transition from a Project Pou
   542     def ProjectRemovePouTransition(self, pou_name, transition_name):
   597     def ProjectRemovePouTransition(self, pou_name, transition_name):
   543         pou = self.Project.getpou(pou_name)
   598         # Search if the pou removed is currently opened
   544         pou.removetransition(transition_name)
   599         if self.Project is not None:
   545         self.BufferProject()
   600             pou = self.Project.getpou(pou_name)
       
   601             if pou is not None:
       
   602                 pou.removetransition(transition_name)
       
   603                 self.BufferProject()
   546     
   604     
   547     # Add an Action to a Project Pou
   605     # Add an Action to a Project Pou
   548     def ProjectAddPouAction(self, pou_name, action_name, action_type):
   606     def ProjectAddPouAction(self, pou_name, action_name, action_type):
   549         pou = self.Project.getpou(pou_name)
   607         if self.Project is not None:
   550         pou.addaction(action_name, action_type)
   608             pou = self.Project.getpou(pou_name)
   551         self.BufferProject()
   609             if pou is not None:
       
   610                 pou.addaction(action_name, action_type)
       
   611                 self.BufferProject()
   552     
   612     
   553     # Remove an Action from a Project Pou
   613     # Remove an Action from a Project Pou
   554     def ProjectRemovePouAction(self, pou_name, action_name):
   614     def ProjectRemovePouAction(self, pou_name, action_name):
   555         # Search if the pou removed is currently opened
   615         # Search if the pou removed is currently opened
   556         for i, element in enumerate(self.ElementsOpened):
   616         if self.Project is not None:
   557             words = element.split("::")
   617             pou = self.Project.getpou(pou_name)
   558             if words[0] == "A" and words[1] == pou_name and words[2] == action_name:
   618             if pou is not None:
   559                 self.RemoveElementEditing(i)
   619                 pou.removeaction(action_name)
   560         pou = self.Project.getpou(pou_name)
   620                 self.BufferProject()
   561         pou.removeaction(action_name)
       
   562         self.BufferProject()
       
   563     
   621     
   564     # Change the name of a pou
   622     # Change the name of a pou
   565     def ChangeDataTypeName(self, old_name, new_name):
   623     def ChangeDataTypeName(self, old_name, new_name):
   566         # Found the pou corresponding to old name and change its name to new name
   624         if self.Project is not None:
   567         datatype = self.Project.getdataType(old_name)
   625             # Found the pou corresponding to old name and change its name to new name
   568         datatype.setname(new_name)
   626             datatype = self.Project.getdataType(old_name)
   569         self.Project.updateElementName(old_name, new_name)
   627             if datatype is not None:
   570         self.BufferProject()
   628                 datatype.setname(new_name)
       
   629                 self.Project.updateElementName(old_name, new_name)
       
   630                 self.BufferProject()
   571     
   631     
   572     # Change the name of a pou
   632     # Change the name of a pou
   573     def ChangePouName(self, old_name, new_name):
   633     def ChangePouName(self, old_name, new_name):
   574         # Found the pou corresponding to old name and change its name to new name
   634         if self.Project is not None:
   575         pou = self.Project.getpou(old_name)
   635             # Found the pou corresponding to old name and change its name to new name
   576         pou.setname(new_name)
   636             pou = self.Project.getpou(old_name)
   577         self.Project.updateElementName(old_name, new_name)
   637             if pou is not None:
   578         self.Project.RefreshElementUsingTree()
   638                 pou.setname(new_name)
   579         self.Project.RefreshCustomBlockTypes()
   639                 self.Project.updateElementName(old_name, new_name)
   580         self.BufferProject()
   640                 self.Project.RefreshElementUsingTree()
       
   641                 self.Project.RefreshCustomBlockTypes()
       
   642                 self.BufferProject()
   581     
   643     
   582     # Change the name of a pou transition
   644     # Change the name of a pou transition
   583     def ChangePouTransitionName(self, pou_name, old_name, new_name):
   645     def ChangePouTransitionName(self, pou_name, old_name, new_name):
   584         # Found the pou transition corresponding to old name and change its name to new name
   646         if self.Project is not None:
   585         pou = self.Project.getpou(pou_name)
   647             # Found the pou transition corresponding to old name and change its name to new name
   586         transition = pou.gettransition(old_name)
   648             pou = self.Project.getpou(pou_name)
   587         transition.setname(new_name)
   649             if pou is not None:
   588         pou.updateElementName(old_name, new_name)
   650                 transition = pou.gettransition(old_name)
   589         self.BufferProject()
   651                 if transition is not None:
       
   652                     transition.setname(new_name)
       
   653                     pou.updateElementName(old_name, new_name)
       
   654                     self.BufferProject()
   590     
   655     
   591     # Change the name of a pou action
   656     # Change the name of a pou action
   592     def ChangePouActionName(self, pou_name, old_name, new_name):
   657     def ChangePouActionName(self, pou_name, old_name, new_name):
   593         # Found the pou action corresponding to old name and change its name to new name
   658         if self.Project is not None:
   594         pou = self.Project.getpou(pou_name)
   659             # Found the pou action corresponding to old name and change its name to new name
   595         action = pou.getaction(old_name)
   660             pou = self.Project.getpou(pou_name)
   596         action.setname(new_name)
   661             if pou is not None:
   597         pou.updateElementName(old_name, new_name)
   662                 action = pou.getaction(old_name)
   598         self.BufferProject()
   663                 if action is not None:
       
   664                     action.setname(new_name)
       
   665                     pou.updateElementName(old_name, new_name)
       
   666                     self.BufferProject()
   599     
   667     
   600     # Change the name of a pou variable
   668     # Change the name of a pou variable
   601     def ChangePouVariableName(self, pou_name, old_name, new_name):
   669     def ChangePouVariableName(self, pou_name, old_name, new_name):
   602         # Found the pou action corresponding to old name and change its name to new name
   670         if self.Project is not None:
   603         pou = self.Project.getpou(pou_name)
   671             # Found the pou action corresponding to old name and change its name to new name
   604         for type, varlist in pou.getvars():
   672             pou = self.Project.getpou(pou_name)
   605             for var in varlist.getvariable():
   673             if pou is not None:
   606                 if var.getname() == old_name:
   674                 for type, varlist in pou.getvars():
   607                     var.setname(new_name)
   675                     for var in varlist.getvariable():
   608         self.Project.RefreshCustomBlockTypes()
   676                         if var.getname() == old_name:
   609         self.BufferProject()
   677                             var.setname(new_name)
       
   678                 self.Project.RefreshCustomBlockTypes()
       
   679                 self.BufferProject()
   610         
   680         
   611     # Change the name of a configuration
   681     # Change the name of a configuration
   612     def ChangeConfigurationName(self, old_name, new_name):
   682     def ChangeConfigurationName(self, old_name, new_name):
   613         # Found the configuration corresponding to old name and change its name to new name
   683         if self.Project is not None:
   614         configuration = self.Project.getconfiguration(old_name)
   684             # Found the configuration corresponding to old name and change its name to new name
   615         configuration.setname(new_name)
   685             configuration = self.Project.getconfiguration(old_name)
   616         self.BufferProject()
   686             if configuration is not None:
       
   687                 configuration.setname(new_name)
       
   688                 self.BufferProject()
   617     
   689     
   618     # Change the name of a configuration resource
   690     # Change the name of a configuration resource
   619     def ChangeConfigurationResourceName(self, config_name, old_name, new_name):
   691     def ChangeConfigurationResourceName(self, config_name, old_name, new_name):
   620         # Found the resource corresponding to old name and change its name to new name
   692         if self.Project is not None:
   621         resource = self.Project.getconfigurationResource(config_name)
   693             # Found the resource corresponding to old name and change its name to new name
   622         resource.setName(new_name)
   694             resource = self.Project.getconfigurationResource(config_name)
   623         self.BufferProject()
   695             if resource is not None:
       
   696                 resource.setName(new_name)
       
   697                 self.BufferProject()
   624     
   698     
   625     # Return the type of the pou given by its name
   699     # Return the type of the pou given by its name
   626     def GetPouType(self, name):
   700     def GetPouType(self, name, debug = False):
   627         # Found the pou correponding to name and return its type
   701         project = self.GetProject(debug)
   628         pou = self.Project.getpou(name)
   702         if project is not None:
   629         return pou.getpouType()
   703             # Found the pou correponding to name and return its type
       
   704             pou = project.getpou(name)
       
   705             if pou is not None:
       
   706                 return pou.getpouType()
       
   707         return None
   630     
   708     
   631     # Return pous with SFC language
   709     # Return pous with SFC language
   632     def GetSFCPous(self):
   710     def GetSFCPous(self, debug = False):
   633         list = []
   711         list = []
   634         if self.Project:
   712         project = self.GetProject(debug)
   635             for pou in self.Project.getpous():
   713         if project is not None:
       
   714             for pou in project.getpous():
   636                 if pou.getBodyType() == "SFC":
   715                 if pou.getBodyType() == "SFC":
   637                     list.append(pou.getname())
   716                     list.append(pou.getname())
   638         return list
   717         return list
   639     
   718     
   640     # Return the body language of the pou given by its name
   719     # Return the body language of the pou given by its name
   641     def GetPouBodyType(self, name):
   720     def GetPouBodyType(self, name, debug = False):
   642         # Found the pou correponding to name and return its body language
   721         project = self.GetProject(debug)
   643         pou = self.Project.getpou(name)
   722         if project is not None:
   644         return pou.getbodyType()
   723             # Found the pou correponding to name and return its body language
       
   724             pou = project.getpou(name)
       
   725             if pou is not None:
       
   726                 return pou.getbodyType()
       
   727         return None
   645     
   728     
   646     # Return the actions of a pou
   729     # Return the actions of a pou
   647     def GetPouTransitions(self, pou_name):
   730     def GetPouTransitions(self, pou_name, debug = False):
   648         transitions = []
   731         transitions = []
   649         pou = self.Project.getpou(pou_name)
   732         project = self.GetProject(debug)
   650         if pou.getbodyType() == "SFC":
   733         if project is not None:
   651             for transition in pou.gettransitionList():
   734             # Found the pou correponding to name and return its transitions if SFC
   652                 transitions.append(transition.getname())
   735             pou = project.getpou(pou_name)
       
   736             if pou is not None and pou.getbodyType() == "SFC":
       
   737                 for transition in pou.gettransitionList():
       
   738                     transitions.append(transition.getname())
   653         return transitions
   739         return transitions
   654     
   740     
   655     # Return the body language of the transition given by its name
   741     # Return the body language of the transition given by its name
   656     def GetTransitionBodyType(self, pou_name, pou_transition):
   742     def GetTransitionBodyType(self, pou_name, pou_transition, debug = False):
   657         # Found the pou correponding to name and return its body language
   743         project = self.GetProject(debug)
   658         pou = self.Project.getpou(pou_name)
   744         if project is not None:
   659         transition = pou.gettransition(pou_transition)
   745             # Found the pou correponding to name
   660         return transition.getbodyType()
   746             pou = project.getpou(pou_name)
       
   747             if pou is not None:
       
   748                 # Found the pou transition correponding to name and return its body language
       
   749                 transition = pou.gettransition(pou_transition)
       
   750                 if transition is not None:
       
   751                     return transition.getbodyType()
       
   752         return None
   661     
   753     
   662     # Return the actions of a pou
   754     # Return the actions of a pou
   663     def GetPouActions(self, pou_name):
   755     def GetPouActions(self, pou_name, debug = False):
   664         actions = []
   756         actions = []
   665         pou = self.Project.getpou(pou_name)
   757         project = self.GetProject(debug)
   666         if pou.getbodyType() == "SFC":
   758         if project is not None:
   667             for action in pou.getactionList():
   759             # Found the pou correponding to name and return its actions if SFC
   668                 actions.append(action.getname())
   760             pou = project.getpou(pou_name)
       
   761             if pou.getbodyType() == "SFC":
       
   762                 for action in pou.getactionList():
       
   763                     actions.append(action.getname())
   669         return actions
   764         return actions
   670     
   765     
   671     # Return the body language of the pou given by its name
   766     # Return the body language of the pou given by its name
   672     def GetActionBodyType(self, pou_name, pou_action):
   767     def GetActionBodyType(self, pou_name, pou_action, debug = False):
   673         # Found the pou correponding to name and return its body language
   768         project = self.GetProject(debug)
   674         pou = self.Project.getpou(pou_name)
   769         if project is not None:
   675         action = pou.getaction(pou_action)
   770             # Found the pou correponding to name and return its body language
   676         return action.getbodyType()
   771             pou = project.getpou(pou_name)
       
   772             if pou is not None:
       
   773                 action = pou.getaction(pou_action)
       
   774                 if action is not None:
       
   775                     return action.getbodyType()
       
   776         return None
   677     
   777     
   678     # Extract varlists from a list of vars
   778     # Extract varlists from a list of vars
   679     def ExtractVarLists(self, vars):
   779     def ExtractVarLists(self, vars):
   680         varlist_list = []
   780         varlist_list = []
   681         current_varlist = None
   781         current_varlist = None
   729             current_varlist.appendvariable(tempvar)
   829             current_varlist.appendvariable(tempvar)
   730         return varlist_list
   830         return varlist_list
   731 
   831 
   732     # Replace the configuration globalvars by those given
   832     # Replace the configuration globalvars by those given
   733     def SetConfigurationGlobalVars(self, name, vars):
   833     def SetConfigurationGlobalVars(self, name, vars):
   734         # Found the configuration corresponding to name
   834         if self.Project is not None:
   735         configuration = self.Project.getconfiguration(name)
   835             # Found the configuration corresponding to name
   736         if configuration:
   836             configuration = self.Project.getconfiguration(name)
   737             # Set configuration global vars
   837             if configuration is not None:
   738             configuration.setglobalVars([])
   838                 # Set configuration global vars
   739             for vartype, varlist in self.ExtractVarLists(vars):
   839                 configuration.setglobalVars([])
   740                 configuration.globalVars.append(varlist)
   840                 for vartype, varlist in self.ExtractVarLists(vars):
       
   841                     configuration.globalVars.append(varlist)
   741     
   842     
   742     # Return the configuration globalvars
   843     # Return the configuration globalvars
   743     def GetConfigurationGlobalVars(self, name):
   844     def GetConfigurationGlobalVars(self, name, debug = False):
   744         vars = []
   845         vars = []
   745         # Found the configuration corresponding to name
   846         project = self.GetProject(debug)
   746         configuration = self.Project.getconfiguration(name)
   847         if project is not None:
   747         if configuration:
   848             # Found the configuration corresponding to name
   748             # Extract variables from every varLists
   849             configuration = project.getconfiguration(name)
   749             for varlist in configuration.getglobalVars():
   850             if configuration is not None:
   750                 for var in varlist.getvariable():
   851                 # Extract variables from every varLists
   751                     tempvar = {"Name" : var.getname(), "Class" : "Global"}
   852                 for varlist in configuration.getglobalVars():
   752                     vartype_content = var.gettype().getcontent()
   853                     for var in varlist.getvariable():
   753                     if vartype_content["name"] == "derived":
   854                         tempvar = {"Name" : var.getname(), "Class" : "Global"}
   754                         tempvar["Type"] = vartype_content["value"].getname()
   855                         vartype_content = var.gettype().getcontent()
   755                     elif vartype_content["name"] in ["string", "wstring"]:
   856                         if vartype_content["name"] == "derived":
   756                         tempvar["Type"] = vartype_content["name"].upper()
   857                             tempvar["Type"] = vartype_content["value"].getname()
   757                     else:
   858                         elif vartype_content["name"] in ["string", "wstring"]:
   758                         tempvar["Type"] = vartype_content["name"]
   859                             tempvar["Type"] = vartype_content["name"].upper()
   759                     tempvar["Edit"] = True
   860                         else:
   760                     initial = var.getinitialValue()
   861                             tempvar["Type"] = vartype_content["name"]
   761                     if initial:
   862                         tempvar["Edit"] = True
   762                         tempvar["Initial Value"] = initial.getvalue()
   863                         initial = var.getinitialValue()
   763                     else:
   864                         if initial:
   764                         tempvar["Initial Value"] = ""
   865                             tempvar["Initial Value"] = initial.getvalue()
   765                     address = var.getaddress()
   866                         else:
   766                     if address:
   867                             tempvar["Initial Value"] = ""
   767                         tempvar["Location"] = address
   868                         address = var.getaddress()
   768                     else:
   869                         if address:
   769                         tempvar["Location"] = ""
   870                             tempvar["Location"] = address
   770                     if varlist.getretain():
   871                         else:
   771                         tempvar["Retain"] = "Yes"
   872                             tempvar["Location"] = ""
   772                     else:
   873                         if varlist.getretain():
   773                         tempvar["Retain"] = "No"
   874                             tempvar["Retain"] = "Yes"
   774                     if varlist.getconstant():
   875                         else:
   775                         tempvar["Constant"] = "Yes"
   876                             tempvar["Retain"] = "No"
   776                     else:
   877                         if varlist.getconstant():
   777                         tempvar["Constant"] = "No"
   878                             tempvar["Constant"] = "Yes"
   778                     vars.append(tempvar)
   879                         else:
       
   880                             tempvar["Constant"] = "No"
       
   881                         vars.append(tempvar)
   779         return vars
   882         return vars
   780 
   883 
   781     # Replace the resource globalvars by those given
   884     # Replace the resource globalvars by those given
   782     def SetConfigurationResourceGlobalVars(self, config_name, name, vars):
   885     def SetConfigurationResourceGlobalVars(self, config_name, name, vars):
   783         # Found the resource corresponding to name
   886         if self.Project is not None:
   784         resource = self.Project.getconfigurationResource(config_name, name)
   887             # Found the resource corresponding to name
   785         # Set resource global vars
   888             resource = self.Project.getconfigurationResource(config_name, name)
   786         if resource:
   889             # Set resource global vars
   787             resource.setglobalVars([])
   890             if resource is not None:
   788             for vartype, varlist in self.ExtractVarLists(vars):
   891                 resource.setglobalVars([])
   789                 resource.globalVars.append(varlist)
   892                 for vartype, varlist in self.ExtractVarLists(vars):
       
   893                     resource.globalVars.append(varlist)
   790     
   894     
   791     # Return the resource globalvars
   895     # Return the resource globalvars
   792     def GetConfigurationResourceGlobalVars(self, config_name, name):
   896     def GetConfigurationResourceGlobalVars(self, config_name, name, debug = False):
   793         vars = []
   897         vars = []
   794         # Found the resource corresponding to name
   898         project = self.GetProject(debug)
   795         resource = self.Project.getconfigurationResource(config_name, name)
   899         if project is not None:
   796         if resource:
   900             # Found the resource corresponding to name
   797             # Extract variables from every varLists
   901             resource = project.getconfigurationResource(config_name, name)
   798             for varlist in resource.getglobalVars():
   902             if resource:
   799                 for var in varlist.getvariable():
   903                 # Extract variables from every varLists
   800                     tempvar = {"Name" : var.getname(), "Class" : "Global"}
   904                 for varlist in resource.getglobalVars():
   801                     vartype_content = var.gettype().getcontent()
   905                     for var in varlist.getvariable():
   802                     if vartype_content["name"] == "derived":
   906                         tempvar = {"Name" : var.getname(), "Class" : "Global"}
   803                         tempvar["Type"] = vartype_content["value"].getname()
   907                         vartype_content = var.gettype().getcontent()
   804                     elif vartype_content["name"] in ["string", "wstring"]:
   908                         if vartype_content["name"] == "derived":
   805                         tempvar["Type"] = vartype_content["name"].upper()
   909                             tempvar["Type"] = vartype_content["value"].getname()
   806                     else:
   910                         elif vartype_content["name"] in ["string", "wstring"]:
   807                         tempvar["Type"] = vartype_content["name"]
   911                             tempvar["Type"] = vartype_content["name"].upper()
   808                     tempvar["Edit"] = True
   912                         else:
   809                     initial = var.getinitialValue()
   913                             tempvar["Type"] = vartype_content["name"]
   810                     if initial:
   914                         tempvar["Edit"] = True
   811                         tempvar["Initial Value"] = initial.getvalue()
   915                         initial = var.getinitialValue()
   812                     else:
   916                         if initial:
   813                         tempvar["Initial Value"] = ""
   917                             tempvar["Initial Value"] = initial.getvalue()
   814                     address = var.getaddress()
   918                         else:
   815                     if address:
   919                             tempvar["Initial Value"] = ""
   816                         tempvar["Location"] = address
   920                         address = var.getaddress()
   817                     else:
   921                         if address:
   818                         tempvar["Location"] = ""
   922                             tempvar["Location"] = address
   819                     if varlist.getretain():
   923                         else:
   820                         tempvar["Retain"] = "Yes"
   924                             tempvar["Location"] = ""
   821                     else:
   925                         if varlist.getretain():
   822                         tempvar["Retain"] = "No"
   926                             tempvar["Retain"] = "Yes"
   823                     if varlist.getconstant():
   927                         else:
   824                         tempvar["Constant"] = "Yes"
   928                             tempvar["Retain"] = "No"
   825                     else:
   929                         if varlist.getconstant():
   826                         tempvar["Constant"] = "No"
   930                             tempvar["Constant"] = "Yes"
   827                     vars.append(tempvar)
   931                         else:
       
   932                             tempvar["Constant"] = "No"
       
   933                         vars.append(tempvar)
   828         return vars
   934         return vars
   829     
   935     
   830     # Return the interface of the pou given by its name
   936     # Return the interface of the pou given by its name
   831     def GetPouInterfaceVarsByName(self, name):
   937     def GetPouInterfaceVarsByName(self, name, debug = False):
   832         # Found the pou correponding to name and return the interface
   938         project = self.GetProject(debug)
   833         return self.GetPouInterfaceVars(self.Project.getpou(name))
   939         if project is not None:
       
   940             # Found the pou correponding to name and return the interface vars
       
   941             pou = project.getpou(name)
       
   942             if pou is not None:
       
   943                 return self.GetPouInterfaceVars(pou)
       
   944         return None
   834     
   945     
   835     # Return the interface for the given pou
   946     # Return the interface for the given pou
   836     def GetPouInterfaceVars(self, pou):
   947     def GetPouInterfaceVars(self, pou):
   837         vars = []
   948         vars = []
   838         # Verify that the pou has an interface
   949         # Verify that the pou has an interface
   839         if pou.interface:
   950         if pou.interface is not None:
   840             # Extract variables from every varLists
   951             # Extract variables from every varLists
   841             for type, varlist in pou.getvars():
   952             for type, varlist in pou.getvars():
   842                 for var in varlist.getvariable():
   953                 for var in varlist.getvariable():
   843                     tempvar = {"Name" : var.getname(), "Class" : type}
   954                     tempvar = {"Name" : var.getname(), "Class" : type}
   844                     vartype_content = var.gettype().getcontent()
   955                     vartype_content = var.gettype().getcontent()
   872                     vars.append(tempvar)
   983                     vars.append(tempvar)
   873         return vars
   984         return vars
   874 
   985 
   875     # Replace the Pou interface by the one given
   986     # Replace the Pou interface by the one given
   876     def SetPouInterfaceVars(self, name, vars):
   987     def SetPouInterfaceVars(self, name, vars):
   877         # Found the pou corresponding to name and add interface if there isn't one yet
   988         if self.Project is not None:
   878         pou = self.Project.getpou(name)
   989             # Found the pou corresponding to name and add interface if there isn't one yet
   879         if not pou.interface:
   990             pou = self.Project.getpou(name)
   880             pou.interface = plcopen.pou_interface()
   991             if pou is not None:
   881         # Set Pou interface
   992                 if pou.interface is None:
   882         pou.setvars(self.ExtractVarLists(vars))
   993                     pou.interface = plcopen.pou_interface()
   883         self.Project.RefreshElementUsingTree()
   994                 # Set Pou interface
   884         self.Project.RefreshCustomBlockTypes()
   995                 pou.setvars(self.ExtractVarLists(vars))
       
   996                 self.Project.RefreshElementUsingTree()
       
   997                 self.Project.RefreshCustomBlockTypes()
   885     
   998     
   886     # Replace the return type of the pou given by its name (only for functions)
   999     # Replace the return type of the pou given by its name (only for functions)
   887     def SetPouInterfaceReturnType(self, name, type):
  1000     def SetPouInterfaceReturnType(self, name, type):
   888         pou = self.Project.getpou(name)
  1001         if self.Project is not None:
   889         if not pou.interface:
  1002             pou = self.Project.getpou(name)
   890             pou.interface = plcopen.pou_interface()
  1003             if pou is not None:
   891         # If there isn't any return type yet, add it
  1004                 if pou.interface is None:
   892         return_type = pou.interface.getreturnType()
  1005                     pou.interface = plcopen.pou_interface()
   893         if not return_type:
  1006                 # If there isn't any return type yet, add it
   894             return_type = plcopen.dataType()
  1007                 return_type = pou.interface.getreturnType()
   895             pou.interface.setreturnType(return_type)
  1008                 if not return_type:
   896         # Change return type
  1009                     return_type = plcopen.dataType()
   897         if type in self.GetBaseTypes():
  1010                     pou.interface.setreturnType(return_type)
   898             if type == "STRING":
  1011                 # Change return type
   899                 return_type.setcontent({"name" : "string", "value" : plcopen.elementaryTypes_string()})
  1012                 if type in self.GetBaseTypes():
   900             elif type == "WSTRING":
  1013                     if type == "STRING":
   901                 return_type.setcontent({"name" : "wstring", "value" : plcopen.elementaryTypes_wstring()})
  1014                         return_type.setcontent({"name" : "string", "value" : plcopen.elementaryTypes_string()})
   902             else:
  1015                     elif type == "WSTRING":
   903                 return_type.setcontent({"name" : type, "value" : None})
  1016                         return_type.setcontent({"name" : "wstring", "value" : plcopen.elementaryTypes_wstring()})
   904         else:
  1017                     else:
   905             derived_type = plcopen.derivedTypes_derived()
  1018                         return_type.setcontent({"name" : type, "value" : None})
   906             derived_type.setname(type)
  1019                 else:
   907             return_type.setcontent({"name" : "derived", "value" : derived_type})
  1020                     derived_type = plcopen.derivedTypes_derived()
   908         self.Project.RefreshElementUsingTree()
  1021                     derived_type.setname(type)
   909         self.Project.RefreshCustomBlockTypes()
  1022                     return_type.setcontent({"name" : "derived", "value" : derived_type})
       
  1023                 self.Project.RefreshElementUsingTree()
       
  1024                 self.Project.RefreshCustomBlockTypes()
   910     
  1025     
   911     def UpdateProjectUsedPous(self, old_name, new_name):
  1026     def UpdateProjectUsedPous(self, old_name, new_name):
   912         if self.Project:
  1027         if self.Project:
   913             self.Project.updateElementName(old_name, new_name)
  1028             self.Project.updateElementName(old_name, new_name)
   914     
  1029     
   917         if pou:
  1032         if pou:
   918             pou.updateElementName(old_name, new_name)
  1033             pou.updateElementName(old_name, new_name)
   919     
  1034     
   920     # Return the return type of the pou given by its name
  1035     # Return the return type of the pou given by its name
   921     def GetPouInterfaceReturnTypeByName(self, name):
  1036     def GetPouInterfaceReturnTypeByName(self, name):
   922         # Found the pou correponding to name and return the return type
  1037         project = self.GetProject(debug)
   923         return self.GetPouInterfaceReturnType(self.Project.getpou(name))
  1038         if project is not None:
       
  1039             # Found the pou correponding to name and return the return type
       
  1040             pou = project.getpou(name)
       
  1041             if pou is not None:
       
  1042                 return self.GetPouInterfaceReturnType(pou)
       
  1043         return False
   924     
  1044     
   925     # Return the return type of the given pou
  1045     # Return the return type of the given pou
   926     def GetPouInterfaceReturnType(self, pou):
  1046     def GetPouInterfaceReturnType(self, pou):
   927         # Verify that the pou has an interface
  1047         # Verify that the pou has an interface
   928         if pou.interface:
  1048         if pou.interface is not None:
   929             # Return the return type if there is one
  1049             # Return the return type if there is one
   930             return_type = pou.interface.getreturnType()
  1050             return_type = pou.interface.getreturnType()
   931             if return_type:
  1051             if return_type:
   932                 returntype_content = return_type.getcontent()
  1052                 returntype_content = return_type.getcontent()
   933                 if returntype_content["name"] == "derived":
  1053                 if returntype_content["name"] == "derived":
   946     def ClearPluginTypes(self):
  1066     def ClearPluginTypes(self):
   947         for i in xrange(len(self.PluginTypes)):
  1067         for i in xrange(len(self.PluginTypes)):
   948             self.PluginTypes.pop(0)
  1068             self.PluginTypes.pop(0)
   949 
  1069 
   950     # Function that returns the block definition associated to the block type given
  1070     # Function that returns the block definition associated to the block type given
   951     def GetBlockType(self, type, inputs = None):
  1071     def GetBlockType(self, type, inputs = None, debug = False):
   952         for category in BlockTypes + self.PluginTypes:
  1072         for category in BlockTypes + self.PluginTypes:
   953             for blocktype in category["list"]:
  1073             for blocktype in category["list"]:
   954                 if inputs:
  1074                 if inputs:
   955                     block_inputs = tuple([var_type for name, var_type, modifier in blocktype["inputs"]])
  1075                     block_inputs = tuple([var_type for name, var_type, modifier in blocktype["inputs"]])
   956                     same_inputs = inputs == block_inputs
  1076                     same_inputs = inputs == block_inputs
   957                 else:
  1077                 else:
   958                     same_inputs = True
  1078                     same_inputs = True
   959                 if blocktype["name"] == type and same_inputs:
  1079                 if blocktype["name"] == type and same_inputs:
   960                     return blocktype
  1080                     return blocktype
   961         if self.Project:
  1081         project = self.GetProject(debug)
   962             return self.Project.GetCustomBlockType(type, inputs)
  1082         if project is not None:
       
  1083             return project.GetCustomBlockType(type, inputs)
   963         return None
  1084         return None
   964 
  1085 
   965     # Return Block types checking for recursion
  1086     # Return Block types checking for recursion
   966     def GetBlockTypes(self, tagname = ""):
  1087     def GetBlockTypes(self, tagname = "", debug = False):
   967         type = None
  1088         type = None
   968         if self.Project:
  1089         if self.Project:
   969             name = ""
  1090             name = ""
   970             words = tagname.split("::")
  1091             words = tagname.split("::")
   971             if words[0] in ["P","T","A"]:
  1092             if words[0] in ["P","T","A"]:
   972                 name = words[1]
  1093                 name = words[1]
   973                 type = self.GetPouType(name)
  1094                 type = self.GetPouType(name, debug)
   974         if type == "function":
  1095         if type == "function":
   975             blocktypes = []
  1096             blocktypes = []
   976             for category in BlockTypes + self.PluginTypes:
  1097             for category in BlockTypes + self.PluginTypes:
   977                 cat = {"name" : category["name"], "list" : []}
  1098                 cat = {"name" : category["name"], "list" : []}
   978                 for block in category["list"]:
  1099                 for block in category["list"]:
   980                         cat["list"].append(block)
  1101                         cat["list"].append(block)
   981                 if len(cat["list"]) > 0:
  1102                 if len(cat["list"]) > 0:
   982                     blocktypes.append(cat)
  1103                     blocktypes.append(cat)
   983         else:
  1104         else:
   984             blocktypes = [category for category in BlockTypes + self.PluginTypes]
  1105             blocktypes = [category for category in BlockTypes + self.PluginTypes]
   985         if self.Project:
  1106         project = self.GetProject(debug)
   986             blocktypes.append({"name" : "User-defined POUs", "list": self.Project.GetCustomBlockTypes(name)})
  1107         if project is not None:
       
  1108             blocktypes.append({"name" : "User-defined POUs", "list": project.GetCustomBlockTypes(name)})
   987         return blocktypes
  1109         return blocktypes
   988 
  1110 
   989     # Return Function Block types checking for recursion
  1111     # Return Function Block types checking for recursion
   990     def GetFunctionBlockTypes(self, tagname = ""):
  1112     def GetFunctionBlockTypes(self, tagname = "", debug = False):
   991         blocktypes = []
  1113         blocktypes = []
   992         for category in BlockTypes + self.PluginTypes:
  1114         for category in BlockTypes + self.PluginTypes:
   993             for block in category["list"]:
  1115             for block in category["list"]:
   994                 if block["type"] != "function":
  1116                 if block["type"] != "function":
   995                     blocktypes.append(block["name"])
  1117                     blocktypes.append(block["name"])
   996         if self.Project:
  1118         project = self.GetProject(debug)
       
  1119         if project is not None:
   997             name = ""
  1120             name = ""
   998             words = tagname.split("::")
  1121             words = tagname.split("::")
   999             if words[0] in ["P","T","A"]:
  1122             if words[0] in ["P","T","A"]:
  1000                 name = words[1]
  1123                 name = words[1]
  1001             blocktypes.extend(self.Project.GetCustomFunctionBlockTypes(name))
  1124             blocktypes.extend(project.GetCustomFunctionBlockTypes(name))
  1002         return blocktypes
  1125         return blocktypes
  1003 
  1126 
  1004     # Return Block types checking for recursion
  1127     # Return Block types checking for recursion
  1005     def GetBlockResource(self):
  1128     def GetBlockResource(self, debug = False):
  1006         blocktypes = []
  1129         blocktypes = []
  1007         for category in BlockTypes[:-1]:
  1130         for category in BlockTypes[:-1]:
  1008             for blocktype in category["list"]:
  1131             for blocktype in category["list"]:
  1009                 if blocktype["type"] == "program":
  1132                 if blocktype["type"] == "program":
  1010                     blocktypes.append(blocktype["name"])
  1133                     blocktypes.append(blocktype["name"])
  1011         if self.Project:
  1134         project = self.GetProject(debug)
  1012             blocktypes.extend(self.Project.GetCustomBlockResource())
  1135         if project is not None:
       
  1136             blocktypes.extend(project.GetCustomBlockResource())
  1013         return blocktypes
  1137         return blocktypes
  1014 
  1138 
  1015     # Return Data Types checking for recursion
  1139     # Return Data Types checking for recursion
  1016     def GetDataTypes(self, tagname = "", basetypes = True):
  1140     def GetDataTypes(self, tagname = "", basetypes = True, debug = False):
  1017         if basetypes:
  1141         if basetypes:
  1018             datatypes = self.GetBaseTypes()
  1142             datatypes = self.GetBaseTypes()
  1019         else:
  1143         else:
  1020             datatypes = []
  1144             datatypes = []
  1021         if self.Project:
  1145         project = self.GetProject(debug)
       
  1146         if project is not None:
  1022             name = ""
  1147             name = ""
  1023             words = tagname.split("::")
  1148             words = tagname.split("::")
  1024             if words[0] in ["D"]:
  1149             if words[0] in ["D"]:
  1025                 name = words[1]
  1150                 name = words[1]
  1026             datatypes.extend(self.Project.GetCustomDataTypes(name))
  1151             datatypes.extend(project.GetCustomDataTypes(name))
  1027         return datatypes
  1152         return datatypes
  1028 
  1153 
  1029     # Return Base Type of given possible derived type
  1154     # Return Base Type of given possible derived type
  1030     def GetBaseType(self, type):
  1155     def GetBaseType(self, type, debug = False):
  1031         if self.Project:
  1156         project = self.GetProject(debug)
  1032             return self.Project.GetBaseType(type)
  1157         if project is not None:
       
  1158             return project.GetBaseType(type)
  1033         return None
  1159         return None
  1034 
  1160 
  1035     # Return Base Types
  1161     # Return Base Types
  1036     def GetBaseTypes(self):
  1162     def GetBaseTypes(self):
  1037         return [value for value in TypeHierarchy.keys() if not value.startswith("ANY")]
  1163         return [value for value in TypeHierarchy.keys() if not value.startswith("ANY")]
  1038 
  1164 
  1039     def IsOfType(self, type, reference):
  1165     def IsOfType(self, type, reference, debug = False):
  1040         if self.Project:
  1166         project = self.GetProject(debug)
  1041             return self.Project.IsOfType(type, reference)
  1167         if project is not None:
       
  1168             return project.IsOfType(type, reference)
  1042         elif reference is None:
  1169         elif reference is None:
  1043             return True
  1170             return True
  1044         elif type == reference:
  1171         elif type == reference:
  1045             return True
  1172             return True
  1046         else:
  1173         else:
  1051     def IsEndType(self, type):
  1178     def IsEndType(self, type):
  1052         if type is not None:
  1179         if type is not None:
  1053             return not type.startswith("ANY")
  1180             return not type.startswith("ANY")
  1054         return True
  1181         return True
  1055 
  1182 
  1056     def GetDataTypeRange(self, type):
  1183     def GetDataTypeRange(self, type, debug = False):
  1057         if self.Project:
  1184         project = self.GetProject(debug)
  1058             return self.Project.GetDataTypeRange(type)
  1185         if project is not None:
       
  1186             return project.GetDataTypeRange(type)
  1059         elif type in DataTypeRange:
  1187         elif type in DataTypeRange:
  1060             return DataTypeRange[type]
  1188             return DataTypeRange[type]
  1061         return None
  1189         return None
  1062     
  1190     
  1063     # Return Subrange types
  1191     # Return Subrange types
  1064     def GetSubrangeBaseTypes(self, exclude):
  1192     def GetSubrangeBaseTypes(self, exclude, debug = False):
  1065         if self.Project:
  1193         project = self.GetProject(debug)
  1066             return self.Project.GetSubrangeBaseTypes(exclude)
  1194         if project is not None:
       
  1195             return project.GetSubrangeBaseTypes(exclude)
  1067         return []
  1196         return []
  1068     
  1197     
  1069     # Return Enumerated Values
  1198     # Return Enumerated Values
  1070     def GetEnumeratedDataValues(self):
  1199     def GetEnumeratedDataValues(self, debug = False):
  1071         if self.Project:
  1200         project = self.GetProject(debug)
  1072             return self.Project.GetEnumeratedDataTypeValues()
  1201         if project is not None:
       
  1202             return project.GetEnumeratedDataTypeValues()
  1073         return []
  1203         return []
  1074 
  1204 
  1075 #-------------------------------------------------------------------------------
  1205 #-------------------------------------------------------------------------------
  1076 #                   Project Element tag name computation functions
  1206 #                   Project Element tag name computation functions
  1077 #-------------------------------------------------------------------------------
  1207 #-------------------------------------------------------------------------------
  1109 #-------------------------------------------------------------------------------
  1239 #-------------------------------------------------------------------------------
  1110 #                    Project opened Data types management functions
  1240 #                    Project opened Data types management functions
  1111 #-------------------------------------------------------------------------------
  1241 #-------------------------------------------------------------------------------
  1112 
  1242 
  1113     # Return the data type informations
  1243     # Return the data type informations
  1114     def GetDataTypeInfos(self, tagname):
  1244     def GetDataTypeInfos(self, tagname, debug = False):
  1115         words = tagname.split("::")
  1245         project = self.GetProject(debug)
  1116         if words[0] == "D":
  1246         if project is not None:
  1117             infos = {}
  1247             words = tagname.split("::")
  1118             datatype = self.Project.getdataType(words[1])
  1248             if words[0] == "D":
  1119             basetype_content = datatype.baseType.getcontent()
  1249                 infos = {}
  1120             if basetype_content["value"] is None:
  1250                 datatype = project.getdataType(words[1])
  1121                 infos["type"] = "Directly"
  1251                 basetype_content = datatype.baseType.getcontent()
  1122                 infos["base_type"] = basetype_content["name"]
  1252                 if basetype_content["value"] is None:
  1123             elif basetype_content["name"] == "derived":
  1253                     infos["type"] = "Directly"
  1124                 infos["type"] = "Directly"
  1254                     infos["base_type"] = basetype_content["name"]
  1125                 infos["base_type"] = basetype_content["value"].getname()
  1255                 elif basetype_content["name"] == "derived":
  1126             elif basetype_content["name"] in ["subrangeSigned", "subrangeUnsigned"]:
  1256                     infos["type"] = "Directly"
  1127                 infos["type"] = "Subrange"
  1257                     infos["base_type"] = basetype_content["value"].getname()
  1128                 infos["min"] = basetype_content["value"].range.getlower()
  1258                 elif basetype_content["name"] in ["subrangeSigned", "subrangeUnsigned"]:
  1129                 infos["max"] = basetype_content["value"].range.getupper()
  1259                     infos["type"] = "Subrange"
  1130                 base_type = basetype_content["value"].baseType.getcontent()
  1260                     infos["min"] = basetype_content["value"].range.getlower()
  1131                 if base_type["value"] is None:
  1261                     infos["max"] = basetype_content["value"].range.getupper()
  1132                     infos["base_type"] = base_type["name"]
  1262                     base_type = basetype_content["value"].baseType.getcontent()
       
  1263                     if base_type["value"] is None:
       
  1264                         infos["base_type"] = base_type["name"]
       
  1265                     else:
       
  1266                         infos["base_type"] = base_type["value"].getname()
       
  1267                 elif basetype_content["name"] == "enum":
       
  1268                     infos["type"] = "Enumerated"
       
  1269                     infos["values"] = []
       
  1270                     for value in basetype_content["value"].values.getvalue():
       
  1271                         infos["values"].append(value.getname())
       
  1272                 elif basetype_content["name"] == "array":
       
  1273                     infos["type"] = "Array"
       
  1274                     infos["dimensions"] = []
       
  1275                     for dimension in basetype_content["value"].getdimension():
       
  1276                         infos["dimensions"].append((dimension.getlower(), dimension.getupper()))
       
  1277                     base_type = basetype_content["value"].baseType.getcontent()
       
  1278                     if base_type["value"] is None:
       
  1279                         infos["base_type"] = base_type["name"]
       
  1280                     else:
       
  1281                         infos["base_type"] = base_type["value"].getname()
       
  1282                 if datatype.initialValue is not None:
       
  1283                     infos["initial"] = str(datatype.initialValue.getvalue())
  1133                 else:
  1284                 else:
  1134                     infos["base_type"] = base_type["value"].getname()
  1285                     infos["initial"] = ""
  1135             elif basetype_content["name"] == "enum":
  1286                 return infos
  1136                 infos["type"] = "Enumerated"
       
  1137                 infos["values"] = []
       
  1138                 for value in basetype_content["value"].values.getvalue():
       
  1139                     infos["values"].append(value.getname())
       
  1140             elif basetype_content["name"] == "array":
       
  1141                 infos["type"] = "Array"
       
  1142                 infos["dimensions"] = []
       
  1143                 for dimension in basetype_content["value"].getdimension():
       
  1144                     infos["dimensions"].append((dimension.getlower(), dimension.getupper()))
       
  1145                 base_type = basetype_content["value"].baseType.getcontent()
       
  1146                 if base_type["value"] is None:
       
  1147                     infos["base_type"] = base_type["name"]
       
  1148                 else:
       
  1149                     infos["base_type"] = base_type["value"].getname()
       
  1150             if datatype.initialValue is not None:
       
  1151                 infos["initial"] = str(datatype.initialValue.getvalue())
       
  1152             else:
       
  1153                 infos["initial"] = ""
       
  1154             return infos
       
  1155         return None
  1287         return None
  1156     
  1288     
  1157     # Change the data type informations
  1289     # Change the data type informations
  1158     def SetDataTypeInfos(self, tagname, infos):
  1290     def SetDataTypeInfos(self, tagname, infos):
  1159         words = tagname.split("::")
  1291         words = tagname.split("::")
  1160         if words[0] == "D":
  1292         if self.Project is not None and words[0] == "D":
  1161             datatype = self.Project.getdataType(words[1])
  1293             datatype = self.Project.getdataType(words[1])
  1162             if infos["type"] == "Directly":
  1294             if infos["type"] == "Directly":
  1163                 if infos["base_type"] in self.GetBaseTypes():
  1295                 if infos["base_type"] in self.GetBaseTypes():
  1164                     if infos["base_type"] == "STRING":
  1296                     if infos["base_type"] == "STRING":
  1165                         datatype.baseType.setcontent({"name" : "string", "value" : plcopen.elementaryTypes_string()})
  1297                         datatype.baseType.setcontent({"name" : "string", "value" : plcopen.elementaryTypes_string()})
  1230 #-------------------------------------------------------------------------------
  1362 #-------------------------------------------------------------------------------
  1231 #                       Project opened Pous management functions
  1363 #                       Project opened Pous management functions
  1232 #-------------------------------------------------------------------------------
  1364 #-------------------------------------------------------------------------------
  1233 
  1365 
  1234     # Return edited element
  1366     # Return edited element
  1235     def GetEditedElement(self, tagname):
  1367     def GetEditedElement(self, tagname, debug = False):
  1236         words = tagname.split("::")
  1368         project = self.GetProject(debug)
  1237         if words[0] == "D":
  1369         if project is not None:
  1238             return self.Project.getdataType(words[1])
  1370             words = tagname.split("::")
  1239         elif words[0] == "P":
  1371             if words[0] == "D":
  1240             return self.Project.getpou(words[1])
  1372                 return project.getdataType(words[1])
  1241         elif words[0] in ['T', 'A']:
  1373             elif words[0] == "P":
  1242             pou = self.Project.getpou(words[1])
  1374                 return project.getpou(words[1])
  1243             if words[0] == 'T':
  1375             elif words[0] in ['T', 'A']:
  1244                 return pou.gettransition(words[2])
  1376                 pou = project.getpou(words[1])
  1245             elif words[0] == 'A':
  1377                 if pou is not None:
  1246                 return pou.getaction(words[2])
  1378                     if words[0] == 'T':
  1247         elif words[0] == 'C':
  1379                         return pou.gettransition(words[2])
  1248             return self.Project.getconfiguration(words[1])
  1380                     elif words[0] == 'A':
  1249         elif words[0] == 'R':
  1381                         return pou.getaction(words[2])
  1250             return self.Project.getconfigurationResource(words[1], words[2])
  1382             elif words[0] == 'C':
       
  1383                 return project.getconfiguration(words[1])
       
  1384             elif words[0] == 'R':
       
  1385                 return project.getconfigurationResource(words[1], words[2])
  1251         return None
  1386         return None
  1252     
  1387     
  1253     # Return edited element name
  1388     # Return edited element name
  1254     def GetEditedElementName(self, tagname):
  1389     def GetEditedElementName(self, tagname):
  1255         words = tagname.split("::")
  1390         words = tagname.split("::")
  1258         else:
  1393         else:
  1259             return words[2]
  1394             return words[2]
  1260         return None
  1395         return None
  1261     
  1396     
  1262     # Return edited element name and type
  1397     # Return edited element name and type
  1263     def GetEditedElementType(self, tagname):
  1398     def GetEditedElementType(self, tagname, debug = False):
  1264         words = tagname.split("::")
  1399         words = tagname.split("::")
  1265         if words[0] in ["P","T","A"]:
  1400         if words[0] in ["P","T","A"]:
  1266             return words[1], self.GetPouType(words[1])
  1401             return words[1], self.GetPouType(words[1], debug)
  1267         return None, None
  1402         return None, None
  1268 
  1403 
  1269     # Return language in which edited element is written
  1404     # Return language in which edited element is written
  1270     def GetEditedElementBodyType(self, tagname):
  1405     def GetEditedElementBodyType(self, tagname, debug = False):
  1271         words = tagname.split("::")
  1406         words = tagname.split("::")
  1272         if words[0] == "P":
  1407         if words[0] == "P":
  1273             return self.GetPouBodyType(words[1])
  1408             return self.GetPouBodyType(words[1], debug)
  1274         elif words[0] == 'T':
  1409         elif words[0] == 'T':
  1275             return self.GetTransitionBodyType(words[1], words[2])
  1410             return self.GetTransitionBodyType(words[1], words[2], debug)
  1276         elif words[0] == 'A':
  1411         elif words[0] == 'A':
  1277             return self.GetActionBodyType(words[1], words[2])
  1412             return self.GetActionBodyType(words[1], words[2], debug)
  1278         return None
  1413         return None
  1279 
  1414 
  1280     # Return the edited element variables
  1415     # Return the edited element variables
  1281     def GetEditedElementInterfaceVars(self, tagname):
  1416     def GetEditedElementInterfaceVars(self, tagname, debug = False):
  1282         words = tagname.split("::")
  1417         words = tagname.split("::")
  1283         if words[0] in ["P","T","A"]:
  1418         if words[0] in ["P","T","A"]:
  1284             pou = self.Project.getpou(words[1])
  1419             project = self.GetProject(debug)
  1285             return self.GetPouInterfaceVars(pou)
  1420             if project is not None:
       
  1421                 pou = project.getpou(words[1])
       
  1422                 if pou is not None:
       
  1423                     return self.GetPouInterfaceVars(pou)
  1286         return []
  1424         return []
  1287 
  1425 
  1288     # Return the edited element return type
  1426     # Return the edited element return type
  1289     def GetEditedElementInterfaceReturnType(self, tagname):
  1427     def GetEditedElementInterfaceReturnType(self, tagname, debug = False):
  1290         words = tagname.split("::")
  1428         words = tagname.split("::")
  1291         if words[0] == "P":
  1429         if words[0] == "P":
  1292             pou = self.Project.getpou(words[1])
  1430             project = self.GetProject(debug)
  1293             return self.GetPouInterfaceReturnType(pou)
  1431             if project is not None:
       
  1432                 pou = self.Project.getpou(words[1])
       
  1433                 if pou is not None:
       
  1434                     return self.GetPouInterfaceReturnType(pou)
  1294         elif words[0] == 'T':
  1435         elif words[0] == 'T':
  1295             return "BOOL"
  1436             return "BOOL"
  1296         return None
  1437         return None
  1297     
  1438     
  1298     # Change the edited element text
  1439     # Change the edited element text
  1299     def SetEditedElementText(self, tagname, text):
  1440     def SetEditedElementText(self, tagname, text):
  1300         element = self.GetEditedElement(tagname)
  1441         if self.Project is not None:
  1301         if element != None:
  1442             element = self.GetEditedElement(tagname)
  1302             element.settext(text)
  1443             if element is not None:
  1303             self.Project.RefreshElementUsingTree()
  1444                 element.settext(text)
       
  1445                 self.Project.RefreshElementUsingTree()
  1304     
  1446     
  1305     # Return the edited element text
  1447     # Return the edited element text
  1306     def GetEditedElementText(self, tagname):
  1448     def GetEditedElementText(self, tagname, debug = False):
  1307         element = self.GetEditedElement(tagname)
  1449         element = self.GetEditedElement(tagname, debug)
  1308         if element != None:
  1450         if element is not None:
  1309             return element.gettext()
  1451             return element.gettext()
  1310         return ""
  1452         return ""
  1311 
  1453 
  1312     # Return the edited element transitions
  1454     # Return the edited element transitions
  1313     def GetEditedElementTransitions(self, tagname):
  1455     def GetEditedElementTransitions(self, tagname, debug = False):
  1314         pou = self.GetEditedElement(tagname)
  1456         pou = self.GetEditedElement(tagname, debug)
  1315         if pou != None and pou.getbodyType() == "SFC":
  1457         if pou is not None and pou.getbodyType() == "SFC":
  1316             transitions = []
  1458             transitions = []
  1317             for transition in pou.gettransitionList():
  1459             for transition in pou.gettransitionList():
  1318                 transitions.append(transition.getname())
  1460                 transitions.append(transition.getname())
  1319             return transitions
  1461             return transitions
  1320         return []
  1462         return []
  1321 
  1463 
  1322     # Return edited element transitions
  1464     # Return edited element transitions
  1323     def GetEditedElementActions(self, tagname):
  1465     def GetEditedElementActions(self, tagname, debug = False):
  1324         pou = self.GetEditedElement(tagname)
  1466         pou = self.GetEditedElement(tagname, debug)
  1325         if pou != None and pou.getbodyType() == "SFC":
  1467         if pou is None and pou.getbodyType() == "SFC":
  1326             actions = []
  1468             actions = []
  1327             for action in pou.getactionList():
  1469             for action in pou.getactionList():
  1328                 actions.append(action.getname())
  1470                 actions.append(action.getname())
  1329             return actions
  1471             return actions
  1330         return []
  1472         return []
  1331 
  1473 
  1332     # Return the names of the pou elements
  1474     # Return the names of the pou elements
  1333     def GetEditedElementVariables(self, tagname):
  1475     def GetEditedElementVariables(self, tagname, debug = False):
  1334         words = tagname.split("::")
  1476         words = tagname.split("::")
  1335         if words[0] in ["P","T","A"]:
  1477         if words[0] in ["P","T","A"]:
  1336             return self.GetProjectPouVariables(words[1])
  1478             return self.GetProjectPouVariables(words[1], debug)
  1337         return []
  1479         return []
  1338 
  1480 
  1339     # Return the current pou editing informations
  1481     # Return the current pou editing informations
  1340     def GetEditedElementInstanceInfos(self, tagname, id = None, exclude = []):
  1482     def GetEditedElementInstanceInfos(self, tagname, id = None, exclude = [], debug = False):
  1341         infos = {}
  1483         infos = {}
  1342         instance = None
  1484         instance = None
  1343         element = self.GetEditedElement(tagname)
  1485         element = self.GetEditedElement(tagname, debug)
  1344         if element is not None:
  1486         if element is not None:
  1345             # if id is defined
  1487             # if id is defined
  1346             if id is not None:
  1488             if id is not None:
  1347                 instance = element.getinstance(id)
  1489                 instance = element.getinstance(id)
  1348             else:
  1490             else:
  1385                     connector["negated"] = variable.getnegated()
  1527                     connector["negated"] = variable.getnegated()
  1386                     connector["edge"] = variable.getedge()
  1528                     connector["edge"] = variable.getedge()
  1387                     infos["connectors"]["outputs"].append(connector)
  1529                     infos["connectors"]["outputs"].append(connector)
  1388             elif isinstance(instance, plcopen.fbdObjects_inVariable):
  1530             elif isinstance(instance, plcopen.fbdObjects_inVariable):
  1389                 infos["name"] = instance.getexpression()
  1531                 infos["name"] = instance.getexpression()
  1390                 infos["value_type"] = self.GetEditedElementVarValueType(tagname, infos["name"])
  1532                 infos["value_type"] = self.GetEditedElementVarValueType(tagname, infos["name"], debug)
  1391                 infos["type"] = "input"
  1533                 infos["type"] = "input"
  1392                 executionOrder = instance.getexecutionOrderId()
  1534                 executionOrder = instance.getexecutionOrderId()
  1393                 if executionOrder is not None:
  1535                 if executionOrder is not None:
  1394                     infos["executionOrder"] = executionOrder
  1536                     infos["executionOrder"] = executionOrder
  1395                 else:
  1537                 else:
  1398                 infos["connector"]["position"] = instance.connectionPointOut.getrelPositionXY()
  1540                 infos["connector"]["position"] = instance.connectionPointOut.getrelPositionXY()
  1399                 infos["connector"]["negated"] = instance.getnegated()
  1541                 infos["connector"]["negated"] = instance.getnegated()
  1400                 infos["connector"]["edge"] = instance.getedge()
  1542                 infos["connector"]["edge"] = instance.getedge()
  1401             elif isinstance(instance, plcopen.fbdObjects_outVariable):
  1543             elif isinstance(instance, plcopen.fbdObjects_outVariable):
  1402                 infos["name"] = instance.getexpression()
  1544                 infos["name"] = instance.getexpression()
  1403                 infos["value_type"] = self.GetEditedElementVarValueType(tagname, infos["name"])
  1545                 infos["value_type"] = self.GetEditedElementVarValueType(tagname, infos["name"], debug)
  1404                 infos["type"] = "output"
  1546                 infos["type"] = "output"
  1405                 executionOrder = instance.getexecutionOrderId()
  1547                 executionOrder = instance.getexecutionOrderId()
  1406                 if executionOrder is not None:
  1548                 if executionOrder is not None:
  1407                     infos["executionOrder"] = executionOrder
  1549                     infos["executionOrder"] = executionOrder
  1408                 else:
  1550                 else:
  1417                     for link in connections:
  1559                     for link in connections:
  1418                         dic = {"refLocalId":link.getrefLocalId(),"points":link.getpoints(),"formalParameter":link.getformalParameter()}
  1560                         dic = {"refLocalId":link.getrefLocalId(),"points":link.getpoints(),"formalParameter":link.getformalParameter()}
  1419                         infos["connector"]["links"].append(dic)
  1561                         infos["connector"]["links"].append(dic)
  1420             elif isinstance(instance, plcopen.fbdObjects_inOutVariable):
  1562             elif isinstance(instance, plcopen.fbdObjects_inOutVariable):
  1421                 infos["name"] = instance.getexpression()
  1563                 infos["name"] = instance.getexpression()
  1422                 infos["value_type"] = self.GetEditedElementVarValueType(tagname, infos["name"])
  1564                 infos["value_type"] = self.GetEditedElementVarValueType(tagname, infos["name"], debug)
  1423                 infos["type"] = "inout"
  1565                 infos["type"] = "inout"
  1424                 executionOrder = instance.getexecutionOrderId()
  1566                 executionOrder = instance.getexecutionOrderId()
  1425                 if executionOrder is not None:
  1567                 if executionOrder is not None:
  1426                     infos["executionOrder"] = executionOrder
  1568                     infos["executionOrder"] = executionOrder
  1427                 else:
  1569                 else:
  1622                 if connections:
  1764                 if connections:
  1623                     for link in connections:
  1765                     for link in connections:
  1624                         dic = {"refLocalId":link.getrefLocalId(),"points":link.getpoints(),"formalParameter":link.getformalParameter()}
  1766                         dic = {"refLocalId":link.getrefLocalId(),"points":link.getpoints(),"formalParameter":link.getformalParameter()}
  1625                         infos["connector"]["links"].append(dic)
  1767                         infos["connector"]["links"].append(dic)
  1626             return infos
  1768             return infos
  1627         return False
  1769         return None
  1628     
  1770     
  1629     def ClearEditedElementExecutionOrder(self, tagname):
  1771     def ClearEditedElementExecutionOrder(self, tagname):
  1630         element = self.GetEditedElement(tagname)
  1772         element = self.GetEditedElement(tagname)
  1631         if element is not None:
  1773         if element is not None:
  1632             element.resetexecutionOrder()
  1774             element.resetexecutionOrder()
  1635         element = self.GetEditedElement(tagname)
  1777         element = self.GetEditedElement(tagname)
  1636         if element is not None:
  1778         if element is not None:
  1637             element.compileexecutionOrder()
  1779             element.compileexecutionOrder()
  1638     
  1780     
  1639     # Return the variable type of the given pou
  1781     # Return the variable type of the given pou
  1640     def GetEditedElementVarValueType(self, tagname, varname):
  1782     def GetEditedElementVarValueType(self, tagname, varname, debug = False):
  1641         words = tagname.split("::")
  1783         project = self.GetProject(debug)
  1642         if words[0] in ["P","T","A"]:
  1784         if project is not None:
  1643             pou = self.Project.getpou(words[1])
  1785             words = tagname.split("::")
  1644             for type, varlist in pou.getvars():
  1786             if words[0] in ["P","T","A"]:
  1645                 for var in varlist.getvariable():
  1787                 pou = self.Project.getpou(words[1])
  1646                     if var.getname() == varname:
  1788                 if pou is not None:
  1647                         vartype_content = var.gettype().getcontent()
  1789                     for type, varlist in pou.getvars():
  1648                         if vartype_content["name"] == "derived":
  1790                         for var in varlist.getvariable():
  1649                             return vartype_content["value"].getname()
  1791                             if var.getname() == varname:
  1650                         elif vartype_content["name"] in ["string", "wstring"]:
  1792                                 vartype_content = var.gettype().getcontent()
  1651                             return vartype_content["name"].upper()
  1793                                 if vartype_content["name"] == "derived":
  1652                         else:
  1794                                     return vartype_content["value"].getname()
  1653                             return vartype_content["name"]
  1795                                 elif vartype_content["name"] in ["string", "wstring"]:
       
  1796                                     return vartype_content["name"].upper()
       
  1797                                 else:
       
  1798                                     return vartype_content["name"]
  1654         return None
  1799         return None
  1655     
  1800     
  1656     def SetConnectionWires(self, connection, connector):
  1801     def SetConnectionWires(self, connection, connector):
  1657         wires = connector.GetWires()
  1802         wires = connector.GetWires()
  1658         idx = 0
  1803         idx = 0
  1674                 else:
  1819                 else:
  1675                     connection.setconnectionParameter(idx, None)
  1820                     connection.setconnectionParameter(idx, None)
  1676                 idx += 1
  1821                 idx += 1
  1677     
  1822     
  1678     def AddEditedElementPouVar(self, tagname, type, name):
  1823     def AddEditedElementPouVar(self, tagname, type, name):
  1679         words = tagname.split("::")
  1824         if self.Project is not None:
  1680         if words[0] in ['P', 'T', 'A']:
  1825             words = tagname.split("::")
  1681             pou = self.Project.getpou(words[1])
  1826             if words[0] in ['P', 'T', 'A']:
  1682             if not pou.interface:
  1827                 pou = self.Project.getpou(words[1])
  1683                 pou.interface = plcopen.pou_interface()
  1828                 if pou is not None:
  1684             pou.addpouVar(type, name)
  1829                     if pou.interface is None:
       
  1830                         pou.interface = plcopen.pou_interface()
       
  1831                     pou.addpouVar(type, name)
  1685             
  1832             
  1686     def ChangeEditedElementPouVar(self, tagname, old_type, old_name, new_type, new_name):
  1833     def ChangeEditedElementPouVar(self, tagname, old_type, old_name, new_type, new_name):
  1687         words = tagname.split("::")
  1834         if self.Project is not None:
  1688         if words[0] in ['P', 'T', 'A']:
  1835             words = tagname.split("::")
  1689             pou = self.Project.getpou(words[1])
  1836             if words[0] in ['P', 'T', 'A']:
  1690             pou.changepouVar(old_type, old_name, new_type, new_name)
  1837                 pou = self.Project.getpou(words[1])
       
  1838                 if pou is not None:
       
  1839                     pou.changepouVar(old_type, old_name, new_type, new_name)
  1691     
  1840     
  1692     def RemoveEditedElementPouVar(self, tagname, type, name):
  1841     def RemoveEditedElementPouVar(self, tagname, type, name):
  1693         words = tagname.split("::")
  1842         if self.Project is not None:
  1694         if words[0] in ['P', 'T', 'A']:
  1843             words = tagname.split("::")
  1695             pou = self.Project.getpou(words[1])
  1844             if words[0] in ['P', 'T', 'A']:
  1696             pou.removepouVar(type, name)
  1845                 pou = self.Project.getpou(words[1])
       
  1846                 if pou is not None:
       
  1847                     pou.removepouVar(type, name)
  1697     
  1848     
  1698     def AddEditedElementBlock(self, tagname, id, blocktype, blockname = None):
  1849     def AddEditedElementBlock(self, tagname, id, blocktype, blockname = None):
  1699         element = self.GetEditedElement(tagname)
  1850         element = self.GetEditedElement(tagname)
  1700         if element is not None:
  1851         if element is not None:
  1701             block = plcopen.fbdObjects_block()
  1852             block = plcopen.fbdObjects_block()
  2273             if isinstance(instance, plcopen.fbdObjects_block):
  2424             if isinstance(instance, plcopen.fbdObjects_block):
  2274                 self.RemoveEditedElementPouVar(tagname, instance.gettypeName(), instance.getinstanceName())
  2425                 self.RemoveEditedElementPouVar(tagname, instance.gettypeName(), instance.getinstanceName())
  2275             element.removeinstance(id)
  2426             element.removeinstance(id)
  2276             self.Project.RefreshElementUsingTree()
  2427             self.Project.RefreshElementUsingTree()
  2277 
  2428 
  2278     def GetEditedResourceVariables(self, tagname):
  2429     def GetEditedResourceVariables(self, tagname, debug = False):
  2279         varlist = []
  2430         varlist = []
  2280         words = tagname.split("::")
  2431         words = tagname.split("::")
  2281         for var in self.GetConfigurationGlobalVars(words[1]):
  2432         for var in self.GetConfigurationGlobalVars(words[1], debug):
  2282             if var["Type"] == "BOOL":
  2433             if var["Type"] == "BOOL":
  2283                 varlist.append(var["Name"])
  2434                 varlist.append(var["Name"])
  2284         for var in self.GetConfigurationResourceGlobalVars(words[1], words[2]):
  2435         for var in self.GetConfigurationResourceGlobalVars(words[1], words[2], debug):
  2285             if var["Type"] == "BOOL":
  2436             if var["Type"] == "BOOL":
  2286                 varlist.append(var["Name"])
  2437                 varlist.append(var["Name"])
  2287         return varlist
  2438         return varlist
  2288 
  2439 
  2289     def SetEditedResourceInfos(self, tagname, tasks, instances):
  2440     def SetEditedResourceInfos(self, tagname, tasks, instances):
  2319                 if instance["Task"] != "":
  2470                 if instance["Task"] != "":
  2320                     task_list[instance["Task"]].appendpouInstance(new_instance)
  2471                     task_list[instance["Task"]].appendpouInstance(new_instance)
  2321                 else:
  2472                 else:
  2322                     resource.appendpouInstance(new_instance)
  2473                     resource.appendpouInstance(new_instance)
  2323 
  2474 
  2324     def GetEditedResourceInfos(self, tagname):
  2475     def GetEditedResourceInfos(self, tagname, debug = False):
  2325         resource = self.GetEditedElement(tagname)
  2476         resource = self.GetEditedElement(tagname, debug)
  2326         if resource is not None:
  2477         if resource is not None:
  2327             tasks = resource.gettask()
  2478             tasks = resource.gettask()
  2328             instances = resource.getpouInstance()
  2479             instances = resource.getpouInstance()
  2329             tasks_data = []
  2480             tasks_data = []
  2330             instances_data = []
  2481             instances_data = []
  2381                 self.SetFilePath(filepath)
  2532                 self.SetFilePath(filepath)
  2382                 self.Project.RefreshElementUsingTree()
  2533                 self.Project.RefreshElementUsingTree()
  2383                 self.Project.RefreshDataTypeHierarchy()
  2534                 self.Project.RefreshDataTypeHierarchy()
  2384                 self.Project.RefreshCustomBlockTypes()
  2535                 self.Project.RefreshCustomBlockTypes()
  2385                 self.ProjectBuffer = UndoBuffer(self.Copy(self.Project), True)
  2536                 self.ProjectBuffer = UndoBuffer(self.Copy(self.Project), True)
       
  2537                 self.ProgramChunks = []
       
  2538                 self.CurrentCompiledProject = None
  2386                 self.Buffering = False
  2539                 self.Buffering = False
  2387                 self.ElementsOpened = []
       
  2388                 self.CurrentElementEditing = None
  2540                 self.CurrentElementEditing = None
  2389                 return None
  2541                 return None
  2390         return "No PLC project found"
  2542         return "No PLC project found"
  2391 
  2543 
  2392     def SaveXMLFile(self, filepath = None):
  2544     def SaveXMLFile(self, filepath = None):
  2435     def EndBuffering(self):
  2587     def EndBuffering(self):
  2436         if self.Buffering:
  2588         if self.Buffering:
  2437             self.Project = self.Copy(self.Project)
  2589             self.Project = self.Copy(self.Project)
  2438             self.Buffering = False
  2590             self.Buffering = False
  2439 
  2591 
       
  2592     # Return if project is saved
  2440     def ProjectIsSaved(self):
  2593     def ProjectIsSaved(self):
  2441         if self.ProjectBuffer:
  2594         if self.ProjectBuffer is not None:
  2442             return self.ProjectBuffer.IsCurrentSaved()
  2595             return self.ProjectBuffer.IsCurrentSaved()
  2443         else:
  2596         else:
  2444             return True
  2597             return True
  2445 
  2598 
  2446     def LoadPrevious(self):
  2599     def LoadPrevious(self):