PLCControler.py
changeset 249 d8425712acef
parent 236 9f594b90bb1a
child 252 166ee9d2e233
--- a/PLCControler.py	Fri Sep 05 18:12:23 2008 +0200
+++ b/PLCControler.py	Fri Sep 05 18:13:18 2008 +0200
@@ -37,31 +37,34 @@
 duration_model = re.compile("(?:([0-9]{1,2})h)?(?:([0-9]{1,2})m(?!s))?(?:([0-9]{1,2})s)?(?:([0-9]{1,3}(?:\.[0-9]*)?)ms)?")
 
 ITEMS_EDITABLE = [ITEM_PROJECT,
-                    ITEM_POU,
-                    ITEM_VARIABLE,
-                    ITEM_TRANSITION,
-                    ITEM_ACTION,
-                    ITEM_CONFIGURATION,
-                    ITEM_RESOURCE,
-                    ITEM_DATATYPE] = range(8)
-
-ITEMS_UNEDITABLE=[ITEM_DATATYPES,
-                  ITEM_FUNCTION,
-                  ITEM_FUNCTIONBLOCK,
-                  ITEM_PROGRAM,
-                  ITEM_VAR_LOCAL,
+                  ITEM_POU,
+                  ITEM_VARIABLE,
+                  ITEM_TRANSITION,
+                  ITEM_ACTION,
+                  ITEM_CONFIGURATION,
+                  ITEM_RESOURCE,
+                  ITEM_DATATYPE
+                 ] = range(8)
+
+ITEMS_UNEDITABLE = [ITEM_DATATYPES,
+                    ITEM_FUNCTION,
+                    ITEM_FUNCTIONBLOCK,
+                    ITEM_PROGRAM,
+                    ITEM_TRANSITIONS,
+                    ITEM_ACTIONS,
+                    ITEM_CONFIGURATIONS,
+                    ITEM_RESOURCES,
+                    ITEM_PROPERTIES
+                   ] = range(8, 17)
+ 
+ITEMS_VARIABLE = [ITEM_VAR_LOCAL,
                   ITEM_VAR_GLOBAL,
                   ITEM_VAR_EXTERNAL,
                   ITEM_VAR_TEMP,
                   ITEM_VAR_INPUT,
                   ITEM_VAR_OUTPUT,
-                  ITEM_VAR_INOUT,
-                  ITEM_TRANSITIONS,
-                  ITEM_ACTIONS,
-                  ITEM_CONFIGURATIONS,
-                  ITEM_RESOURCES,
-                  ITEM_PROPERTIES,
-                  ]=range(9,25)
+                  ITEM_VAR_INOUT
+                 ] = range(17, 24)
 
 VAR_CLASS_INFOS = {"Local" :    (plcopen.interface_localVars,    ITEM_VAR_LOCAL),
                    "Global" :   (plcopen.interface_globalVars,   ITEM_VAR_GLOBAL),
@@ -179,19 +182,26 @@
         self.FilePath = ""
         self.FileName = ""
         self.ProgramChunks = []
+        self.CurrentCompiledProject = None
         self.PluginTypes = []
         self.ProgramFilePath = ""
         
     def GetQualifierTypes(self):
         return plcopen.QualifierList
 
+    def GetProject(self, debug = False):
+        if debug and self.CurrentCompiledProject is not None:
+            return self.CurrentCompiledProject
+        else:
+            return self.Project
+
 #-------------------------------------------------------------------------------
 #                         Project management functions
 #-------------------------------------------------------------------------------
 
     # Return if a project is opened
     def HasOpenedProject(self):
-        return self.Project != None
+        return self.Project is not None
 
     # Create a new project by replacing the current one
     def CreateNewProject(self, properties):
@@ -203,42 +213,45 @@
         self.SetFilePath("")
         # Initialize the project buffer
         self.ProjectBuffer = UndoBuffer(self.Copy(self.Project), False)
+        self.ProgramChunks = []
+        self.CurrentCompiledProject = None
         self.Buffering = False
     
     # Return project data type names
-    def GetProjectDataTypeNames(self):
-        if self.Project:
-            return [datatype.getname() for datatype in self.Project.getdataTypes()]
+    def GetProjectDataTypeNames(self, debug = False):
+        project = self.GetProject(debug)
+        if project is not None:
+            return [datatype.getname() for datatype in project.getdataTypes()]
         return []
     
     # Return project pou names
-    def GetProjectPouNames(self):
-        if self.Project:
-            return [pou.getname() for pou in self.Project.getpous()]
+    def GetProjectPouNames(self, debug = False):
+        project = self.GetProject(debug)
+        if project is not None:
+            return [pou.getname() for pou in project.getpous()]
         return []
     
     # Return project pou names
-    def GetProjectConfigNames(self):
-        if self.Project:
-            return [config.getName() for config in self.Project.getconfigurations()]
+    def GetProjectConfigNames(self, debug = False):
+        project = self.GetProject(debug)
+        if project is not None:
+            return [config.getName() for config in project.getconfigurations()]
         return []
     
     # Return project pou variables
-    def GetProjectPouVariables(self, pou_name=None):
+    def GetProjectPouVariables(self, pou_name = None, debug = False):
         variables = []
-        for pou in self.Project.getpous():
-            if not pou_name or pou_name == pou.getname():
-                variables.extend([var["Name"] for var in self.GetPouInterfaceVars(pou)])
-                for transition in pou.gettransitionList():
-                    variables.append(transition.getname())
-                for action in pou.getactionList():
-                    variables.append(action.getname())
+        project = self.GetProject(debug)
+        if project is not None:
+            for pou in project.getpous():
+                if pou_name is None or pou_name == pou.getname():
+                    variables.extend([var["Name"] for var in self.GetPouInterfaceVars(pou)])
+                    for transition in pou.gettransitionList():
+                        variables.append(transition.getname())
+                    for action in pou.getactionList():
+                        variables.append(action.getname())
         return variables
     
-    # Return if project is saved
-    def ProjectIsSaved(self):
-        return self.ProjectBuffer.IsCurrentSaved()
-    
     # Return file path if project is an open file
     def GetFilePath(self):
         return self.FilePath
@@ -249,10 +262,12 @@
     
     # Return file name and point out if file is up to date
     def GetFilename(self):
-        if self.ProjectBuffer.IsCurrentSaved():
-            return self.FileName
-        else:
-            return "~%s~"%self.FileName
+        if self.Project is not None:
+            if self.ProjectBuffer.IsCurrentSaved():
+                return self.FileName
+            else:
+                return "~%s~"%self.FileName
+        return ""
     
     # Change file path and save file name or create a default one if file path not defined
     def SetFilePath(self, filepath):
@@ -265,32 +280,37 @@
     
     # Change project properties
     def SetProjectProperties(self, name = None, properties = None):
-        if name != None:
-            self.Project.setname(name)
-        if properties != None:
-            self.Project.setfileHeader(properties)
-            self.Project.setcontentHeader(properties)
-        if name != None or properties != None:
-            self.BufferProject()
+        if self.Project is not None:
+            if name is not None:
+                self.Project.setname(name)
+            if properties is not None:
+                self.Project.setfileHeader(properties)
+                self.Project.setcontentHeader(properties)
+            if name is not None or properties is not None:
+                self.BufferProject()
             
     # Return project properties
-    def GetProjectProperties(self):
-        properties = self.Project.getfileHeader()
-        properties.update(self.Project.getcontentHeader())
-        return properties
+    def GetProjectProperties(self, debug = False):
+        project = self.GetProject(debug)
+        if project is not None:
+            properties = project.getfileHeader()
+            properties.update(project.getcontentHeader())
+            return properties
+        return None
     
     # Return project informations
-    def GetProjectInfos(self):
-        if self.Project:
-            infos = {"name": self.Project.getname(), "type": ITEM_PROJECT}
+    def GetProjectInfos(self, debug = False):
+        project = self.GetProject(debug)
+        if project is not None:
+            infos = {"name": project.getname(), "type": ITEM_PROJECT}
             datatypes = {"name": "Data Types", "type": ITEM_DATATYPES, "values":[]}
-            for datatype in self.Project.getdataTypes():
+            for datatype in project.getdataTypes():
                 datatypes["values"].append({"name": datatype.getname(), "type": ITEM_DATATYPE, 
                     "tagname": self.ComputeDataTypeName(datatype.getname()), "values": []})
             pou_types = {"function": {"name": "Functions", "type": ITEM_FUNCTION, "values":[]},
                          "functionBlock": {"name": "Function Blocks", "type": ITEM_FUNCTIONBLOCK, "values":[]},
                          "program": {"name": "Programs", "type": ITEM_PROGRAM, "values":[]}}
-            for pou in self.Project.getpous():
+            for pou in project.getpous():
                 pou_type = pou.getpouType()
                 pou_infos = {"name": pou.getname(), "type": ITEM_POU,
                              "tagname": self.ComputePouName(pou.getname())}
@@ -312,7 +332,7 @@
                     pou_infos["values"] = pou_values
                     pou_types[pou_type]["values"].append(pou_infos)
             configurations = {"name": "Configurations", "type": ITEM_CONFIGURATIONS, "values": []}
-            for config in self.Project.getconfigurations():
+            for config in project.getconfigurations():
                 config_name = config.getname()
                 config_infos = {"name": config_name, "type": ITEM_CONFIGURATION, 
                     "tagname": self.ComputeConfigurationName(config.getname()), 
@@ -333,27 +353,28 @@
         return None
 
     # Return project topology informations
-    def GetProjectTopology(self):
-        if self.Project:
-            infos = {"name": self.Project.getname(), "type": ITEM_PROJECT, "values" : []}
-            for config in self.Project.getconfigurations():
+    def GetProjectTopology(self, debug = False):
+        project = self.GetProject(debug)
+        if project is not None:
+            infos = {"name": project.getname(), "type": ITEM_PROJECT, "values" : []}
+            for config in project.getconfigurations():
                 config_infos = {"name" : config.getname(), "type": ITEM_CONFIGURATION, "values" : []}
                 for resource in config.getresource():
                     resource_infos = {"name" : resource.getname(), "type": ITEM_RESOURCE, "values": []}
                     for task in resource.gettask():
                         for pou in task.getpouInstance():
-                            instance_infos = self.GetPouTopology(pou.getname(), pou.gettype())
+                            instance_infos = self.GetPouTopology(pou.getname(), pou.gettype(), debug=debug)
                             if instance_infos is not None:
                                 resource_infos["values"].append(instance_infos)
                     for pou in resource.getpouInstance():
-                        instance_infos = self.GetPouTopology(pou.getname(), pou.gettype())
+                        instance_infos = self.GetPouTopology(pou.getname(), pou.gettype(), debug=debug)
                         if instance_infos is not None:
                             resource_infos["values"].append(instance_infos)
                     for varlist in resource.getglobalVars():
                         for variable in varlist.getvariable():
                             vartype_content = variable.gettype().getcontent()
                             if vartype_content["name"] == "derived":
-                                var_infos = self.GetPouTopology(variable.getname(), vartype_content["value"].getname(), True)
+                                var_infos = self.GetPouTopology(variable.getname(), vartype_content["value"].getname(), True, debug)
                                 if var_infos is not None:
                                     resource_infos["values"].append(var_infos)
                             elif vartype_content["name"] in ["string", "wstring"]:
@@ -369,7 +390,7 @@
                     for variable in varlist.getvariable():
                         vartype_content = variable.gettype().getcontent()
                         if vartype_content["name"] == "derived":
-                            var_infos = self.GetPouTopology(variable.getname(), vartype_content["value"].getname(), True)
+                            var_infos = self.GetPouTopology(variable.getname(), vartype_content["value"].getname(), True, debug)
                             if var_infos is not None:
                                 config_infos["values"].append(var_infos)
                         elif vartype_content["name"] in ["string", "wstring"]:
@@ -385,17 +406,31 @@
         return None
     
     # Return pou topology informations
-    def GetPouTopology(self, name, type, global_var=False):
-        if self.Project:
-            pou = self.Project.getpou(type)
+    def GetPouTopology(self, name, type, global_var = False, debug = False):
+        project = self.GetProject(debug)
+        if project is not None:
+            pou = project.getpou(type)
             if pou is not None:
                 pou_type = pou.getpouType()
                 if pou_type == "function":
                     return None
                 elif pou_type == "program":
-                    pou_infos = {"name" : name, "elmt_type" : type, "type" : ITEM_PROGRAM, "values" : []}
+                    pou_infos = {"name" : name, "elmt_type" : type, "type" : ITEM_PROGRAM, 
+                                 "tagname" : self.ComputePouName(pou.getname()), "values" : []}
                 else:
-                    pou_infos = {"name" : name, "elmt_type" : type, "type" : ITEM_FUNCTIONBLOCK, "values" : []}
+                    pou_infos = {"name" : name, "elmt_type" : type, "type" : ITEM_FUNCTIONBLOCK, 
+                                 "tagname" : self.ComputePouName(pou.getname()), "values" : []}
+                if pou.getbodyType() == "SFC":
+                    for transition in pou.gettransitionList():
+                        pou_infos["values"].append({"name" : transition.getname(), 
+                            "elmt_type" : "TRANSITION", "type" : ITEM_TRANSITION, 
+                            "tagname" : self.ComputePouActionName(pou.getname(), transition.getname()),
+                            "values" : []})
+                    for action in pou.getactionList():
+                        pou_infos["values"].append({"name": action.getname(), 
+                            "elmt_type" : "ACTION", "type": ITEM_ACTION, 
+                            "tagname" : self.ComputePouActionName(pou.getname(), action.getname()),
+                            "values" : []})
                 if pou.interface:
                     # Extract variables from every varLists
                     for type, varlist in pou.getvars():
@@ -419,7 +454,7 @@
                                                             "elmt_type" : vartype_content["name"], 
                                                             "type" : current_var_class, "values" : []})
                 return pou_infos
