Adding support for Debugging in PLCOpenEditor
authorlbessard
Fri, 05 Sep 2008 18:13:18 +0200
changeset 249 d8425712acef
parent 248 f7df265edd54
child 250 e6b58eafef1a
Adding support for Debugging in PLCOpenEditor
LDViewer.py
PLCControler.py
PLCOpenEditor.py
SFCViewer.py
TextViewer.py
Viewer.py
graphics/FBD_Objects.py
graphics/GraphicCommons.py
graphics/LD_Objects.py
graphics/SFC_Objects.py
--- a/LDViewer.py	Fri Sep 05 18:12:23 2008 +0200
+++ b/LDViewer.py	Fri Sep 05 18:13:18 2008 +0200
@@ -166,8 +166,8 @@
 
 class LD_Viewer(Viewer):
 
-    def __init__(self, parent, tagname, window, controler):
-        Viewer.__init__(self, parent, tagname, window, controler)
+    def __init__(self, parent, tagname, window, controler, debug = False, instancepath = ""):
+        Viewer.__init__(self, parent, tagname, window, controler, debug, instancepath)
         self.Rungs = []
         self.RungComments = []
         self.CurrentLanguage = "LD"
@@ -176,6 +176,11 @@
 #                          Refresh functions
 #-------------------------------------------------------------------------------
 
+    def ResetView(self):
+        self.Rungs = []
+        self.RungComments = []
+        Viewer.ResetView(self)
+
     def RefreshView(self):
         Viewer.RefreshView(self)
         for i, rung in enumerate(self.Rungs):
@@ -450,12 +455,12 @@
         dialog = LDElementDialog(self.ParentWindow, "coil")
         dialog.SetPreviewFont(self.GetFont())
         varlist = []
-        vars = self.Controler.GetEditedElementInterfaceVars(self.TagName)
+        vars = self.Controler.GetEditedElementInterfaceVars(self.TagName, self.Debug)
         if vars:
             for var in vars:
                 if var["Class"] != "Input" and var["Type"] == "BOOL":
                     varlist.append(var["Name"])
-        returntype = self.Controler.GetEditedElementInterfaceReturnType(self.TagName)
+        returntype = self.Controler.GetEditedElementInterfaceReturnType(self.TagName, self.Debug)
         if returntype == "BOOL":
             varlist.append(self.Controler.GetEditedElementName(self.TagName))
         dialog.SetVariables(varlist)
@@ -540,7 +545,7 @@
             dialog = LDElementDialog(self.ParentWindow, "contact")
             dialog.SetPreviewFont(self.GetFont())
             varlist = []
-            vars = self.Controler.GetEditedElementInterfaceVars(self.TagName)
+            vars = self.Controler.GetEditedElementInterfaceVars(self.TagName, self.Debug)
             if vars:
                 for var in vars:
                     if var["Class"] != "Output" and var["Type"] == "BOOL":
@@ -762,12 +767,12 @@
                         dialog = LDElementDialog(self.ParentWindow, "coil")
                         dialog.SetPreviewFont(self.GetFont())
                         varlist = []
-                        vars = self.Controler.GetEditedElementInterfaceVars(self.TagName)
+                        vars = self.Controler.GetEditedElementInterfaceVars(self.TagName, self.Debug)
                         if vars:
                             for var in vars:
                                 if var["Class"] != "Input" and var["Type"] == "BOOL":
                                     varlist.append(var["Name"])
-                        returntype = self.Controler.GetEditedElementInterfaceReturnType(self.TagName)
+                        returntype = self.Controler.GetEditedElementInterfaceReturnType(self.TagName, self.Debug)
                         if returntype == "BOOL":
                             varlist.append(self.Controler.GetEditedElementName(self.TagName))
                         dialog.SetVariables(varlist)
@@ -1184,7 +1189,7 @@
             dialog = LDElementDialog(self.ParentWindow, "contact")
             dialog.SetPreviewFont(self.GetFont())
             varlist = []
-            vars = self.Controler.GetEditedElementInterfaceVars(self.TagName)
+            vars = self.Controler.GetEditedElementInterfaceVars(self.TagName, self.Debug)
             if vars:
                 for var in vars:
                     if var["Class"] != "Output" and var["Type"] == "BOOL":
@@ -1208,12 +1213,12 @@
             dialog = LDElementDialog(self.ParentWindow, "coil")
             dialog.SetPreviewFont(self.GetFont())
             varlist = []
-            vars = self.Controler.GetEditedElementInterfaceVars(self.TagName)
+            vars = self.Controler.GetEditedElementInterfaceVars(self.TagName, self.Debug)
             if vars:
                 for var in vars:
                     if var["Class"] != "Input" and var["Type"] == "BOOL":
                         varlist.append(var["Name"])
-            returntype = self.Controler.GetEditedElementInterfaceReturnType(self.TagName)
+            returntype = self.Controler.GetEditedElementInterfaceReturnType(self.TagName, self.Debug)
             if returntype == "BOOL":
                 varlist.append(self.Controler.GetEditedElementName(self.TagName))
             dialog.SetVariables(varlist)
--- 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
--- a/PLCOpenEditor.py	Fri Sep 05 18:12:23 2008 +0200
+++ b/PLCOpenEditor.py	Fri Sep 05 18:13:18 2008 +0200
@@ -215,8 +215,9 @@
             AppendMenu(parent, help='', id=wx.ID_CLOSE_ALL,
                   kind=wx.ITEM_NORMAL, text=u'Close Project')
             parent.AppendSeparator()
-        AppendMenu(parent, help='', id=wx.ID_SAVE,
-              kind=wx.ITEM_NORMAL, text=u'Save\tCTRL+S')
+        if not self.Debug:
+            AppendMenu(parent, help='', id=wx.ID_SAVE,
+                  kind=wx.ITEM_NORMAL, text=u'Save\tCTRL+S')
         if self.ModeSolo:
             AppendMenu(parent, help='', id=wx.ID_SAVEAS,
                   kind=wx.ITEM_NORMAL, text=u'Save As...\tCTRL+SHIFT+S')
@@ -229,9 +230,10 @@
               kind=wx.ITEM_NORMAL, text=u'Preview')
         AppendMenu(parent, help='', id=wx.ID_PRINT,
               kind=wx.ITEM_NORMAL, text=u'Print')