-            block_infos = self.GetBlockType(type)
+            block_infos = self.GetBlockType(type, debug = debug)
             if block_infos is not None:
                 if block_infos["type"] == "function":
                     return None
@@ -433,7 +468,7 @@
                     pou_infos["values"].append({"name" : varname, "elmt_type" : vartype, "type" : ITEM_VAR_INPUT, "values" : []})
                 return pou_infos
             
-            if type in self.GetDataTypes():
+            if type in self.GetDataTypes(debug = debug):
                 if global_var:
                     return {"name" : name, "elmt_type" : type, "type" : ITEM_VAR_GLOBAL, "values" : []}
                 else:
@@ -441,21 +476,31 @@
         return None
 
     # Return if data type given by name is used by another data type or pou
-    def DataTypeIsUsed(self, name):
-        return self.Project.ElementIsUsed(name) or self.Project.DataTypeIsDerived(name)
+    def DataTypeIsUsed(self, name, debug = False):
+        project = self.GetProject(debug)
+        if project is not None:
+            return project.ElementIsUsed(name) or project.DataTypeIsDerived(name)
+        return False
 
     # Return if pou given by name is used by another pou
-    def PouIsUsed(self, name):
-        return self.Project.ElementIsUsed(name)
+    def PouIsUsed(self, name, debug = False):
+        project = self.GetProject(debug)
+        if project is not None:
+            return project.ElementIsUsed(name)
+        return False
 
     # Return if pou given by name is directly or undirectly used by the reference pou
-    def PouIsUsedBy(self, name, reference):
-        return self.Project.ElementIsUsedBy(name, reference)
+    def PouIsUsedBy(self, name, reference, debug = False):
+        project = self.GetProject(debug)
+        if project is not None:
+            return project.ElementIsUsedBy(name, reference)
+        return False
 
     def GenerateProgram(self, filepath):
-        if self.Project:
+        if self.Project is not None:
             try:
                 self.ProgramChunks = GenerateCurrentProgram(self, self.Project)
+                self.CurrentCompiledProject = self.Copy(self.Project)
                 program_text = "".join([item[0] for item in self.ProgramChunks])
                 programfile = open(filepath, "w")
                 programfile.write(program_text)
@@ -490,190 +535,245 @@
     
     # Add a Data Type to Project
     def ProjectAddDataType(self, datatype_name):
-        # Add the pou to project
-        self.Project.appenddataType(datatype_name)
-        self.BufferProject()
-    
+        if self.Project is not None:
+            # Add the datatype to project
+            self.Project.appenddataType(datatype_name)
+            self.BufferProject()
+        
     # Remove a Data Type from project
     def ProjectRemoveDataType(self, datatype_name):
-        self.Project.removedataType(datatype_name)
-        self.BufferProject()
+        if self.Project is not None:
+            self.Project.removedataType(datatype_name)
+            self.BufferProject()
     
     # Add a Pou to Project
     def ProjectAddPou(self, pou_name, pou_type, body_type):
-        # Add the pou to project
-        self.Project.appendpou(pou_name, pou_type, body_type)
-        if pou_type == "function":
-            self.SetPouInterfaceReturnType(pou_name, "BOOL")
-        self.BufferProject()
+        if self.Project is not None:
+            # Add the pou to project
+            self.Project.appendpou(pou_name, pou_type, body_type)
+            if pou_type == "function":
+                self.SetPouInterfaceReturnType(pou_name, "BOOL")
+            self.BufferProject()
     
     # Remove a Pou from project
     def ProjectRemovePou(self, pou_name):
-        self.Project.removepou(pou_name)
-        self.BufferProject()
+        if self.Project is not None:
+            self.Project.removepou(pou_name)
+            self.BufferProject()
     
     # Add a configuration to Project
     def ProjectAddConfiguration(self, config_name):
-        self.Project.addconfiguration(config_name)
-        self.BufferProject()
+        if self.Project is not None:
+            self.Project.addconfiguration(config_name)
+            self.BufferProject()
     
     # Remove a configuration from project
     def ProjectRemoveConfiguration(self, config_name):
-        self.Project.removeconfiguration(config_name)
-        self.BufferProject()
+        if self.Project is not None:
+            self.Project.removeconfiguration(config_name)
+            self.BufferProject()
     
     # Add a resource to a configuration of the Project
     def ProjectAddConfigurationResource(self, config_name, resource_name):
-        self.Project.addconfigurationResource(config_name, resource_name)
-        self.BufferProject()
+        if self.Project is not None:
+            self.Project.addconfigurationResource(config_name, resource_name)
+            self.BufferProject()
     
     # Remove a resource from a configuration of the project
     def ProjectRemoveConfigurationResource(self, config_name, resource_name):
-        self.Project.removeconfigurationResource(config_name, resource_name)
-        self.BufferProject()
+        if self.Project is not None:
+            self.Project.removeconfigurationResource(config_name, resource_name)
+            self.BufferProject()
     
     # Add a Transition to a Project Pou
     def ProjectAddPouTransition(self, pou_name, transition_name, transition_type):
-        pou = self.Project.getpou(pou_name)
-        pou.addtransition(transition_name, transition_type)
-        self.BufferProject()
+        if self.Project is not None:
+            pou = self.Project.getpou(pou_name)
+            if pou is not None:
+                pou.addtransition(transition_name, transition_type)
+                self.BufferProject()
     
     # Remove a Transition from a Project Pou
     def ProjectRemovePouTransition(self, pou_name, transition_name):
-        pou = self.Project.getpou(pou_name)
-        pou.removetransition(transition_name)
-        self.BufferProject()
+        # Search if the pou removed is currently opened
+        if self.Project is not None:
+            pou = self.Project.getpou(pou_name)
+            if pou is not None:
+                pou.removetransition(transition_name)
+                self.BufferProject()
     
     # Add an Action to a Project Pou
     def ProjectAddPouAction(self, pou_name, action_name, action_type):
-        pou = self.Project.getpou(pou_name)
-        pou.addaction(action_name, action_type)
-        self.BufferProject()
+        if self.Project is not None:
+            pou = self.Project.getpou(pou_name)
+            if pou is not None:
+                pou.addaction(action_name, action_type)
+                self.BufferProject()
     
     # Remove an Action from a Project Pou
     def ProjectRemovePouAction(self, pou_name, action_name):
         # Search if the pou removed is currently opened
-        for i, element in enumerate(self.ElementsOpened):
-            words = element.split("::")
-            if words[0] == "A" and words[1] == pou_name and words[2] == action_name:
-                self.RemoveElementEditing(i)
-        pou = self.Project.getpou(pou_name)
-        pou.removeaction(action_name)
-        self.BufferProject()
+        if self.Project is not None:
+            pou = self.Project.getpou(pou_name)
+            if pou is not None:
+                pou.removeaction(action_name)
+                self.BufferProject()
     
     # Change the name of a pou
     def ChangeDataTypeName(self, old_name, new_name):
-        # Found the pou corresponding to old name and change its name to new name
-        datatype = self.Project.getdataType(old_name)
-        datatype.setname(new_name)
-        self.Project.updateElementName(old_name, new_name)
-        self.BufferProject()
+        if self.Project is not None:
+            # Found the pou corresponding to old name and change its name to new name
+            datatype = self.Project.getdataType(old_name)
+            if datatype is not None:
+                datatype.setname(new_name)
+                self.Project.updateElementName(old_name, new_name)
+                self.BufferProject()
     
     # Change the name of a pou
     def ChangePouName(self, old_name, new_name):
-        # Found the pou corresponding to old name and change its name to new name
-        pou = self.Project.getpou(old_name)
-        pou.setname(new_name)
-        self.Project.updateElementName(old_name, new_name)
-        self.Project.RefreshElementUsingTree()
-        self.Project.RefreshCustomBlockTypes()
-        self.BufferProject()
+        if self.Project is not None:
+            # Found the pou corresponding to old name and change its name to new name
+            pou = self.Project.getpou(old_name)
+            if pou is not None:
+                pou.setname(new_name)
+                self.Project.updateElementName(old_name, new_name)
+                self.Project.RefreshElementUsingTree()
+                self.Project.RefreshCustomBlockTypes()
+                self.BufferProject()
     
     # Change the name of a pou transition
     def ChangePouTransitionName(self, pou_name, old_name, new_name):
-        # Found the pou transition corresponding to old name and change its name to new name
-        pou = self.Project.getpou(pou_name)
-        transition = pou.gettransition(old_name)
-        transition.setname(new_name)
-        pou.updateElementName(old_name, new_name)
-        self.BufferProject()
+        if self.Project is not None:
+            # Found the pou transition corresponding to old name and change its name to new name
+            pou = self.Project.getpou(pou_name)
+            if pou is not None:
+                transition = pou.gettransition(old_name)
+                if transition is not None:
+                    transition.setname(new_name)
+                    pou.updateElementName(old_name, new_name)
+                    self.BufferProject()
     
     # Change the name of a pou action
     def ChangePouActionName(self, pou_name, old_name, new_name):
-        # Found the pou action corresponding to old name and change its name to new name
-        pou = self.Project.getpou(pou_name)
-        action = pou.getaction(old_name)
-        action.setname(new_name)
-        pou.updateElementName(old_name, new_name)
-        self.BufferProject()
+        if self.Project is not None:
+            # Found the pou action corresponding to old name and change its name to new name
+            pou = self.Project.getpou(pou_name)
+            if pou is not None:
+                action = pou.getaction(old_name)
+                if action is not None:
+                    action.setname(new_name)
+                    pou.updateElementName(old_name, new_name)
+                    self.BufferProject()
     
     # Change the name of a pou variable
     def ChangePouVariableName(self, pou_name, old_name, new_name):
-        # Found the pou action corresponding to old name and change its name to new name
-        pou = self.Project.getpou(pou_name)
-        for type, varlist in pou.getvars():
-            for var in varlist.getvariable():
-                if var.getname() == old_name:
-                    var.setname(new_name)
-        self.Project.RefreshCustomBlockTypes()
-        self.BufferProject()
+        if self.Project is not None:
+            # Found the pou action corresponding to old name and change its name to new name
+            pou = self.Project.getpou(pou_name)
+            if pou is not None:
+                for type, varlist in pou.getvars():
+                    for var in varlist.getvariable():
+                        if var.getname() == old_name:
+                            var.setname(new_name)
+                self.Project.RefreshCustomBlockTypes()
+                self.BufferProject()
         
     # Change the name of a configuration
     def ChangeConfigurationName(self, old_name, new_name):