-        parent.AppendSeparator()
-        AppendMenu(parent, help='', id=wx.ID_PROPERTIES,
-              kind=wx.ITEM_NORMAL, text=u'Properties')
+        if not self.Debug:
+            parent.AppendSeparator()
+            AppendMenu(parent, help='', id=wx.ID_PROPERTIES,
+                  kind=wx.ITEM_NORMAL, text=u'Properties')
         parent.AppendSeparator()
         if self.ModeSolo:
             AppendMenu(parent, help='', id=wx.ID_EXIT,
@@ -246,7 +248,8 @@
         self.Bind(wx.EVT_MENU, self.OnCloseTabMenu, id=wx.ID_CLOSE)
         if self.ModeSolo:
             self.Bind(wx.EVT_MENU, self.OnCloseProjectMenu, id=wx.ID_CLOSE_ALL)
-        self.Bind(wx.EVT_MENU, self.OnSaveProjectMenu, id=wx.ID_SAVE)
+        if not self.Debug:
+            self.Bind(wx.EVT_MENU, self.OnSaveProjectMenu, id=wx.ID_SAVE)
         if self.ModeSolo:
             self.Bind(wx.EVT_MENU, self.OnSaveProjectAsMenu, id=wx.ID_SAVEAS)
             self.Bind(wx.EVT_MENU, self.OnGenerateProgramMenu,
@@ -254,7 +257,8 @@
         self.Bind(wx.EVT_MENU, self.OnPageSetupMenu, id=wx.ID_PAGE_SETUP)
         self.Bind(wx.EVT_MENU, self.OnPreviewMenu, id=wx.ID_PREVIEW)
         self.Bind(wx.EVT_MENU, self.OnPrintMenu, id=wx.ID_PRINT)
-        self.Bind(wx.EVT_MENU, self.OnPropertiesMenu, id=wx.ID_PROPERTIES)
+        if not self.Debug:
+            self.Bind(wx.EVT_MENU, self.OnPropertiesMenu, id=wx.ID_PROPERTIES)
         if self.ModeSolo:
             self.Bind(wx.EVT_MENU, self.OnQuitMenu, id=wx.ID_EXIT)
         else:
@@ -263,54 +267,56 @@
     def _init_coll_EditMenu_Items(self, parent):
         AppendMenu(parent, help='', id=wx.ID_REFRESH,
               kind=wx.ITEM_NORMAL, text=u'Refresh\tCTRL+R')
-        if not self.ModeSolo:
-            AppendMenu(parent, help='', id=wx.ID_CLEAR,
-                  kind=wx.ITEM_NORMAL, text=u'Clear Errors\tCTRL+K')
-        AppendMenu(parent, help='', id=wx.ID_UNDO,
-              kind=wx.ITEM_NORMAL, text=u'Undo\tCTRL+Z')
-        AppendMenu(parent, help='', id=wx.ID_REDO,
-              kind=wx.ITEM_NORMAL, text=u'Redo\tCTRL+Y')
-        parent.AppendSeparator()
-        AppendMenu(parent, help='', id=wx.ID_CUT,
-              kind=wx.ITEM_NORMAL, text=u'Cut\tCTRL+X')
-        AppendMenu(parent, help='', id=wx.ID_COPY,
-              kind=wx.ITEM_NORMAL, text=u'Copy\tCTRL+C')
-        AppendMenu(parent, help='', id=wx.ID_PASTE,
-              kind=wx.ITEM_NORMAL, text=u'Paste\tCTRL+V')
-        parent.AppendSeparator()
-        addmenu = wx.Menu(title='')
-        parent.AppendMenu(wx.ID_ADD, "Add Element", addmenu)
-        AppendMenu(addmenu, help='', id=ID_PLCOPENEDITOREDITMENUADDDATATYPE,
-              kind=wx.ITEM_NORMAL, text=u'Data Type')
-        AppendMenu(addmenu, help='', id=ID_PLCOPENEDITOREDITMENUADDFUNCTION,
-              kind=wx.ITEM_NORMAL, text=u'Function')
-        AppendMenu(addmenu, help='', id=ID_PLCOPENEDITOREDITMENUADDFUNCTIONBLOCK,
-              kind=wx.ITEM_NORMAL, text=u'Function Block')
-        AppendMenu(addmenu, help='', id=ID_PLCOPENEDITOREDITMENUADDPROGRAM,
-              kind=wx.ITEM_NORMAL, text=u'Program')
-        AppendMenu(addmenu, help='', id=ID_PLCOPENEDITOREDITMENUADDCONFIGURATION,
-              kind=wx.ITEM_NORMAL, text=u'Configuration')
-        AppendMenu(parent, help='', id=wx.ID_DELETE,
-              kind=wx.ITEM_NORMAL, text=u'Delete')
+        if not self.Debug:
+            if not self.ModeSolo:
+                AppendMenu(parent, help='', id=wx.ID_CLEAR,
+                      kind=wx.ITEM_NORMAL, text=u'Clear Errors\tCTRL+K')
+            AppendMenu(parent, help='', id=wx.ID_UNDO,
+                  kind=wx.ITEM_NORMAL, text=u'Undo\tCTRL+Z')
+            AppendMenu(parent, help='', id=wx.ID_REDO,
+                  kind=wx.ITEM_NORMAL, text=u'Redo\tCTRL+Y')
+            parent.AppendSeparator()
+            AppendMenu(parent, help='', id=wx.ID_CUT,
+                  kind=wx.ITEM_NORMAL, text=u'Cut\tCTRL+X')
+            AppendMenu(parent, help='', id=wx.ID_COPY,
+                  kind=wx.ITEM_NORMAL, text=u'Copy\tCTRL+C')
+            AppendMenu(parent, help='', id=wx.ID_PASTE,
+                  kind=wx.ITEM_NORMAL, text=u'Paste\tCTRL+V')
+            parent.AppendSeparator()
+            addmenu = wx.Menu(title='')
+            parent.AppendMenu(wx.ID_ADD, "Add Element", addmenu)
+            AppendMenu(addmenu, help='', id=ID_PLCOPENEDITOREDITMENUADDDATATYPE,
+                  kind=wx.ITEM_NORMAL, text=u'Data Type')
+            AppendMenu(addmenu, help='', id=ID_PLCOPENEDITOREDITMENUADDFUNCTION,
+                  kind=wx.ITEM_NORMAL, text=u'Function')
+            AppendMenu(addmenu, help='', id=ID_PLCOPENEDITOREDITMENUADDFUNCTIONBLOCK,
+                  kind=wx.ITEM_NORMAL, text=u'Function Block')
+            AppendMenu(addmenu, help='', id=ID_PLCOPENEDITOREDITMENUADDPROGRAM,
+                  kind=wx.ITEM_NORMAL, text=u'Program')
+            AppendMenu(addmenu, help='', id=ID_PLCOPENEDITOREDITMENUADDCONFIGURATION,
+                  kind=wx.ITEM_NORMAL, text=u'Configuration')
+            AppendMenu(parent, help='', id=wx.ID_DELETE,
+                  kind=wx.ITEM_NORMAL, text=u'Delete')
         self.Bind(wx.EVT_MENU, self.OnRefreshMenu, id=wx.ID_REFRESH)
-        if not self.ModeSolo:
-            self.Bind(wx.EVT_MENU, self.OnClearErrorsMenu, id=wx.ID_CLEAR)
-        self.Bind(wx.EVT_MENU, self.OnUndoMenu, id=wx.ID_UNDO)
-        self.Bind(wx.EVT_MENU, self.OnRedoMenu, id=wx.ID_REDO)
-        self.Bind(wx.EVT_MENU, self.OnCutMenu, id=wx.ID_CUT)
-        self.Bind(wx.EVT_MENU, self.OnCopyMenu, id=wx.ID_COPY)
-        self.Bind(wx.EVT_MENU, self.OnPasteMenu, id=wx.ID_PASTE)
-        self.Bind(wx.EVT_MENU, self.OnAddDataTypeMenu,
-              id=ID_PLCOPENEDITOREDITMENUADDDATATYPE)
-        self.Bind(wx.EVT_MENU, self.GenerateAddPouFunction("function"),
-              id=ID_PLCOPENEDITOREDITMENUADDFUNCTION)
-        self.Bind(wx.EVT_MENU, self.GenerateAddPouFunction("functionBlock"),
-              id=ID_PLCOPENEDITOREDITMENUADDFUNCTIONBLOCK)
-        self.Bind(wx.EVT_MENU, self.GenerateAddPouFunction("program"),
-              id=ID_PLCOPENEDITOREDITMENUADDPROGRAM)
-        self.Bind(wx.EVT_MENU, self.OnAddConfigurationMenu,
-              id=ID_PLCOPENEDITOREDITMENUADDCONFIGURATION)
-        self.Bind(wx.EVT_MENU, self.OnDeleteMenu, id=wx.ID_DELETE)
+        if not self.Debug:
+            if not self.ModeSolo:
+                self.Bind(wx.EVT_MENU, self.OnClearErrorsMenu, id=wx.ID_CLEAR)
+            self.Bind(wx.EVT_MENU, self.OnUndoMenu, id=wx.ID_UNDO)
+            self.Bind(wx.EVT_MENU, self.OnRedoMenu, id=wx.ID_REDO)
+            self.Bind(wx.EVT_MENU, self.OnCutMenu, id=wx.ID_CUT)
+            self.Bind(wx.EVT_MENU, self.OnCopyMenu, id=wx.ID_COPY)
+            self.Bind(wx.EVT_MENU, self.OnPasteMenu, id=wx.ID_PASTE)
+            self.Bind(wx.EVT_MENU, self.OnAddDataTypeMenu,
+                  id=ID_PLCOPENEDITOREDITMENUADDDATATYPE)
+            self.Bind(wx.EVT_MENU, self.GenerateAddPouFunction("function"),
+                  id=ID_PLCOPENEDITOREDITMENUADDFUNCTION)
+            self.Bind(wx.EVT_MENU, self.GenerateAddPouFunction("functionBlock"),
+                  id=ID_PLCOPENEDITOREDITMENUADDFUNCTIONBLOCK)
+            self.Bind(wx.EVT_MENU, self.GenerateAddPouFunction("program"),
+                  id=ID_PLCOPENEDITOREDITMENUADDPROGRAM)
+            self.Bind(wx.EVT_MENU, self.OnAddConfigurationMenu,
+                  id=ID_PLCOPENEDITOREDITMENUADDCONFIGURATION)
+            self.Bind(wx.EVT_MENU, self.OnDeleteMenu, id=wx.ID_DELETE)
 
     def _init_coll_HelpMenu_Items(self, parent):
         AppendMenu(parent, help='', id=wx.ID_HELP, 
@@ -382,135 +388,164 @@
             self.TreeNoteBook = wx.aui.AuiNotebook(self)
             self.AUIManager.AddPane(self.TreeNoteBook, wx.aui.AuiPaneInfo().Caption("Project").Left().Layer(1).BestSize(wx.Size(200, 500)).CloseButton(False))
         
+        typestreestyle = wx.TR_HAS_BUTTONS|wx.TR_SINGLE|wx.SUNKEN_BORDER
+        if not self.Debug:
+            typestreestyle |= wx.TR_HIDE_ROOT
         self.TypesTree = wx.TreeCtrl(id=ID_PLCOPENEDITORTYPESTREE,
                   name='TypesTree', parent=self.TreeNoteBook, 
                   pos=wx.Point(0, 0), size=wx.Size(0, 0),
-                  style=wx.TR_HAS_BUTTONS|wx.TR_EDIT_LABELS|wx.TR_SINGLE|wx.SUNKEN_BORDER)
+                  style=typestreestyle)
         self.TreeNoteBook.AddPage(self.TypesTree, "Types")
         
-        if wx.Platform == '__WXMSW__':
-            self.Bind(wx.EVT_TREE_ITEM_RIGHT_CLICK, self.OnTypesTreeRightUp,
+        if not self.Debug:
+            if wx.Platform == '__WXMSW__':
+                self.Bind(wx.EVT_TREE_ITEM_RIGHT_CLICK, self.OnTypesTreeRightUp,
+                      id=ID_PLCOPENEDITORTYPESTREE)
+                self.Bind(wx.EVT_TREE_SEL_CHANGED, self.OnTypesTreeItemSelected,
+                      id=ID_PLCOPENEDITORTYPESTREE)
+            else:
+                if wx.VERSION >= (2, 6, 0):
+                    self.TypesTree.Bind(wx.EVT_RIGHT_UP, self.OnTypesTreeRightUp)
+                    self.TypesTree.Bind(wx.EVT_LEFT_UP, self.OnTypesTreeLeftUp)
+                else:
+                    wx.EVT_RIGHT_UP(self.TypesTree, self.OnTypesTreeRightUp)
+                    wx.EVT_LEFT_UP(self.TypesTree, self.OnTypesTreeLeftUp)
+                self.Bind(wx.EVT_TREE_SEL_CHANGING, self.OnTypesTreeItemChanging,
+                      id=ID_PLCOPENEDITORTYPESTREE)
+            self.Bind(wx.EVT_TREE_BEGIN_DRAG, self.OnTypesTreeBeginDrag,
                   id=ID_PLCOPENEDITORTYPESTREE)
-            self.Bind(wx.EVT_TREE_SEL_CHANGED, self.OnTypesTreeItemSelected,
+            self.Bind(wx.EVT_TREE_BEGIN_LABEL_EDIT, self.OnTypesTreeItemBeginEdit,
                   id=ID_PLCOPENEDITORTYPESTREE)
-        else:
-            if wx.VERSION >= (2, 6, 0):
-                self.TypesTree.Bind(wx.EVT_RIGHT_UP, self.OnTypesTreeRightUp)
-                self.TypesTree.Bind(wx.EVT_LEFT_UP, self.OnTypesTreeLeftUp)
-            else:
-                wx.EVT_RIGHT_UP(self.TypesTree, self.OnTypesTreeRightUp)
-                wx.EVT_LEFT_UP(self.TypesTree, self.OnTypesTreeLeftUp)
-            self.Bind(wx.EVT_TREE_SEL_CHANGING, self.OnTypesTreeItemChanging,
+            self.Bind(wx.EVT_TREE_END_LABEL_EDIT, self.OnTypesTreeItemEndEdit,
                   id=ID_PLCOPENEDITORTYPESTREE)
-        self.Bind(wx.EVT_TREE_BEGIN_DRAG, self.OnTypesTreeBeginDrag,
-              id=ID_PLCOPENEDITORTYPESTREE)
-        self.Bind(wx.EVT_TREE_BEGIN_LABEL_EDIT, self.OnTypesTreeItemBeginEdit,
-              id=ID_PLCOPENEDITORTYPESTREE)
-        self.Bind(wx.EVT_TREE_END_LABEL_EDIT, self.OnTypesTreeItemEndEdit,
-              id=ID_PLCOPENEDITORTYPESTREE)
-        self.Bind(wx.EVT_TREE_ITEM_ACTIVATED, self.OnTypesTreeItemActivated,
-              id=ID_PLCOPENEDITORTYPESTREE)
+            self.Bind(wx.EVT_TREE_ITEM_ACTIVATED, self.OnTypesTreeItemActivated,
+                  id=ID_PLCOPENEDITORTYPESTREE)
         
         self.InstancesTree = wx.TreeCtrl(id=ID_PLCOPENEDITORINSTANCESTREE,
                   name='InstancesTree', parent=self.TreeNoteBook, 
                   pos=wx.Point(0, 0), size=wx.Size(0, 0),
-                  style=wx.TR_HAS_BUTTONS|wx.TR_EDIT_LABELS|wx.TR_SINGLE|wx.SUNKEN_BORDER)
+                  style=wx.TR_HAS_BUTTONS|wx.TR_SINGLE|wx.SUNKEN_BORDER)
         self.TreeNoteBook.AddPage(self.InstancesTree, "Instances")
         
-        if wx.VERSION < (2, 8, 0):
-            self.ToolBar = self.CreateToolBar(wx.TB_HORIZONTAL|wx.TB_FLAT|wx.NO_BORDER, 
-                  ID_PLCOPENEDITORTOOLBAR, 'ToolBar')
-            self.ToolBar.SetToolBitmapSize(wx.Size(25, 25))
-            self.ToolBar.AddRadioTool(ID_PLCOPENEDITORTOOLBARSELECTION, 
-                  wx.Bitmap(os.path.join(CWD, 'Images', 'select.png')), wx.NullBitmap, "Select an object")
-            self.ToolBar.Realize()
-        else:
-            ToolBar = wx.ToolBar(self, ID_PLCOPENEDITORTOOLBAR, wx.DefaultPosition, wx.DefaultSize,
-                    wx.TB_FLAT | wx.TB_NODIVIDER | wx.NO_BORDER)
-            ToolBar.SetToolBitmapSize(wx.Size(25, 25))
-            ToolBar.AddRadioTool(ID_PLCOPENEDITORTOOLBARSELECTION, 
-                  wx.Bitmap(os.path.join(CWD, 'Images', 'select.png')), wx.NullBitmap, "Select an object")
-            ToolBar.Realize()
-            self.Panes["ToolBar"] = ToolBar
-            self.AUIManager.AddPane(ToolBar, wx.aui.AuiPaneInfo().
-                      Name("ToolBar").Caption("Toolbar").
-                      ToolbarPane().Top().
-                      LeftDockable(False).RightDockable(False))
-        
-        self.Bind(wx.EVT_TOOL, self.OnSelectionTool, 
-              id=ID_PLCOPENEDITORTOOLBARSELECTION)
+        if self.Debug:
+            self.Bind(wx.EVT_TREE_BEGIN_DRAG, self.OnInstancesTreeBeginDrag,
+                  id=ID_PLCOPENEDITORINSTANCESTREE)
+            self.Bind(wx.EVT_TREE_ITEM_ACTIVATED, self.OnInstancesTreeItemActivated,
+                  id=ID_PLCOPENEDITORINSTANCESTREE)
             
-        if wx.VERSION < (2, 8, 0):
-            self.SecondSplitter = wx.SplitterWindow(id=ID_PLCOPENEDITORSECONDSPLITTER,
-                  name='SecondSplitter', parent=self.MainSplitter, point=wx.Point(0, 0),
-                  size=wx.Size(0, 0), style=wx.SP_3D)
-            self.SecondSplitter.SetMinimumPaneSize(1)
+            if wx.VERSION < (2, 8, 0):
+                self.TabsOpened = wx.Notebook(id=ID_PLCOPENEDITORTABSOPENED,
+                      name='TabsOpened', parent=self.MainSplitter, pos=wx.Point(0,
+                      0), size=wx.Size(0, 0), style=0)
+                if wx.VERSION >= (2, 6, 0):
+                    self.TabsOpened.Bind(wx.EVT_NOTEBOOK_PAGE_CHANGED,
+                        self.OnPouSelectedChanged, id=ID_PLCOPENEDITORTABSOPENED)
+                else:
+                    wx.EVT_NOTEBOOK_PAGE_CHANGED(self.TabsOpened, ID_PLCOPENEDITORTABSOPENED,
+                        self.OnPouSelectedChanged)
             
-            self.MainSplitter.SplitVertically(self.TreeNoteBook, self.SecondSplitter, 200)
+                self.MainSplitter.SplitVertically(self.TreeNoteBook, self.TabsOpened, 200)
+            else:
+                self.TabsOpened = wx.aui.AuiNotebook(self)
+                self.TabsOpened.Bind(wx.aui.EVT_AUINOTEBOOK_PAGE_CHANGED,
+                        self.OnPouSelectedChanged)
+                self.AUIManager.AddPane(self.TabsOpened, wx.aui.AuiPaneInfo().CentrePane())
+        else:
+            if wx.VERSION < (2, 8, 0):
+                self.ToolBar = self.CreateToolBar(wx.TB_HORIZONTAL|wx.TB_FLAT|wx.NO_BORDER, 
+                      ID_PLCOPENEDITORTOOLBAR, 'ToolBar')
+                self.ToolBar.SetToolBitmapSize(wx.Size(25, 25))
+                self.ToolBar.AddRadioTool(ID_PLCOPENEDITORTOOLBARSELECTION, 
+                      wx.Bitmap(os.path.join(CWD, 'Images', 'select.png')), wx.NullBitmap, "Select an object")
+                self.ToolBar.Realize()
+            else:
+                ToolBar = wx.ToolBar(self, ID_PLCOPENEDITORTOOLBAR, wx.DefaultPosition, wx.DefaultSize,
+                        wx.TB_FLAT | wx.TB_NODIVIDER | wx.NO_BORDER)
+                ToolBar.SetToolBitmapSize(wx.Size(25, 25))
+                ToolBar.AddRadioTool(ID_PLCOPENEDITORTOOLBARSELECTION, 
+                      wx.Bitmap(os.path.join(CWD, 'Images', 'select.png')), wx.NullBitmap, "Select an object")
+                ToolBar.Realize()
+                self.Panes["ToolBar"] = ToolBar
+                self.AUIManager.AddPane(ToolBar, wx.aui.AuiPaneInfo().
+                          Name("ToolBar").Caption("Toolbar").
+                          ToolbarPane().Top().
+                          LeftDockable(False).RightDockable(False))
             
-            self.VariablePanelIndexer = VariablePanelIndexer(self.SecondSplitter, self, self.Controler)
-        
-            self.ThirdSplitter = wx.SplitterWindow(id=ID_PLCOPENEDITORTHIRDSPLITTER,
-                  name='ThirdSplitter', parent=self.SecondSplitter, point=wx.Point(0, 0),
-                  size=wx.Size(0, 0), style=wx.SP_3D)
-            self.ThirdSplitter.SetMinimumPaneSize(1)
+            self.Bind(wx.EVT_TOOL, self.OnSelectionTool, 
+                  id=ID_PLCOPENEDITORTOOLBARSELECTION)
             
-            self.SecondSplitter.SplitHorizontally(self.ThirdSplitter, self.VariablePanelIndexer, -200)
+            if wx.VERSION < (2, 8, 0):
+                self.SecondSplitter = wx.SplitterWindow(id=ID_PLCOPENEDITORSECONDSPLITTER,
+                      name='SecondSplitter', parent=self.MainSplitter, point=wx.Point(0, 0),
+                      size=wx.Size(0, 0), style=wx.SP_3D)
+                self.SecondSplitter.SetMinimumPaneSize(1)
+                
+                self.MainSplitter.SplitVertically(self.TreeNoteBook, self.SecondSplitter, 200)
+                
+                self.VariablePanelIndexer = VariablePanelIndexer(self.SecondSplitter, self, self.Controler)
             
-            self.TabsOpened = wx.Notebook(id=ID_PLCOPENEDITORTABSOPENED,
-                  name='TabsOpened', parent=self.SecondSplitter, pos=wx.Point(0,
-                  0), size=wx.Size(0, 0), style=0)
-            if wx.VERSION >= (2, 6, 0):
-                self.TabsOpened.Bind(wx.EVT_NOTEBOOK_PAGE_CHANGED,
-                    self.OnPouSelectedChanged, id=ID_PLCOPENEDITORTABSOPENED)
+                self.ThirdSplitter = wx.SplitterWindow(id=ID_PLCOPENEDITORTHIRDSPLITTER,
+                      name='ThirdSplitter', parent=self.SecondSplitter, point=wx.Point(0, 0),
+                      size=wx.Size(0, 0), style=wx.SP_3D)
+                self.ThirdSplitter.SetMinimumPaneSize(1)
+                
+                self.SecondSplitter.SplitHorizontally(self.ThirdSplitter, self.VariablePanelIndexer, -200)
+                
+                self.TabsOpened = wx.Notebook(id=ID_PLCOPENEDITORTABSOPENED,
+                      name='TabsOpened', parent=self.SecondSplitter, pos=wx.Point(0,
+                      0), size=wx.Size(0, 0), style=0)
+                if wx.VERSION >= (2, 6, 0):
+                    self.TabsOpened.Bind(wx.EVT_NOTEBOOK_PAGE_CHANGED,
+                        self.OnPouSelectedChanged, id=ID_PLCOPENEDITORTABSOPENED)
+                else:
+                    wx.EVT_NOTEBOOK_PAGE_CHANGED(self.TabsOpened, ID_PLCOPENEDITORTABSOPENED,
+                        self.OnPouSelectedChanged)
+            
+                self.LibraryPanel = wx.Panel(id=ID_PLCOPENEDITORLIBRARYPANEL,
+                      name='LibraryPanel', parent=self.ThirdSplitter, pos=wx.Point(0,
+                      0), size=wx.Size(0, 0), style=wx.SUNKEN_BORDER)
+                
+                self.ThirdSplitter.SplitVertically(self.TabsOpened, self.LibraryPanel, -250)
             else:
-                wx.EVT_NOTEBOOK_PAGE_CHANGED(self.TabsOpened, ID_PLCOPENEDITORTABSOPENED,
-                    self.OnPouSelectedChanged)
-        
-            self.LibraryPanel = wx.Panel(id=ID_PLCOPENEDITORLIBRARYPANEL,
-                  name='LibraryPanel', parent=self.ThirdSplitter, pos=wx.Point(0,
-                  0), size=wx.Size(0, 0), style=wx.SUNKEN_BORDER)
+                self.VariablePanelIndexer = VariablePanelIndexer(self, self, self.Controler)
+                self.AUIManager.AddPane(self.VariablePanelIndexer, wx.aui.AuiPaneInfo().Caption("Variables").Bottom().Layer(0).BestSize(wx.Size(800, 200)).CloseButton(False))
             
-            self.ThirdSplitter.SplitVertically(self.TabsOpened, self.LibraryPanel, -250)
-        else:
-            self.VariablePanelIndexer = VariablePanelIndexer(self, self, self.Controler)
-            self.AUIManager.AddPane(self.VariablePanelIndexer, wx.aui.AuiPaneInfo().Caption("Variables").Bottom().Layer(0).BestSize(wx.Size(800, 200)).CloseButton(False))
-        
-            self.TabsOpened = wx.aui.AuiNotebook(self)
-            self.TabsOpened.Bind(wx.aui.EVT_AUINOTEBOOK_PAGE_CHANGED,
-                    self.OnPouSelectedChanged)
-            self.AUIManager.AddPane(self.TabsOpened, wx.aui.AuiPaneInfo().CentrePane())
-        
-            self.LibraryPanel = wx.Panel(id=ID_PLCOPENEDITORLIBRARYPANEL,
-                  name='LibraryPanel', parent=self, pos=wx.Point(0,
-                  0), size=wx.Size(0, 0), style=0)
-            self.AUIManager.AddPane(self.LibraryPanel, wx.aui.AuiPaneInfo().Caption("Library").Right().Layer(0).BestSize(wx.Size(250, 400)).CloseButton(False))
-        
-        if wx.Platform == '__WXMSW__':
-            treestyle = wx.TR_HAS_BUTTONS|wx.TR_SINGLE|wx.SUNKEN_BORDER
-        else:
-            treestyle = wx.TR_HAS_BUTTONS|wx.TR_HIDE_ROOT|wx.TR_SINGLE|wx.SUNKEN_BORDER
-        self.LibraryTree = wx.TreeCtrl(id=ID_PLCOPENEDITORLIBRARYTREE,
-                  name='LibraryTree', parent=self.LibraryPanel, 
-                  pos=wx.Point(0, 0), size=wx.Size(0, 0),
-                  style=treestyle)
-        self.Bind(wx.EVT_TREE_SEL_CHANGED, self.OnLibraryTreeItemSelected,
-              id=ID_PLCOPENEDITORLIBRARYTREE)
-        self.Bind(wx.EVT_TREE_BEGIN_DRAG, self.OnLibraryTreeBeginDrag,
-              id=ID_PLCOPENEDITORLIBRARYTREE)
-        
-        self.LibraryComment = wx.TextCtrl(id=ID_PLCOPENEDITORLIBRARYCOMMENT,
-                  name='LibraryComment', parent=self.LibraryPanel, 
-                  pos=wx.Point(0, 0), size=wx.Size(0, 60), 
-                  style=wx.TE_READONLY|wx.TE_MULTILINE)
-        
-        self._init_sizers()
+                self.TabsOpened = wx.aui.AuiNotebook(self)
+                self.TabsOpened.Bind(wx.aui.EVT_AUINOTEBOOK_PAGE_CHANGED,
+                        self.OnPouSelectedChanged)
+                self.AUIManager.AddPane(self.TabsOpened, wx.aui.AuiPaneInfo().CentrePane())
+            
+                self.LibraryPanel = wx.Panel(id=ID_PLCOPENEDITORLIBRARYPANEL,
+                      name='LibraryPanel', parent=self, pos=wx.Point(0,
+                      0), size=wx.Size(0, 0), style=0)
+                self.AUIManager.AddPane(self.LibraryPanel, wx.aui.AuiPaneInfo().Caption("Library").Right().Layer(0).BestSize(wx.Size(250, 400)).CloseButton(False))
+            
+            if wx.Platform == '__WXMSW__':
+                librarytreestyle = wx.TR_HAS_BUTTONS|wx.TR_SINGLE|wx.SUNKEN_BORDER
+            else:
+                librarytreestyle = wx.TR_HAS_BUTTONS|wx.TR_HIDE_ROOT|wx.TR_SINGLE|wx.SUNKEN_BORDER
+            self.LibraryTree = wx.TreeCtrl(id=ID_PLCOPENEDITORLIBRARYTREE,
+                      name='LibraryTree', parent=self.LibraryPanel, 
+                      pos=wx.Point(0, 0), size=wx.Size(0, 0),
+                      style=librarytreestyle)
+            self.Bind(wx.EVT_TREE_SEL_CHANGED, self.OnLibraryTreeItemSelected,
+                  id=ID_PLCOPENEDITORLIBRARYTREE)
+            self.Bind(wx.EVT_TREE_BEGIN_DRAG, self.OnLibraryTreeBeginDrag,
+                  id=ID_PLCOPENEDITORLIBRARYTREE)
+            
+            self.LibraryComment = wx.TextCtrl(id=ID_PLCOPENEDITORLIBRARYCOMMENT,
+                      name='LibraryComment', parent=self.LibraryPanel, 
+                      pos=wx.Point(0, 0), size=wx.Size(0, 60), 
+                      style=wx.TE_READONLY|wx.TE_MULTILINE)
+            
+            self._init_sizers()
         
         if wx.VERSION >= (2, 8, 0):
             self.AUIManager.Update()
     
-    def __init__(self, parent, controler = None, fileOpen = None):
+    def __init__(self, parent, controler = None, fileOpen = None, debug = False):
         self.ModeSolo = controler == None
+        self.Debug = debug
         if self.ModeSolo:
             self.Controler = PLCControler()
             if fileOpen is not None:
@@ -622,7 +657,7 @@
             self.SetTitle("PLCOpenEditor")
 
     def ShowProperties(self):
-        old_values = self.Controler.GetProjectProperties()
+        old_values = self.Controler.GetProjectProperties(self.Debug)
         dialog = ProjectDialog(self)
         dialog.SetValues(old_values)
         if dialog.ShowModal() == wx.ID_OK:
@@ -635,7 +670,7 @@
                 self.RefreshEditMenu()
                 self.RefreshTypesTree()
                 for i in xrange(self.TabsOpened.GetPageCount()):
-                    editor = self.GetPage(i)
+                    editor = self.TabsOpened.GetPage(i)
                     editor.RefreshScaling()
         dialog.Destroy()
 
@@ -767,15 +802,16 @@
     def OnCloseTabMenu(self, event):
         selected = self.TabsOpened.GetSelection()
         if selected >= 0:
-            tagname = self.TabsOpened.GetPage(selected).GetTagName()
             self.TabsOpened.DeletePage(selected)
-            self.VariablePanelIndexer.RemoveVariablePanel(tagname)
+            if not self.Debug:
+                tagname = self.TabsOpened.GetPage(selected).GetTagName()
+                self.VariablePanelIndexer.RemoveVariablePanel(tagname)
             if self.TabsOpened.GetPageCount() > 0:
                 new_index = min(selected, self.TabsOpened.GetPageCount() - 1)
-                tagname = self.TabsOpened.GetPage(new_index).GetTagName()
                 self.TabsOpened.SetSelection(new_index)
-                self.VariablePanelIndexer.ChangeVariablePanel(tagname)
-            self.RefreshTitle()
+                if not self.Debug:
+                    tagname = self.TabsOpened.GetPage(new_index).GetTagName()
+                    self.VariablePanelIndexer.ChangeVariablePanel(tagname)
             self.RefreshFileMenu()
             self.RefreshEditMenu()
             self.RefreshToolBar()
@@ -845,7 +881,7 @@
         if filepath != "":
             directory, filename = os.path.split(filepath)
         else:
-            directory, filename = os.getcwd(), "%(projectName)s.xml"%self.Controler.GetProjectProperties()
+            directory, filename = os.getcwd(), "%(projectName)s.xml"%self.Controler.GetProjectProperties(self.Debug)
         dialog = wx.FileDialog(self, "Choose a file", directory, filename,  "PLCOpen files (*.xml)|*.xml|All files|*.*", wx.SAVE|wx.OVERWRITE_PROMPT)
         if dialog.ShowModal() == wx.ID_OK:
             filepath = dialog.GetPath()
@@ -874,7 +910,7 @@
         selected = self.TabsOpened.GetSelection()        
         if selected != -1:
             data = wx.PrintDialogData(self.PrintData)
-            properties = self.Controler.GetProjectProperties()
+            properties = self.Controler.GetProjectProperties(self.Debug)
             page_size = map(int, properties["pageSize"])
             margins = (self.PageSetupData.GetMarginTopLeft(), self.PageSetupData.GetMarginBottomRight())
             printout = GraphicPrintout(self.TabsOpened.GetPage(selected), page_size, margins, True)
@@ -894,7 +930,7 @@
         if selected != -1:
             dialog_data = wx.PrintDialogData(self.PrintData)
             dialog_data.SetToPage(1)
-            properties = self.Controler.GetProjectProperties()
+            properties = self.Controler.GetProjectProperties(self.Debug)
             page_size = map(int, properties["pageSize"])
             margins = (self.PageSetupData.GetMarginTopLeft(), self.PageSetupData.GetMarginBottomRight())
             printer = wx.Printer(dialog_data)
@@ -949,7 +985,8 @@
         if selected != -1:
             window = self.TabsOpened.GetPage(selected)
             window.RefreshView()
-            self.VariablePanelIndexer.RefreshVariablePanel(window.GetTagName())
+            if not self.Debug:
+                self.VariablePanelIndexer.RefreshVariablePanel(window.GetTagName())
         event.Skip()
 
     def OnClearErrorsMenu(self, event):
@@ -962,7 +999,7 @@
         idxs.reverse()
         for idx in idxs:
             tagname = self.TabsOpened.GetPage(idx).GetTagName()
-            if self.Controler.GetEditedElement(tagname) is None:
+            if self.Controler.GetEditedElement(tagname, self.Debug) is None:
                 self.VariablePanelIndexer.RemoveVariablePanel(tagname)
                 self.TabsOpened.DeletePage(idx)
         selected = self.TabsOpened.GetSelection()        
@@ -983,7 +1020,7 @@
         idxs.reverse()
         for idx in idxs:
             tagname = self.TabsOpened.GetPage(idx).GetTagName()
-            if self.Controler.GetEditedElement(tagname) is None:
+            if self.Controler.GetEditedElement(tagname, self.Debug) is None:
                 self.VariablePanelIndexer.RemoveVariablePanel(tagname)
                 self.TabsOpened.DeletePage(idx)
         selected = self.TabsOpened.GetSelection()
@@ -1031,7 +1068,7 @@
                 tagname = ""
                 if type == ITEM_DATATYPE:
                     name = self.TypesTree.GetItemText(selected)
-                    if not self.Controler.DataTypeIsUsed(name):
+                    if not self.Controler.DataTypeIsUsed(name, self.Debug):
                         self.Controler.ProjectRemoveDataType(name)
                         tagname = self.Controler.ComputeDataTypeName(name)
                     else:
@@ -1040,9 +1077,9 @@
                         message.Destroy()
                 elif type == ITEM_POU:
                     name = self.TypesTree.GetItemText(selected)
-                    if not self.Controler.DataTypeIsUsed(name):
-                        self.Controler.ProjectRemoveDataType(name)
-                        tagname = self.Controler.ComputeDataTypeName(name)
+                    if not self.Controler.PouIsUsed(name, self.Debug):
+                        self.Controler.ProjectRemovePou(name)
+                        tagname = self.Controler.ComputePouName(name)
                     else:
                         message = wx.MessageDialog(self, "%s is used by one or more POUs. It can't be removed!"%selected, "Error", wx.OK|wx.ICON_ERROR)
                         message.ShowModal()
@@ -1100,13 +1137,20 @@
     def OnPouSelectedChanged(self, event):
         old_selected = self.TabsOpened.GetSelection()
         if old_selected >= 0:
-            self.TabsOpened.GetPage(old_selected).ResetBuffer()
+            if self.Debug:
+                pass
+            else:
+                self.TabsOpened.GetPage(old_selected).ResetBuffer()
         selected = event.GetSelection()
         if selected >= 0:
             window = self.TabsOpened.GetPage(selected)
-            self.SelectTypesTreeItem(window.GetTagName())
+            if self.Debug:
+                self.SelectTypesTreeItem(window.GetTagName())
+            else:
+                self.SelectInstancesTreeItem(self.InstancesTree.GetRootItem(), window.GetInstancePath())
             window.RefreshView()
-            self.VariablePanelIndexer.ChangeVariablePanel(window.GetTagName())
+            if not self.Debug:
+                self.VariablePanelIndexer.ChangeVariablePanel(window.GetTagName())
             self.RefreshFileMenu()
             self.RefreshEditMenu()
             self.RefreshToolBar()
@@ -1141,14 +1185,14 @@
             window = self.TabsOpened.GetPage(idx)
             words = window.GetTagName().split("::")
             if words[0] == "P":
-                pou_type = self.Controler.GetEditedElementType(window.GetTagName())[1].upper()
-                pou_body_type = self.Controler.GetEditedElementBodyType(window.GetTagName())
+                pou_type = self.Controler.GetEditedElementType(window.GetTagName(), self.Debug)[1].upper()
+                pou_body_type = self.Controler.GetEditedElementBodyType(window.GetTagName(), self.Debug)
                 self.SetPageBitmap(idx, GenerateBitmap(pou_type, pou_body_type))
             elif words[0] == "T":
-                pou_body_type = self.Controler.GetEditedElementBodyType(window.GetTagName())
+                pou_body_type = self.Controler.GetEditedElementBodyType(window.GetTagName(), self.Debug)
                 self.SetPageBitmap(idx, GenerateBitmap("TRANSITION", pou_body_type))
             elif words[0] == "A":
-                pou_body_type = self.Controler.GetEditedElementBodyType(window.GetTagName())
+                pou_body_type = self.Controler.GetEditedElementBodyType(window.GetTagName(), self.Debug)
                 self.SetPageBitmap(idx, GenerateBitmap("ACTION", pou_body_type))
             elif words[0] == "C":
                 self.SetPageBitmap(idx, GenerateBitmap("CONFIGURATION"))
@@ -1156,7 +1200,10 @@
                 self.SetPageBitmap(idx, GenerateBitmap("RESOURCE"))
             elif words[0] == "D":
                 self.SetPageBitmap(idx, GenerateBitmap("DATATYPE"))
-            self.TabsOpened.SetPageText(idx, "-".join(words[1:]))
+            if self.Debug:
+                self.TabsOpened.SetPageText(idx, window.GetInstancePath())
+            else:
+                self.TabsOpened.SetPageText(idx, "-".join(words[1:]))
 
 
 #-------------------------------------------------------------------------------
@@ -1164,7 +1211,7 @@
 #-------------------------------------------------------------------------------
 
     def RefreshTypesTree(self):
-        infos = self.Controler.GetProjectInfos()
+        infos = self.Controler.GetProjectInfos(self.Debug)
         root = self.TypesTree.GetRootItem()
         if not root.IsOk():
             root = self.TypesTree.AddRoot(infos["name"])
@@ -1182,7 +1229,7 @@
             self.TypesTree.SetItemBackgroundColour(root, wx.WHITE)
             self.TypesTree.SetItemTextColour(root, wx.BLACK)
         if infos["type"] == ITEM_POU:
-            self.TypesTree.SetItemImage(root, self.TypesTreeImageDict[self.Controler.GetPouBodyType(infos["name"])])
+            self.TypesTree.SetItemImage(root, self.TypesTreeImageDict[self.Controler.GetPouBodyType(infos["name"], self.Debug)])
         else:
             self.TypesTree.SetItemImage(root, self.TypesTreeImageDict[infos["type"]])      
             
@@ -1204,7 +1251,7 @@
             self.TypesTree.Delete(item)
 
     def SelectTypesTreeItem(self, tagname):
-        if self.TypesTree:
+        if self.TypesTree is not None:
             root = self.TypesTree.GetRootItem()
             words = tagname.split("::")
             if words[0] == "D":
@@ -1223,7 +1270,7 @@
 
     def RecursiveTypesTreeItemSelection(self, root, items):
         found = False
-        if self.TypesTree:
+        if self.TypesTree is not None:
             if wx.VERSION >= (2, 6, 0):
                 item, root_cookie = self.TypesTree.GetFirstChild(root)
             else:
@@ -1247,7 +1294,7 @@
             self.SelectedItem = event.GetItem()
         if self.SelectedItem is not None and self.TypesTree.GetPyData(self.SelectedItem) == ITEM_POU:
             block_name = self.TypesTree.GetItemText(self.SelectedItem)
-            block_type = self.Controler.GetPouType(block_name)
+            block_type = self.Controler.GetPouType(block_name, self.Debug)
             if block_type != "program":
                 data = wx.TextDataObject(str((block_name, block_type, "")))
                 dragSource = wx.DropSource(self.TypesTree)
@@ -1278,7 +1325,7 @@
                 if itemtype == ITEM_PROJECT:
                     self.Controler.SetProjectProperties(name = new_name)
                 elif itemtype == ITEM_DATATYPE:
-                    if new_name.upper() in [name.upper() for name in self.Controler.GetProjectDataTypeNames() if name != old_name]:
+                    if new_name.upper() in [name.upper() for name in self.Controler.GetProjectDataTypeNames(self.Debug) if name != old_name]:
                         message = "\"%s\" data type already exists!"%new_name
                         abort = True
                     if not abort:
@@ -1287,10 +1334,10 @@
                                                 self.Controler.ComputeDataTypeName(new_name))
                         self.RefreshPageTitles()
                 elif itemtype == ITEM_POU:
-                    if new_name.upper() in [name.upper() for name in self.Controler.GetProjectPouNames() if name != old_name]:
+                    if new_name.upper() in [name.upper() for name in self.Controler.GetProjectPouNames(self.Debug) if name != old_name]:
                         message = "\"%s\" pou already exists!"%new_name
                         abort = True
-                    elif new_name.upper() in [name.upper() for name in self.Controler.GetProjectPouVariables()]:
+                    elif new_name.upper() in [name.upper() for name in self.Controler.GetProjectPouVariables(debug = self.Debug)]:
                         messageDialog = wx.MessageDialog(self, "A variable is defined with \"%s\" as name. It can generate a conflict. Do you wish to continue?"%new_name, "Error", wx.YES_NO|wx.ICON_QUESTION)
                         if messageDialog.ShowModal() == wx.ID_NO:
                             abort = True
@@ -1307,9 +1354,9 @@
                         parent = self.TypesTree.GetItemParent(parent)
                         parent_type = self.TypesTree.GetPyData(parent)
                     pou_name = self.TypesTree.GetItemText(parent)
-                    if new_name.upper() in [name.upper() for name in self.Controler.GetProjectPouNames()]:
+                    if new_name.upper() in [name.upper() for name in self.Controler.GetProjectPouNames(self.Debug)]:
                         message = "A pou with \"%s\" as name exists!"%new_name
-                    elif new_name.upper() in [name.upper() for name in self.Controler.GetProjectPouVariables(pou_name) if name != old_name]:
+                    elif new_name.upper() in [name.upper() for name in self.Controler.GetProjectPouVariables(pou_name, self.Debug) if name != old_name]:
                         message = "A variable with \"%s\" as name already exists in this pou!"%new_name
                     else:
                         self.Controler.ChangePouTransitionName(pou_name, old_name, new_name)
@@ -1323,9 +1370,9 @@
                         parent = self.TypesTree.GetItemParent(parent)
                         parent_type = self.TypesTree.GetPyData(parent)
                     pou_name = self.TypesTree.GetItemText(parent)
-                    if new_name.upper() in [name.upper() for name in self.Controler.GetProjectPouNames()]:
+                    if new_name.upper() in [name.upper() for name in self.Controler.GetProjectPouNames(self.Debug)]:
                         message = "A pou with \"%s\" as name exists!"%new_name
-                    elif new_name.upper() in [name.upper() for name in self.Controler.GetProjectPouVariables(pou_name) if name != old_name]:
+                    elif new_name.upper() in [name.upper() for name in self.Controler.GetProjectPouVariables(pou_name, self.Debug) if name != old_name]:
                         message = "A variable with \"%s\" as name already exists in this pou!"%new_name
                     else:
                         self.Controler.ChangePouActionName(pou_name, old_name, new_name)
@@ -1333,15 +1380,15 @@
                                                 self.Controler.ComputePouActionName(pou_name, new_name))
                         self.RefreshPageTitles()
                 elif itemtype == ITEM_CONFIGURATION:
-                    if new_name.upper() in [name.upper() for name in self.Controler.GetProjectConfigNames() if name != old_name]:
+                    if new_name.upper() in [name.upper() for name in self.Controler.GetProjectConfigNames(self.Debug) if name != old_name]:
                         message = "\"%s\" config already exists!"%new_name
                         abort = True
-                    elif new_name.upper() in [name.upper() for name in self.Controler.GetProjectPouNames()]:
+                    elif new_name.upper() in [name.upper() for name in self.Controler.GetProjectPouNames(self.Debug)]:
                         messageDialog = wx.MessageDialog(self, "A pou is defined with \"%s\" as name. It can generate a conflict. Do you wish to continue?"%new_name, "Error", wx.YES_NO|wx.ICON_QUESTION)
                         if messageDialog.ShowModal() == wx.ID_NO:
                             abort = True
                         messageDialog.Destroy()
-                    elif new_name.upper() in [name.upper() for name in self.Controler.GetProjectPouVariables()]:
+                    elif new_name.upper() in [name.upper() for name in self.Controler.GetProjectPouVariables(debug = self.Debug)]:
                         messageDialog = wx.MessageDialog(self, "A variable is defined with \"%s\" as name. It can generate a conflict. Do you wish to continue?"%new_name, "Error", wx.YES_NO|wx.ICON_QUESTION)
                         if messageDialog.ShowModal() == wx.ID_NO:
                             abort = True
@@ -1358,15 +1405,15 @@
                         parent = self.TypesTree.GetItemParent(parent)
                         parent_type = self.TypesTree.GetPyData(parent)
                     config_name = self.TypesTree.GetItemText(parent)
-                    if new_name.upper() in [name.upper() for name in self.Controler.GetProjectConfigNames()]:
+                    if new_name.upper() in [name.upper() for name in self.Controler.GetProjectConfigNames(self.Debug)]:
                         message = "\"%s\" config already exists!"%new_name
                         abort = True
-                    elif new_name.upper() in [name.upper() for name in self.Controler.GetProjectPouNames()]:
+                    elif new_name.upper() in [name.upper() for name in self.Controler.GetProjectPouNames(self.Debug)]:
                         messageDialog = wx.MessageDialog(self, "A pou is defined with \"%s\" as name. It can generate a conflict. Do you wish to continue?"%new_name, "Error", wx.YES_NO|wx.ICON_QUESTION)
                         if messageDialog.ShowModal() == wx.ID_NO:
                             abort = True
                         messageDialog.Destroy()
-                    elif new_name.upper() in [name.upper() for name in self.Controler.GetProjectPouVariables()]:
+                    elif new_name.upper() in [name.upper() for name in self.Controler.GetProjectPouVariables(debug = self.Debug)]:
                         messageDialog = wx.MessageDialog(self, "A variable is defined with \"%s\" as name. It can generate a conflict. Do you wish to continue?"%new_name, "Error", wx.YES_NO|wx.ICON_QUESTION)
                         if messageDialog.ShowModal() == wx.ID_NO:
                             abort = True
@@ -1501,7 +1548,7 @@
                 self.TabsOpened.AddPage(new_window, "")
                 self.VariablePanelIndexer.AddVariablePanel(tagname, "resource")
             elif elementtype in [ITEM_POU, ITEM_TRANSITION, ITEM_ACTION]:
-                bodytype = self.Controler.GetEditedElementBodyType(tagname)
+                bodytype = self.Controler.GetEditedElementBodyType(tagname, self.Debug)
                 if bodytype == "FBD":
                     new_window = Viewer(self.TabsOpened, tagname, self, self.Controler)
                     new_window.RefreshScaling(False)
@@ -1513,14 +1560,14 @@
                     new_window.RefreshScaling(False)
                 else:
                     new_window = TextViewer(self.TabsOpened, tagname, self, self.Controler)
-                    new_window.SetTextSyntax(elementtype)
+                    new_window.SetTextSyntax(bodytype)
                     if bodytype == "IL":
                         new_window.SetKeywords(IL_KEYWORDS)
                     else:
                         new_window.SetKeywords(ST_KEYWORDS)
                 self.TabsOpened.AddPage(new_window, "")
                 words = tagname.split("::")
-                self.VariablePanelIndexer.AddVariablePanel(tagname, self.Controler.GetPouType(words[1]))
+                self.VariablePanelIndexer.AddVariablePanel(tagname, self.Controler.GetPouType(words[1], self.Debug))
             elif elementtype == ITEM_DATATYPE:
                 new_window = DataTypeEditor(self.TabsOpened, tagname, self, self.Controler)
                 self.TabsOpened.AddPage(new_window, "")
@@ -1550,7 +1597,7 @@
         type = self.TypesTree.GetPyData(item)
         if type == ITEM_POU:
             menu = wx.Menu(title='')
-            if self.Controler.GetPouBodyType(name) == "SFC":
+            if self.Controler.GetPouBodyType(name, self.Debug) == "SFC":
                 new_id = wx.NewId()
                 AppendMenu(menu, help='', id=new_id, kind=wx.ITEM_NORMAL, text="Add Transition")
                 self.Bind(wx.EVT_MENU, self.GenerateAddTransitionFunction(name), id=new_id)
@@ -1644,7 +1691,7 @@
 #-------------------------------------------------------------------------------
 
     def RefreshInstancesTree(self):
-        infos = self.Controler.GetProjectTopology()
+        infos = self.Controler.GetProjectTopology(self.Debug)
         root = self.InstancesTree.GetRootItem()
         if not root.IsOk():
             root = self.InstancesTree.AddRoot(infos["name"])
@@ -1654,10 +1701,10 @@
     def GenerateInstancesTreeBranch(self, root, infos):
         to_delete = []
         if infos.get("elmt_type", None) is not None:
-            self.InstancesTree.SetItemText(root, "%s(%s)"%(infos["name"], infos["elmt_type"]))
+            self.InstancesTree.SetItemText(root, "%s (%s)"%(infos["name"], infos["elmt_type"]))
         else:
             self.InstancesTree.SetItemText(root, infos["name"])
-        self.InstancesTree.SetPyData(root, infos["type"])
+        self.InstancesTree.SetPyData(root, (infos["type"], infos.get("tagname", None)))
         self.InstancesTree.SetItemImage(root, self.InstancesTreeImageDict[infos["type"]])      
             
         if wx.VERSION >= (2, 6, 0):
@@ -1677,62 +1724,140 @@
         for item in to_delete:
             self.InstancesTree.Delete(item)
 
+    def OnInstancesTreeBeginDrag(self, event):
+        selected_item = event.GetItem()
+        selected_infos = self.InstancesTree.GetPyData(selected_item)
+        if selected_item is not None and selected_infos[0] in ITEMS_VARIABLE:
+            var_path = self.InstancesTree.GetItemText(selected_item).split(" (")[0]
+            parent_item = self.InstancesTree.GetItemParent(selected_item)
+            while self.InstancesTree.GetPyData(parent_item)[0] != ITEM_PROJECT:
+                parent_name = self.InstancesTree.GetItemText(parent_item).split(" (")[0]
+                var_path = "%s.%s"%(parent_name, var_path)
+                parent_item = self.InstancesTree.GetItemParent(parent_item)
+            data = wx.TextDataObject(str((var_path, "debug")))
+            dragSource = wx.DropSource(self.InstancesTree)
+            dragSource.SetData(data)
+            dragSource.DoDragDrop()
+        event.Skip()
+
+    def OnInstancesTreeItemActivated(self, event):
+        selected_item = event.GetItem()
+        selected_infos = self.InstancesTree.GetPyData(selected_item)
+        if selected_item is not None and selected_infos[0] in [ITEM_FUNCTIONBLOCK, ITEM_PROGRAM, ITEM_TRANSITION, ITEM_ACTION]:
+            instance_path = self.InstancesTree.GetItemText(selected_item).split(" (")[0]
+            parent_item = self.InstancesTree.GetItemParent(selected_item)
+            while self.InstancesTree.GetPyData(parent_item)[0] != ITEM_PROJECT:
+                parent_name = self.InstancesTree.GetItemText(parent_item).split(" (")[0]
+                instance_path = "%s.%s"%(parent_name, instance_path)
+                parent_item = self.InstancesTree.GetItemParent(parent_item)
+            openedidx = self.IsOpened(instance_path)
+            if openedidx is not None:
+                old_selected = self.TabsOpened.GetSelection()
+                if old_selected != openedidx:
+                    if old_selected >= 0:
+                        self.TabsOpened.GetPage(old_selected).ResetBuffer()
+                    self.TabsOpened.SetSelection(openedidx)
+                self.TabsOpened.GetPage(openedidx).RefreshView()
+            elif selected_infos[1] is not None:
+                bodytype = self.Controler.GetEditedElementBodyType(selected_infos[1], self.Debug)
+                if bodytype == "FBD":
+                    new_window = Viewer(self.TabsOpened, selected_infos[1], self, self.Controler, True, instance_path)
+                    new_window.RefreshScaling(False)
+                elif bodytype == "LD":
+                    new_window = LD_Viewer(self.TabsOpened, selected_infos[1], self, self.Controler, True, instance_path)
+                    new_window.RefreshScaling(False)
+                elif bodytype == "SFC":
+                    new_window = SFC_Viewer(self.TabsOpened, selected_infos[1], self, self.Controler, True, instance_path)
+                    new_window.RefreshScaling(False)
+                else:
+                    new_window = TextViewer(self.TabsOpened, selected_infos[1], self, self.Controler, True, instance_path)
+                    new_window.SetTextSyntax(bodytype)
+                    if bodytype == "IL":
+                        new_window.SetKeywords(IL_KEYWORDS)
+                    else:
+                        new_window.SetKeywords(ST_KEYWORDS)
+                self.TabsOpened.AddPage(new_window, "")
+                new_window.RefreshView()
+                new_window.SetFocus()
+                self.RefreshPageTitles()
+        event.Skip()
+
+    def SelectInstancesTreeItem(self, root, instancepath):
+        found = False
+        if self.InstancesTree is not None:
+            paths = instancepath.split(".")
+            if wx.VERSION >= (2, 6, 0):
+                item, root_cookie = self.InstancesTree.GetFirstChild(root)
+            else:
+                item, root_cookie = self.InstancesTree.GetFirstChild(root, 0)
+            while item.IsOk() and not found:
+                if self.InstancesTree.GetItemText(item) == paths[0]:
+                    if len(paths) == 1:
+                        self.InstancesTree.SelectItem(item)
+                        return True
+                    else:
+                        found = self.SelectInstancesTreeItem(item, paths[1:])
+                else:
+                    item, root_cookie = self.InstancesTree.GetNextChild(root, root_cookie)
+        return found
+
 #-------------------------------------------------------------------------------
 #                         Library Tree Management Functions
 #-------------------------------------------------------------------------------
 
     def RefreshLibraryTree(self):
-        to_delete = []
-        blocktypes = self.Controler.GetBlockTypes()
-        root = self.LibraryTree.GetRootItem()
-        if not root.IsOk():
-            if wx.Platform == '__WXMSW__':
-                root = self.LibraryTree.AddRoot("Block Types")
-                self.LibraryTree.SetPyData(root, {"type" : CATEGORY})
+        if not self.Debug:
+            to_delete = []
+            blocktypes = self.Controler.GetBlockTypes(debug = self.Debug)
+            root = self.LibraryTree.GetRootItem()
+            if not root.IsOk():
+                if wx.Platform == '__WXMSW__':
+                    root = self.LibraryTree.AddRoot("Block Types")
+                    self.LibraryTree.SetPyData(root, {"type" : CATEGORY})
+                else:
+                    root = self.LibraryTree.AddRoot("")
+            if wx.VERSION >= (2, 6, 0):
+                category_item, root_cookie = self.LibraryTree.GetFirstChild(root)
             else:
-                root = self.LibraryTree.AddRoot("")
-        if wx.VERSION >= (2, 6, 0):
-            category_item, root_cookie = self.LibraryTree.GetFirstChild(root)
-        else:
-            category_item, root_cookie = self.LibraryTree.GetFirstChild(root, 0)
-        for category in blocktypes:
-            if not category_item.IsOk():
-                category_item = self.LibraryTree.AppendItem(root, category["name"])
-                if wx.Platform != '__WXMSW__':
-                    category_item, root_cookie = self.LibraryTree.GetNextChild(root, root_cookie)
-            else:
-                self.LibraryTree.SetItemText(category_item, category["name"])
-            self.LibraryTree.SetPyData(category_item, {"type" : CATEGORY})
-            if wx.VERSION >= (2, 6, 0):
-                blocktype_item, category_cookie = self.LibraryTree.GetFirstChild(category_item)
-            else:
-                blocktype_item, category_cookie = self.LibraryTree.GetFirstChild(category_item, 0)        
-            for blocktype in category["list"]:
-                if not blocktype_item.IsOk():
-                    blocktype_item = self.LibraryTree.AppendItem(category_item, blocktype["name"])
+                category_item, root_cookie = self.LibraryTree.GetFirstChild(root, 0)
+            for category in blocktypes:
+                if not category_item.IsOk():
+                    category_item = self.LibraryTree.AppendItem(root, category["name"])
                     if wx.Platform != '__WXMSW__':
-                        blocktype_item, category_cookie = self.LibraryTree.GetNextChild(category_item, category_cookie)
+                        category_item, root_cookie = self.LibraryTree.GetNextChild(root, root_cookie)
                 else:
-                    self.LibraryTree.SetItemText(blocktype_item, blocktype["name"])
-                self.LibraryTree.SetPyData(blocktype_item, {"type" : BLOCK, "block_type" : blocktype["type"], "inputs" : tuple([type for name, type, modifier in blocktype["inputs"]])})
-                blocktype_item, category_cookie = self.LibraryTree.GetNextChild(category_item, category_cookie)
-            while blocktype_item.IsOk():
-                to_delete.append(blocktype_item)
-                blocktype_item, category_cookie = self.LibraryTree.GetNextChild(category_item, category_cookie)
-            category_item, root_cookie = self.LibraryTree.GetNextChild(root, root_cookie)
-        while category_item.IsOk():
-            to_delete.append(category_item)
-            category_item, root_cookie = self.LibraryTree.GetNextChild(root, root_cookie)
-        for item in to_delete:
-            self.LibraryTree.Delete(item)
-        if wx.Platform == '__WXMSW__':        
-            self.LibraryTree.Expand(root)
+                    self.LibraryTree.SetItemText(category_item, category["name"])
+                self.LibraryTree.SetPyData(category_item, {"type" : CATEGORY})
+                if wx.VERSION >= (2, 6, 0):
+                    blocktype_item, category_cookie = self.LibraryTree.GetFirstChild(category_item)
+                else:
+                    blocktype_item, category_cookie = self.LibraryTree.GetFirstChild(category_item, 0)        
+                for blocktype in category["list"]:
+                    if not blocktype_item.IsOk():
+                        blocktype_item = self.LibraryTree.AppendItem(category_item, blocktype["name"])
+                        if wx.Platform != '__WXMSW__':
+                            blocktype_item, category_cookie = self.LibraryTree.GetNextChild(category_item, category_cookie)
+                    else:
+                        self.LibraryTree.SetItemText(blocktype_item, blocktype["name"])
+                    self.LibraryTree.SetPyData(blocktype_item, {"type" : BLOCK, "block_type" : blocktype["type"], "inputs" : tuple([type for name, type, modifier in blocktype["inputs"]])})
+                    blocktype_item, category_cookie = self.LibraryTree.GetNextChild(category_item, category_cookie)
+                while blocktype_item.IsOk():
+                    to_delete.append(blocktype_item)
+                    blocktype_item, category_cookie = self.LibraryTree.GetNextChild(category_item, category_cookie)
+                category_item, root_cookie = self.LibraryTree.GetNextChild(root, root_cookie)
+            while category_item.IsOk():
+                to_delete.append(category_item)
+                category_item, root_cookie = self.LibraryTree.GetNextChild(root, root_cookie)
+            for item in to_delete:
+                self.LibraryTree.Delete(item)
+            if wx.Platform == '__WXMSW__':        
+                self.LibraryTree.Expand(root)
 
     def OnLibraryTreeItemSelected(self, event):
         selected = event.GetItem()
         pydata = self.LibraryTree.GetPyData(selected)
         if pydata["type"] != CATEGORY:
-            blocktype = self.Controler.GetBlockType(self.LibraryTree.GetItemText(selected), pydata["inputs"])
+            blocktype = self.Controler.GetBlockType(self.LibraryTree.GetItemText(selected), pydata["inputs"], debug = self.Debug)
             if blocktype:
                 self.LibraryComment.SetValue(blocktype["comment"])
             else:
@@ -1756,54 +1881,56 @@
 #-------------------------------------------------------------------------------
 
     def ResetToolBar(self):
-        for item in self.CurrentToolBar:
-            if wx.VERSION >= (2, 6, 0):
-                self.Unbind(wx.EVT_MENU, id=item)
+        if not self.Debug:
+            for item in self.CurrentToolBar:
+                if wx.VERSION >= (2, 6, 0):
+                    self.Unbind(wx.EVT_MENU, id=item)
+                else:
+                    self.Disconnect(id=item, eventType=wx.wxEVT_COMMAND_MENU_SELECTED) 
+                
+                if wx.VERSION < (2, 8, 0):
+                    ToolBar = self.ToolBar
+                else:
+                    ToolBar = self.Panes["ToolBar"]
+                if ToolBar:
+                    ToolBar.DeleteTool(item)
+                    ToolBar.Realize()
+                    if wx.VERSION >= (2, 8, 0):
+                        self.AUIManager.GetPane("ToolBar").BestSize(ToolBar.GetBestSize())
+                        self.AUIManager.Update()
+
+    def RefreshToolBar(self):
+        if not self.Debug:
+            selected = self.TabsOpened.GetSelection()
+            if selected != -1:
+                language = self.Controler.GetEditedElementBodyType(self.TabsOpened.GetPage(selected).GetTagName(), self.Debug)
             else:
-                self.Disconnect(id=item, eventType=wx.wxEVT_COMMAND_MENU_SELECTED) 
-            
-            if wx.VERSION < (2, 8, 0):
-                ToolBar = self.ToolBar
-            else:
-                ToolBar = self.Panes["ToolBar"]
-            if ToolBar:
-                ToolBar.DeleteTool(item)
-                ToolBar.Realize()
-                if wx.VERSION >= (2, 8, 0):
-                    self.AUIManager.GetPane("ToolBar").BestSize(ToolBar.GetBestSize())
-                    self.AUIManager.Update()
-
-    def RefreshToolBar(self):
-        selected = self.TabsOpened.GetSelection()
-        if selected != -1:
-            language = self.Controler.GetEditedElementBodyType(self.TabsOpened.GetPage(selected).GetTagName())
-        else:
-            language = None
-        if language is not None and language != self.CurrentLanguage:
-            self.ResetToolBar()
-            self.CurrentLanguage = language
-            self.CurrentToolBar = []
-            if wx.VERSION < (2, 8, 0):
-                ToolBar = self.ToolBar
-            else:
-                ToolBar = self.Panes["ToolBar"]
-            if ToolBar:
-                for radio, modes, id, method, picture, help in ToolBarItems[language]:
-                    if modes & self.DrawingMode:
-                        if radio or self.DrawingMode == FREEDRAWING_MODE:
-                            ToolBar.AddRadioTool(id, wx.Bitmap(os.path.join(CWD, "Images", picture)), wx.NullBitmap, help)
-                        else:
-                            ToolBar.AddSimpleTool(id, wx.Bitmap(os.path.join(CWD, "Images", picture)), help)
-                        self.Bind(wx.EVT_TOOL, getattr(self, method), id=id)
-                        self.CurrentToolBar.append(id)
-                ToolBar.Realize()
-                if wx.VERSION >= (2, 8, 0):
-                    self.AUIManager.GetPane("ToolBar").BestSize(ToolBar.GetBestSize())
-                    self.AUIManager.Update()
-        elif not language:
-            self.ResetToolBar()
-            self.CurrentLanguage = language
-        self.ResetCurrentMode()
+                language = None
+            if language is not None and language != self.CurrentLanguage:
+                self.ResetToolBar()
+                self.CurrentLanguage = language
+                self.CurrentToolBar = []
+                if wx.VERSION < (2, 8, 0):
+                    ToolBar = self.ToolBar
+                else:
+                    ToolBar = self.Panes["ToolBar"]
+                if ToolBar:
+                    for radio, modes, id, method, picture, help in ToolBarItems[language]:
+                        if modes & self.DrawingMode:
+                            if radio or self.DrawingMode == FREEDRAWING_MODE:
+                                ToolBar.AddRadioTool(id, wx.Bitmap(os.path.join(CWD, "Images", picture)), wx.NullBitmap, help)
+                            else:
+                                ToolBar.AddSimpleTool(id, wx.Bitmap(os.path.join(CWD, "Images", picture)), help)
+                            self.Bind(wx.EVT_TOOL, getattr(self, method), id=id)
+                            self.CurrentToolBar.append(id)
+                    ToolBar.Realize()
+                    if wx.VERSION >= (2, 8, 0):
+                        self.AUIManager.GetPane("ToolBar").BestSize(ToolBar.GetBestSize())
+                        self.AUIManager.Update()
+            elif not language:
+                self.ResetToolBar()
+                self.CurrentLanguage = language
+            self.ResetCurrentMode()
 
 
 #-------------------------------------------------------------------------------
@@ -1965,7 +2092,7 @@
 
     def OnAddDataTypeMenu(self, event):
         dialog = DataTypeDialog(self, "Add a new data type", "Please enter data type name", "", wx.OK|wx.CANCEL)
-        dialog.SetDataTypeNames(self.Controler.GetProjectDataTypeNames())
+        dialog.SetDataTypeNames(self.Controler.GetProjectDataTypeNames(self.Debug))
         if dialog.ShowModal() == wx.ID_OK:
             self.Controler.ProjectAddDataType(dialog.GetValue())
             self.RefreshTitle()
@@ -1977,8 +2104,8 @@
     def GenerateAddPouFunction(self, pou_type):
         def OnAddPouMenu(event):
             dialog = PouDialog(self, pou_type)
-            dialog.SetPouNames(self.Controler.GetProjectPouNames())
-            dialog.SetPouElementNames(self.Controler.GetProjectPouVariables())
+            dialog.SetPouNames(self.Controler.GetProjectPouNames(self.Debug))
+            dialog.SetPouElementNames(self.Controler.GetProjectPouVariables(debug = self.Debug))
             if dialog.ShowModal() == wx.ID_OK:
                 values = dialog.GetValues()
                 self.Controler.ProjectAddPou(values["pouName"], values["pouType"], values["language"])
@@ -1993,8 +2120,8 @@
     def GenerateAddTransitionFunction(self, pou_name):
         def OnAddTransitionMenu(event):
             dialog = PouTransitionDialog(self)
-            dialog.SetPouNames(self.Controler.GetProjectPouNames())
-            dialog.SetPouElementNames(self.Controler.GetProjectPouVariables(pou_name))
+            dialog.SetPouNames(self.Controler.GetProjectPouNames(self.Debug))
+            dialog.SetPouElementNames(self.Controler.GetProjectPouVariables(pou_name, self.Debug))
             if dialog.ShowModal() == wx.ID_OK: 
                 values = dialog.GetValues()
                 self.Controler.ProjectAddPouTransition(pou_name, values["transitionName"], values["language"])
@@ -2008,8 +2135,8 @@
     def GenerateAddActionFunction(self, pou_name):
         def OnAddActionMenu(event):
             dialog = PouActionDialog(self)
-            dialog.SetPouNames(self.Controler.GetProjectPouNames())
-            dialog.SetPouElementNames(self.Controler.GetProjectPouVariables(pou_name))
+            dialog.SetPouNames(self.Controler.GetProjectPouNames(self.Debug))
+            dialog.SetPouElementNames(self.Controler.GetProjectPouVariables(pou_name, self.Debug))
             if dialog.ShowModal() == wx.ID_OK:
                 values = dialog.GetValues()
                 self.Controler.ProjectAddPouAction(pou_name, values["actionName"], values["language"])
@@ -2022,8 +2149,8 @@
 
     def OnAddConfigurationMenu(self, event):
         dialog = ConfigurationNameDialog(self, "Please enter configuration name", "Add new configuration")
-        dialog.SetPouNames(self.Controler.GetProjectPouNames())
-        dialog.SetPouElementNames(self.Controler.GetProjectPouVariables())
+        dialog.SetPouNames(self.Controler.GetProjectPouNames(self.Debug))
+        dialog.SetPouElementNames(self.Controler.GetProjectPouVariables(debug = self.Debug))
         if dialog.ShowModal() == wx.ID_OK:
             value = dialog.GetValue()
             self.Controler.ProjectAddConfiguration(value)
@@ -2037,8 +2164,8 @@
     def GenerateAddResourceFunction(self, config_name):
         def OnAddResourceMenu(event):
             dialog = ResourceNameDialog(self, "Please enter resource name", "Add new resource")
-            dialog.SetPouNames(self.Controler.GetProjectPouNames())
-            dialog.SetPouElementNames(self.Controler.GetProjectPouVariables())
+            dialog.SetPouNames(self.Controler.GetProjectPouNames(self.Debug))
+            dialog.SetPouElementNames(self.Controler.GetProjectPouVariables(debug = self.Debug))
             if dialog.ShowModal() == wx.ID_OK:
                 value = dialog.GetValue()
                 self.Controler.ProjectAddConfigurationResource(config_name, value)
@@ -2059,7 +2186,7 @@
         selected = self.TypesTree.GetSelection()
         if self.TypesTree.GetPyData(selected) == ITEM_DATATYPE:
             name = self.TypesTree.GetItemText(selected)
-            if not self.Controler.DataTypeIsUsed(name):
+            if not self.Controler.DataTypeIsUsed(name, self.Debug):
                 self.Controler.ProjectRemoveDataType(name)
                 tagname = self.Controler.ComputeDataTypeName(name)
                 idx = self.IsOpened(tagname)
@@ -2079,7 +2206,7 @@
         selected = self.TypesTree.GetSelection()
         if self.TypesTree.GetPyData(selected) == ITEM_POU: 
             name = self.TypesTree.GetItemText(selected)
-            if not self.Controler.PouIsUsed(name):
+            if not self.Controler.PouIsUsed(name, self.Debug):
                 self.Controler.ProjectRemovePou(name)
                 tagname = self.Controler.ComputePouName(name)
                 idx = self.IsOpened(tagname)
@@ -3598,7 +3725,7 @@
                 if values is not None and values[1] == "location":
                     location = values[0]
                     variable_type = self.ParentWindow.Table.GetValueByName(row, "Type")
-                    base_type = self.ParentWindow.Controler.GetBaseType(variable_type)
+                    base_type = self.ParentWindow.Controler.GetBaseType(variable_type, self.Debug)
                     message = None
                     if location.startswith("%"):
                         if base_type != values[2]:
@@ -3628,13 +3755,13 @@
                                 self.ParentWindow.Table.ResetView(self.ParentWindow.VariablesGrid)
                                 self.ParentWindow.SaveValues()
                             dialog.Destroy()
+        if message is not None:
             wx.CallAfter(self.ShowMessage, message)
             
     def ShowMessage(self, message):
-        if message is not None:
-            message = wx.MessageDialog(self.ParentWindow, message, "Error", wx.OK|wx.ICON_ERROR)
-            message.ShowModal()
-            message.Destroy()
+        message = wx.MessageDialog(self.ParentWindow, message, "Error", wx.OK|wx.ICON_ERROR)
+        message.ShowModal()
+        message.Destroy()
 
 [ID_VARIABLEEDITORPANEL, ID_VARIABLEEDITORPANELVARIABLESGRID, 
  ID_VARIABLEEDITORPANELRETURNTYPE, ID_VARIABLEEDITORPANELCLASSFILTER, 
@@ -3834,21 +3961,21 @@
         self.TagName = tagname
     
     def RefreshView(self):
-        self.PouNames = self.Controler.GetProjectPouNames()
+        self.PouNames = self.Controler.GetProjectPouNames(self.ParentWindow.Debug)
         
         words = self.TagName.split("::")
         if self.ElementType == "config":
             self.PouIsUsed = False
             returnType = None
-            self.Values = self.Controler.GetConfigurationGlobalVars(words[1])
+            self.Values = self.Controler.GetConfigurationGlobalVars(words[1], self.ParentWindow.Debug)
         elif self.ElementType == "resource":
             self.PouIsUsed = False
             returnType = None
-            self.Values = self.Controler.GetConfigurationResourceGlobalVars(words[1], words[2])
-        else:
-            self.PouIsUsed = self.Controler.PouIsUsed(words[1])
-            returnType = self.Controler.GetEditedElementInterfaceReturnType(self.TagName)
-            self.Values = self.Controler.GetEditedElementInterfaceVars(self.TagName)
+            self.Values = self.Controler.GetConfigurationResourceGlobalVars(words[1], words[2], self.ParentWindow.Debug)
+        else:
+            self.PouIsUsed = self.Controler.PouIsUsed(words[1], self.ParentWindow.Debug)
+            returnType = self.Controler.GetEditedElementInterfaceReturnType(self.TagName, self.ParentWindow.Debug)
+            self.Values = self.Controler.GetEditedElementInterfaceVars(self.TagName, self.ParentWindow.Debug)
         
         if returnType and self.ReturnType.IsEnabled():
             self.ReturnType.SetStringSelection(returnType)
@@ -3981,13 +4108,13 @@
                 self.Bind(wx.EVT_MENU, self.GetVariableTypeFunction(base_type), id=new_id)
             type_menu.AppendMenu(wx.NewId(), "Base Types", base_menu)
             datatype_menu = wx.Menu(title='')
-            for datatype in self.Controler.GetDataTypes(basetypes = False):
+            for datatype in self.Controler.GetDataTypes(basetypes = False, debug = self.Debug):
                 new_id = wx.NewId()
                 AppendMenu(datatype_menu, help='', id=new_id, kind=wx.ITEM_NORMAL, text=datatype)
                 self.Bind(wx.EVT_MENU, self.GetVariableTypeFunction(datatype), id=new_id)
             type_menu.AppendMenu(wx.NewId(), "User Data Types", datatype_menu)
             functionblock_menu = wx.Menu(title='')
-            for functionblock_type in self.Controler.GetFunctionBlockTypes():
+            for functionblock_type in self.Controler.GetFunctionBlockTypes(debug = self.Debug):
                 new_id = wx.NewId()
                 AppendMenu(functionblock_menu, help='', id=new_id, kind=wx.ITEM_NORMAL, text=functionblock_type)
                 self.Bind(wx.EVT_MENU, self.GetVariableTypeFunction(functionblock_type), id=new_id)
--- a/SFCViewer.py	Fri Sep 05 18:12:23 2008 +0200
+++ b/SFCViewer.py	Fri Sep 05 18:13:18 2008 +0200
@@ -29,8 +29,8 @@
 
 class SFC_Viewer(Viewer):
     
-    def __init__(self, parent, tagname, window, controler):
-        Viewer.__init__(self, parent, tagname, window, controler)
+    def __init__(self, parent, tagname, window, controler, debug = False, instancepath = ""):
+        Viewer.__init__(self, parent, tagname, window, controler, debug, instancepath)
         self.CurrentLanguage = "SFC"
     
     def ConnectConnectors(self, start, end):
@@ -356,8 +356,8 @@
 
     def AddInitialStep(self, pos):
         dialog = StepNameDialog(self.ParentWindow, "Add a new initial step", "Please enter step name", "", wx.OK|wx.CANCEL)
-        dialog.SetPouNames(self.Controler.GetProjectPouNames())
-        dialog.SetVariables(self.Controler.GetEditedElementInterfaceVars(self.TagName))
+        dialog.SetPouNames(self.Controler.GetProjectPouNames(self.Debug))
+        dialog.SetVariables(self.Controler.GetEditedElementInterfaceVars(self.TagName, self.Debug))
         dialog.SetStepNames([block.GetName() for block in self.Blocks if isinstance(block, SFC_Step)])
         if dialog.ShowModal() == wx.ID_OK:
             id = self.GetNewId()
@@ -378,8 +378,8 @@
     def AddStep(self):
         if self.SelectedElement in self.Wires or isinstance(self.SelectedElement, SFC_Step):
             dialog = StepNameDialog(self.ParentWindow, "Add a new step", "Please enter step name", "", wx.OK|wx.CANCEL)
-            dialog.SetPouNames(self.Controler.GetProjectPouNames())
-            dialog.SetVariables(self.Controler.GetEditedElementInterfaceVars(self.TagName))
+            dialog.SetPouNames(self.Controler.GetProjectPouNames(self.Debug))
+            dialog.SetVariables(self.Controler.GetEditedElementInterfaceVars(self.TagName, self.Debug))
             dialog.SetStepNames([block.GetName() for block in self.Blocks if isinstance(block, SFC_Step)])
             if dialog.ShowModal() == wx.ID_OK:
                 name = dialog.GetValue()
@@ -435,8 +435,8 @@
             if not connectors["action"]:
                 dialog = ActionBlockDialog(self.ParentWindow)
                 dialog.SetQualifierList(self.Controler.GetQualifierTypes())
-                dialog.SetActionList(self.Controler.GetEditedElementActions(self.TagName))
-                dialog.SetVariableList(self.Controler.GetEditedElementInterfaceVars(self.TagName))
+                dialog.SetActionList(self.Controler.GetEditedElementActions(self.TagName, self.Debug))
+                dialog.SetVariableList(self.Controler.GetEditedElementInterfaceVars(self.TagName, self.Debug))
                 if dialog.ShowModal() == wx.ID_OK:
                     actions = dialog.GetValues()
                     self.SelectedElement.AddAction()
@@ -718,8 +718,8 @@
             Viewer.EditStepContent(self, step)
         else:
             dialog = StepNameDialog(self.ParentWindow, "Edit step name", "Please enter step name", step.GetName(), wx.OK|wx.CANCEL)
-            dialog.SetPouNames(self.Controler.GetProjectPouNames())
-            dialog.SetVariables(self.Controler.GetEditedElementInterfaceVars(self.TagName))
+            dialog.SetPouNames(self.Controler.GetProjectPouNames(self.Debug))
+            dialog.SetVariables(self.Controler.GetEditedElementInterfaceVars(self.TagName, self.Debug))
             dialog.SetStepNames([block.GetName() for block in self.Blocks if isinstance(block, SFC_Step) and block.GetName() != step.GetName()])
             if dialog.ShowModal() == wx.ID_OK:
                 value = dialog.GetValue()
--- a/TextViewer.py	Fri Sep 05 18:12:23 2008 +0200
+++ b/TextViewer.py	Fri Sep 05 18:13:18 2008 +0200
@@ -99,7 +99,7 @@
             else:
                 event(self, function)
     
-    def __init__(self, parent, tagname, window, controler):
+    def __init__(self, parent, tagname, window, controler, debug = False, instancepath = ""):
         wx.stc.StyledTextCtrl.__init__(self, parent, ID_TEXTVIEWER, size=wx.Size(0, 0), style=0)
         
         self.CmdKeyAssign(ord('+'), wx.stc.STC_SCMOD_CTRL, wx.stc.STC_CMD_ZOOMIN)
@@ -150,6 +150,8 @@
         self.CurrentAction = None
         self.TagName = tagname
         self.Errors = []
+        self.Debug = debug
+        self.InstancePath = instancepath
         
         self.ParentWindow = window
         self.Controler = controler
@@ -169,8 +171,14 @@
     def GetTagName(self):
         return self.TagName
     
+    def GetInstancePath(self):
+        return self.InstancePath
+    
     def IsViewing(self, tagname):
-        return self.TagName == tagname
+        if self.Debug:
+            return self.InstancePath == tagname
+        else:
+            return self.TagName == tagname
     
     def SetMode(self, mode):
         pass
@@ -201,7 +209,7 @@
         except:
             values = event.GetDragText()
         if isinstance(values, tuple):
-            if values[1] in ["functionBlock", "program", "location"]:
+            if values[1] in ["functionBlock", "program", "location", "debug"]:
                 event.SetDragText("")
             elif values[1] == "function":
                 event.SetDragText(values[0])
@@ -251,7 +259,7 @@
         self.DisableEvents = True
         old_cursor_pos = self.GetCurrentPos()
         old_text = self.GetText()
-        new_text = self.Controler.GetEditedElementText(self.TagName)
+        new_text = self.Controler.GetEditedElementText(self.TagName, self.Debug)
         self.SetText(new_text)
         new_cursor_pos = GetCursorPos(old_text, new_text)
         if new_cursor_pos != None:
@@ -264,12 +272,12 @@
         self.DisableEvents = False
         
         words = self.TagName.split("::")
-        self.Variables = [variable["Name"].upper() for variable in self.Controler.GetEditedElementInterfaceVars(self.TagName)]
-        if self.Controler.GetEditedElementType(self.TagName)[1] == "function" or words[0] == "T" and self.TextSyntax == "IL":
+        self.Variables = [variable["Name"].upper() for variable in self.Controler.GetEditedElementInterfaceVars(self.TagName, self.Debug)]
+        if self.Controler.GetEditedElementType(self.TagName, self.Debug)[1] == "function" or words[0] == "T" and self.TextSyntax == "IL":
             self.Variables.append(words[-1].upper())
         
         self.Functions = []
-        for category in self.Controler.GetBlockTypes(self.TagName):
+        for category in self.Controler.GetBlockTypes(self.TagName, self.Debug):
             for blocktype in category["list"]:
                 if blocktype["type"] == "function" and blocktype["name"] not in self.Keywords and blocktype["name"] not in self.Variables:
                     self.Functions.append(blocktype["name"].upper())
--- a/Viewer.py	Fri Sep 05 18:12:23 2008 +0200
+++ b/Viewer.py	Fri Sep 05 18:13:18 2008 +0200
@@ -96,15 +96,17 @@
             message = "Invalid value \"%s\" for viewer block"%data
             values = None
         if values is not None:
-            if values[1] == "program":
+            if values[1] == "debug":
+                pass
+            elif values[1] == "program":
                 message = "Programs can't be used by other POUs!"
             elif values[1] in ["function", "functionBlock", "program"]:
-                name, type = self.ParentWindow.Controler.GetEditedElementType(self.ParentWindow.GetTagName())
+                name, type = self.ParentWindow.Controler.GetEditedElementType(self.ParentWindow.GetTagName(), self.ParentWindow.Debug)
                 if name == values[0]:
                     message = "\"%s\" can't use itself!"%name
                 elif type == "function" and values[1] != "function":
                     message = "Function Blocks can't be used by Functions!"
-                elif self.ParentWindow.Controler.PouIsUsedBy(name, values[0]):
+                elif self.ParentWindow.Controler.PouIsUsedBy(name, values[0], self.ParentWindow.Debug):
                     message = "\"%s\" is already used by \"%s\"!"%(name, values[0])
                 else:
                     blockname = values[2]
@@ -119,9 +121,9 @@
                         else:
                             return
                         dialog.Destroy()
-                    if blockname.upper() in [name.upper() for name in self.ParentWindow.Controler.GetProjectPouNames()]:
+                    if blockname.upper() in [name.upper() for name in self.ParentWindow.Controler.GetProjectPouNames(self.ParentWindow.Debug)]:
                         message = "\"%s\" pou already exists!"%blockname
-                    elif blockname.upper() in [name.upper() for name in self.ParentWindow.Controler.GetEditedElementVariables(self.ParentWindow.GetTagName())]:
+                    elif blockname.upper() in [name.upper() for name in self.ParentWindow.Controler.GetEditedElementVariables(self.ParentWindow.GetTagName(), self.ParentWindow.Debug)]:
                         message = "\"%s\" element for this pou already exists!"%blockname
                     else:
                         id = self.ParentWindow.GetNewId()
@@ -139,6 +141,7 @@
                         self.ParentWindow.RefreshBlockModel(block)
                         self.ParentWindow.RefreshBuffer()
                         self.ParentWindow.RefreshScrollBars()
+                        self.ParentWindow.RefreshVisibleElements()
                         self.ParentWindow.ParentWindow.RefreshVariablePanel(self.ParentWindow.GetTagName())
                         self.ParentWindow.Refresh(False)
             elif values[1] != "location":
@@ -164,16 +167,17 @@
                     self.ParentWindow.RefreshVariableModel(variable)
                     self.ParentWindow.RefreshBuffer()
                     self.ParentWindow.RefreshScrollBars()
+                    self.ParentWindow.RefreshVisibleElements()
                     self.ParentWindow.Refresh(False)
                 else:
                     message = "Variable don't belong to this POU!"
-        wx.CallAfter(self.ShowMessage, message)
+        if message is not None:
+            wx.CallAfter(self.ShowMessage, message)
 
     def ShowMessage(self, message):
-        if message is not None:
-            message = wx.MessageDialog(self.ParentWindow, message, "Error", wx.OK|wx.ICON_ERROR)
-            message.ShowModal()
-            message.Destroy()
+        message = wx.MessageDialog(self.ParentWindow, message, "Error", wx.OK|wx.ICON_ERROR)
+        message.ShowModal()
+        message.Destroy()
 
 
 """
@@ -288,7 +292,7 @@
         self._init_coll_ContextualMenu_Items(self.ContextualMenu)
     
     # Create a new Viewer
-    def __init__(self, parent, tagname, window, controler):
+    def __init__(self, parent, tagname, window, controler, debug = False, instancepath = ""):
         wx.ScrolledWindow.__init__(self, parent, pos=wx.Point(0, 0), size=wx.Size(0, 0), 
             style=wx.HSCROLL | wx.VSCROLL)
         self._init_menus()
@@ -306,6 +310,8 @@
         self.current_id = 0
         self.TagName = tagname
         self.Errors = []
+        self.Debug = debug
+        self.InstancePath = instancepath
         
         # Initialize Block, Wire and Comment numbers
         self.block_id = self.wire_id = self.comment_id = 0
@@ -318,7 +324,8 @@
         self.ParentWindow = window
         self.Controler = controler
         
-        self.SetDropTarget(ViewerDropTarget(self))
+        if not self.Debug:
+            self.SetDropTarget(ViewerDropTarget(self))
         
         dc = wx.ClientDC(self)
         font = wx.Font(faces["size"], wx.SWISS, wx.NORMAL, wx.NORMAL, faceName = faces["mono"])
@@ -331,6 +338,8 @@
             width, height = dc.GetTextExtent("ABCDEFGHIJKLMNOPQRSTUVWXYZ")
         self.SetFont(font)
         
+        self.ResetView()
+        
         # Link Viewer event to corresponding methods
         self.Bind(wx.EVT_PAINT, self.OnPaint)
         self.Bind(wx.EVT_LEFT_DOWN, self.OnViewerLeftDown)
@@ -341,7 +350,7 @@
         self.Bind(wx.EVT_LEAVE_WINDOW, self.OnLeaveViewer)
         self.Bind(wx.EVT_MOTION, self.OnViewerMotion)
         self.Bind(wx.EVT_CHAR, self.OnChar)
-        #self.Bind(wx.EVT_SCROLLWIN, self.OnMoveWindow)
+        self.Bind(wx.EVT_SCROLLWIN, self.OnScrollWindow)
         self.Bind(wx.EVT_SIZE, self.OnMoveWindow)
     
     def GetScrolledRect(self, rect):
@@ -357,8 +366,14 @@
     def GetTagName(self):
         return self.TagName
     
+    def GetInstancePath(self):
+        return self.InstancePath
+    
     def IsViewing(self, tagname):
-        return self.TagName == tagname
+        if self.Debug:
+            return self.InstancePath == tagname
+        else:
+            return self.TagName == tagname
     
     # Returns a new id
     def GetNewId(self):
@@ -367,6 +382,7 @@
     
     # Destructor
     def __del__(self):
+        self.Flush()
         self.ResetView()
 
     def GetLogicalDC(self, buffered=False):
@@ -427,6 +443,21 @@
             comments.sort(lambda x,y:self.Comments[x].__cmp__(self.Comments[y]))
         return blocks + wires + comments
 
+    def RefreshVisibleElements(self, xp = None, yp = None):
+        x, y = self.CalcUnscrolledPosition(0, 0)
+        if xp is not None:
+            x = xp * self.GetScrollPixelsPerUnit()[0]
+        if yp is not None:
+            y = yp * self.GetScrollPixelsPerUnit()[1]
+        width, height = self.GetClientSize()
+        screen = wx.Rect(x, y, width, height)
+        for comment in self.Comments:
+            comment.TestVisible(screen)
+        for wire in self.Wires:
+            wire.TestVisible(screen)
+        for block in self.Blocks:
+            block.TestVisible(screen)
+            
 #-------------------------------------------------------------------------------
 #                              Reset functions
 #-------------------------------------------------------------------------------
@@ -436,9 +467,16 @@
         self.Blocks = {}
         self.Wires = {}
         self.Comments = {}
+        self.Subscribed = {}
         self.SelectedElement = None
         self.HighlightedElement = None
     
+    def Flush(self):
+        for block in self.Blocks:
+            block.Flush()
+        for element, iec_path in self.Subscribed.iteritems():
+            self.Controler.UnsubscribeDebugIECVariable(iec_path, element)
+    
     # Remove all elements
     def CleanView(self):
         for block in self.Blocks.keys():
@@ -469,7 +507,7 @@
 
     # Refresh the current scaling
     def RefreshScaling(self, refresh=True):
-        properties = self.Controler.GetProjectProperties()
+        properties = self.Controler.GetProjectProperties(self.Debug)
         scaling = properties["scaling"][self.CurrentLanguage]
         if scaling != (0, 0):
             self.Scaling = scaling
@@ -508,21 +546,48 @@
     def RefreshView(self):
         self.current_id = 0
         # Start by reseting Viewer
+        self.Flush()
         self.ResetView()
-        instance = True
+        instance = {}
         # List of ids of already loaded blocks
         ids = []
         # Load Blocks until they are all loaded
-        while instance:
-            instance = self.Controler.GetEditedElementInstanceInfos(self.TagName, exclude=ids)
-            if instance:
+        while instance is not None:
+            instance = self.Controler.GetEditedElementInstanceInfos(self.TagName, exclude = ids, debug = self.Debug)
+            if instance is not None:
                 self.loadInstance(instance, ids)
         self.RefreshScrollBars()
         
         for wire in self.Wires:
             if not wire.IsConnectedCompatible():
                 wire.MarkAsInvalid()
-        
+            if self.Debug:
+                block = wire.EndConnected.GetParentBlock()
+                if isinstance(block, LD_PowerRail):
+                    wire.SetValue(True)
+                if isinstance(block, FBD_Block):
+                    blockname = block.GetName()
+                    connectorname = wire.EndConnected.GetName()
+                    if blockname != "":
+                        iec_path = "%s.%s.%s"%(self.InstancePath, block.GetName(), connectorname)
+                    else:
+                        if connectorname == "":
+                            connectorname = "OUT"
+                        iec_path = "%s.%s%d_%s"%(self.InstancePath, block.GetType(), block.GetId(), connectorname)
+                    self.Subscribed[wire] = iec_path.upper()
+                    self.Controler.SubscribeDebugIECVariable(iec_path.upper(), wire)
+
+        if self.Debug:
+            for block in self.Blocks.keys():
+                if isinstance(block, (LD_Contact, LD_Coil)):
+                    block.SetValue(False)
+                    block.SpreadCurrent()
+                if isinstance(block, LD_Contact):
+                    iec_path = "%s.%s"%(self.InstancePath, block.GetName())
+                    self.Subscribed[block] = iec_path.upper()
+                    self.Controler.SubscribeDebugIECVariable(iec_path.upper(), block)
+        
+        self.RefreshVisibleElements()
         self.ShowErrors()
         self.Refresh(False)
     
@@ -796,16 +861,16 @@
     def CreateWires(self, start_connector, links, ids):
         for link in links:
             refLocalId = link["refLocalId"]
-            if refLocalId != None:
+            if refLocalId is not None:
                 if refLocalId not in ids:
-                    new_instance = self.Controler.GetEditedElementInstanceInfos(self.TagName, refLocalId)
-                    if new_instance:
+                    new_instance = self.Controler.GetEditedElementInstanceInfos(self.TagName, refLocalId, debug = self.Debug)
+                    if new_instance is not None:
                         self.loadInstance(new_instance, ids)
                 connected = self.FindElementById(refLocalId)
-                if connected:
+                if connected is not None:
                     points = link["points"]
                     end_connector = connected.GetConnector(wx.Point(points[-1][0], points[-1][1]), link["formalParameter"])
-                    if end_connector:
+                    if end_connector is not None:
                         wire = Wire(self)
                         wire.SetPoints(points)
                         start_connector.Connect((wire, 0), False)
@@ -815,13 +880,13 @@
                         self.AddWire(wire)
 
     def IsOfType(self, type, reference):
-        return self.Controler.IsOfType(type, reference)
+        return self.Controler.IsOfType(type, reference, self.Debug)
     
     def IsEndType(self, type):
         return self.Controler.IsEndType(type)
 
     def GetBlockType(self, type, inputs = None):
-        return self.Controler.GetBlockType(type, inputs)
+        return self.Controler.GetBlockType(type, inputs, self.Debug)
 
 #-------------------------------------------------------------------------------
 #                          Search Element functions
@@ -848,7 +913,7 @@
                 return element
         return None
     
-    def FindBlockConnector(self, pos, direction = None, exclude = True):
+    def FindBlockConnector(self, pos, direction = None, exclude = None):
         for block in self.Blocks:
             result = block.TestConnector(pos, direction, exclude)
             if result:
@@ -877,7 +942,7 @@
 
     def PopupBlockMenu(self, connector = None):
         if connector is not None and connector.IsCompatible("BOOL"):
-            type = self.Controler.GetEditedElementType(self.TagName)
+            type = self.Controler.GetEditedElementType(self.TagName, self.Debug)
             self.ContextualMenu.Enable(ID_VIEWERCONTEXTUALMENUITEMS0, True)
             self.ContextualMenu.Enable(ID_VIEWERCONTEXTUALMENUITEMS1, True)
             self.ContextualMenu.Enable(ID_VIEWERCONTEXTUALMENUITEMS2, type != "function")
@@ -892,9 +957,9 @@
         self.ContextualMenu.Enable(ID_VIEWERCONTEXTUALMENUITEMS8, False)
         self.ContextualMenu.Enable(ID_VIEWERCONTEXTUALMENUITEMS9, False)
         self.ContextualMenu.Enable(ID_VIEWERCONTEXTUALMENUITEMS14, False)
-        self.ContextualMenu.Enable(ID_VIEWERCONTEXTUALMENUITEMS16, self.SelectedElement.GetType() in self.Controler.GetProjectPouNames())
+        self.ContextualMenu.Enable(ID_VIEWERCONTEXTUALMENUITEMS16, self.SelectedElement.GetType() in self.Controler.GetProjectPouNames(self.Debug))
         self.ContextualMenu.Enable(ID_VIEWERCONTEXTUALMENUITEMS17, True)
-        if connector:
+        if connector is not None:
             if connector.IsNegated():
                 self.ContextualMenu.Check(ID_VIEWERCONTEXTUALMENUITEMS1, True)
             elif connector.GetEdge() == "rising":
@@ -966,106 +1031,106 @@
 #-------------------------------------------------------------------------------
 
     def OnAlignLeftMenu(self, event):
-        if self.SelectedElement and isinstance(self.SelectedElement, Graphic_Group):
+        if self.SelectedElement is not None and isinstance(self.SelectedElement, Graphic_Group):
             self.SelectedElement.AlignElements(ALIGN_LEFT, None)
             self.RefreshBuffer()
             self.Refresh(False)
         event.Skip()
     
     def OnAlignCenterMenu(self, event):
-        if self.SelectedElement and isinstance(self.SelectedElement, Graphic_Group):
+        if self.SelectedElement is not None and isinstance(self.SelectedElement, Graphic_Group):
             self.SelectedElement.AlignElements(ALIGN_CENTER, None)
             self.RefreshBuffer()
             self.Refresh(False)
         event.Skip()
     
     def OnAlignRightMenu(self, event):
-        if self.SelectedElement and isinstance(self.SelectedElement, Graphic_Group):
+        if self.SelectedElement is not None and isinstance(self.SelectedElement, Graphic_Group):
             self.SelectedElement.AlignElements(ALIGN_RIGHT, None)
             self.RefreshBuffer()
             self.Refresh(False)
         event.Skip()
     
     def OnAlignTopMenu(self, event):
-        if self.SelectedElement and isinstance(self.SelectedElement, Graphic_Group):
+        if self.SelectedElement is not None and isinstance(self.SelectedElement, Graphic_Group):
             self.SelectedElement.AlignElements(None, ALIGN_TOP)
             self.RefreshBuffer()
             self.Refresh(False)
         event.Skip()
     
     def OnAlignMiddleMenu(self, event):
-        if self.SelectedElement and isinstance(self.SelectedElement, Graphic_Group):
+        if self.SelectedElement is not None and isinstance(self.SelectedElement, Graphic_Group):
             self.SelectedElement.AlignElements(None, ALIGN_MIDDLE)
             self.RefreshBuffer()
             self.Refresh(False)
         event.Skip()
     
     def OnAlignBottomMenu(self, event):
-        if self.SelectedElement and isinstance(self.SelectedElement, Graphic_Group):
+        if self.SelectedElement is not None and isinstance(self.SelectedElement, Graphic_Group):
             self.SelectedElement.AlignElements(None, ALIGN_BOTTOM)
             self.RefreshBuffer()
             self.Refresh(False)
         event.Skip()
         
     def OnNoModifierMenu(self, event):
-        if self.SelectedElement and self.IsBlock(self.SelectedElement):
+        if self.SelectedElement is not None and self.IsBlock(self.SelectedElement):
             self.SelectedElement.SetConnectorNegated(False)
             self.SelectedElement.Refresh()
             self.RefreshBuffer()
         event.Skip()
     
     def OnNegatedMenu(self, event):
-        if self.SelectedElement and self.IsBlock(self.SelectedElement):
+        if self.SelectedElement is not None and self.IsBlock(self.SelectedElement):
             self.SelectedElement.SetConnectorNegated(True)
             self.SelectedElement.Refresh()
             self.RefreshBuffer()
         event.Skip()
 
     def OnRisingEdgeMenu(self, event):
-        if self.SelectedElement and self.IsBlock(self.SelectedElement):
+        if self.SelectedElement is not None and self.IsBlock(self.SelectedElement):
             self.SelectedElement.SetConnectorEdge("rising")
             self.SelectedElement.Refresh()
             self.RefreshBuffer()
         event.Skip()
 
     def OnFallingEdgeMenu(self, event):
-        if self.SelectedElement and self.IsBlock(self.SelectedElement):
+        if self.SelectedElement is not None and self.IsBlock(self.SelectedElement):
             self.SelectedElement.SetConnectorEdge("falling")
             self.SelectedElement.Refresh()
             self.RefreshBuffer()
         event.Skip()
 
     def OnAddSegmentMenu(self, event):
-        if self.SelectedElement and self.IsWire(self.SelectedElement):
+        if self.SelectedElement is not None and self.IsWire(self.SelectedElement):
             self.SelectedElement.AddSegment()
             self.SelectedElement.Refresh()
         event.Skip()
 
     def OnDeleteSegmentMenu(self, event):
-        if self.SelectedElement and self.IsWire(self.SelectedElement):
+        if self.SelectedElement is not None and self.IsWire(self.SelectedElement):
             self.SelectedElement.DeleteSegment()
             self.SelectedElement.Refresh()
         event.Skip()
 
     def OnAddBranchMenu(self, event):
-        if self.SelectedElement and self.IsBlock(self.SelectedElement):
+        if self.SelectedElement is not None and self.IsBlock(self.SelectedElement):
             self.AddDivergenceBranch(self.SelectedElement)
             self.RefreshBuffer()
         event.Skip()
 
     def OnDeleteBranchMenu(self, event):
-        if self.SelectedElement and self.IsBlock(self.SelectedElement):
+        if self.SelectedElement is not None and self.IsBlock(self.SelectedElement):
             self.RemoveDivergenceBranch(self.SelectedElement)
             self.RefreshBuffer()
         event.Skip()
 
     def OnEditBlockMenu(self, event):
-        if self.SelectedElement:
+        if self.SelectedElement is not None:
             self.ParentWindow.EditProjectElement(ITEM_POU, "P::%s"%self.SelectedElement.GetType())
         event.Skip()
 
     def OnDeleteMenu(self, event):
-        if self.SelectedElement:
+        if self.SelectedElement is not None:
             self.SelectedElement.Delete()
             self.SelectedElement = None
             self.RefreshBuffer()
@@ -1090,13 +1155,13 @@
         if self.Mode == MODE_SELECTION:
             dc = self.GetLogicalDC()
             pos = event.GetLogicalPosition(dc)
-            if event.ControlDown() and self.SelectedElement:
+            if event.ControlDown() and self.SelectedElement is not None:
                 element = self.FindElement(pos, True)
-                if element:
+                if element is not None:
                     if isinstance(self.SelectedElement, Graphic_Group):
                         self.SelectedElement.SetSelected(False)
                         self.SelectedElement.SelectElement(element)
-                    elif self.SelectedElement:
+                    elif self.SelectedElement is not None:
                         group = Graphic_Group(self)
                         group.SelectElement(self.SelectedElement)
                         group.SelectElement(element)
@@ -1109,16 +1174,16 @@
                     self.SelectedElement.SetSelected(True)
             else:
                 element = self.FindElement(pos)
-                if element is None or element.TestHandle(pos) == (0, 0):
+                if not self.Debug and (element is None or element.TestHandle(pos) == (0, 0)):
                     connector = self.FindBlockConnector(pos)
                 else:
                     connector = None
-                if self.DrawingWire:
+                if not self.Debug and self.DrawingWire:
                     self.DrawingWire = False
                     if self.SelectedElement is not None:
                         if element is None or element.TestHandle(pos) == (0, 0):
                             connector = self.FindBlockConnector(pos, self.SelectedElement.GetConnectionDirection())
-                        if connector:
+                        if connector is not None:
                             event.Dragging = lambda : True
                             self.SelectedElement.OnMotion(event, self.GetLogicalDC(), self.Scaling)
                         if self.SelectedElement.EndConnected is not None:
@@ -1134,7 +1199,7 @@
                             self.SelectedElement = None
                             element = None
                             self.RefreshRect(self.GetScrolledRect(rect), False)
-                elif connector:
+                elif not self.Debug and connector is not None:
                     self.DrawingWire = True
                     scaled_pos = GetScaledEventPosition(event, self.GetLogicalDC(), self.Scaling)
                     if (connector.GetDirection() == EAST):
@@ -1146,17 +1211,20 @@
                     wire.ProcessDragging(0, 0, False, None)
                     wire.Handle = (HANDLE_POINT, 1)
                     self.AddWire(wire)
-                    if self.SelectedElement:
+                    if self.SelectedElement is not None:
                         self.SelectedElement.SetSelected(False)
                     self.SelectedElement = wire
                     self.SelectedElement.Refresh()
                 else:
-                    if self.SelectedElement and self.SelectedElement != element:
+                    if self.SelectedElement is not None and self.SelectedElement != element:
                         self.SelectedElement.SetSelected(False)
                         self.SelectedElement = None
-                    if element:
+                    if element is not None:
                         self.SelectedElement = element
-                        self.SelectedElement.OnLeftDown(event, dc, self.Scaling)
+                        if self.Debug:
+                            Graphic_Element.OnLeftDown(self.SelectedElement, event, dc, self.Scaling)
+                        else:
+                            self.SelectedElement.OnLeftDown(event, dc, self.Scaling)
                         self.SelectedElement.Refresh()
                     else:
                         self.rubberBand.Reset()
@@ -1209,9 +1277,9 @@
                     wx.CallAfter(self.AddNewJump, bbox)
                 elif self.Mode == MODE_ACTION:
                     wx.CallAfter(self.AddNewActionBlock, bbox)
-        elif self.Mode == MODE_SELECTION and self.SelectedElement:
+        elif self.Mode == MODE_SELECTION and self.SelectedElement is not None:
             dc = self.GetLogicalDC()
-            if self.DrawingWire:
+            if not self.Debug and self.DrawingWire:
                 pos = event.GetLogicalPosition(dc)
                 connector = self.FindBlockConnector(pos, self.SelectedElement.GetConnectionDirection())
                 if self.SelectedElement.EndConnected is not None:
@@ -1236,7 +1304,10 @@
                     self.SelectedElement = None
                     self.RefreshRect(self.GetScrolledRect(rect), False)
             else:
-                self.SelectedElement.OnLeftUp(event, dc, self.Scaling)
+                if self.Debug:
+                    Graphic_Element.OnLeftUp(self.SelectedElement, event, dc, self.Scaling)
+                else:
+                    self.SelectedElement.OnLeftUp(event, dc, self.Scaling)
                 wx.CallAfter(self.SetCursor, wx.NullCursor)
         if self.Mode != MODE_SELECTION and not self.SavedMode:
             wx.CallAfter(self.ParentWindow.ResetCurrentMode)
@@ -1247,27 +1318,35 @@
             dc = self.GetLogicalDC()
             pos = event.GetLogicalPosition(dc)
             element = self.FindElement(pos)
-            if self.SelectedElement and self.SelectedElement != element:
+            if self.SelectedElement is not None and self.SelectedElement != element:
                 self.SelectedElement.SetSelected(False)
                 self.SelectedElement = None
             if element:
                 self.SelectedElement = element
-                self.SelectedElement.OnRightDown(event, dc, self.Scaling)
+                if self.Debug:
+                    Graphic_Element.OnRightDown(self.SelectedElement, event, dc, self.Scaling)
+                else:
+                    self.SelectedElement.OnRightDown(event, dc, self.Scaling)
                 self.SelectedElement.Refresh()
         event.Skip()
     
     def OnViewerRightUp(self, event):
         dc = self.GetLogicalDC()
-        if self.SelectedElement:
-            self.SelectedElement.OnRightUp(event, dc, self.Scaling)
+        if self.SelectedElement is not None:
+            if self.Debug:
+                Graphic_Element.OnRightUp(self.SelectedElement, event, dc, self.Scaling)
+            else:
+                self.SelectedElement.OnRightUp(event, dc, self.Scaling)
             wx.CallAfter(self.SetCursor, wx.NullCursor)
-        else:
+        elif not self.Debug:
             self.PopupDefaultMenu(False)
         event.Skip()
     
     def OnViewerLeftDClick(self, event):
-        if self.Mode == MODE_SELECTION and self.SelectedElement:
-            if event.ControlDown() and self.IsBlock(self.SelectedElement) and self.SelectedElement.GetType() in self.Controler.GetProjectPouNames():
+        if self.Mode == MODE_SELECTION and self.SelectedElement is not None:
+            if self.Debug:
+                Graphic_Element.OnLeftDClick(self.SelectedElement, event, self.GetLogicalDC(), self.Scaling)
+            elif event.ControlDown() and self.IsBlock(self.SelectedElement) and self.SelectedElement.GetType() in self.Controler.GetProjectPouNames(self.Debug):
                 self.ParentWindow.EditProjectElement(ITEM_POU, self.SelectedElement.GetType())
             else:
                 self.SelectedElement.OnLeftDClick(event, self.GetLogicalDC(), self.Scaling)
@@ -1287,9 +1366,9 @@
             self.HighlightedElement = highlighted
         if self.rubberBand.IsShown():
             self.rubberBand.OnMotion(event, dc, self.Scaling)
-        elif self.Mode == MODE_SELECTION and self.SelectedElement:
+        elif not self.Debug and self.Mode == MODE_SELECTION and self.SelectedElement is not None:
             if self.DrawingWire:
-                connector = self.FindBlockConnector(pos, self.SelectedElement.GetConnectionDirection(), False)
+                connector = self.FindBlockConnector(pos, self.SelectedElement.GetConnectionDirection(), self.SelectedElement.EndConnected)
                 if not connector or self.SelectedElement.EndConnected == None:
                     self.SelectedElement.ResetPoints()
                     movex, movey = self.SelectedElement.OnMotion(event, dc, self.Scaling)
@@ -1304,7 +1383,7 @@
         event.Skip()
 
     def OnLeaveViewer(self, event):
-        if self.SelectedElement and self.SelectedElement.GetDragging():
+        if self.SelectedElement is not None and self.SelectedElement.GetDragging():
             event.Skip()
         elif self.HighlightedElement is not None:
             self.HighlightedElement.SetHighlighted(False)
@@ -1312,7 +1391,7 @@
         event.Skip()
 
     def UpdateScrollPos(self, event):
-        if (event.Dragging() and self.SelectedElement) or self.rubberBand.IsShown():
+        if (event.Dragging() and self.SelectedElement is not None) or self.rubberBand.IsShown():
             position = event.GetPosition()
             move_window = wx.Point()
             window_size = self.GetClientSize()
@@ -1338,11 +1417,11 @@
         xmax = self.GetScrollRange(wx.HORIZONTAL) - self.GetScrollThumb(wx.HORIZONTAL)
         ymax = self.GetScrollRange(wx.VERTICAL) - self.GetScrollThumb(wx.VERTICAL)
         keycode = event.GetKeyCode()
-        if self.Scaling:
+        if self.Scaling is not None:
             scaling = self.Scaling
         else:
             scaling = (8, 8)
-        if keycode == wx.WXK_DELETE and self.SelectedElement:
+        if not self.Debug and keycode == wx.WXK_DELETE and self.SelectedElement is not None:
             rect = self.SelectedElement.GetRedrawRect(1, 1)
             self.SelectedElement.Delete()
             self.SelectedElement = None
@@ -1350,14 +1429,14 @@
             self.RefreshScrollBars()
             self.SetCursor(wx.NullCursor)
             self.RefreshRect(self.GetScrolledRect(rect), False)
-        elif keycode == wx.WXK_RETURN and self.SelectedElement:
+        elif not self.Debug and keycode == wx.WXK_RETURN and self.SelectedElement is not None:
             self.SelectedElement.OnLeftDClick(event, self.GetLogicalDC(), self.Scaling)
         elif keycode == wx.WXK_LEFT:
             if event.ControlDown() and event.ShiftDown():
                 self.Scroll(0, ypos)
             elif event.ControlDown():
                 event.Skip()
-            elif self.SelectedElement:
+            elif not self.Debug and self.SelectedElement is not None:
                 self.SelectedElement.Move(-scaling[0], 0)
                 self.SelectedElement.RefreshModel()
                 self.RefreshBuffer()
@@ -1368,7 +1447,7 @@
                 self.Scroll(xmax, ypos)
             elif event.ControlDown():
                 event.Skip()
-            elif self.SelectedElement:
+            elif not self.Debug and self.SelectedElement is not None:
                 self.SelectedElement.Move(scaling[0], 0)
                 self.SelectedElement.RefreshModel()
                 self.RefreshBuffer()
@@ -1379,7 +1458,7 @@
                 self.Scroll(xpos, 0)
             elif event.ControlDown():
                 event.Skip()
-            elif self.SelectedElement:
+            elif not self.Debug and self.SelectedElement is not None:
                 self.SelectedElement.Move(0, -scaling[1])
                 self.SelectedElement.RefreshModel()
                 self.RefreshBuffer()
@@ -1390,13 +1469,13 @@
                 self.Scroll(xpos, ymax)
             elif event.ControlDown():
                 event.Skip()
-            elif self.SelectedElement:
+            elif not self.Debug and self.SelectedElement is not None:
                 self.SelectedElement.Move(0, scaling[1])
                 self.SelectedElement.RefreshModel()
                 self.RefreshBuffer()
                 self.RefreshScrollBars()
                 self.RefreshRect(self.GetScrolledRect(self.SelectedElement.GetRedrawRect(0, scaling[1])), False)
-        elif keycode == wx.WXK_SPACE and self.SelectedElement is not None and self.SelectedElement.Dragging:
+        elif not self.Debug and keycode == wx.WXK_SPACE and self.SelectedElement is not None and self.SelectedElement.Dragging:
             if self.IsBlock(self.SelectedElement) or self.IsComment(self.SelectedElement):
                 self.CopyBlock(self.SelectedElement, wx.Point(*self.SelectedElement.GetPosition()))
                 self.RefreshBuffer()
@@ -1421,9 +1500,9 @@
     def AddNewBlock(self, bbox):
         dialog = BlockPropertiesDialog(self.ParentWindow, self.Controler)
         dialog.SetPreviewFont(self.GetFont())
-        dialog.SetBlockList(self.Controler.GetBlockTypes(self.TagName))
-        dialog.SetPouNames(self.Controler.GetProjectPouNames())
-        dialog.SetPouElementNames(self.Controler.GetEditedElementVariables(self.TagName))
+        dialog.SetBlockList(self.Controler.GetBlockTypes(self.TagName, self.Debug))
+        dialog.SetPouNames(self.Controler.GetProjectPouNames(self.Debug))
+        dialog.SetPouElementNames(self.Controler.GetEditedElementVariables(self.TagName, self.Debug))
         dialog.SetMinBlockSize((bbox.width, bbox.height))
         if dialog.ShowModal() == wx.ID_OK:
             id = self.GetNewId()
@@ -1439,6 +1518,7 @@
             self.RefreshBlockModel(block)
             self.RefreshBuffer()
             self.RefreshScrollBars()
+            self.RefreshVisibleElements()
             self.ParentWindow.RefreshVariablePanel(self.TagName)
             self.ParentWindow.RefreshInstancesTree()
             block.Refresh()
@@ -1449,12 +1529,12 @@
         dialog.SetPreviewFont(self.GetFont())
         dialog.SetMinVariableSize((bbox.width, bbox.height))
         varlist = []
-        vars = self.Controler.GetEditedElementInterfaceVars(self.TagName)
+        vars = self.Controler.GetEditedElementInterfaceVars(self.TagName, self.Debug)
         if vars:
             for var in vars:
                 if var["Edit"]:
                     varlist.append((var["Name"], var["Class"], var["Type"]))
-        returntype = self.Controler.GetEditedElementInterfaceReturnType(self.TagName)
+        returntype = self.Controler.GetEditedElementInterfaceReturnType(self.TagName, self.Debug)
         if returntype:
             varlist.append((self.Controler.GetEditedElementName(self.TagName), "Output", returntype))
         dialog.SetVariables(varlist)
@@ -1469,6 +1549,7 @@
             self.RefreshVariableModel(variable)
             self.RefreshBuffer()
             self.RefreshScrollBars()
+            self.RefreshVisibleElements()
             variable.Refresh()
         dialog.Destroy()
 
@@ -1487,6 +1568,7 @@
             self.RefreshConnectionModel(connection)
             self.RefreshBuffer()
             self.RefreshScrollBars()
+            self.RefreshVisibleElements()
             connection.Refresh()
         dialog.Destroy()
 
@@ -1507,6 +1589,7 @@
             self.RefreshCommentModel(comment)
             self.RefreshBuffer()
             self.RefreshScrollBars()
+            self.RefreshVisibleElements()
             comment.Refresh()
         dialog.Destroy()
 
@@ -1514,7 +1597,7 @@
         dialog = LDElementDialog(self.ParentWindow, self.Controler, "contact")
         dialog.SetPreviewFont(self.GetFont())
         varlist = []
-        vars = self.Controler.GetEditedElementInterfaceVars(self.TagName)
+        vars = self.Controler.GetEditedElementInterfaceVars(self.TagName, self.Debug)
         if vars:
             for var in vars:
                 if var["Class"] != "Output" and var["Type"] == "BOOL":
@@ -1533,6 +1616,7 @@
             self.RefreshContactModel(contact)
             self.RefreshBuffer()
             self.RefreshScrollBars()
+            self.RefreshVisibleElements()
             contact.Refresh()
         dialog.Destroy()
 
@@ -1540,12 +1624,12 @@
         dialog = LDElementDialog(self.ParentWindow, self.Controler, "coil")
         dialog.SetPreviewFont(self.GetFont())
         varlist = []
-        vars = self.Controler.GetEditedElementInterfaceVars(self.TagName)
+        vars = self.Controler.GetEditedElementInterfaceVars(self.TagName, self.Debug)
         if vars:
             for var in vars:
                 if var["Class"] != "Input" and var["Type"] == "BOOL":
                     varlist.append(var["Name"])
-        returntype = self.Controler.GetEditedElementInterfaceReturnType(self.TagName)
+        returntype = self.Controler.GetEditedElementInterfaceReturnType(self.TagName, self.Debug)
         if returntype == "BOOL":
             varlist.append(self.Controler.GetEditedElementName(self.TagName))
         dialog.SetVariables(varlist)
@@ -1562,6 +1646,7 @@
             self.RefreshCoilModel(coil)
             self.RefreshBuffer()
             self.RefreshScrollBars()
+            self.RefreshVisibleElements()
             coil.Refresh()
         dialog.Destroy()
 
@@ -1580,14 +1665,15 @@
             self.RefreshPowerRailModel(powerrail)
             self.RefreshBuffer()
             self.RefreshScrollBars()
+            self.RefreshVisibleElements()
             powerrail.Refresh()
         dialog.Destroy()
 
     def AddNewStep(self, bbox, initial = False):
         dialog = StepContentDialog(self.ParentWindow, self.Controler, initial)
         dialog.SetPreviewFont(self.GetFont())
-        dialog.SetPouNames(self.Controler.GetProjectPouNames())
-        dialog.SetVariables(self.Controler.GetEditedElementInterfaceVars(self.TagName))
+        dialog.SetPouNames(self.Controler.GetProjectPouNames(self.Debug))
+        dialog.SetVariables(self.Controler.GetEditedElementInterfaceVars(self.TagName, self.Debug))
         dialog.SetStepNames([block.GetName() for block in self.Blocks if isinstance(block, SFC_Step)])
         dialog.SetMinStepSize((bbox.width, bbox.height))
         if dialog.ShowModal() == wx.ID_OK:
@@ -1614,13 +1700,14 @@
             self.RefreshStepModel(step)
             self.RefreshBuffer()
             self.RefreshScrollBars()
+            self.RefreshVisibleElements()
             step.Refresh()
         dialog.Destroy()
 
     def AddNewTransition(self, bbox):
         dialog = TransitionContentDialog(self.ParentWindow, self.Controler, self.GetDrawingMode() == FREEDRAWING_MODE)
         dialog.SetPreviewFont(self.GetFont())
-        dialog.SetTransitions(self.Controler.GetEditedElementTransitions(self.TagName))
+        dialog.SetTransitions(self.Controler.GetEditedElementTransitions(self.TagName, self.Debug))
         if dialog.ShowModal() == wx.ID_OK:
             id = self.GetNewId()
             values = dialog.GetValues()
@@ -1633,6 +1720,7 @@
             self.RefreshTransitionModel(transition)
             self.RefreshBuffer()
             self.RefreshScrollBars()
+            self.RefreshVisibleElements()
             transition.Refresh()
         dialog.Destroy()
 
@@ -1652,6 +1740,7 @@
             self.RefreshDivergenceModel(divergence)
             self.RefreshBuffer()
             self.RefreshScrollBars()
+            self.RefreshVisibleElements()
             divergence.Refresh()
         dialog.Destroy()
 
@@ -1673,14 +1762,15 @@
             self.RefreshJumpModel(jump)
             self.RefreshBuffer()
             self.RefreshScrollBars()
+            self.RefreshVisibleElements()
             jump.Refresh()
         dialog.Destroy()
 
     def AddNewActionBlock(self, bbox):
         dialog = ActionBlockDialog(self.ParentWindow)
         dialog.SetQualifierList(self.Controler.GetQualifierTypes())
-        dialog.SetActionList(self.Controler.GetEditedElementActions(self.TagName))
-        dialog.SetVariableList(self.Controler.GetEditedElementInterfaceVars(self.TagName))
+        dialog.SetActionList(self.Controler.GetEditedElementActions(self.TagName, self.Debug))
+        dialog.SetVariableList(self.Controler.GetEditedElementInterfaceVars(self.TagName, self.Debug))
         if dialog.ShowModal() == wx.ID_OK:
             actions = dialog.GetValues()
             id = self.GetNewId()
@@ -1693,6 +1783,7 @@
             self.RefreshActionBlockModel(actionblock)
             self.RefreshBuffer()
             self.RefreshScrollBars()
+            self.RefreshVisibleElements()
             actionblock.Refresh()
         dialog.Destroy()
 
@@ -1703,9 +1794,9 @@
     def EditBlockContent(self, block):
         dialog = BlockPropertiesDialog(self.ParentWindow, self.Controler)
         dialog.SetPreviewFont(self.GetFont())
-        dialog.SetBlockList(self.Controler.GetBlockTypes(self.TagName))
-        dialog.SetPouNames(self.Controler.GetProjectPouNames())
-        variable_names = self.Controler.GetEditedElementVariables(self.TagName)
+        dialog.SetBlockList(self.Controler.GetBlockTypes(self.TagName, self.Debug))
+        dialog.SetPouNames(self.Controler.GetProjectPouNames(self.Debug))
+        variable_names = self.Controler.GetEditedElementVariables(self.TagName, self.Debug)
         if block.GetName() != "":
             variable_names.remove(block.GetName())
         dialog.SetPouElementNames(variable_names)
@@ -1729,6 +1820,7 @@
                 self.RefreshView()
             self.RefreshBuffer()
             self.RefreshScrollBars()
+            self.RefreshVisibleElements()
             self.ParentWindow.RefreshVariablePanel(self.TagName)
             self.ParentWindow.RefreshInstancesTree()
             block.Refresh(rect)
@@ -1739,12 +1831,12 @@
         dialog.SetPreviewFont(self.GetFont())
         dialog.SetMinVariableSize(variable.GetSize())
         varlist = []
-        vars = self.Controler.GetEditedElementInterfaceVars(self.TagName)
+        vars = self.Controler.GetEditedElementInterfaceVars(self.TagName, self.Debug)
         if vars:
             for var in vars:
                 if var["Edit"]:
                     varlist.append((var["Name"], var["Class"], var["Type"]))
-        returntype = self.Controler.GetEditedElementInterfaceReturnType(self.TagName)
+        returntype = self.Controler.GetEditedElementInterfaceReturnType(self.TagName, self.Debug)
         if returntype:
             varlist.append((self.Controler.GetEditedElementName(self.TagName), "Output", returntype))
         dialog.SetVariables(varlist)
@@ -1767,6 +1859,7 @@
             if old_values["executionOrder"] != new_values["executionOrder"]:
                 self.RefreshView()
             self.RefreshBuffer()
+            self.RefreshVisibleElements()
             self.RefreshScrollBars()
             variable.Refresh(rect)
         dialog.Destroy()
@@ -1792,6 +1885,7 @@
             self.RefreshConnectionModel(connection)
             self.RefreshBuffer()
             self.RefreshScrollBars()
+            self.RefreshVisibleElements()
             connection.Refresh(rect)
         dialog.Destroy()
 
@@ -1799,7 +1893,7 @@
         dialog = LDElementDialog(self.ParentWindow, self.Controler, "contact")
         dialog.SetPreviewFont(self.GetFont())
         varlist = []
-        vars = self.Controler.GetEditedElementInterfaceVars(self.TagName)
+        vars = self.Controler.GetEditedElementInterfaceVars(self.TagName, self.Debug)
         if vars:
             for var in vars:
                 if var["Class"] != "Output" and var["Type"] == "BOOL":
@@ -1818,6 +1912,7 @@
             self.RefreshContactModel(contact)
             self.RefreshBuffer()
             self.RefreshScrollBars()
+            self.RefreshVisibleElements()
             contact.Refresh(rect)
         dialog.Destroy()
 
@@ -1825,12 +1920,12 @@
         dialog = LDElementDialog(self.ParentWindow, self.Controler, "coil")
         dialog.SetPreviewFont(self.GetFont())
         varlist = []
-        vars = self.Controler.GetEditedElementInterfaceVars(self.TagName)
+        vars = self.Controler.GetEditedElementInterfaceVars(self.TagName, self.Debug)
         if vars:
             for var in vars:
                 if var["Class"] != "Input" and var["Type"] == "BOOL":
                     varlist.append(var["Name"])
-        returntype = self.Controler.GetEditedElementInterfaceReturnType(self.TagName)
+        returntype = self.Controler.GetEditedElementInterfaceReturnType(self.TagName, self.Debug)
         if returntype == "BOOL":
             varlist.append(self.Controler.GetEditedElementName(self.TagName))
         dialog.SetVariables(varlist)
@@ -1847,6 +1942,7 @@
             self.RefreshCoilModel(coil)
             self.RefreshBuffer()
             self.RefreshScrollBars()
+            self.RefreshVisibleElements()
             coil.Refresh(rect)
         dialog.Destroy()
 
@@ -1868,14 +1964,15 @@
             self.RefreshPowerRailModel(powerrail)
             self.RefreshBuffer()
             self.RefreshScrollBars()
+            self.RefreshVisibleElements()
             powerrail.Refresh(rect)
         dialog.Destroy()
 
     def EditStepContent(self, step):
         dialog = StepContentDialog(self.ParentWindow, self.Controler, step.GetInitial())
         dialog.SetPreviewFont(self.GetFont())
-        dialog.SetPouNames(self.Controler.GetProjectPouNames())
-        dialog.SetVariables(self.Controler.GetEditedElementInterfaceVars(self.TagName))
+        dialog.SetPouNames(self.Controler.GetProjectPouNames(self.Debug))
+        dialog.SetVariables(self.Controler.GetEditedElementInterfaceVars(self.TagName, self.Debug))
         dialog.SetStepNames([block.GetName() for block in self.Blocks if isinstance(block, SFC_Step) and block.GetName() != step.GetName()])
         dialog.SetMinStepSize(step.GetSize())
         values = {"name" : step.GetName()}
@@ -1905,12 +2002,13 @@
             self.RefreshStepModel(step)
             self.RefreshBuffer()
             self.RefreshScrollBars()
+            self.RefreshVisibleElements()
             step.Refresh(rect)
         
     def EditTransitionContent(self, transition):
         dialog = TransitionContentDialog(self.ParentWindow, self.Controler, self.GetDrawingMode() == FREEDRAWING_MODE)
         dialog.SetPreviewFont(self.GetFont())
-        dialog.SetTransitions(self.Controler.GetEditedElementTransitions(self.TagName))
+        dialog.SetTransitions(self.Controler.GetEditedElementTransitions(self.TagName, self.Debug))
         dialog.SetValues({"type":transition.GetType(),"value":transition.GetCondition(), "priority":transition.GetPriority()})
         dialog.SetElementSize(transition.GetSize())
         if dialog.ShowModal() == wx.ID_OK:
@@ -1922,6 +2020,7 @@
             self.RefreshTransitionModel(transition)
             self.RefreshBuffer()
             self.RefreshScrollBars()
+            self.RefreshVisibleElements()
             transition.Refresh(rect)
         dialog.Destroy()
 
@@ -1940,14 +2039,15 @@
             self.RefreshJumpModel(jump)
             self.RefreshBuffer()
             self.RefreshScrollBars()
+            self.RefreshVisibleElements()
             jump.Refresh(rect)
         dialog.Destroy()
 
     def EditActionBlockContent(self, actionblock):
         dialog = ActionBlockDialog(self.ParentWindow)
         dialog.SetQualifierList(self.Controler.GetQualifierTypes())
-        dialog.SetActionList(self.Controler.GetEditedElementActions(self.TagName))
-        dialog.SetVariableList(self.Controler.GetEditedElementInterfaceVars(self.TagName))
+        dialog.SetActionList(self.Controler.GetEditedElementActions(self.TagName, self.Debug))
+        dialog.SetVariableList(self.Controler.GetEditedElementInterfaceVars(self.TagName, self.Debug))
         dialog.SetValues(actionblock.GetActions())
         if dialog.ShowModal() == wx.ID_OK:
             actions = dialog.GetValues()
@@ -1958,6 +2058,7 @@
             self.RefreshActionBlockModel(actionblock)
             self.RefreshBuffer()
             self.RefreshScrollBars()
+            self.RefreshVisibleElements()
             actionblock.Refresh(rect)
         dialog.Destroy()
 
@@ -1975,6 +2076,7 @@
             self.RefreshCommentModel(comment)
             self.RefreshBuffer()
             self.RefreshScrollBars()
+            self.RefreshVisibleElements()
             comment.Refresh(rect)
         dialog.Destroy()
 
@@ -2242,7 +2344,7 @@
 #-------------------------------------------------------------------------------
     
     def Cut(self):
-        if self.IsBlock(self.SelectedElement) or self.IsComment(self.SelectedElement):
+        if not self.Debug and (self.IsBlock(self.SelectedElement) or self.IsComment(self.SelectedElement)):
             self.ParentWindow.SetCopyBuffer(self.SelectedElement.Clone(self))
             rect = self.SelectedElement.GetRedrawRect(1, 1)
             self.SelectedElement.Delete()
@@ -2254,12 +2356,12 @@
             self.RefreshRect(self.GetScrolledRect(rect), False)
         
     def Copy(self):
-        if self.IsBlock(self.SelectedElement) or self.IsComment(self.SelectedElement):
+        if not self.Debug and (self.IsBlock(self.SelectedElement) or self.IsComment(self.SelectedElement)):
             self.ParentWindow.SetCopyBuffer(self.SelectedElement.Clone(self))
             
     def Paste(self):
         element = self.ParentWindow.GetCopyBuffer()
-        if element is not None and self.CanAddBlock(element):
+        if not self.Debug and element is not None and self.CanAddBlock(element):
             block = self.CopyBlock(element, wx.Point(*self.CalcUnscrolledPosition(30, 30)))
             if self.SelectedElement is not None:
                 self.SelectedElement.SetSelected(False)
@@ -2267,6 +2369,7 @@
             self.SelectedElement.SetSelected(True)
             self.RefreshBuffer()
             self.RefreshScrollBars()
+            self.RefreshVisibleElements()
             self.ParentWindow.RefreshVariablePanel(self.TagName)
             self.ParentWindow.RefreshInstancesTree()
 
@@ -2283,7 +2386,7 @@
         id = self.GetNewId()
         if isinstance(element, FBD_Block) and element.GetName() != "" or isinstance(element, SFC_Step):
             if isinstance(element, FBD_Block):
-                names = [varname.upper() for varname in self.Controler.GetEditedElementVariables(self.TagName)]
+                names = [varname.upper() for varname in self.Controler.GetEditedElementVariables(self.TagName, self.Debug)]
                 format = "Block%d"
             elif isinstance(element, SFC_Step):
                 names = [block.GetName().upper() for block in self.Blocks if isinstance(block, SFC_Step)]
@@ -2360,9 +2463,17 @@
 #                            Drawing functions
 #-------------------------------------------------------------------------------
 
+    def OnScrollWindow(self, event):
+        if event.GetOrientation() == wx.HORIZONTAL:
+            self.RefreshVisibleElements(xp = event.GetPosition())
+        else:
+            self.RefreshVisibleElements(yp = event.GetPosition())
+        event.Skip()
+
     def OnMoveWindow(self, event):
         self.GetBestSize()
         self.RefreshScrollBars()
+        self.RefreshVisibleElements()
         event.Skip()
 
     def DoDrawing(self, dc, printing = False):
@@ -2398,17 +2509,22 @@
         
         # Draw all elements
         for comment in self.Comments:
-            if comment != self.SelectedElement:
+            if comment != self.SelectedElement and (comment.IsVisible() or printing):
                 comment.Draw(dc)
         for wire in self.Wires:
-            if wire != self.SelectedElement:
-                wire.Draw(dc)
+            if wire != self.SelectedElement and (wire.IsVisible() or printing):
+                 if not self.Debug or wire.GetValue() != True:
+                    wire.Draw(dc)
+        if self.Debug:
+            for wire in self.Wires:
+                if wire != self.SelectedElement and (wire.IsVisible() or printing) and wire.GetValue() == True:
+                    wire.Draw(dc)
         for block in self.Blocks:
-            if block != self.SelectedElement:
+            if block != self.SelectedElement and (block.IsVisible() or printing):
                 block.Draw(dc)
         
-        if self.SelectedElement:
-                self.SelectedElement.Draw(dc)
+        if self.SelectedElement is not None and (self.SelectedElement.IsVisible() or printing):
+            self.SelectedElement.Draw(dc)
         
         if not printing:
             if self.rubberBand.IsShown():
--- a/graphics/FBD_Objects.py	Fri Sep 05 18:12:23 2008 +0200
+++ b/graphics/FBD_Objects.py	Fri Sep 05 18:13:18 2008 +0200
@@ -64,9 +64,12 @@
         block.Outputs = [output.Clone(block) for output in self.Outputs]
         return block
     
-    # Destructor
-    def __del__(self):
+    def Flush(self):
+        for input in self.Inputs:
+            input.Flush()
         self.Inputs = []
+        for output in self.Outputs:
+            output.Flush()
         self.Outputs = []
     
     # Returns the RedrawRect
@@ -434,10 +437,13 @@
             variable.Output = self.Output.Clone(variable)
         return variable
     
-    # Destructor
-    def __del__(self):
-        self.Input = None
-        self.Output = None
+    def Flush(self):
+        if self.Input is not None:
+            self.Input.Flush()
+            self.Input = None
+        if self.Output is not None:
+            self.Output.Flush()
+            self.Output = None
     
     # Returns the RedrawRect
     def GetRedrawRect(self, movex = 0, movey = 0):
@@ -672,9 +678,10 @@
         self.RefreshConnectors()
         self.RefreshNameSize()
     
-    # Destructor
-    def __del__(self):
-        self.Connector = None
+    def Flush(self):
+        if self.Connector:
+            self.Connector.Flush()
+            self.Connector = None
     
     # Returns the RedrawRect
     def GetRedrawRect(self, movex = 0, movey = 0):
--- a/graphics/GraphicCommons.py	Fri Sep 05 18:12:23 2008 +0200
+++ b/graphics/GraphicCommons.py	Fri Sep 05 18:13:18 2008 +0200
@@ -24,6 +24,7 @@
 
 import wx
 from math import *
+from types import *
 
 #-------------------------------------------------------------------------------
 #                               Common constants
@@ -309,9 +310,19 @@
         self.Pos = wx.Point(0, 0)
         self.Size = wx.Size(0, 0)
         self.BoundingBox = wx.Rect(0, 0, 0, 0)
+        self.Visible = False
         self.CurrentCursor = 0
         ResetCursors()
     
+    def TestVisible(self, screen):
+        self.Visible = self.BoundingBox.Intersects(screen)
+    
+    def IsVisible(self):
+        return self.Visible
+    
+    def SpreadCurrent(self):
+        pass
+    
     def IsOfType(self, type, reference):
         return self.Parent.IsOfType(type, reference)
     
@@ -663,6 +674,12 @@
     def __del__(self):
         self.Elements = []
     
+    def IsVisible(self):
+        for element in self.Elements:
+            if element.IsVisible():
+                return True
+        return False
+    
     # Refresh the list of wire excluded
     def RefreshWireExclusion(self):
         self.WireExcluded = []
@@ -862,10 +879,18 @@
             self.Negated = False
             self.Edge = "none"
         self.OneConnected = onlyone
+        self.Valid = True
+        self.Value = None
         self.Pen = wx.BLACK_PEN
         self.Errors = {}
         self.RefreshNameSize()
     
+    def Flush(self):
+        self.ParentBlock = None
+        for wire, handle in self.Wires:
+            wire.Flush()
+        self.Wires = []
+    
     # Returns the RedrawRect
     def GetRedrawRect(self, movex = 0, movey = 0):
         parent_pos = self.ParentBlock.GetPosition()
@@ -941,9 +966,23 @@
         self.Name = name
         self.RefreshNameSize()
 
-    def SetValue(self, value):
+    def RefreshValue(self):
+        self.Value = self.ReceivingCurrent()
+    
+    def MarkAsInvalid(self):
+        self.Valid = False
+    
+    def ReceivingCurrent(self):
+        current = False
         for wire, handle in self.Wires:
-            wire.SetValue(value)
+            value = wire.GetValue()
+            if isinstance(value, BooleanType):
+                current |= wire.GetValue()
+        return current
+    
+    def SpreadCurrent(self, spreading):
+        for wire, handle in self.Wires:
+            wire.SetValue(spreading)
     
     # Changes the connector name size
     def RefreshNameSize(self):
@@ -1105,15 +1144,15 @@
     # Tests if the point given is near from the end point of this connector
     def TestPoint(self, pt, direction = None, exclude = True):
         parent_pos = self.ParentBlock.GetPosition()
-        if not (len(self.Wires) > 0 and self.OneConnected and exclude):
-            if direction is None or self.Direction == direction:
-                # Calculate a square around the end point of this connector
-                x = parent_pos[0] + self.Pos.x + self.Direction[0] * CONNECTOR_SIZE - ANCHOR_DISTANCE
-                y = parent_pos[1] + self.Pos.y + self.Direction[1] * CONNECTOR_SIZE - ANCHOR_DISTANCE
-                width = ANCHOR_DISTANCE * 2 + abs(self.Direction[0]) * CONNECTOR_SIZE
-                height = ANCHOR_DISTANCE * 2 + abs(self.Direction[1]) * CONNECTOR_SIZE
-                rect = wx.Rect(x, y, width, height)
-                return rect.InsideXY(pt.x, pt.y)
+        if (not (len(self.Wires) > 0 and self.OneConnected and exclude) or self.Type == "BOOL")\
+            and direction is None or self.Direction == direction:
+            # Calculate a square around the end point of this connector
+            x = parent_pos[0] + self.Pos.x + self.Direction[0] * CONNECTOR_SIZE - ANCHOR_DISTANCE
+            y = parent_pos[1] + self.Pos.y + self.Direction[1] * CONNECTOR_SIZE - ANCHOR_DISTANCE
+            width = ANCHOR_DISTANCE * 2 + abs(self.Direction[0]) * CONNECTOR_SIZE
+            height = ANCHOR_DISTANCE * 2 + abs(self.Direction[1]) * CONNECTOR_SIZE
+            rect = wx.Rect(x, y, width, height)
+            return rect.InsideXY(pt.x, pt.y)
         return False
     
     # Draws the highlightment of this element if it is highlighted
@@ -1152,7 +1191,12 @@
             dc.SetPen(wx.RED_PEN)
             dc.SetBrush(wx.Brush(wx.Colour(255, 255, 0)))
         else:
-            dc.SetPen(self.Pen)
+            if not self.Valid:
+                dc.SetPen(wx.RED_PEN)
+            elif isinstance(self.Value, BooleanType) and self.Value:
+                dc.SetPen(wx.GREEN_PEN)
+            else:
+                dc.SetPen(self.Pen)
             dc.SetBrush(wx.WHITE_BRUSH)
         parent_pos = self.ParentBlock.GetPosition()
         
@@ -1226,12 +1270,14 @@
         self.SelectedSegment = None
         self.Valid = True
         self.Value = None
+        self.ValueSize = None
         self.OverStart = False
         self.OverEnd = False
         self.ComputingType = False
-    
-    # Destructor of a wire
-    def __del__(self):
+        parent_font = parent.GetFont()
+        self.Font = wx.Font(parent_font.GetPointSize() * 0.75, wx.SWISS, wx.NORMAL, wx.NORMAL, faceName = parent_font.GetFaceName())
+        
+    def Flush(self):
         self.StartConnected = None
         self.EndConnected = None
     
@@ -1242,6 +1288,21 @@
             rect = rect.Union(self.StartConnected.GetRedrawRect(movex, movey))
         if self.EndConnected:
             rect = rect.Union(self.EndConnected.GetRedrawRect(movex, movey))
+        if self.ValueSize is not None:
+            width, height = self.ValueSize
+            width, height = self.ValueSize
+            if self.BoundingBox[2] > width * 4 or self.BoundingBox[3] > height * 4:
+                x = self.Points[0].x + width * self.StartPoint[1][0] / 2
+                y = self.Points[0].y + (height * self.StartPoint[1][1] - 1) / 2
+                rect = rect.Union(wx.Rect(x, y, width, height))
+                x = self.Points[-1].x + width * self.EndPoint[1][0] / 2
+                y = self.Points[-1].y + (height * self.EndPoint[1][1] - 1) / 2
+                rect = rect.Union(wx.Rect(x, y, width, height))
+            else:
+                middle = len(self.Segments) / 2 + len(self.Segments) % 2 - 1
+                x = self.Points[middle].x - width / 2
+                y = self.Points[middle].y - height / 2
+                rect = rect.Union(wx.Rect(x, y, width, height))
         return rect
     
     # Forbids to change the wire position
@@ -1315,7 +1376,32 @@
         return False
     
     def SetValue(self, value):
-        self.Value = value
+        if value is not None and not isinstance(value, BooleanType):
+            if isinstance(value, StringType):
+                value = "\"%s\""%value
+            else:
+                value = str(value)
+            if len(value) > 4:
+                value = value[:4] + "_"
+        if self.Value != value:
+            self.Value = value
+            if isinstance(self.Value, StringType):
+                dc = wx.ClientDC(self.Parent)
+                dc.SetFont(self.Font)
+                self.ValueSize = dc.GetTextExtent(self.Value)
+            else:
+                self.ValueSize = None
+            if self.StartConnected:
+                self.StartConnected.RefreshValue()
+            if self.EndConnected:
+                self.EndConnected.RefreshValue()
+            self.Refresh()
+            if isinstance(value, BooleanType):
+                block = self.StartConnected.GetParentBlock()
+                block.SpreadCurrent()
+    
+    def GetValue(self):
+        return self.Value
     
     # Unconnect the start and end points
     def Clean(self):
@@ -1362,9 +1448,9 @@
     def MarkAsInvalid(self):
         self.Valid = False
         if self.StartConnected:
-            self.StartConnected.SetPen(wx.RED_PEN)
+            self.StartConnected.MarkAsInvalid()
         if self.EndConnected:
-            self.EndConnected.SetPen(wx.RED_PEN)
+            self.EndConnected.MarkAsInvalid()
     
     # Reinitialize the wire points
     def ResetPoints(self):
@@ -1750,7 +1836,7 @@
                 height = lastheight
             # Calculate the real points from the new size, it's important for
             # keeping a proportionality in the points position with the size
-            # duringa resize dragging
+            # during a resize dragging
             for i, point in enumerate(self.RealPoints):
                 if not (i == 0 and self.StartConnected) and not (i == len(self.Points) - 1 and self.EndConnected):
                     point[0] = point[0] * width / float(max(lastwidth, 1))
@@ -2093,10 +2179,12 @@
     # Draws the wire lines and points
     def Draw(self, dc):
         Graphic_Element.Draw(self, dc)
-        if self.Valid:
+        if not self.Valid:
+            dc.SetPen(wx.RED_PEN)
+        elif isinstance(self.Value, BooleanType) and self.Value:
+            dc.SetPen(wx.GREEN_PEN)
+        else:
             dc.SetPen(wx.BLACK_PEN)
-        else:
-            dc.SetPen(wx.RED_PEN)
         dc.SetBrush(wx.BLACK_BRUSH)
         # Draw the start and end points if they are not connected or the mouse is over them
         if len(self.Points) > 0 and (not self.StartConnected or self.OverStart):
@@ -2107,12 +2195,30 @@
         dc.DrawLines(self.Points)
         dc.DrawPoint(self.Points[-1].x, self.Points[-1].y)
         # Draw the segment selected in red
-        if self.SelectedSegment != None:
+        if self.SelectedSegment is not None:
             dc.SetPen(wx.RED_PEN)
             dc.DrawLine(self.Points[self.SelectedSegment].x, self.Points[self.SelectedSegment].y,
                         self.Points[self.SelectedSegment + 1].x, self.Points[self.SelectedSegment + 1].y)
             if self.SelectedSegment == len(self.Segments) - 1:
                 dc.DrawPoint(self.Points[-1].x, self.Points[-1].y)
+        if self.Value is not None and not isinstance(self.Value, BooleanType):
+            dc.SetFont(self.Font)
+            dc.SetTextForeground(wx.NamedColour("purple"))
+            width, height = self.ValueSize
+            if self.BoundingBox[2] > width * 4 or self.BoundingBox[3] > height * 4:
+                x = self.Points[0].x + width * self.StartPoint[1][0] / 2
+                y = self.Points[0].y + height * (self.StartPoint[1][1] - 1) / 2
+                dc.DrawText(self.Value, x, y)
+                x = self.Points[-1].x + width * self.EndPoint[1][0] / 2
+                y = self.Points[-1].y + height * (self.EndPoint[1][1] - 1) / 2
+                dc.DrawText(self.Value, x, y)
+            else:
+                middle = len(self.Segments) / 2 + len(self.Segments) % 2 - 1
+                x = (self.Points[middle].x + self.Points[middle + 1].x - width) / 2
+                y = (self.Points[middle].y + self.Points[middle + 1].y - height) / 2
+                dc.DrawText(self.Value, x, y)
+            dc.SetFont(self.Parent.GetFont())
+            dc.SetTextForeground(wx.BLACK)
 
 
 #-------------------------------------------------------------------------------
@@ -2283,3 +2389,4 @@
                     y += wordheight + 5
             if y + wordheight > self.Pos.y + self.Size[1] - 10:
                 break
+
--- a/graphics/LD_Objects.py	Fri Sep 05 18:12:23 2008 +0200
+++ b/graphics/LD_Objects.py	Fri Sep 05 18:13:18 2008 +0200
@@ -49,8 +49,10 @@
             connectors = [True]
         self.SetType(type, connectors)
         
-    # Destructor
-    def __del__(self):
+    def Flush(self):
+        for connector in self.Connectors:
+            if connector is not None:
+                connector.Flush()
         self.Connectors = []
     
     # Make a clone of this LD_PowerRail
@@ -376,13 +378,45 @@
         # Create an input and output connector
         self.Input = Connector(self, "", "BOOL", wx.Point(0, self.Size[1] / 2 + 1), WEST)
         self.Output = Connector(self, "", "BOOL", wx.Point(self.Size[0], self.Size[1] / 2 + 1), EAST)
+        self.Value = None
+        self.PreviousValue = False
+        self.PreviousSpreading = False
         self.RefreshNameSize()
         self.RefreshTypeSize()
     
-    # Destructor
-    def __del__(self):
-        self.Input = None
-        self.Output = None
+    def Flush(self):
+        if self.Input is not None:
+            self.Input.Flush()
+            self.Input = None
+        if self.Output is not None:
+            self.Output.Flush()
+            self.Output = None
+    
+    def SetValue(self, value):
+        self.PreviousValue = self.Value
+        self.Value = value
+        if self.Value != self.PreviousValue:
+            self.Refresh()
+            self.SpreadCurrent()
+    
+    def SpreadCurrent(self):
+        spreading = self.Input.ReceivingCurrent()
+        if self.Value is not None:
+            if self.Type == CONTACT_NORMAL:
+                spreading &= self.Value
+            elif self.Type == CONTACT_REVERSE:
+                spreading &= not self.Value
+            elif self.Type == CONTACT_RISING:
+                spreading &= self.Value and not self.PreviousValue
+            elif self.Type == CONTACT_FALLING:
+                spreading &= self.Value and not self.PreviousValue
+            else:
+                spreading = False
+        if spreading and not self.PreviousSpreading:
+            self.Output.SpreadCurrent(True)
+        elif not spreading and self.PreviousSpreading:
+            self.Output.SpreadCurrent(False)
+        self.PreviousSpreading = spreading
     
     # Make a clone of this LD_Contact
     def Clone(self, parent, id = None, pos = None):
@@ -565,7 +599,19 @@
     # Draws contact
     def Draw(self, dc):
         Graphic_Element.Draw(self, dc)
-        dc.SetPen(wx.BLACK_PEN)
+        if self.Value is not None:            
+            if self.Type == CONTACT_NORMAL and self.Value:
+                dc.SetPen(wx.GREEN_PEN)
+            elif self.Type == CONTACT_REVERSE and not self.Value:
+                dc.SetPen(wx.GREEN_PEN)
+            elif self.Type == CONTACT_RISING and self.Value and not self.PreviousValue:
+                dc.SetPen(wx.GREEN_PEN)
+            elif self.Type == CONTACT_FALLING and self.Value and not self.PreviousValue:
+                dc.SetPen(wx.GREEN_PEN)
+            else:
+                dc.SetPen(wx.BLACK_PEN)
+        else:
+            dc.SetPen(wx.BLACK_PEN)
         dc.SetBrush(wx.BLACK_BRUSH)
         
         # Compiling contact type modifier symbol
@@ -628,13 +674,33 @@
         # Create an input and output connector
         self.Input = Connector(self, "", "BOOL", wx.Point(0, self.Size[1] / 2 + 1), WEST)
         self.Output = Connector(self, "", "BOOL", wx.Point(self.Size[0], self.Size[1] / 2 + 1), EAST)
+        self.Value = None
+        self.PreviousValue = False
         self.RefreshNameSize()
         self.RefreshTypeSize()
         
-    # Destructor
-    def __del__(self):
-        self.Input = None
-        self.Output = None
+    def Flush(self):
+        if self.Input is not None:
+            self.Input.Flush()
+            self.Input = None
+        if self.Output is not None:
+            self.Output.Flush()
+            self.Output = None
+    
+    def SetValue(self, value):
+        if self.Value != value:
+            self.Value = value
+            self.Refresh()
+    
+    def SpreadCurrent(self):
+        self.PreviousValue = self.Value
+        self.Value = self.Input.ReceivingCurrent()
+        if self.Value and not self.PreviousValue:
+            self.Output.SpreadCurrent(True)
+        elif not self.Value and self.PreviousValue:
+            self.Output.SpreadCurrent(False)
+        if self.Value != self.PreviousValue:
+            self.Refresh()
     
     # Make a clone of this LD_Coil
     def Clone(self, parent, id = None, pos = None):
@@ -817,7 +883,10 @@
     # Draws coil
     def Draw(self, dc):
         Graphic_Element.Draw(self, dc)
-        dc.SetPen(wx.Pen(wx.BLACK, 2, wx.SOLID))
+        if self.Value is not None and self.Value:
+            dc.SetPen(wx.Pen(wx.GREEN, 2, wx.SOLID))
+        else:
+            dc.SetPen(wx.Pen(wx.BLACK, 2, wx.SOLID))
         dc.SetBrush(wx.TRANSPARENT_BRUSH)
         
         # Compiling coil type modifier symbol 
@@ -846,7 +915,10 @@
             dc.DrawEllipticArc(self.Pos.x, self.Pos.y - int(self.Size[1] * (sqrt(2) - 1.) / 2.) + 1, self.Size[0], int(self.Size[1] * sqrt(2)) - 1, -45, 45)
             # Draw a point to avoid hole in left arc
             if not getattr(dc, "printing", False):
-                dc.SetPen(wx.BLACK_PEN)
+                if self.Value is not None and self.Value:
+                    dc.SetPen(wx.GREEN_PEN)
+                else:
+                    dc.SetPen(wx.BLACK_PEN)
                 dc.DrawPoint(self.Pos.x + 1, self.Pos.y + self.Size[1] / 2 + 1)
             name_size = self.NameSize
             if typetext != "":
--- a/graphics/SFC_Objects.py	Fri Sep 05 18:12:23 2008 +0200
+++ b/graphics/SFC_Objects.py	Fri Sep 05 18:13:18 2008 +0200
@@ -59,11 +59,16 @@
         self.Output = None
         self.Action = None
     
-    # Destructor
-    def __del__(self):
-        self.Input = None
-        self.Output = None
-        self.Action = None
+    def Flush(self):
+        if self.Input is not None:
+            self.Input.Flush()
+            self.Input = None
+        if self.Output is not None:
+            self.Output.Flush()
+            self.Output = None
+        if self.Output is not None:
+            self.Action.Flush()
+            self.Action = None
     
     # Make a clone of this SFC_Step
     def Clone(self, parent, id = None, name = "Step", pos = None):
@@ -518,11 +523,15 @@
         self.SetPriority(priority)
         self.Errors = {}
     
-    # Destructor
-    def __del__(self):
-        self.Input = None
-        self.Output = None
-        if self.Type == "connection":
+    def Flush(self):
+        if self.Input is not None:
+            self.Input.Flush()
+            self.Input = None
+        if self.Output is not None:
+            self.Output.Flush()
+            self.Output = None
+        if self.Type == "connection" and self.Condition is not None:
+            self.Condition.Flush()
             self.Condition = None
     
     # Make a clone of this SFC_Transition
@@ -921,9 +930,12 @@
                 self.Inputs.append(Connector(self, "", None, wx.Point(i * SFC_DEFAULT_SEQUENCE_INTERVAL, 0), NORTH, onlyone = True))
             self.Outputs = [Connector(self, "", None, wx.Point(self.Size[0] / 2, self.Size[1]), SOUTH, onlyone = True)]
     
-    # Destructor
-    def __del__(self):
+    def Flush(self):
+        for input in self.Inputs:
+            input.Flush()
         self.Inputs = []
+        for output in self.Outputs:
+            output.Flush()
         self.Outputs = []
     
     # Make a clone of this SFC_Divergence
@@ -1338,9 +1350,10 @@
         # Create an input and output connector
         self.Input = Connector(self, "", None, wx.Point(self.Size[0] / 2, 0), NORTH, onlyone = True)
         
-    # Destructor
-    def __del__(self):
-        self.Input = None
+    def Flush(self):
+        if self.Input is not None:
+            self.Input.Flush()
+            self.Input = None
     
     # Make a clone of this SFC_Jump
     def Clone(self, parent, id = None, pos = None):
@@ -1564,9 +1577,10 @@
         self.Input = Connector(self, "", None, wx.Point(0, SFC_ACTION_MIN_SIZE[1] / 2), WEST, onlyone = True)
         self.SetActions(actions)
     
-    # Destructor
-    def __del__(self):
-        self.Input = None
+    def Flush(self):
+        if self.Input is not None:
+            self.Input.Flush()
+            self.Input = None
     
     # Make a clone of this SFC_ActionBlock
     def Clone(self, parent, id = None, pos = None):