-        # Found the configuration corresponding to old name and change its name to new name
-        configuration = self.Project.getconfiguration(old_name)
-        configuration.setname(new_name)
-        self.BufferProject()
+        if self.Project is not None:
+            # Found the configuration corresponding to old name and change its name to new name
+            configuration = self.Project.getconfiguration(old_name)
+            if configuration is not None:
+                configuration.setname(new_name)
+                self.BufferProject()
     
     # Change the name of a configuration resource
     def ChangeConfigurationResourceName(self, config_name, old_name, new_name):
-        # Found the resource corresponding to old name and change its name to new name
-        resource = self.Project.getconfigurationResource(config_name)
-        resource.setName(new_name)
-        self.BufferProject()
+        if self.Project is not None:
+            # Found the resource corresponding to old name and change its name to new name
+            resource = self.Project.getconfigurationResource(config_name)
+            if resource is not None:
+                resource.setName(new_name)
+                self.BufferProject()
     
     # Return the type of the pou given by its name
-    def GetPouType(self, name):
-        # Found the pou correponding to name and return its type
-        pou = self.Project.getpou(name)
-        return pou.getpouType()
+    def GetPouType(self, name, debug = False):
+        project = self.GetProject(debug)
+        if project is not None:
+            # Found the pou correponding to name and return its type
+            pou = project.getpou(name)
+            if pou is not None:
+                return pou.getpouType()
+        return None
     
     # Return pous with SFC language
-    def GetSFCPous(self):
+    def GetSFCPous(self, debug = False):
         list = []
-        if self.Project:
-            for pou in self.Project.getpous():
+        project = self.GetProject(debug)
+        if project is not None:
+            for pou in project.getpous():
                 if pou.getBodyType() == "SFC":
                     list.append(pou.getname())
         return list
     
     # Return the body language of the pou given by its name
-    def GetPouBodyType(self, name):
-        # Found the pou correponding to name and return its body language
-        pou = self.Project.getpou(name)
-        return pou.getbodyType()
+    def GetPouBodyType(self, name, debug = False):
+        project = self.GetProject(debug)
+        if project is not None:
+            # Found the pou correponding to name and return its body language
+            pou = project.getpou(name)
+            if pou is not None:
+                return pou.getbodyType()
+        return None
     
     # Return the actions of a pou
-    def GetPouTransitions(self, pou_name):
+    def GetPouTransitions(self, pou_name, debug = False):
         transitions = []
-        pou = self.Project.getpou(pou_name)
-        if pou.getbodyType() == "SFC":
-            for transition in pou.gettransitionList():
-                transitions.append(transition.getname())
+        project = self.GetProject(debug)
+        if project is not None:
+            # Found the pou correponding to name and return its transitions if SFC
+            pou = project.getpou(pou_name)
+            if pou is not None and pou.getbodyType() == "SFC":
+                for transition in pou.gettransitionList():
+                    transitions.append(transition.getname())
         return transitions
     
     # Return the body language of the transition given by its name
-    def GetTransitionBodyType(self, pou_name, pou_transition):
-        # Found the pou correponding to name and return its body language
-        pou = self.Project.getpou(pou_name)
-        transition = pou.gettransition(pou_transition)
-        return transition.getbodyType()
+    def GetTransitionBodyType(self, pou_name, pou_transition, debug = False):
+        project = self.GetProject(debug)
+        if project is not None:
+            # Found the pou correponding to name
+            pou = project.getpou(pou_name)
+            if pou is not None:
+                # Found the pou transition correponding to name and return its body language
+                transition = pou.gettransition(pou_transition)
+                if transition is not None:
+                    return transition.getbodyType()
+        return None
     
     # Return the actions of a pou
-    def GetPouActions(self, pou_name):
+    def GetPouActions(self, pou_name, debug = False):
         actions = []
-        pou = self.Project.getpou(pou_name)
-        if pou.getbodyType() == "SFC":
-            for action in pou.getactionList():
-                actions.append(action.getname())
+        project = self.GetProject(debug)
+        if project is not None:
+            # Found the pou correponding to name and return its actions if SFC
+            pou = project.getpou(pou_name)
+            if pou.getbodyType() == "SFC":
+                for action in pou.getactionList():
+                    actions.append(action.getname())
         return actions
     
     # Return the body language of the pou given by its name
-    def GetActionBodyType(self, pou_name, pou_action):
-        # Found the pou correponding to name and return its body language
-        pou = self.Project.getpou(pou_name)
-        action = pou.getaction(pou_action)
-        return action.getbodyType()
+    def GetActionBodyType(self, pou_name, pou_action, debug = False):
+        project = self.GetProject(debug)
+        if project is not None:
+            # Found the pou correponding to name and return its body language
+            pou = project.getpou(pou_name)
+            if pou is not None:
+                action = pou.getaction(pou_action)
+                if action is not None:
+                    return action.getbodyType()
+        return None
     
     # Extract varlists from a list of vars
     def ExtractVarLists(self, vars):
@@ -731,112 +831,123 @@
 
     # Replace the configuration globalvars by those given
     def SetConfigurationGlobalVars(self, name, vars):
-        # Found the configuration corresponding to name
-        configuration = self.Project.getconfiguration(name)
-        if configuration:
-            # Set configuration global vars
-            configuration.setglobalVars([])
-            for vartype, varlist in self.ExtractVarLists(vars):
-                configuration.globalVars.append(varlist)
+        if self.Project is not None:
+            # Found the configuration corresponding to name
+            configuration = self.Project.getconfiguration(name)
+            if configuration is not None:
+                # Set configuration global vars
+                configuration.setglobalVars([])
+                for vartype, varlist in self.ExtractVarLists(vars):
+                    configuration.globalVars.append(varlist)
     
     # Return the configuration globalvars
-    def GetConfigurationGlobalVars(self, name):
+    def GetConfigurationGlobalVars(self, name, debug = False):
         vars = []
-        # Found the configuration corresponding to name
-        configuration = self.Project.getconfiguration(name)
-        if configuration:
-            # Extract variables from every varLists
-            for varlist in configuration.getglobalVars():
-                for var in varlist.getvariable():
-                    tempvar = {"Name" : var.getname(), "Class" : "Global"}
-                    vartype_content = var.gettype().getcontent()
-                    if vartype_content["name"] == "derived":
-                        tempvar["Type"] = vartype_content["value"].getname()
-                    elif vartype_content["name"] in ["string", "wstring"]:
-                        tempvar["Type"] = vartype_content["name"].upper()
-                    else:
-                        tempvar["Type"] = vartype_content["name"]
-                    tempvar["Edit"] = True
-                    initial = var.getinitialValue()
-                    if initial:
-                        tempvar["Initial Value"] = initial.getvalue()
-                    else:
-                        tempvar["Initial Value"] = ""
-                    address = var.getaddress()
-                    if address:
-                        tempvar["Location"] = address
-                    else:
-                        tempvar["Location"] = ""
-                    if varlist.getretain():
-                        tempvar["Retain"] = "Yes"
-                    else:
-                        tempvar["Retain"] = "No"
-                    if varlist.getconstant():
-                        tempvar["Constant"] = "Yes"
-                    else:
-                        tempvar["Constant"] = "No"
-                    vars.append(tempvar)
+        project = self.GetProject(debug)
+        if project is not None:
+            # Found the configuration corresponding to name
+            configuration = project.getconfiguration(name)
+            if configuration is not None:
+                # Extract variables from every varLists
+                for varlist in configuration.getglobalVars():
+                    for var in varlist.getvariable():
+                        tempvar = {"Name" : var.getname(), "Class" : "Global"}
+                        vartype_content = var.gettype().getcontent()
+                        if vartype_content["name"] == "derived":
+                            tempvar["Type"] = vartype_content["value"].getname()
+                        elif vartype_content["name"] in ["string", "wstring"]:
+                            tempvar["Type"] = vartype_content["name"].upper()
+                        else:
+                            tempvar["Type"] = vartype_content["name"]
+                        tempvar["Edit"] = True
+                        initial = var.getinitialValue()
+                        if initial:
+                            tempvar["Initial Value"] = initial.getvalue()
+                        else:
+                            tempvar["Initial Value"] = ""
+                        address = var.getaddress()
+                        if address:
+                            tempvar["Location"] = address
+                        else:
+                            tempvar["Location"] = ""
+                        if varlist.getretain():
+                            tempvar["Retain"] = "Yes"
+                        else:
+                            tempvar["Retain"] = "No"
+                        if varlist.getconstant():
+                            tempvar["Constant"] = "Yes"
+                        else:
+                            tempvar["Constant"] = "No"
+                        vars.append(tempvar)
         return vars
 
     # Replace the resource globalvars by those given
     def SetConfigurationResourceGlobalVars(self, config_name, name, vars):
-        # Found the resource corresponding to name
-        resource = self.Project.getconfigurationResource(config_name, name)
-        # Set resource global vars
-        if resource:
-            resource.setglobalVars([])
-            for vartype, varlist in self.ExtractVarLists(vars):
-                resource.globalVars.append(varlist)
+        if self.Project is not None:
+            # Found the resource corresponding to name
+            resource = self.Project.getconfigurationResource(config_name, name)
+            # Set resource global vars
+            if resource is not None:
+                resource.setglobalVars([])
+                for vartype, varlist in self.ExtractVarLists(vars):
+                    resource.globalVars.append(varlist)
     
     # Return the resource globalvars
-    def GetConfigurationResourceGlobalVars(self, config_name, name):
+    def GetConfigurationResourceGlobalVars(self, config_name, name, debug = False):
         vars = []
-        # Found the resource corresponding to name
-        resource = self.Project.getconfigurationResource(config_name, name)
-        if resource:
-            # Extract variables from every varLists
-            for varlist in resource.getglobalVars():
-                for var in varlist.getvariable():
-                    tempvar = {"Name" : var.getname(), "Class" : "Global"}
-                    vartype_content = var.gettype().getcontent()
-                    if vartype_content["name"] == "derived":
-                        tempvar["Type"] = vartype_content["value"].getname()
-                    elif vartype_content["name"] in ["string", "wstring"]:
-                        tempvar["Type"] = vartype_content["name"].upper()
-                    else:
-                        tempvar["Type"] = vartype_content["name"]
-                    tempvar["Edit"] = True
-                    initial = var.getinitialValue()
-                    if initial:
-                        tempvar["Initial Value"] = initial.getvalue()
-                    else:
-                        tempvar["Initial Value"] = ""
-                    address = var.getaddress()
-                    if address:
-                        tempvar["Location"] = address
-                    else:
-                        tempvar["Location"] = ""
-                    if varlist.getretain():
-                        tempvar["Retain"] = "Yes"
-                    else:
-                        tempvar["Retain"] = "No"
-                    if varlist.getconstant():
-                        tempvar["Constant"] = "Yes"
-                    else:
-                        tempvar["Constant"] = "No"
-                    vars.append(tempvar)
+        project = self.GetProject(debug)
+        if project is not None:
+            # Found the resource corresponding to name
+            resource = project.getconfigurationResource(config_name, name)
+            if resource:
+                # Extract variables from every varLists
+                for varlist in resource.getglobalVars():
+                    for var in varlist.getvariable():
+                        tempvar = {"Name" : var.getname(), "Class" : "Global"}
+                        vartype_content = var.gettype().getcontent()
+                        if vartype_content["name"] == "derived":
+                            tempvar["Type"] = vartype_content["value"].getname()
+                        elif vartype_content["name"] in ["string", "wstring"]:
+                            tempvar["Type"] = vartype_content["name"].upper()
+                        else:
+                            tempvar["Type"] = vartype_content["name"]
+                        tempvar["Edit"] = True
+                        initial = var.getinitialValue()
+                        if initial:
+                            tempvar["Initial Value"] = initial.getvalue()
+                        else:
+                            tempvar["Initial Value"] = ""
+                        address = var.getaddress()
+                        if address:
+                            tempvar["Location"] = address
+                        else:
+                            tempvar["Location"] = ""
+                        if varlist.getretain():
+                            tempvar["Retain"] = "Yes"
+                        else:
+                            tempvar["Retain"] = "No"
+                        if varlist.getconstant():
+                            tempvar["Constant"] = "Yes"
+                        else:
+                            tempvar["Constant"] = "No"
+                        vars.append(tempvar)
         return vars
     
     # Return the interface of the pou given by its name
-    def GetPouInterfaceVarsByName(self, name):
-        # Found the pou correponding to name and return the interface
-        return self.GetPouInterfaceVars(self.Project.getpou(name))
+    def GetPouInterfaceVarsByName(self, name, debug = False):
+        project = self.GetProject(debug)
+        if project is not None:
+            # Found the pou correponding to name and return the interface vars
+            pou = project.getpou(name)
+            if pou is not None:
+                return self.GetPouInterfaceVars(pou)
+        return None
     
     # Return the interface for the given pou
     def GetPouInterfaceVars(self, pou):
         vars = []
         # Verify that the pou has an interface
-        if pou.interface:
+        if pou.interface is not None:
             # Extract variables from every varLists
             for type, varlist in pou.getvars():
                 for var in varlist.getvariable():
@@ -874,39 +985,43 @@
 
     # Replace the Pou interface by the one given
     def SetPouInterfaceVars(self, name, vars):
-        # Found the pou corresponding to name and add interface if there isn't one yet
-        pou = self.Project.getpou(name)
-        if not pou.interface:
-            pou.interface = plcopen.pou_interface()
-        # Set Pou interface
-        pou.setvars(self.ExtractVarLists(vars))
-        self.Project.RefreshElementUsingTree()
-        self.Project.RefreshCustomBlockTypes()
+        if self.Project is not None:
+            # Found the pou corresponding to name and add interface if there isn't one yet
+            pou = self.Project.getpou(name)
+            if pou is not None:
+                if pou.interface is None:
+                    pou.interface = plcopen.pou_interface()
+                # Set Pou interface
+                pou.setvars(self.ExtractVarLists(vars))
+                self.Project.RefreshElementUsingTree()
+                self.Project.RefreshCustomBlockTypes()
     
     # Replace the return type of the pou given by its name (only for functions)
     def SetPouInterfaceReturnType(self, name, type):
-        pou = self.Project.getpou(name)
-        if not pou.interface:
-            pou.interface = plcopen.pou_interface()
-        # If there isn't any return type yet, add it
-        return_type = pou.interface.getreturnType()
-        if not return_type:
-            return_type = plcopen.dataType()
-            pou.interface.setreturnType(return_type)
-        # Change return type
-        if type in self.GetBaseTypes():
-            if type == "STRING":
-                return_type.setcontent({"name" : "string", "value" : plcopen.elementaryTypes_string()})
-            elif type == "WSTRING":
-                return_type.setcontent({"name" : "wstring", "value" : plcopen.elementaryTypes_wstring()})
-            else:
-                return_type.setcontent({"name" : type, "value" : None})
-        else:
-            derived_type = plcopen.derivedTypes_derived()
-            derived_type.setname(type)
-            return_type.setcontent({"name" : "derived", "value" : derived_type})
-        self.Project.RefreshElementUsingTree()
-        self.Project.RefreshCustomBlockTypes()
+        if self.Project is not None:
+            pou = self.Project.getpou(name)
+            if pou is not None:
+                if pou.interface is None:
+                    pou.interface = plcopen.pou_interface()
+                # If there isn't any return type yet, add it
+                return_type = pou.interface.getreturnType()
+                if not return_type:
+                    return_type = plcopen.dataType()
+                    pou.interface.setreturnType(return_type)
+                # Change return type
+                if type in self.GetBaseTypes():
+                    if type == "STRING":
+                        return_type.setcontent({"name" : "string", "value" : plcopen.elementaryTypes_string()})
+                    elif type == "WSTRING":
+                        return_type.setcontent({"name" : "wstring", "value" : plcopen.elementaryTypes_wstring()})
+                    else:
+                        return_type.setcontent({"name" : type, "value" : None})
+                else:
+                    derived_type = plcopen.derivedTypes_derived()
+                    derived_type.setname(type)
+                    return_type.setcontent({"name" : "derived", "value" : derived_type})
+                self.Project.RefreshElementUsingTree()
+                self.Project.RefreshCustomBlockTypes()
     
     def UpdateProjectUsedPous(self, old_name, new_name):
         if self.Project:
@@ -919,13 +1034,18 @@
     
     # Return the return type of the pou given by its name
     def GetPouInterfaceReturnTypeByName(self, name):
-        # Found the pou correponding to name and return the return type
-        return self.GetPouInterfaceReturnType(self.Project.getpou(name))
+        project = self.GetProject(debug)
+        if project is not None:
+            # Found the pou correponding to name and return the return type
+            pou = project.getpou(name)
+            if pou is not None:
+                return self.GetPouInterfaceReturnType(pou)
+        return False
     
     # Return the return type of the given pou
     def GetPouInterfaceReturnType(self, pou):
         # Verify that the pou has an interface
-        if pou.interface:
+        if pou.interface is not None:
             # Return the return type if there is one
             return_type = pou.interface.getreturnType()
             if return_type:
@@ -948,7 +1068,7 @@
             self.PluginTypes.pop(0)
 
     # Function that returns the block definition associated to the block type given
-    def GetBlockType(self, type, inputs = None):
+    def GetBlockType(self, type, inputs = None, debug = False):
         for category in BlockTypes + self.PluginTypes:
             for blocktype in category["list"]:
                 if inputs:
@@ -958,19 +1078,20 @@
                     same_inputs = True
                 if blocktype["name"] == type and same_inputs:
                     return blocktype
-        if self.Project:
-            return self.Project.GetCustomBlockType(type, inputs)
+        project = self.GetProject(debug)
+        if project is not None:
+            return project.GetCustomBlockType(type, inputs)
         return None
 
     # Return Block types checking for recursion
-    def GetBlockTypes(self, tagname = ""):
+    def GetBlockTypes(self, tagname = "", debug = False):
         type = None
         if self.Project:
             name = ""
             words = tagname.split("::")
             if words[0] in ["P","T","A"]:
                 name = words[1]
-                type = self.GetPouType(name)
+                type = self.GetPouType(name, debug)
         if type == "function":
             blocktypes = []
             for category in BlockTypes + self.PluginTypes:
@@ -982,63 +1103,69 @@
                     blocktypes.append(cat)
         else:
             blocktypes = [category for category in BlockTypes + self.PluginTypes]
-        if self.Project:
-            blocktypes.append({"name" : "User-defined POUs", "list": self.Project.GetCustomBlockTypes(name)})
+        project = self.GetProject(debug)
+        if project is not None:
+            blocktypes.append({"name" : "User-defined POUs", "list": project.GetCustomBlockTypes(name)})
         return blocktypes
 
     # Return Function Block types checking for recursion
-    def GetFunctionBlockTypes(self, tagname = ""):
+    def GetFunctionBlockTypes(self, tagname = "", debug = False):
         blocktypes = []
         for category in BlockTypes + self.PluginTypes:
             for block in category["list"]:
                 if block["type"] != "function":
                     blocktypes.append(block["name"])
-        if self.Project:
+        project = self.GetProject(debug)
+        if project is not None:
             name = ""
             words = tagname.split("::")
             if words[0] in ["P","T","A"]:
                 name = words[1]
-            blocktypes.extend(self.Project.GetCustomFunctionBlockTypes(name))
+            blocktypes.extend(project.GetCustomFunctionBlockTypes(name))
         return blocktypes
 
     # Return Block types checking for recursion
-    def GetBlockResource(self):
+    def GetBlockResource(self, debug = False):
         blocktypes = []
         for category in BlockTypes[:-1]:
             for blocktype in category["list"]:
                 if blocktype["type"] == "program":
                     blocktypes.append(blocktype["name"])
-        if self.Project:
-            blocktypes.extend(self.Project.GetCustomBlockResource())
+        project = self.GetProject(debug)
+        if project is not None:
+            blocktypes.extend(project.GetCustomBlockResource())
         return blocktypes
 
     # Return Data Types checking for recursion
-    def GetDataTypes(self, tagname = "", basetypes = True):
+    def GetDataTypes(self, tagname = "", basetypes = True, debug = False):
         if basetypes:
             datatypes = self.GetBaseTypes()
         else:
             datatypes = []
-        if self.Project:
+        project = self.GetProject(debug)
+        if project is not None:
             name = ""
             words = tagname.split("::")
             if words[0] in ["D"]:
                 name = words[1]
-            datatypes.extend(self.Project.GetCustomDataTypes(name))
+            datatypes.extend(project.GetCustomDataTypes(name))
         return datatypes
 
     # Return Base Type of given possible derived type
-    def GetBaseType(self, type):
-        if self.Project:
-            return self.Project.GetBaseType(type)
+    def GetBaseType(self, type, debug = False):
+        project = self.GetProject(debug)
+        if project is not None:
+            return project.GetBaseType(type)
         return None
 
     # Return Base Types
     def GetBaseTypes(self):
         return [value for value in TypeHierarchy.keys() if not value.startswith("ANY")]
 
-    def IsOfType(self, type, reference):
-        if self.Project:
-            return self.Project.IsOfType(type, reference)
+    def IsOfType(self, type, reference, debug = False):
+        project = self.GetProject(debug)
+        if project is not None:
+            return project.IsOfType(type, reference)
         elif reference is None:
             return True
         elif type == reference:
@@ -1053,23 +1180,26 @@
             return not type.startswith("ANY")
         return True
 
-    def GetDataTypeRange(self, type):
-        if self.Project:
-            return self.Project.GetDataTypeRange(type)
+    def GetDataTypeRange(self, type, debug = False):
+        project = self.GetProject(debug)
+        if project is not None:
+            return project.GetDataTypeRange(type)
         elif type in DataTypeRange:
             return DataTypeRange[type]
         return None
     
     # Return Subrange types
-    def GetSubrangeBaseTypes(self, exclude):
-        if self.Project:
-            return self.Project.GetSubrangeBaseTypes(exclude)
+    def GetSubrangeBaseTypes(self, exclude, debug = False):
+        project = self.GetProject(debug)
+        if project is not None:
+            return project.GetSubrangeBaseTypes(exclude)
         return []
     
     # Return Enumerated Values
-    def GetEnumeratedDataValues(self):
-        if self.Project:
-            return self.Project.GetEnumeratedDataTypeValues()
+    def GetEnumeratedDataValues(self, debug = False):
+        project = self.GetProject(debug)
+        if project is not None:
+            return project.GetEnumeratedDataTypeValues()
         return []
 
 #-------------------------------------------------------------------------------
@@ -1111,53 +1241,55 @@
 #-------------------------------------------------------------------------------
 
     # Return the data type informations
-    def GetDataTypeInfos(self, tagname):
-        words = tagname.split("::")
-        if words[0] == "D":
-            infos = {}
-            datatype = self.Project.getdataType(words[1])
-            basetype_content = datatype.baseType.getcontent()
-            if basetype_content["value"] is None:
-                infos["type"] = "Directly"
-                infos["base_type"] = basetype_content["name"]
-            elif basetype_content["name"] == "derived":
-                infos["type"] = "Directly"
-                infos["base_type"] = basetype_content["value"].getname()
-            elif basetype_content["name"] in ["subrangeSigned", "subrangeUnsigned"]:
-                infos["type"] = "Subrange"
-                infos["min"] = basetype_content["value"].range.getlower()
-                infos["max"] = basetype_content["value"].range.getupper()
-                base_type = basetype_content["value"].baseType.getcontent()
-                if base_type["value"] is None:
-                    infos["base_type"] = base_type["name"]
+    def GetDataTypeInfos(self, tagname, debug = False):
+        project = self.GetProject(debug)
+        if project is not None:
+            words = tagname.split("::")
+            if words[0] == "D":
+                infos = {}
+                datatype = project.getdataType(words[1])
+                basetype_content = datatype.baseType.getcontent()
+                if basetype_content["value"] is None:
+                    infos["type"] = "Directly"
+                    infos["base_type"] = basetype_content["name"]
+                elif basetype_content["name"] == "derived":
+                    infos["type"] = "Directly"
+                    infos["base_type"] = basetype_content["value"].getname()
+                elif basetype_content["name"] in ["subrangeSigned", "subrangeUnsigned"]:
+                    infos["type"] = "Subrange"
+                    infos["min"] = basetype_content["value"].range.getlower()
+                    infos["max"] = basetype_content["value"].range.getupper()
+                    base_type = basetype_content["value"].baseType.getcontent()
+                    if base_type["value"] is None:
+                        infos["base_type"] = base_type["name"]
+                    else:
+                        infos["base_type"] = base_type["value"].getname()
+                elif basetype_content["name"] == "enum":
+                    infos["type"] = "Enumerated"
+                    infos["values"] = []
+                    for value in basetype_content["value"].values.getvalue():
+                        infos["values"].append(value.getname())
+                elif basetype_content["name"] == "array":
+                    infos["type"] = "Array"
+                    infos["dimensions"] = []
+                    for dimension in basetype_content["value"].getdimension():
+                        infos["dimensions"].append((dimension.getlower(), dimension.getupper()))
+                    base_type = basetype_content["value"].baseType.getcontent()
+                    if base_type["value"] is None:
+                        infos["base_type"] = base_type["name"]
+                    else:
+                        infos["base_type"] = base_type["value"].getname()
+                if datatype.initialValue is not None:
+                    infos["initial"] = str(datatype.initialValue.getvalue())
                 else:
-                    infos["base_type"] = base_type["value"].getname()
-            elif basetype_content["name"] == "enum":
-                infos["type"] = "Enumerated"
-                infos["values"] = []
-                for value in basetype_content["value"].values.getvalue():
-                    infos["values"].append(value.getname())
-            elif basetype_content["name"] == "array":
-                infos["type"] = "Array"
-                infos["dimensions"] = []
-                for dimension in basetype_content["value"].getdimension():
-                    infos["dimensions"].append((dimension.getlower(), dimension.getupper()))
-                base_type = basetype_content["value"].baseType.getcontent()
-                if base_type["value"] is None:
-                    infos["base_type"] = base_type["name"]
-                else:
-                    infos["base_type"] = base_type["value"].getname()
-            if datatype.initialValue is not None:
-                infos["initial"] = str(datatype.initialValue.getvalue())
-            else:
-                infos["initial"] = ""
-            return infos
+                    infos["initial"] = ""
+                return infos
         return None
     
     # Change the data type informations
     def SetDataTypeInfos(self, tagname, infos):
         words = tagname.split("::")
-        if words[0] == "D":
+        if self.Project is not None and words[0] == "D":
             datatype = self.Project.getdataType(words[1])
             if infos["type"] == "Directly":
                 if infos["base_type"] in self.GetBaseTypes():
@@ -1232,22 +1364,25 @@
 #-------------------------------------------------------------------------------
 
     # Return edited element
-    def GetEditedElement(self, tagname):
-        words = tagname.split("::")
-        if words[0] == "D":
-            return self.Project.getdataType(words[1])
-        elif words[0] == "P":
-            return self.Project.getpou(words[1])
-        elif words[0] in ['T', 'A']:
-            pou = self.Project.getpou(words[1])
-            if words[0] == 'T':
-                return pou.gettransition(words[2])
-            elif words[0] == 'A':
-                return pou.getaction(words[2])
-        elif words[0] == 'C':
-            return self.Project.getconfiguration(words[1])
-        elif words[0] == 'R':
-            return self.Project.getconfigurationResource(words[1], words[2])
+    def GetEditedElement(self, tagname, debug = False):
+        project = self.GetProject(debug)
+        if project is not None:
+            words = tagname.split("::")
+            if words[0] == "D":
+                return project.getdataType(words[1])
+            elif words[0] == "P":
+                return project.getpou(words[1])
+            elif words[0] in ['T', 'A']:
+                pou = project.getpou(words[1])
+                if pou is not None:
+                    if words[0] == 'T':
+                        return pou.gettransition(words[2])
+                    elif words[0] == 'A':
+                        return pou.getaction(words[2])
+            elif words[0] == 'C':
+                return project.getconfiguration(words[1])
+            elif words[0] == 'R':
+                return project.getconfigurationResource(words[1], words[2])
         return None
     
     # Return edited element name
@@ -1260,59 +1395,66 @@
         return None
     
     # Return edited element name and type
-    def GetEditedElementType(self, tagname):
+    def GetEditedElementType(self, tagname, debug = False):
         words = tagname.split("::")
         if words[0] in ["P","T","A"]:
-            return words[1], self.GetPouType(words[1])
+            return words[1], self.GetPouType(words[1], debug)
         return None, None
 
     # Return language in which edited element is written
-    def GetEditedElementBodyType(self, tagname):
+    def GetEditedElementBodyType(self, tagname, debug = False):
         words = tagname.split("::")
         if words[0] == "P":
-            return self.GetPouBodyType(words[1])
+            return self.GetPouBodyType(words[1], debug)
         elif words[0] == 'T':
-            return self.GetTransitionBodyType(words[1], words[2])
+            return self.GetTransitionBodyType(words[1], words[2], debug)
         elif words[0] == 'A':
-            return self.GetActionBodyType(words[1], words[2])
+            return self.GetActionBodyType(words[1], words[2], debug)
         return None
 
     # Return the edited element variables
-    def GetEditedElementInterfaceVars(self, tagname):
+    def GetEditedElementInterfaceVars(self, tagname, debug = False):
         words = tagname.split("::")
         if words[0] in ["P","T","A"]:
-            pou = self.Project.getpou(words[1])
-            return self.GetPouInterfaceVars(pou)
+            project = self.GetProject(debug)
+            if project is not None:
+                pou = project.getpou(words[1])
+                if pou is not None:
+                    return self.GetPouInterfaceVars(pou)
         return []
 
     # Return the edited element return type
-    def GetEditedElementInterfaceReturnType(self, tagname):
+    def GetEditedElementInterfaceReturnType(self, tagname, debug = False):
         words = tagname.split("::")
         if words[0] == "P":
-            pou = self.Project.getpou(words[1])
-            return self.GetPouInterfaceReturnType(pou)
+            project = self.GetProject(debug)
+            if project is not None:
+                pou = self.Project.getpou(words[1])
+                if pou is not None:
+                    return self.GetPouInterfaceReturnType(pou)
         elif words[0] == 'T':
             return "BOOL"
         return None
     
     # Change the edited element text
     def SetEditedElementText(self, tagname, text):
-        element = self.GetEditedElement(tagname)
-        if element != None:
-            element.settext(text)
-            self.Project.RefreshElementUsingTree()
+        if self.Project is not None:
+            element = self.GetEditedElement(tagname)
+            if element is not None:
+                element.settext(text)
+                self.Project.RefreshElementUsingTree()
     
     # Return the edited element text
-    def GetEditedElementText(self, tagname):
-        element = self.GetEditedElement(tagname)
-        if element != None:
+    def GetEditedElementText(self, tagname, debug = False):
+        element = self.GetEditedElement(tagname, debug)
+        if element is not None:
             return element.gettext()
         return ""
 
     # Return the edited element transitions
-    def GetEditedElementTransitions(self, tagname):
-        pou = self.GetEditedElement(tagname)
-        if pou != None and pou.getbodyType() == "SFC":
+    def GetEditedElementTransitions(self, tagname, debug = False):
+        pou = self.GetEditedElement(tagname, debug)
+        if pou is not None and pou.getbodyType() == "SFC":
             transitions = []
             for transition in pou.gettransitionList():
                 transitions.append(transition.getname())
@@ -1320,9 +1462,9 @@
         return []
 
     # Return edited element transitions
-    def GetEditedElementActions(self, tagname):
-        pou = self.GetEditedElement(tagname)
-        if pou != None and pou.getbodyType() == "SFC":
+    def GetEditedElementActions(self, tagname, debug = False):
+        pou = self.GetEditedElement(tagname, debug)
+        if pou is None and pou.getbodyType() == "SFC":
             actions = []
             for action in pou.getactionList():
                 actions.append(action.getname())
@@ -1330,17 +1472,17 @@
         return []
 
     # Return the names of the pou elements
-    def GetEditedElementVariables(self, tagname):
+    def GetEditedElementVariables(self, tagname, debug = False):
         words = tagname.split("::")
         if words[0] in ["P","T","A"]:
-            return self.GetProjectPouVariables(words[1])
+            return self.GetProjectPouVariables(words[1], debug)
         return []
 
     # Return the current pou editing informations
-    def GetEditedElementInstanceInfos(self, tagname, id = None, exclude = []):
+    def GetEditedElementInstanceInfos(self, tagname, id = None, exclude = [], debug = False):
         infos = {}
         instance = None
-        element = self.GetEditedElement(tagname)
+        element = self.GetEditedElement(tagname, debug)
         if element is not None:
             # if id is defined
             if id is not None:
@@ -1387,7 +1529,7 @@
                     infos["connectors"]["outputs"].append(connector)
             elif isinstance(instance, plcopen.fbdObjects_inVariable):
                 infos["name"] = instance.getexpression()
-                infos["value_type"] = self.GetEditedElementVarValueType(tagname, infos["name"])
+                infos["value_type"] = self.GetEditedElementVarValueType(tagname, infos["name"], debug)
                 infos["type"] = "input"
                 executionOrder = instance.getexecutionOrderId()
                 if executionOrder is not None:
@@ -1400,7 +1542,7 @@
                 infos["connector"]["edge"] = instance.getedge()
             elif isinstance(instance, plcopen.fbdObjects_outVariable):
                 infos["name"] = instance.getexpression()
-                infos["value_type"] = self.GetEditedElementVarValueType(tagname, infos["name"])
+                infos["value_type"] = self.GetEditedElementVarValueType(tagname, infos["name"], debug)
                 infos["type"] = "output"
                 executionOrder = instance.getexecutionOrderId()
                 if executionOrder is not None:
@@ -1419,7 +1561,7 @@
                         infos["connector"]["links"].append(dic)
             elif isinstance(instance, plcopen.fbdObjects_inOutVariable):
                 infos["name"] = instance.getexpression()
-                infos["value_type"] = self.GetEditedElementVarValueType(tagname, infos["name"])
+                infos["value_type"] = self.GetEditedElementVarValueType(tagname, infos["name"], debug)
                 infos["type"] = "inout"
                 executionOrder = instance.getexecutionOrderId()
                 if executionOrder is not None:
@@ -1624,7 +1766,7 @@
                         dic = {"refLocalId":link.getrefLocalId(),"points":link.getpoints(),"formalParameter":link.getformalParameter()}
                         infos["connector"]["links"].append(dic)
             return infos
-        return False
+        return None
     
     def ClearEditedElementExecutionOrder(self, tagname):
         element = self.GetEditedElement(tagname)
@@ -1637,20 +1779,23 @@
             element.compileexecutionOrder()
     
     # Return the variable type of the given pou
-    def GetEditedElementVarValueType(self, tagname, varname):
-        words = tagname.split("::")
-        if words[0] in ["P","T","A"]:
-            pou = self.Project.getpou(words[1])
-            for type, varlist in pou.getvars():
-                for var in varlist.getvariable():
-                    if var.getname() == varname:
-                        vartype_content = var.gettype().getcontent()
-                        if vartype_content["name"] == "derived":
-                            return vartype_content["value"].getname()
-                        elif vartype_content["name"] in ["string", "wstring"]:
-                            return vartype_content["name"].upper()
-                        else:
-                            return vartype_content["name"]
+    def GetEditedElementVarValueType(self, tagname, varname, debug = False):
+        project = self.GetProject(debug)
+        if project is not None:
+            words = tagname.split("::")
+            if words[0] in ["P","T","A"]:
+                pou = self.Project.getpou(words[1])
+                if pou is not None:
+                    for type, varlist in pou.getvars():
+                        for var in varlist.getvariable():
+                            if var.getname() == varname:
+                                vartype_content = var.gettype().getcontent()
+                                if vartype_content["name"] == "derived":
+                                    return vartype_content["value"].getname()
+                                elif vartype_content["name"] in ["string", "wstring"]:
+                                    return vartype_content["name"].upper()
+                                else:
+                                    return vartype_content["name"]
         return None
     
     def SetConnectionWires(self, connection, connector):
@@ -1676,24 +1821,30 @@
                 idx += 1
     
     def AddEditedElementPouVar(self, tagname, type, name):
-        words = tagname.split("::")
-        if words[0] in ['P', 'T', 'A']:
-            pou = self.Project.getpou(words[1])
-            if not pou.interface:
-                pou.interface = plcopen.pou_interface()
-            pou.addpouVar(type, name)
+        if self.Project is not None:
+            words = tagname.split("::")
+            if words[0] in ['P', 'T', 'A']:
+                pou = self.Project.getpou(words[1])
+                if pou is not None:
+                    if pou.interface is None:
+                        pou.interface = plcopen.pou_interface()
+                    pou.addpouVar(type, name)
             
     def ChangeEditedElementPouVar(self, tagname, old_type, old_name, new_type, new_name):
-        words = tagname.split("::")
-        if words[0] in ['P', 'T', 'A']:
-            pou = self.Project.getpou(words[1])
-            pou.changepouVar(old_type, old_name, new_type, new_name)
+        if self.Project is not None:
+            words = tagname.split("::")
+            if words[0] in ['P', 'T', 'A']:
+                pou = self.Project.getpou(words[1])
+                if pou is not None:
+                    pou.changepouVar(old_type, old_name, new_type, new_name)
     
     def RemoveEditedElementPouVar(self, tagname, type, name):
-        words = tagname.split("::")
-        if words[0] in ['P', 'T', 'A']:
-            pou = self.Project.getpou(words[1])
-            pou.removepouVar(type, name)
+        if self.Project is not None:
+            words = tagname.split("::")
+            if words[0] in ['P', 'T', 'A']:
+                pou = self.Project.getpou(words[1])
+                if pou is not None:
+                    pou.removepouVar(type, name)
     
     def AddEditedElementBlock(self, tagname, id, blocktype, blockname = None):
         element = self.GetEditedElement(tagname)
@@ -2275,13 +2426,13 @@
             element.removeinstance(id)
             self.Project.RefreshElementUsingTree()
 
-    def GetEditedResourceVariables(self, tagname):
+    def GetEditedResourceVariables(self, tagname, debug = False):
         varlist = []
         words = tagname.split("::")
-        for var in self.GetConfigurationGlobalVars(words[1]):
+        for var in self.GetConfigurationGlobalVars(words[1], debug):
             if var["Type"] == "BOOL":
                 varlist.append(var["Name"])
-        for var in self.GetConfigurationResourceGlobalVars(words[1], words[2]):
+        for var in self.GetConfigurationResourceGlobalVars(words[1], words[2], debug):
             if var["Type"] == "BOOL":
                 varlist.append(var["Name"])
         return varlist
@@ -2321,8 +2472,8 @@
                 else:
                     resource.appendpouInstance(new_instance)
 
-    def GetEditedResourceInfos(self, tagname):
-        resource = self.GetEditedElement(tagname)
+    def GetEditedResourceInfos(self, tagname, debug = False):
+        resource = self.GetEditedElement(tagname, debug)
         if resource is not None:
             tasks = resource.gettask()
             instances = resource.getpouInstance()
@@ -2383,8 +2534,9 @@
                 self.Project.RefreshDataTypeHierarchy()
                 self.Project.RefreshCustomBlockTypes()
                 self.ProjectBuffer = UndoBuffer(self.Copy(self.Project), True)
+                self.ProgramChunks = []
+                self.CurrentCompiledProject = None
                 self.Buffering = False
-                self.ElementsOpened = []
                 self.CurrentElementEditing = None
                 return None
         return "No PLC project found"
@@ -2437,8 +2589,9 @@
             self.Project = self.Copy(self.Project)
             self.Buffering = False
 
+    # Return if project is saved
     def ProjectIsSaved(self):
-        if self.ProjectBuffer:
+        if self.ProjectBuffer is not None:
             return self.ProjectBuffer.IsCurrentSaved()
         else:
             return True