merge
authormjsousa
Tue, 08 Jul 2014 18:01:33 +0100
changeset 1471 3eda8d8f622d
parent 1424 0f2ced10db48 (diff)
parent 1470 f65ab5ff91d1 (current diff)
child 1472 144cf3af992c
merge
--- a/PLCControler.py	Fri Jun 06 18:30:49 2014 +0100
+++ b/PLCControler.py	Tue Jul 08 18:01:33 2014 +0100
@@ -1467,7 +1467,7 @@
                 else:
                     derived_type = PLCOpenParser.CreateElement("derived", "dataType")
                     derived_type.setname(return_type)
-                    return_type.setcontent(derived_type)
+                    return_type_obj.setcontent(derived_type)
 
     def UpdateProjectUsedPous(self, old_name, new_name):
         if self.Project is not None:
--- a/PLCGenerator.py	Fri Jun 06 18:30:49 2014 +0100
+++ b/PLCGenerator.py	Tue Jul 08 18:01:33 2014 +0100
@@ -2,7 +2,7 @@
 # -*- coding: utf-8 -*-
 
 #This file is part of PLCOpenEditor, a library implementing an IEC 61131-3 editor
-#based on the plcopen standard. 
+#based on the plcopen standard.
 #
 #Copyright (C) 2007: Edouard TISSERANT and Laurent BESSARD
 #
@@ -27,14 +27,14 @@
 from types import *
 import re
 
-# Dictionary associating PLCOpen variable categories to the corresponding 
+# Dictionary associating PLCOpen variable categories to the corresponding
 # IEC 61131-3 variable categories
-varTypeNames = {"localVars" : "VAR", "tempVars" : "VAR_TEMP", "inputVars" : "VAR_INPUT", 
+varTypeNames = {"localVars" : "VAR", "tempVars" : "VAR_TEMP", "inputVars" : "VAR_INPUT",
                 "outputVars" : "VAR_OUTPUT", "inOutVars" : "VAR_IN_OUT", "externalVars" : "VAR_EXTERNAL",
                 "globalVars" : "VAR_GLOBAL", "accessVars" : "VAR_ACCESS"}
 
 
-# Dictionary associating PLCOpen POU categories to the corresponding 
+# Dictionary associating PLCOpen POU categories to the corresponding
 # IEC 61131-3 POU categories
 pouTypeNames = {"function" : "FUNCTION", "functionBlock" : "FUNCTION_BLOCK", "program" : "PROGRAM"}
 
@@ -125,16 +125,16 @@
         if not self.DatatypeComputed.get(datatype_name, True):
             # If not mark data type as computed
             self.DatatypeComputed[datatype_name] = True
-            
+
             # Getting datatype model from project
             datatype = self.Project.getdataType(datatype_name)
             tagname = self.Controler.ComputeDataTypeName(datatype.getname())
-            datatype_def = [("  ", ()), 
+            datatype_def = [("  ", ()),
                             (datatype.getname(), (tagname, "name")),
                             (" : ", ())]
             basetype_content = datatype.baseType.getcontent()
             basetype_content_type = basetype_content.getLocalTag()
-            # Data type derived directly from a user defined type 
+            # Data type derived directly from a user defined type
             if basetype_content_type == "derived":
                 basetype_name = basetype_content.getname()
                 self.GenerateDataType(basetype_name)
@@ -143,11 +143,11 @@
             elif basetype_content_type in ["subrangeSigned", "subrangeUnsigned"]:
                 base_type = basetype_content.baseType.getcontent()
                 base_type_type = base_type.getLocalTag()
-                # Subrange derived directly from a user defined type 
+                # Subrange derived directly from a user defined type
                 if base_type_type == "derived":
                     basetype_name = base_type_type.getname()
                     self.GenerateDataType(basetype_name)
-                # Subrange derived directly from an elementary type 
+                # Subrange derived directly from an elementary type
                 else:
                     basetype_name = base_type_type
                 min_value = basetype_content.range.getlower()
@@ -162,7 +162,7 @@
             elif basetype_content_type == "enum":
                 values = [[(value.getname(), (tagname, "value", i))]
                           for i, value in enumerate(
-                              basetype_content.xpath("ppx:values/ppx:value", 
+                              basetype_content.xpath("ppx:values/ppx:value",
                                   namespaces=PLCOpenParser.NSMAP))]
                 datatype_def += [("(", ())]
                 datatype_def += JoinList([(", ", ())], values)
@@ -171,16 +171,16 @@
             elif basetype_content_type == "array":
                 base_type = basetype_content.baseType.getcontent()
                 base_type_type = base_type.getLocalTag()
-                # Array derived directly from a user defined type 
+                # Array derived directly from a user defined type
                 if base_type_type == "derived":
                     basetype_name = base_type.getname()
                     self.GenerateDataType(basetype_name)
-                # Array derived directly from an elementary type 
+                # Array derived directly from an elementary type
                 else:
                     basetype_name = base_type_type.upper()
                 dimensions = [[("%s"%dimension.getlower(), (tagname, "range", i, "lower")),
                                ("..", ()),
-                               ("%s"%dimension.getupper(), (tagname, "range", i, "upper"))] 
+                               ("%s"%dimension.getupper(), (tagname, "range", i, "upper"))]
                               for i, dimension in enumerate(basetype_content.getdimension())]
                 datatype_def += [("ARRAY [", ())]
                 datatype_def += JoinList([(",", ())], dimensions)
@@ -192,24 +192,24 @@
                 for i, element in enumerate(basetype_content.getvariable()):
                     element_type = element.type.getcontent()
                     element_type_type = element_type.getLocalTag()
-                    # Structure element derived directly from a user defined type 
+                    # Structure element derived directly from a user defined type
                     if element_type_type == "derived":
                         elementtype_name = element_type.getname()
                         self.GenerateDataType(elementtype_name)
                     elif element_type_type == "array":
                         base_type = element_type.baseType.getcontent()
                         base_type_type = base_type.getLocalTag()
-                        # Array derived directly from a user defined type 
+                        # Array derived directly from a user defined type
                         if base_type_type == "derived":
                             basetype_name = base_type.getname()
                             self.GenerateDataType(basetype_name)
-                        # Array derived directly from an elementary type 
+                        # Array derived directly from an elementary type
                         else:
                             basetype_name = base_type_type.upper()
                         dimensions = ["%s..%s" % (dimension.getlower(), dimension.getupper())
                                       for dimension in element_type.getdimension()]
                         elementtype_name = "ARRAY [%s] OF %s" % (",".join(dimensions), basetype_name)
-                    # Structure element derived directly from an elementary type 
+                    # Structure element derived directly from an elementary type
                     else:
                         elementtype_name = element_type_type.upper()
                     element_text = [("\n    ", ()),
@@ -224,7 +224,7 @@
                 datatype_def += [("STRUCT", ())]
                 datatype_def += JoinList([("", ())], elements)
                 datatype_def += [("\n  END_STRUCT", ())]
-            # Data type derived directly from a elementary type 
+            # Data type derived directly from a elementary type
             else:
                 datatype_def += [(basetype_content_type.upper(), (tagname, "base"))]
             # Data type has an initial value
@@ -240,7 +240,7 @@
         if not self.PouComputed.get(pou_name, True):
             # If not mark POU as computed
             self.PouComputed[pou_name] = True
-            
+
             # Getting POU model from project
             pou = self.Project.getpou(pou_name)
             pou_type = pou.getpouType()
@@ -252,14 +252,14 @@
                 self.Program += program
             else:
                 raise PLCGenException, _("Undefined pou type \"%s\"")%pou_type
-    
+
     # Generate a POU defined and used in text
     def GeneratePouProgramInText(self, text):
         for pou_name in self.PouComputed.keys():
             model = re.compile("(?:^|[^0-9^A-Z])%s(?:$|[^0-9^A-Z])"%pou_name.upper())
             if model.search(text) is not None:
                 self.GeneratePouProgram(pou_name)
-    
+
     # Generate a configuration from its model
     def GenerateConfiguration(self, configuration):
         tagname = self.Controler.ComputeConfigurationName(configuration.getname())
@@ -267,20 +267,20 @@
                   (configuration.getname(), (tagname, "name")),
                   ("\n", ())]
         var_number = 0
-        
+
         varlists = [(varlist, varlist.getvariable()[:]) for varlist in configuration.getglobalVars()]
-        
+
         extra_variables = self.Controler.GetConfigurationExtraVariables()
         extra_global_vars = None
         if len(extra_variables) > 0 and len(varlists) == 0:
             extra_global_vars = PLCOpenParser.CreateElement("globalVars", "interface")
             configuration.setglobalVars([extra_global_vars])
             varlists = [(extra_global_vars, [])]
-            
+
         for variable in extra_variables:
             varlists[-1][0].appendvariable(variable)
             varlists[-1][1].append(variable)
-            
+
         # Generate any global variable in configuration
         for varlist, varlist_variables in varlists:
             variable_type = errorVarTypes.get("VAR_GLOBAL", "var_local")
@@ -301,7 +301,7 @@
                     self.GenerateDataType(var_type)
                 else:
                     var_type = var.gettypeAsText()
-                
+
                 config += [("    ", ()),
                            (var.getname(), (tagname, variable_type, var_number, "name")),
                            (" ", ())]
@@ -321,19 +321,19 @@
                 config += [(";\n", ())]
                 var_number += 1
             config += [("  END_VAR\n", ())]
-        
+
         if extra_global_vars is not None:
             configuration.remove(extra_global_vars)
         else:
             for variable in extra_variables:
                 varlists[-1][0].remove(variable)
-        
+
         # Generate any resource in the configuration
         for resource in configuration.getresource():
             config += self.GenerateResource(resource, configuration.getname())
         config += [("END_CONFIGURATION\n", ())]
         return config
-    
+
     # Generate a resource from its model
     def GenerateResource(self, resource, config_name):
         tagname = self.Controler.ComputeConfigurationResourceName(config_name, resource.getname())
@@ -361,7 +361,7 @@
                     self.GenerateDataType(var_type)
                 else:
                     var_type = var.gettypeAsText()
-                
+
                 resrce += [("      ", ()),
                            (var.getname(), (tagname, variable_type, var_number, "name")),
                            (" ", ())]
@@ -393,7 +393,11 @@
             single = task.getsingle()
             # Single argument if exists
             if single is not None:
-                resrce += [("SINGLE := ", ()),
+                if single[0]=='[' and single[-1]==']' :
+                    SNGLKW = "MULTI"
+                else:
+                    SNGLKW = "SINGLE"
+                resrce += [(SNGLKW + " := ", ()),
                            (single, (tagname, "task", task_number, "single")),
                            (",", ())]
             # Interval argument if exists
@@ -413,7 +417,7 @@
 ##                    resrce += [("%dms"%(interval.microsecond / 1000), (tagname, "task", task_number, "interval", "millisecond"))]
 ##                resrce += [(",", ())]
             # Priority argument
-            resrce += [("PRIORITY := ", ()), 
+            resrce += [("PRIORITY := ", ()),
                        ("%d"%task.getpriority(), (tagname, "task", task_number, "priority")),
                        (");\n", ())]
             task_number += 1
@@ -439,16 +443,16 @@
             instance_number += 1
         resrce += [("  END_RESOURCE\n", ())]
         return resrce
-    
+
     # Generate the entire program for current project
-    def GenerateProgram(self):        
+    def GenerateProgram(self):
         # Find all data types defined
         for datatype in self.Project.getdataTypes():
             self.DatatypeComputed[datatype.getname()] = False
         # Find all data types defined
         for pou in self.Project.getpous():
             self.PouComputed[pou.getname()] = False
-        # Generate data type declaration structure if there is at least one data 
+        # Generate data type declaration structure if there is at least one data
         # type defined
         if len(self.DatatypeComputed) > 0:
             self.Program += [("TYPE\n", ())]
@@ -462,7 +466,7 @@
         # Generate every configurations defined
         for config in self.Project.getconfigurations():
             self.Program += self.GenerateConfiguration(config)
-    
+
     # Return generated program
     def GetGeneratedProgram(self):
         return self.Program
@@ -481,18 +485,18 @@
 [ContactClass, CoilClass, LeftPowerRailClass, RightPowerRailClass] = [
     PLCOpenParser.GetElementClass(instance_name, "ldObjects")
     for instance_name in ["contact", "coil", "leftPowerRail", "rightPowerRail"]]
-[StepClass, TransitionClass, JumpStepClass, 
+[StepClass, TransitionClass, JumpStepClass,
  SelectionConvergenceClass, SelectionDivergenceClass,
  SimultaneousConvergenceClass, SimultaneousDivergenceClass] = [
     PLCOpenParser.GetElementClass(instance_name, "sfcObjects")
-    for instance_name in ["step", "transition", "jumpStep", 
+    for instance_name in ["step", "transition", "jumpStep",
         "selectionConvergence", "selectionDivergence",
         "simultaneousConvergence", "simultaneousDivergence"]]
 TransitionObjClass = PLCOpenParser.GetElementClass("transition", "transitions")
 ActionObjClass = PLCOpenParser.GetElementClass("action", "actions")
 
 class PouProgramGenerator:
-    
+
     # Create a new POU program generator
     def __init__(self, parent, name, type, errors, warnings):
         # Keep Reference to the parent generator
@@ -514,22 +518,22 @@
         self.Program = []
         self.Errors = errors
         self.Warnings = warnings
-    
+
     def GetBlockType(self, type, inputs=None):
         return self.ParentGenerator.Controler.GetBlockType(type, inputs)
-    
+
     def IndentLeft(self):
         if len(self.CurrentIndent) >= 2:
             self.CurrentIndent = self.CurrentIndent[:-2]
-    
+
     def IndentRight(self):
         self.CurrentIndent += "  "
-    
+
     # Generator of unique ID for inline actions
     def GetActionNumber(self):
         self.ActionNumber += 1
         return self.ActionNumber
-    
+
     # Test if a variable has already been defined
     def IsAlreadyDefined(self, name):
         for list_type, option, located, vars in self.Interface:
@@ -537,7 +541,7 @@
                 if name == var_name:
                     return True
         return False
-    
+
     # Return the type of a variable defined in interface
     def GetVariableType(self, name):
         parts = name.split('.')
@@ -569,18 +573,18 @@
                                 current_type = element["Type"]
                                 break
         return current_type
-    
+
     # Return connectors linked by a connection to the given connector
     def GetConnectedConnector(self, connector, body):
         links = connector.getconnections()
         if links is not None and len(links) == 1:
             return self.GetLinkedConnector(links[0], body)
-        return None        
+        return None
 
     def GetLinkedConnector(self, link, body):
         parameter = link.getformalParameter()
         instance = body.getcontentInstance(link.getrefLocalId())
-        if isinstance(instance, (InVariableClass, InOutVariableClass, 
+        if isinstance(instance, (InVariableClass, InOutVariableClass,
              ContinuationClass, ContactClass, CoilClass)):
             return instance.connectionPointOut
         elif isinstance(instance, BlockClass):
@@ -610,13 +614,13 @@
                     if point.x == powerrailposition.x + relposition[0] and point.y == powerrailposition.y + relposition[1]:
                         return outputconnection
         return None
-        
+
     def ExtractRelatedConnections(self, connection):
         for i, related in enumerate(self.RelatedConnections):
             if connection in related:
                 return self.RelatedConnections.pop(i)
         return [connection]
-    
+
     def ComputeInterface(self, pou):
         interface = pou.getinterface()
         if interface is not None:
@@ -626,7 +630,7 @@
             body_content = body.getcontent()
             body_type = body_content.getLocalTag()
             if self.Type == "FUNCTION":
-                returntype_content = interface.getreturnType().getcontent()
+                returntype_content = interface.getreturnType()[0]
                 returntype_content_type = returntype_content.getLocalTag()
                 if returntype_content_type == "derived":
                     self.ReturnType = returntype_content.getname()
@@ -680,7 +684,7 @@
                     self.Interface.append((varTypeNames[varlist_type], option, False, variables))
                 if len(located) > 0:
                     self.Interface.append((varTypeNames[varlist_type], option, True, located))
-    
+
     LITERAL_TYPES = {
         "T": "TIME",
         "D": "DATE",
@@ -699,11 +703,11 @@
         if body_type in ["FBD", "LD", "SFC"]:
             undefined_blocks = []
             for instance in body.getcontentInstances():
-                if isinstance(instance, (InVariableClass, OutVariableClass, 
+                if isinstance(instance, (InVariableClass, OutVariableClass,
                                          InOutVariableClass)):
                     expression = instance.getexpression()
                     var_type = self.GetVariableType(expression)
-                    if (isinstance(pou, TransitionObjClass) 
+                    if (isinstance(pou, TransitionObjClass)
                         and expression == pou.getname()):
                         var_type = "BOOL"
                     elif (not isinstance(pou, (TransitionObjClass, ActionObjClass)) and
@@ -718,7 +722,7 @@
                         parts = expression.split("#")
                         if len(parts) > 1:
                             literal_prefix = parts[0].upper()
-                            var_type = self.LITERAL_TYPES.get(literal_prefix, 
+                            var_type = self.LITERAL_TYPES.get(literal_prefix,
                                                               literal_prefix)
                         elif expression.startswith("'"):
                             var_type = "STRING"
@@ -822,7 +826,7 @@
                     self.TagName = self.ParentGenerator.Controler.ComputePouTransitionName(self.Name, transition.getname())
                     self.ComputeConnectionTypes(transition)
                 self.TagName = previous_tagname
-                
+
     def ComputeBlockInputTypes(self, instance, block_infos, body):
         undefined = {}
         for variable in instance.outputVariables.getvariable():
@@ -883,7 +887,7 @@
         if body_type in ["IL","ST"]:
             text = body_content.getanyText()
             self.ParentGenerator.GeneratePouProgramInText(text.upper())
-            self.Program = [(ReIndentText(text, len(self.CurrentIndent)), 
+            self.Program = [(ReIndentText(text, len(self.CurrentIndent)),
                             (self.TagName, "body", len(self.CurrentIndent)))]
         elif body_type == "SFC":
             self.IndentRight()
@@ -966,7 +970,7 @@
                             self.Program += [(self.CurrentIndent, ())]
                             self.Program += [(instance.getvariable(), coil_info + ("reference",))]
                             self.Program += [(" := ", ())] + expression + [(";\n", ())]
-                        
+
     def FactorizePaths(self, paths):
         same_paths = {}
         uncomputed_index = range(len(paths))
@@ -984,7 +988,7 @@
             if len(elements) > 1:
                 elements_paths = self.FactorizePaths([path for path, num in elements])
                 if len(elements_paths) > 1:
-                    factorized_paths.append([tuple(elements_paths)] + eval(same_path))        
+                    factorized_paths.append([tuple(elements_paths)] + eval(same_path))
                 else:
                     factorized_paths.append(elements_paths + eval(same_path))
                 for path, num in elements:
@@ -1013,7 +1017,7 @@
                 self.ComputedBlocks[block] = True
                 connected_vars = []
                 if not block_infos["extensible"]:
-                    input_connected = dict([("EN", None)] + 
+                    input_connected = dict([("EN", None)] +
                                            [(input_name, None) for input_name in input_names])
                     for variable in input_variables:
                         parameter = variable.getformalParameter()
@@ -1071,7 +1075,7 @@
                             else:
                                 self.Interface[-1][3].append(("ANY", variable_name, None, None))
                             if len(output_variables) > 1 and parameter not in ["", "OUT"]:
-                                vars.append([(parameter, (self.TagName, "block", block.getlocalId(), "output", i)), 
+                                vars.append([(parameter, (self.TagName, "block", block.getlocalId(), "output", i)),
                                              (" => %s"%variable_name, ())])
                             else:
                                 output_info = (self.TagName, "block", block.getlocalId(), "output", i)
@@ -1105,19 +1109,19 @@
                             if expression is not None:
                                 vars.append([(parameter, input_info),
                                              (" := ", ())] + self.ExtractModifier(variable, expression, input_info))
-                self.Program += [(self.CurrentIndent, ()), 
+                self.Program += [(self.CurrentIndent, ()),
                                  (name, (self.TagName, "block", block.getlocalId(), "name")),
                                  ("(", ())]
                 self.Program += JoinList([(", ", ())], vars)
                 self.Program += [(");\n", ())]
-        
+
         if link is not None:
             connectionPoint = link.getposition()[-1]
             output_parameter = link.getformalParameter()
         else:
             connectionPoint = None
             output_parameter = None
-        
+
         output_variable = None
         output_idx = 0
         if output_parameter is not None:
@@ -1130,13 +1134,13 @@
         else:
             for i, variable in enumerate(output_variables):
                 blockPointx, blockPointy = variable.connectionPointOut.getrelPositionXY()
-                if (connectionPoint is None or 
-                    block.getx() + blockPointx == connectionPoint.getx() and 
+                if (connectionPoint is None or
+                    block.getx() + blockPointx == connectionPoint.getx() and
                     block.gety() + blockPointy == connectionPoint.gety()):
                     output_variable = variable
                     output_parameter = variable.getformalParameter()
                     output_idx = i
-        
+
         if output_variable is not None:
             if block_infos["type"] == "function":
                 output_info = (self.TagName, "block", block.getlocalId(), "output", output_idx)
@@ -1149,7 +1153,7 @@
                         output_name = "%s%d_%s"%(type, block.getlocalId(), output_parameter)
                     output_value = [(output_name, output_info)]
                 return self.ExtractModifier(output_variable, output_value, output_info)
-            
+
             if block_infos["type"] == "functionBlock":
                 output_info = (self.TagName, "block", block.getlocalId(), "output", output_idx)
                 output_name = self.ExtractModifier(output_variable, [("%s.%s"%(name, output_parameter), output_info)], output_info)
@@ -1168,7 +1172,7 @@
                         self.Program += output_name
                         self.Program += [(";\n", ())]
                     return [(variable_name, ())]
-                return output_name 
+                return output_name
         if link is not None:
             if output_parameter is None:
                 output_parameter = ""
@@ -1291,7 +1295,7 @@
             elif edge == "falling":
                 return self.AddTrigger("F_TRIG", expression, var_info + ("falling",))
         return expression
-    
+
     def AddTrigger(self, edge, expression, var_info):
         if self.Interface[-1][0] != "VAR" or self.Interface[-1][1] is not None or self.Interface[-1][2]:
             self.Interface.append(("VAR", None, False, []))
@@ -1301,11 +1305,11 @@
             i += 1
             name = "%s%d"%(edge, i)
         self.Interface[-1][3].append((edge, name, None, None))
-        self.Program += [(self.CurrentIndent, ()), (name, var_info), ("(CLK := ", ())] 
+        self.Program += [(self.CurrentIndent, ()), (name, var_info), ("(CLK := ", ())]
         self.Program += expression
         self.Program += [(");\n", ())]
         return [("%s.Q"%name, var_info)]
-    
+
     def ExtractDivergenceInput(self, divergence, pou):
         connectionPointIn = divergence.getconnectionPointIn()
         if connectionPointIn is not None:
@@ -1335,9 +1339,9 @@
         if step_name not in self.SFCNetworks["Steps"].keys():
             if step.getinitialStep():
                 self.InitialSteps.append(step_name)
-            step_infos = {"id" : step.getlocalId(), 
-                          "initial" : step.getinitialStep(), 
-                          "transitions" : [], 
+            step_infos = {"id" : step.getlocalId(),
+                          "initial" : step.getinitialStep(),
+                          "transitions" : [],
                           "actions" : []}
             self.SFCNetworks["Steps"][step_name] = step_infos
             if step.connectionPointIn is not None:
@@ -1365,7 +1369,7 @@
                     if instance in self.SFCNetworks["Transitions"].keys():
                         target_info = (self.TagName, "transition", instance.getlocalId(), "to", step_infos["id"])
                         self.SFCNetworks["Transitions"][instance]["to"].append([(step_name, target_info)])
-    
+
     def GenerateSFCJump(self, jump, pou):
         jump_target = jump.gettargetName()
         if jump.connectionPointIn is not None:
@@ -1393,7 +1397,7 @@
                 if instance in self.SFCNetworks["Transitions"].keys():
                     target_info = (self.TagName, "jump", jump.getlocalId(), "target")
                     self.SFCNetworks["Transitions"][instance]["to"].append([(jump_target, target_info)])
-    
+
     def GenerateSFCStepActions(self, actionBlock, pou):
         connections = actionBlock.connectionPointIn.getconnections()
         if connections is not None and len(connections) == 1:
@@ -1407,8 +1411,8 @@
             if step_name in self.SFCNetworks["Steps"].keys():
                 actions = actionBlock.getactions()
                 for i, action in enumerate(actions):
-                    action_infos = {"id" : actionBlock.getlocalId(), 
-                                    "qualifier" : action["qualifier"], 
+                    action_infos = {"id" : actionBlock.getlocalId(),
+                                    "qualifier" : action["qualifier"],
                                     "content" : action["value"],
                                     "num" : i}
                     if "duration" in action:
@@ -1419,12 +1423,12 @@
                         self.GenerateSFCAction(action["value"], pou)
                     else:
                         action_name = "%s_INLINE%d"%(step_name.upper(), self.GetActionNumber())
-                        self.SFCNetworks["Actions"][action_name] = ([(self.CurrentIndent, ()), 
+                        self.SFCNetworks["Actions"][action_name] = ([(self.CurrentIndent, ()),
                             (action["value"], (self.TagName, "action_block", action_infos["id"], "action", i, "inline")),
                             ("\n", ())], ())
                         action_infos["content"] = action_name
                     self.SFCNetworks["Steps"][step_name]["actions"].append(action_infos)
-    
+
     def GenerateSFCAction(self, action_name, pou):
         if action_name not in self.SFCNetworks["Actions"].keys():
             actionContent = pou.getaction(action_name)
@@ -1435,7 +1439,7 @@
                 self.SFCNetworks["Actions"][action_name] = (self.Program, (self.TagName, "name"))
                 self.Program = []
                 self.TagName = previous_tagname
-    
+
     def GenerateSFCTransition(self, transition, pou):
         if transition not in self.SFCNetworks["Transitions"].keys():
             steps = []
@@ -1457,9 +1461,9 @@
                             steps.extend(self.ExtractConvergenceInputs(step, pou))
                 elif isinstance(instance, SimultaneousConvergenceClass):
                     steps.extend(self.ExtractConvergenceInputs(instance, pou))
-            transition_infos = {"id" : transition.getlocalId(), 
-                                "priority": transition.getpriority(), 
-                                "from": [], 
+            transition_infos = {"id" : transition.getlocalId(),
+                                "priority": transition.getpriority(),
+                                "from": [],
                                 "to" : [],
                                 "content": []}
             self.SFCNetworks["Transitions"][transition] = transition_infos
@@ -1546,7 +1550,7 @@
                 self.ComputeSFCAction(action)
             for transition in step_infos["transitions"]:
                 self.ComputeSFCTransition(transition)
-                
+
     def ComputeSFCAction(self, action_name):
         if action_name in self.SFCNetworks["Actions"].keys():
             action_content, action_info = self.SFCNetworks["Actions"].pop(action_name)
@@ -1555,7 +1559,7 @@
                              (":\n", ())]
             self.Program += action_content
             self.Program += [("%sEND_ACTION\n\n"%self.CurrentIndent, ())]
-    
+
     def ComputeSFCTransition(self, transition):
         if transition in self.SFCNetworks["Transitions"].keys():
             transition_infos = self.SFCNetworks["Transitions"].pop(transition)
@@ -1586,12 +1590,12 @@
             self.Program += [("%sEND_TRANSITION\n\n"%self.CurrentIndent, ())]
             for [(step_name, step_infos)] in transition_infos["to"]:
                 self.ComputeSFCStep(step_name)
-    
+
     def GenerateProgram(self, pou):
         self.ComputeInterface(pou)
         self.ComputeConnectionTypes(pou)
         self.ComputeProgram(pou)
-        
+
         program = [("%s "%self.Type, ()),
                    (self.Name, (self.TagName, "name"))]
         if self.ReturnType is not None:
--- a/ProjectController.py	Fri Jun 06 18:30:49 2014 +0100
+++ b/ProjectController.py	Tue Jul 08 18:01:33 2014 +0100
@@ -440,7 +440,7 @@
         if len(self.Libraries)==0:
             return [],[],()
         self.GetIECProgramsAndVariables()
-        LibIECCflags = '"-I%s" -Wno-unused-function'%os.path.abspath(self.GetIECLibPath())
+        LibIECCflags = '"-I%s/C" -Wno-unused-function'%os.path.abspath(self.GetIECLibPath())
         LocatedCCodeAndFlags=[]
         Extras=[]
         for lib in self.Libraries:
@@ -675,7 +675,7 @@
         # Keep track of generated C files for later use by self.CTNGenerate_C
         self.PLCGeneratedCFiles = C_files
         # compute CFLAGS for plc
-        self.plcCFLAGS = '"-I%s" -Wno-unused-function'%self.ieclib_path
+        self.plcCFLAGS = '"-I%s/C" -Wno-unused-function'%self.ieclib_path
         return True
 
     def GetBuilder(self):
--- a/controls/VariablePanel.py	Fri Jun 06 18:30:49 2014 +0100
+++ b/controls/VariablePanel.py	Tue Jul 08 18:01:33 2014 +0100
@@ -307,13 +307,22 @@
                         self.ParentWindow.SaveValues()
             elif (element_type not in ["config", "resource", "function"] and values[1] == "Global" and
                   self.ParentWindow.Filter in ["All", "Interface", "External"] or
-                  element_type != "function" and values[1] == "location"):
-                if values[1] == "location":
+                  element_type != "function" and values[1] in ["location", "NamedConstant"]):
+                if values[1] in  ["location","NamedConstant"]:
                     var_name = values[3]
                 else:
                     var_name = values[0]
                 tagname = self.ParentWindow.GetTagName()
-                if var_name.upper() in [name.upper()
+                dlg = wx.TextEntryDialog(
+                    self.ParentWindow.ParentWindow.ParentWindow,
+                    _("Confirm or change variable name"),
+                    'Variable Drop', var_name)
+                dlg.SetValue(var_name)
+                var_name = dlg.GetValue() if dlg.ShowModal() == wx.ID_OK else None
+                dlg.Destroy()
+                if var_name is None:
+                    return
+                elif var_name.upper() in [name.upper()
                         for name in self.ParentWindow.Controler.\
                             GetProjectPouNames(self.ParentWindow.Debug)]:
                     message = _("\"%s\" pou already exists!")%var_name
@@ -323,6 +332,7 @@
                     var_infos = self.ParentWindow.DefaultValue.copy()
                     var_infos.Name = var_name
                     var_infos.Type = values[2]
+                    var_infos.Documentation = values[4]
                     if values[1] == "location":
                         location = values[0]
                         if not location.startswith("%"):
@@ -360,12 +370,20 @@
                             else:
                                 var_infos.Class = "Global"
                             var_infos.Location = location
+                    elif values[1] == "NamedConstant":
+                        if element_type in ["functionBlock","program"]:
+                            var_infos.Class = "Local"
+                            var_infos.InitialValue = values[0]
+                        else :
+                            return
                     else:
                         var_infos.Class = "External"
                     var_infos.Number = len(self.ParentWindow.Values)
                     self.ParentWindow.Values.append(var_infos)
                     self.ParentWindow.SaveValues()
                     self.ParentWindow.RefreshValues()
+                else:
+                    message = _("\"%s\" element for this pou already exists!")%var_name
 
         if message is not None:
             wx.CallAfter(self.ShowMessage, message)
@@ -559,6 +577,8 @@
                 self.Values.append(row_content)
                 new_row = self.Table.GetNumberRows()
             self.SaveValues()
+            if self.ElementType == "resource":
+                self.ParentWindow.RefreshView(variablepanel = False)
             self.RefreshValues()
             return new_row
         setattr(self.VariablesGrid, "_AddRow", _AddVariable)
--- a/dialogs/PouDialog.py	Fri Jun 06 18:30:49 2014 +0100
+++ b/dialogs/PouDialog.py	Tue Jul 08 18:01:33 2014 +0100
@@ -2,7 +2,7 @@
 # -*- coding: utf-8 -*-
 
 #This file is part of PLCOpenEditor, a library implementing an IEC 61131-3 editor
-#based on the plcopen standard. 
+#based on the plcopen standard.
 #
 #Copyright (C) 2012: Edouard TISSERANT and Laurent BESSARD
 #
@@ -34,54 +34,56 @@
 def GetPouLanguages():
     _ = lambda x : x
     return [_("IL"), _("ST"), _("LD"), _("FBD"), _("SFC")]
-POU_LANGUAGES_DICT = dict([(_(language), language) for language in GetPouLanguages()])
 
 class PouDialog(wx.Dialog):
-    
+
+    POU_LANGUAGES = GetPouLanguages()
+    POU_LANGUAGES_DICT = dict([(_(language), language) for language in POU_LANGUAGES])
+
     def __init__(self, parent, pou_type = None):
         wx.Dialog.__init__(self, id=-1, parent=parent,
-              name='PouDialog', title=_('Create a new POU'), 
+              name='PouDialog', title=_('Create a new POU'),
               size=wx.Size(300, 200), style=wx.DEFAULT_DIALOG_STYLE)
         self.SetClientSize(wx.Size(300, 200))
-        
+
         main_sizer = wx.FlexGridSizer(cols=1, hgap=0, rows=2, vgap=10)
         main_sizer.AddGrowableCol(0)
         main_sizer.AddGrowableRow(0)
-        
+
         infos_sizer = wx.FlexGridSizer(cols=2, hgap=5, rows=3, vgap=15)
         infos_sizer.AddGrowableCol(1)
-        main_sizer.AddSizer(infos_sizer, border=20, 
+        main_sizer.AddSizer(infos_sizer, border=20,
               flag=wx.GROW|wx.TOP|wx.LEFT|wx.RIGHT)
-        
+
         pouname_label = wx.StaticText(self, label=_('POU Name:'))
-        infos_sizer.AddWindow(pouname_label, border=4, 
+        infos_sizer.AddWindow(pouname_label, border=4,
               flag=wx.ALIGN_CENTER_VERTICAL|wx.TOP)
-        
+
         self.PouName = wx.TextCtrl(self)
         infos_sizer.AddWindow(self.PouName, flag=wx.GROW)
-        
+
         poutype_label = wx.StaticText(self, label=_('POU Type:'))
-        infos_sizer.AddWindow(poutype_label, border=4, 
+        infos_sizer.AddWindow(poutype_label, border=4,
               flag=wx.ALIGN_CENTER_VERTICAL|wx.TOP)
-        
+
         self.PouType = wx.ComboBox(self, style=wx.CB_READONLY)
         self.Bind(wx.EVT_COMBOBOX, self.OnTypeChanged, self.PouType)
         infos_sizer.AddWindow(self.PouType, flag=wx.GROW)
-        
+
         language_label = wx.StaticText(self, label=_('Language:'))
-        infos_sizer.AddWindow(language_label, border=4, 
+        infos_sizer.AddWindow(language_label, border=4,
               flag=wx.ALIGN_CENTER_VERTICAL|wx.TOP)
-        
+
         self.Language = wx.ComboBox(self, style=wx.CB_READONLY)
         infos_sizer.AddWindow(self.Language, flag=wx.GROW)
-        
+
         button_sizer = self.CreateButtonSizer(wx.OK|wx.CANCEL|wx.CENTRE)
         self.Bind(wx.EVT_BUTTON, self.OnOK, button_sizer.GetAffirmativeButton())
-        main_sizer.AddSizer(button_sizer, border=20, 
+        main_sizer.AddSizer(button_sizer, border=20,
               flag=wx.ALIGN_RIGHT|wx.BOTTOM|wx.LEFT|wx.RIGHT)
-            
+
         self.SetSizer(main_sizer)
-        
+
         for option in GetPouTypes():
             self.PouType.Append(_(option))
         if pou_type is not None:
@@ -110,7 +112,7 @@
                 elif i == len(error) - 1:
                     text += _(" and %s")%item
                 else:
-                    text += _(", %s")%item 
+                    text += _(", %s")%item
             message = _("Form isn't complete. %s must be filled!") % text
         elif not TestIdentifier(pou_name):
             message = _("\"%s\" is not a valid identifier!") % pou_name
@@ -136,9 +138,9 @@
             self.EndModal(wx.ID_OK)
 
     def RefreshLanguage(self):
-        selection = POU_LANGUAGES_DICT.get(self.Language.GetStringSelection(), "")
+        selection = self.POU_LANGUAGES_DICT.get(self.Language.GetStringSelection(), "")
         self.Language.Clear()
-        for language in GetPouLanguages():
+        for language in self.POU_LANGUAGES:
             if language != "SFC" or POU_TYPES_DICT[self.PouType.GetStringSelection()] != "function":
                 self.Language.Append(_(language))
         if self.Language.FindString(_(selection)) != wx.NOT_FOUND:
@@ -162,10 +164,10 @@
                 self.PouType.SetStringSelection(_(value))
             elif item == "language":
                 self.Language.SetStringSelection(_(value))
-                
+
     def GetValues(self):
         values = {}
         values["pouName"] = self.PouName.GetValue()
         values["pouType"] = POU_TYPES_DICT[self.PouType.GetStringSelection()]
-        values["language"] = POU_LANGUAGES_DICT[self.Language.GetStringSelection()]
+        values["language"] = self.POU_LANGUAGES_DICT[self.Language.GetStringSelection()]
         return values
--- a/editors/ResourceEditor.py	Fri Jun 06 18:30:49 2014 +0100
+++ b/editors/ResourceEditor.py	Tue Jul 08 18:01:33 2014 +0100
@@ -2,7 +2,7 @@
 # -*- coding: utf-8 -*-
 
 #This file is part of PLCOpenEditor, a library implementing an IEC 61131-3 editor
-#based on the plcopen standard. 
+#based on the plcopen standard.
 #
 #Copyright (C) 2007: Edouard TISSERANT and Laurent BESSARD
 #
@@ -36,25 +36,25 @@
 #                          Configuration Editor class
 #-------------------------------------------------------------------------------
 
-[ID_CONFIGURATIONEDITOR, 
+[ID_CONFIGURATIONEDITOR,
 ] = [wx.NewId() for _init_ctrls in range(1)]
 
 class ConfigurationEditor(EditorPanel):
-    
+
     ID = ID_CONFIGURATIONEDITOR
     VARIABLE_PANEL_TYPE = "config"
-    
+
     def GetBufferState(self):
         return self.Controler.GetBufferState()
-        
+
     def Undo(self):
         self.Controler.LoadPrevious()
         self.ParentWindow.CloseTabsWithoutModel()
-            
+
     def Redo(self):
         self.Controler.LoadNext()
         self.ParentWindow.CloseTabsWithoutModel()
-    
+
     def HasNoModel(self):
         return self.Controler.GetEditedElement(self.TagName) is None
 
@@ -72,12 +72,18 @@
     return [_("Interrupt"), _("Cyclic")]
 TASKTRIGGERINGOPTIONS_DICT = dict([(_(option), option) for option in GetTaskTriggeringOptions()])
 
+SingleCellEditor = lambda *x : wx.grid.GridCellChoiceEditor()
+
+def CheckSingle(single, varlist):
+    return single in varlist
+
+
 def GetInstancesTableColnames():
     _ = lambda x : x
     return [_("Name"), _("Type"), _("Task")]
 
 class ResourceTable(CustomTable):
-    
+
     """
     A custom wx.grid.Grid Table using user supplied data
     """
@@ -86,16 +92,16 @@
         CustomTable.__init__(self, parent, data, colnames)
         self.ColAlignements = []
         self.ColSizes = []
-        
+
     def GetColAlignements(self):
         return self.ColAlignements
-    
+
     def SetColAlignements(self, list):
         self.ColAlignements = list
 
     def GetColSizes(self):
         return self.ColSizes
-    
+
     def SetColSizes(self, list):
         self.ColSizes = list
 
@@ -106,14 +112,14 @@
             if colname == "Triggering":
                 return _(value)
             return value
-        
+
     def SetValue(self, row, col, value):
         if col < len(self.colnames):
             colname = self.GetColLabelValue(col, False)
             if colname == "Triggering":
                 value = TASKTRIGGERINGOPTIONS_DICT[value]
             self.data[row][colname] = value
-    
+
     def _updateColAttrs(self, grid):
         """
         wx.grid.Grid -> update the column attributes to add the
@@ -121,13 +127,13 @@
 
         Otherwise default to the default renderer.
         """
-        
+
         for col in range(self.GetNumberCols()):
             attr = wx.grid.GridCellAttr()
             attr.SetAlignment(self.ColAlignements[col], wx.ALIGN_CENTRE)
             grid.SetColAttr(col, attr)
             grid.SetColSize(col, self.ColSizes[col])
-        
+
         for row in range(self.GetNumberRows()):
             row_highlights = self.Highlights.get(row, {})
             for col in range(self.GetNumberCols()):
@@ -148,10 +154,13 @@
                     if interval != "" and IEC_TIME_MODEL.match(interval.upper()) is None:
                         error = True
                 elif colname == "Single":
-                    editor = wx.grid.GridCellChoiceEditor()
+                    editor = SingleCellEditor(self,colname)
                     editor.SetParameters(self.Parent.VariableList)
                     if self.GetValueByName(row, "Triggering") != "Interrupt":
                         grid.SetReadOnly(row, col, True)
+                    single = self.GetValueByName(row, colname)
+                    if single != "" and not CheckSingle(single,self.Parent.VariableList):
+                        error = True
                 elif colname == "Triggering":
                     editor = wx.grid.GridCellChoiceEditor()
                     editor.SetParameters(",".join(map(_, GetTaskTriggeringOptions())))
@@ -164,10 +173,10 @@
                 elif colname == "Task":
                     editor = wx.grid.GridCellChoiceEditor()
                     editor.SetParameters(self.Parent.TaskList)
-                    
+
                 grid.SetCellEditor(row, col, editor)
                 grid.SetCellRenderer(row, col, renderer)
-                
+
                 if error:
                     highlight_colours = ERROR_HIGHLIGHT
                 else:
@@ -176,7 +185,7 @@
                 grid.SetCellTextColour(row, col, highlight_colours[1])
             self.ResizeRow(grid, row)
 
-    
+
 #-------------------------------------------------------------------------------
 #                        Highlights showing functions
 #-------------------------------------------------------------------------------
@@ -185,7 +194,7 @@
         row_highlights = self.Highlights.setdefault(infos[0], {})
         col_highlights = row_highlights.setdefault(infos[1], [])
         col_highlights.append(highlight_type)
-    
+
     def ClearHighlights(self, highlight_type=None):
         if highlight_type is None:
             self.Highlights = {}
@@ -201,84 +210,84 @@
 
 
 class ResourceEditor(EditorPanel):
-    
+
     VARIABLE_PANEL_TYPE = "resource"
 
     def _init_Editor(self, parent):
         self.Editor = wx.Panel(parent, style=wx.SUNKEN_BORDER|wx.TAB_TRAVERSAL)
-        
+
         main_sizer = wx.FlexGridSizer(cols=1, hgap=0, rows=2, vgap=5)
         main_sizer.AddGrowableCol(0)
         main_sizer.AddGrowableRow(0)
         main_sizer.AddGrowableRow(1)
-        
+
         tasks_sizer = wx.FlexGridSizer(cols=1, hgap=0, rows=2, vgap=5)
         tasks_sizer.AddGrowableCol(0)
         tasks_sizer.AddGrowableRow(1)
-        main_sizer.AddSizer(tasks_sizer, border=5, 
+        main_sizer.AddSizer(tasks_sizer, border=5,
               flag=wx.GROW|wx.TOP|wx.LEFT|wx.RIGHT)
-        
+
         tasks_buttons_sizer = wx.FlexGridSizer(cols=5, hgap=5, rows=1, vgap=0)
         tasks_buttons_sizer.AddGrowableCol(0)
         tasks_buttons_sizer.AddGrowableRow(0)
         tasks_sizer.AddSizer(tasks_buttons_sizer, flag=wx.GROW)
-        
+
         tasks_label = wx.StaticText(self.Editor, label=_(u'Tasks:'))
         tasks_buttons_sizer.AddWindow(tasks_label, flag=wx.ALIGN_BOTTOM)
-        
+
         for name, bitmap, help in [
                 ("AddTaskButton", "add_element", _("Add task")),
                 ("DeleteTaskButton", "remove_element", _("Remove task")),
                 ("UpTaskButton", "up", _("Move task up")),
                 ("DownTaskButton", "down", _("Move task down"))]:
-            button = wx.lib.buttons.GenBitmapButton(self.Editor, 
+            button = wx.lib.buttons.GenBitmapButton(self.Editor,
                   bitmap=GetBitmap(bitmap), size=wx.Size(28, 28), style=wx.NO_BORDER)
             button.SetToolTipString(help)
             setattr(self, name, button)
             tasks_buttons_sizer.AddWindow(button)
-        
+
         self.TasksGrid = CustomGrid(self.Editor, style=wx.VSCROLL)
         self.TasksGrid.Bind(wx.grid.EVT_GRID_CELL_CHANGE, self.OnTasksGridCellChange)
         tasks_sizer.AddWindow(self.TasksGrid, flag=wx.GROW)
-        
+
         instances_sizer = wx.FlexGridSizer(cols=1, hgap=0, rows=2, vgap=5)
         instances_sizer.AddGrowableCol(0)
         instances_sizer.AddGrowableRow(1)
-        main_sizer.AddSizer(instances_sizer, border=5, 
+        main_sizer.AddSizer(instances_sizer, border=5,
               flag=wx.GROW|wx.BOTTOM|wx.LEFT|wx.RIGHT)
-        
+
         instances_buttons_sizer = wx.FlexGridSizer(cols=5, hgap=5, rows=1, vgap=0)
         instances_buttons_sizer.AddGrowableCol(0)
         instances_buttons_sizer.AddGrowableRow(0)
         instances_sizer.AddSizer(instances_buttons_sizer, flag=wx.GROW)
-        
+
         instances_label = wx.StaticText(self.Editor, label=_(u'Instances:'))
         instances_buttons_sizer.AddWindow(instances_label, flag=wx.ALIGN_BOTTOM)
-        
+
         for name, bitmap, help in [
                 ("AddInstanceButton", "add_element", _("Add instance")),
                 ("DeleteInstanceButton", "remove_element", _("Remove instance")),
                 ("UpInstanceButton", "up", _("Move instance up")),
                 ("DownInstanceButton", "down", _("Move instance down"))]:
-            button = wx.lib.buttons.GenBitmapButton(self.Editor, 
+            button = wx.lib.buttons.GenBitmapButton(self.Editor,
                   bitmap=GetBitmap(bitmap), size=wx.Size(28, 28), style=wx.NO_BORDER)
             button.SetToolTipString(help)
             setattr(self, name, button)
             instances_buttons_sizer.AddWindow(button)
-        
+
         self.InstancesGrid = CustomGrid(self.Editor, style=wx.VSCROLL)
-        self.InstancesGrid.Bind(wx.grid.EVT_GRID_CELL_CHANGE, 
+        self.InstancesGrid.Bind(wx.grid.EVT_GRID_CELL_CHANGE,
               self.OnInstancesGridCellChange)
         instances_sizer.AddWindow(self.InstancesGrid, flag=wx.GROW)
-        
+
         self.Editor.SetSizer(main_sizer)
-        
+
     def __init__(self, parent, tagname, window, controler):
         EditorPanel.__init__(self, parent, tagname, window, controler)
-        
+
         self.RefreshHighlightsTimer = wx.Timer(self, -1)
         self.Bind(wx.EVT_TIMER, self.OnRefreshHighlightsTimer, self.RefreshHighlightsTimer)
-        
+
         self.TasksDefaultValue = {"Name" : "", "Triggering" : "", "Single" : "", "Interval" : "", "Priority" : 0}
         self.TasksTable = ResourceTable(self, [], GetTasksTableColnames())
         self.TasksTable.SetColAlignements([wx.ALIGN_LEFT, wx.ALIGN_LEFT, wx.ALIGN_LEFT, wx.ALIGN_RIGHT, wx.ALIGN_RIGHT])
@@ -288,20 +297,20 @@
                                    "Delete": self.DeleteTaskButton,
                                    "Up": self.UpTaskButton,
                                    "Down": self.DownTaskButton})
-        
+
         def _AddTask(new_row):
             self.TasksTable.InsertRow(new_row, self.TasksDefaultValue.copy())
             self.RefreshModel()
             self.RefreshView()
             return new_row
         setattr(self.TasksGrid, "_AddRow", _AddTask)
-        
+
         def _DeleteTask(row):
             self.TasksTable.RemoveRow(row)
             self.RefreshModel()
             self.RefreshView()
         setattr(self.TasksGrid, "_DeleteRow", _DeleteTask)
-        
+
         def _MoveTask(row, move):
             new_row = self.TasksTable.MoveRow(row, move)
             if new_row != row:
@@ -309,11 +318,11 @@
                 self.RefreshView()
             return new_row
         setattr(self.TasksGrid, "_MoveRow", _MoveTask)
-        
+
         self.TasksGrid.SetRowLabelSize(0)
         self.TasksTable.ResetView(self.TasksGrid)
         self.TasksGrid.RefreshButtons()
-        
+
         self.InstancesDefaultValue = {"Name" : "", "Type" : "", "Task" : ""}
         self.InstancesTable = ResourceTable(self, [], GetInstancesTableColnames())
         self.InstancesTable.SetColAlignements([wx.ALIGN_LEFT, wx.ALIGN_LEFT, wx.ALIGN_LEFT])
@@ -323,48 +332,48 @@
                                        "Delete": self.DeleteInstanceButton,
                                        "Up": self.UpInstanceButton,
                                        "Down": self.DownInstanceButton})
-        
+
         def _AddInstance(new_row):
             self.InstancesTable.InsertRow(new_row, self.InstancesDefaultValue.copy())
             self.RefreshModel()
             self.RefreshView()
             return new_row
         setattr(self.InstancesGrid, "_AddRow", _AddInstance)
-        
+
         def _DeleteInstance(row):
             self.InstancesTable.RemoveRow(row)
             self.RefreshModel()
             self.RefreshView()
         setattr(self.InstancesGrid, "_DeleteRow", _DeleteInstance)
-        
+
         def _MoveInstance(row, move):
             new_row = max(0, min(row + move, self.InstancesTable.GetNumberRows() - 1))
             if new_row != row:
                 if self.InstancesTable.GetValueByName(row, "Task") != self.InstancesTable.GetValueByName(new_row, "Task"):
-                    return row 
+                    return row
                 self.InstancesTable.MoveRow(row, move)
                 self.RefreshModel()
                 self.RefreshView()
             return new_row
         setattr(self.InstancesGrid, "_MoveRow", _MoveInstance)
-        
+
         def _RefreshInstanceButtons():
             if self:
                 rows = self.InstancesTable.GetNumberRows()
                 row = self.InstancesGrid.GetGridCursorRow()
                 self.DeleteInstanceButton.Enable(rows > 0)
-                self.UpInstanceButton.Enable(row > 0 and 
+                self.UpInstanceButton.Enable(row > 0 and
                     self.InstancesTable.GetValueByName(row, "Task") == self.InstancesTable.GetValueByName(row - 1, "Task"))
-                self.DownInstanceButton.Enable(0 <= row < rows - 1 and 
+                self.DownInstanceButton.Enable(0 <= row < rows - 1 and
                     self.InstancesTable.GetValueByName(row, "Task") == self.InstancesTable.GetValueByName(row + 1, "Task"))
         setattr(self.InstancesGrid, "RefreshButtons", _RefreshInstanceButtons)
-        
+
         self.InstancesGrid.SetRowLabelSize(0)
         self.InstancesTable.ResetView(self.InstancesGrid)
         self.InstancesGrid.RefreshButtons()
-        
+
         self.TasksGrid.SetFocus()
-        
+
     def __del__(self):
         self.RefreshHighlightsTimer.Stop()
 
@@ -383,11 +392,11 @@
         self.VariableList = ""
         for variable in self.Controler.GetEditedResourceVariables(self.TagName):
             self.VariableList += ",%s"%variable
-        
+
     def RefreshModel(self):
         self.Controler.SetEditedResourceInfos(self.TagName, self.TasksTable.GetData(), self.InstancesTable.GetData())
         self.RefreshBuffer()
-        
+
     # Buffer the last model state
     def RefreshBuffer(self):
         self.Controler.BufferProject()
@@ -397,21 +406,21 @@
 
     def GetBufferState(self):
         return self.Controler.GetBufferState()
-        
+
     def Undo(self):
         self.Controler.LoadPrevious()
         self.ParentWindow.CloseTabsWithoutModel()
-            
+
     def Redo(self):
         self.Controler.LoadNext()
         self.ParentWindow.CloseTabsWithoutModel()
-    
+
     def HasNoModel(self):
         return self.Controler.GetEditedElement(self.TagName) is None
 
     def RefreshView(self, variablepanel=True):
         EditorPanel.RefreshView(self, variablepanel)
-        
+
         tasks, instances = self.Controler.GetEditedResourceInfos(self.TagName)
         self.TasksTable.SetData(tasks)
         self.InstancesTable.SetData(instances)
@@ -422,7 +431,7 @@
         self.InstancesTable.ResetView(self.InstancesGrid)
         self.TasksGrid.RefreshButtons()
         self.InstancesGrid.RefreshButtons()
-        
+
     def OnTasksGridCellChange(self, event):
         row, col = event.GetRow(), event.GetCol()
         if self.TasksTable.GetColLabelValue(col) == "Name":
@@ -439,7 +448,7 @@
                         self.InstancesTable.SetValueByName(i, "Task", new_name)
         self.RefreshModel()
         colname = self.TasksTable.GetColLabelValue(col, False)
-        if colname in ["Triggering", "Name", "Interval"]:
+        if colname in ["Triggering", "Name", "Single", "Interval"]:
             wx.CallAfter(self.RefreshView, False)
         event.Skip()
 
@@ -452,14 +461,14 @@
 #-------------------------------------------------------------------------------
 #                        Highlights showing functions
 #-------------------------------------------------------------------------------
-    
+
     def OnRefreshHighlightsTimer(self, event):
         self.RefreshView()
         event.Skip()
-    
+
     def AddHighlight(self, infos, start, end, highlight_type):
         EditorPanel.AddHighlight(self, infos, start, end, highlight_type)
-        
+
         if infos[0] == "task":
             self.TasksTable.AddHighlight(infos[1:], highlight_type)
         elif infos[0] == "instance":
@@ -468,7 +477,7 @@
 
     def ClearHighlights(self, highlight_type=None):
         EditorPanel.ClearHighlights(self, highlight_type)
-        
+
         self.TasksTable.ClearHighlights(highlight_type)
         self.InstancesTable.ClearHighlights(highlight_type)
         self.TasksTable.ResetView(self.TasksGrid)
--- a/editors/TextViewer.py	Fri Jun 06 18:30:49 2014 +0100
+++ b/editors/TextViewer.py	Tue Jul 08 18:01:33 2014 +0100
@@ -284,7 +284,16 @@
                 pou_name, pou_type = self.Controler.GetEditedElementType(self.TagName, self.Debug)
                 if len(values) > 2 and pou_type == "program":
                     var_name = values[3]
-                    if var_name.upper() in [name.upper() for name in self.Controler.GetProjectPouNames(self.Debug)]:
+                    dlg = wx.TextEntryDialog(
+                        self.ParentWindow,
+                        _("Confirm or change variable name"),
+                        'Variable Drop', var_name)
+                    dlg.SetValue(var_name)
+                    var_name = dlg.GetValue() if dlg.ShowModal() == wx.ID_OK else None
+                    dlg.Destroy()
+                    if var_name is None:
+                        return
+                    elif var_name.upper() in [name.upper() for name in self.Controler.GetProjectPouNames(self.Debug)]:
                         message = _("\"%s\" pou already exists!")%var_name
                     elif var_name.upper() in [name.upper() for name in self.Controler.GetEditedElementVariables(self.TagName, self.Debug)]:
                         message = _("\"%s\" element for this pou already exists!")%var_name
@@ -326,7 +335,16 @@
                 if pou_type == "program":
                     initval = values[0]
                     var_name = values[3]
-                    if var_name.upper() in [name.upper() for name in self.Controler.GetProjectPouNames(self.Debug)]:
+                    dlg = wx.TextEntryDialog(
+                        self.ParentWindow,
+                        _("Confirm or change variable name"),
+                        'Variable Drop', var_name)
+                    dlg.SetValue(var_name)
+                    var_name = dlg.GetValue() if dlg.ShowModal() == wx.ID_OK else None
+                    dlg.Destroy()
+                    if var_name is None:
+                        return
+                    elif var_name.upper() in [name.upper() for name in self.Controler.GetProjectPouNames(self.Debug)]:
                         message = _("\"%s\" pou already exists!")%var_name
                     else:
                         var_type = values[2]
@@ -340,7 +358,16 @@
                         event.SetDragText(var_name)
             elif values[1] == "Global":
                 var_name = values[0]
-                if var_name.upper() in [name.upper() for name in self.Controler.GetProjectPouNames(self.Debug)]:
+                dlg = wx.TextEntryDialog(
+                    self.ParentWindow,
+                    _("Confirm or change variable name"),
+                    'Variable Drop', var_name)
+                dlg.SetValue(var_name)
+                var_name = dlg.GetValue() if dlg.ShowModal() == wx.ID_OK else None
+                dlg.Destroy()
+                if var_name is None:
+                    return
+                elif var_name.upper() in [name.upper() for name in self.Controler.GetProjectPouNames(self.Debug)]:
                     message = _("\"%s\" pou already exists!")%var_name
                 else:
                     if not var_name.upper() in [name.upper() for name in self.Controler.GetEditedElementVariables(self.TagName, self.Debug)]:
--- a/editors/Viewer.py	Fri Jun 06 18:30:49 2014 +0100
+++ b/editors/Viewer.py	Tue Jul 08 18:01:33 2014 +0100
@@ -2,7 +2,7 @@
 # -*- coding: utf-8 -*-
 
 #This file is part of PLCOpenEditor, a library implementing an IEC 61131-3 editor
-#based on the plcopen standard. 
+#based on the plcopen standard.
 #
 #Copyright (C) 2007: Edouard TISSERANT and Laurent BESSARD
 #
@@ -47,7 +47,7 @@
 def ResetCursors():
     global CURSORS
     if CURSORS == None:
-        CURSORS = [wx.NullCursor, 
+        CURSORS = [wx.NullCursor,
                    wx.StockCursor(wx.CURSOR_HAND),
                    wx.StockCursor(wx.CURSOR_SIZENWSE),
                    wx.StockCursor(wx.CURSOR_SIZENESW),
@@ -83,16 +83,16 @@
 
 def GetVariableCreationFunction(variable_type):
     def variableCreationFunction(viewer, id, specific_values):
-        return FBD_Variable(viewer, variable_type, 
-                                    specific_values.name, 
-                                    specific_values.value_type, 
+        return FBD_Variable(viewer, variable_type,
+                                    specific_values.name,
+                                    specific_values.value_type,
                                     id,
                                     specific_values.execution_order)
     return variableCreationFunction
 
 def GetConnectorCreationFunction(connector_type):
     def connectorCreationFunction(viewer, id, specific_values):
-        return FBD_Connector(viewer, connector_type, 
+        return FBD_Connector(viewer, connector_type,
                                      specific_values.name, id)
     return connectorCreationFunction
 
@@ -101,7 +101,7 @@
 
 def GetPowerRailCreationFunction(powerrail_type):
     def powerRailCreationFunction(viewer, id, specific_values):
-        return LD_PowerRail(viewer, powerrail_type, id, 
+        return LD_PowerRail(viewer, powerrail_type, id,
                                     specific_values.connectors)
     return powerRailCreationFunction
 
@@ -113,7 +113,7 @@
                  (False, "falling"): CONTACT_FALLING}
 
 def contactCreationFunction(viewer, id, specific_values):
-    contact_type = CONTACT_TYPES.get((NEGATED_VALUE(specific_values.negated), 
+    contact_type = CONTACT_TYPES.get((NEGATED_VALUE(specific_values.negated),
                                       MODIFIER_VALUE(specific_values.edge)),
                                      CONTACT_NORMAL)
     return LD_Contact(viewer, contact_type, specific_values.name, id)
@@ -125,14 +125,14 @@
               (False, "falling", "none"): COIL_FALLING}
 
 def coilCreationFunction(viewer, id, specific_values):
-    coil_type = COIL_TYPES.get((NEGATED_VALUE(specific_values.negated), 
+    coil_type = COIL_TYPES.get((NEGATED_VALUE(specific_values.negated),
                                 MODIFIER_VALUE(specific_values.edge),
                                 MODIFIER_VALUE(specific_values.storage)),
                                COIL_NORMAL)
     return LD_Coil(viewer, coil_type, specific_values.name, id)
 
 def stepCreationFunction(viewer, id, specific_values):
-    step = SFC_Step(viewer, specific_values.name, 
+    step = SFC_Step(viewer, specific_values.name,
                             specific_values.initial, id)
     if specific_values.action is not None:
         step.AddAction()
@@ -141,14 +141,14 @@
     return step
 
 def transitionCreationFunction(viewer, id, specific_values):
-    transition = SFC_Transition(viewer, specific_values.condition_type, 
-                                        specific_values.condition, 
+    transition = SFC_Transition(viewer, specific_values.condition_type,
+                                        specific_values.condition,
                                         specific_values.priority, id)
     return transition
 
 def GetDivergenceCreationFunction(divergence_type):
     def divergenceCreationFunction(viewer, id, specific_values):
-        return SFC_Divergence(viewer, divergence_type, 
+        return SFC_Divergence(viewer, divergence_type,
                                       specific_values.connectors, id)
     return divergenceCreationFunction
 
@@ -169,12 +169,12 @@
     "rightPowerRail": GetPowerRailCreationFunction(RIGHTRAIL),
     "contact": contactCreationFunction,
     "coil": coilCreationFunction,
-    "step": stepCreationFunction, 
+    "step": stepCreationFunction,
     "transition": transitionCreationFunction,
-    "selectionDivergence": GetDivergenceCreationFunction(SELECTION_DIVERGENCE), 
-    "selectionConvergence": GetDivergenceCreationFunction(SELECTION_CONVERGENCE), 
-    "simultaneousDivergence": GetDivergenceCreationFunction(SIMULTANEOUS_DIVERGENCE), 
-    "simultaneousConvergence": GetDivergenceCreationFunction(SIMULTANEOUS_CONVERGENCE), 
+    "selectionDivergence": GetDivergenceCreationFunction(SELECTION_DIVERGENCE),
+    "selectionConvergence": GetDivergenceCreationFunction(SELECTION_CONVERGENCE),
+    "simultaneousDivergence": GetDivergenceCreationFunction(SIMULTANEOUS_DIVERGENCE),
+    "simultaneousConvergence": GetDivergenceCreationFunction(SIMULTANEOUS_CONVERGENCE),
     "jump": jumpCreationFunction,
     "actionBlock": actionBlockCreationFunction,
 }
@@ -209,11 +209,11 @@
 
 
 class ViewerDropTarget(wx.TextDropTarget):
-    
+
     def __init__(self, parent):
         wx.TextDropTarget.__init__(self)
         self.ParentWindow = parent
-    
+
     def OnDropText(self, x, y, data):
         self.ParentWindow.Select()
         tagname = self.ParentWindow.GetTagName()
@@ -280,9 +280,9 @@
                 if pou_type == "program":
                     location = values[0]
                     if not location.startswith("%"):
-                        dialog = wx.SingleChoiceDialog(self.ParentWindow.ParentWindow, 
-                              _("Select a variable class:"), _("Variable class"), 
-                              ["Input", "Output", "Memory"], 
+                        dialog = wx.SingleChoiceDialog(self.ParentWindow.ParentWindow,
+                              _("Select a variable class:"), _("Variable class"),
+                              ["Input", "Output", "Memory"],
                               wx.DEFAULT_DIALOG_STYLE|wx.OK|wx.CANCEL)
                         if dialog.ShowModal() == wx.ID_OK:
                             selected = dialog.GetSelection()
@@ -298,9 +298,18 @@
                         else:
                             location = "%M" + location
                     var_name = values[3]
-                    if var_name.upper() in [name.upper() for name in self.ParentWindow.Controler.GetProjectPouNames(self.ParentWindow.Debug)]:
+                    dlg = wx.TextEntryDialog(
+                        self.ParentWindow.ParentWindow,
+                        _("Confirm or change variable name"),
+                        'Variable Drop', var_name)
+                    dlg.SetValue(var_name)
+                    var_name = dlg.GetValue() if dlg.ShowModal() == wx.ID_OK else None
+                    dlg.Destroy()
+                    if var_name is None:
+                        return
+                    elif var_name.upper() in [name.upper() for name in self.ParentWindow.Controler.GetProjectPouNames(self.ParentWindow.Debug)]:
                         message = _("\"%s\" pou already exists!")%var_name
-                    else:
+                    elif not var_name.upper() in [name.upper() for name in self.ParentWindow.Controler.GetEditedElementVariables(tagname, self.ParentWindow.Debug)]:
                         if location[1] == "Q":
                             var_class = OUTPUT
                         else:
@@ -309,35 +318,56 @@
                             var_type = values[2]
                         else:
                             var_type = LOCATIONDATATYPES.get(location[2], ["BOOL"])[0]
-                        if not var_name.upper() in [name.upper() for name in self.ParentWindow.Controler.GetEditedElementVariables(tagname, self.ParentWindow.Debug)]:
-                            self.ParentWindow.Controler.AddEditedElementPouVar(tagname, var_type, var_name, location=location, description=values[4])
-                            self.ParentWindow.RefreshVariablePanel()
-                            self.ParentWindow.ParentWindow.RefreshPouInstanceVariablesPanel()
+                        self.ParentWindow.Controler.AddEditedElementPouVar(tagname, var_type, var_name, location=location, description=values[4])
+                        self.ParentWindow.RefreshVariablePanel()
+                        self.ParentWindow.ParentWindow.RefreshPouInstanceVariablesPanel()
                         self.ParentWindow.AddVariableBlock(x, y, scaling, var_class, var_name, var_type)
+                    else:
+                        message = _("\"%s\" element for this pou already exists!")%var_name
             elif values[1] == "NamedConstant":
                 if pou_type == "program":
                     initval = values[0]
                     var_name = values[3]
-                    if var_name.upper() in [name.upper() for name in self.ParentWindow.Controler.GetProjectPouNames(self.ParentWindow.Debug)]:
+                    dlg = wx.TextEntryDialog(
+                        self.ParentWindow.ParentWindow,
+                        _("Confirm or change variable name"),
+                        'Variable Drop', var_name)
+                    dlg.SetValue(var_name)
+                    var_name = dlg.GetValue() if dlg.ShowModal() == wx.ID_OK else None
+                    dlg.Destroy()
+                    if var_name is None:
+                        return
+                    elif var_name.upper() in [name.upper() for name in self.ParentWindow.Controler.GetProjectPouNames(self.ParentWindow.Debug)]:
                         message = _("\"%s\" pou already exists!")%var_name
-                    else:
+                    elif not var_name.upper() in [name.upper() for name in self.ParentWindow.Controler.GetEditedElementVariables(tagname, self.ParentWindow.Debug)]:
                         var_class = INPUT
                         var_type = values[2]
-                        if not var_name.upper() in [name.upper() for name in self.ParentWindow.Controler.GetEditedElementVariables(tagname, self.ParentWindow.Debug)]:
-                            self.ParentWindow.Controler.AddEditedElementPouVar(tagname, var_type, var_name, description=values[4], initval=initval)
-                            self.ParentWindow.RefreshVariablePanel()
-                            self.ParentWindow.ParentWindow.RefreshPouInstanceVariablesPanel()
+                        self.ParentWindow.Controler.AddEditedElementPouVar(tagname, var_type, var_name, description=values[4], initval=initval)
+                        self.ParentWindow.RefreshVariablePanel()
+                        self.ParentWindow.ParentWindow.RefreshPouInstanceVariablesPanel()
                         self.ParentWindow.AddVariableBlock(x, y, scaling, var_class, var_name, var_type)
+                    else:
+                        message = _("\"%s\" element for this pou already exists!")%var_name
             elif values[1] == "Global":
                 var_name = values[0]
-                if var_name.upper() in [name.upper() for name in self.ParentWindow.Controler.GetProjectPouNames(self.ParentWindow.Debug)]:
+                dlg = wx.TextEntryDialog(
+                    self.ParentWindow.ParentWindow,
+                    _("Confirm or change variable name"),
+                    'Variable Drop', var_name)
+                dlg.SetValue(var_name)
+                var_name = dlg.GetValue() if dlg.ShowModal() == wx.ID_OK else None
+                dlg.Destroy()
+                if var_name is None:
+                    return
+                elif var_name.upper() in [name.upper() for name in self.ParentWindow.Controler.GetProjectPouNames(self.ParentWindow.Debug)]:
                     message = _("\"%s\" pou already exists!")%var_name
+                elif not var_name.upper() in [name.upper() for name in self.ParentWindow.Controler.GetEditedElementVariables(tagname, self.ParentWindow.Debug)]:
+                    self.ParentWindow.Controler.AddEditedElementPouExternalVar(tagname, values[2], var_name)
+                    self.ParentWindow.RefreshVariablePanel()
+                    self.ParentWindow.ParentWindow.RefreshPouInstanceVariablesPanel()
+                    self.ParentWindow.AddVariableBlock(x, y, scaling, INPUT, var_name, values[2])
                 else:
-                    if not var_name.upper() in [name.upper() for name in self.ParentWindow.Controler.GetEditedElementVariables(tagname, self.ParentWindow.Debug)]:
-                        self.ParentWindow.Controler.AddEditedElementPouExternalVar(tagname, values[2], var_name)
-                        self.ParentWindow.RefreshVariablePanel()
-                        self.ParentWindow.ParentWindow.RefreshPouInstanceVariablesPanel()
-                    self.ParentWindow.AddVariableBlock(x, y, scaling, INPUT, var_name, values[2])
+                    message = _("\"%s\" element for this pou already exists!")%var_name
             elif values[1] == "Constant":
                 self.ParentWindow.AddVariableBlock(x, y, scaling, INPUT, values[0], None)
             elif values[3] == tagname:
@@ -379,31 +409,31 @@
                 child_menu = wx.Menu(title='')
                 self.GenerateTreeMenu(x, y, scaling, child_menu, child_path, var_class, child_tree)
                 menu.AppendMenu(new_id, "%s." % child_name, child_menu)
-            
+
     def GetAddVariableBlockFunction(self, x, y, scaling, var_class, var_name, var_type):
         def AddVariableFunction(event):
             self.ParentWindow.AddVariableBlock(x, y, scaling, var_class, var_name, var_type)
         return AddVariableFunction
-    
+
     def ShowMessage(self, message):
         message = wx.MessageDialog(self.ParentWindow, message, _("Error"), wx.OK|wx.ICON_ERROR)
         message.ShowModal()
         message.Destroy()
 
 """
-Class that implements a Viewer based on a wx.ScrolledWindow for drawing and 
+Class that implements a Viewer based on a wx.ScrolledWindow for drawing and
 manipulating graphic elements
 """
 
 class Viewer(EditorPanel, DebugViewer):
-    
+
     if wx.VERSION < (2, 6, 0):
         def Bind(self, event, function, id = None):
             if id is not None:
                 event(self, id, function)
             else:
                 event(self, function)
-    
+
     # Add list of menu items to the given menu
     def AddMenuItems(self, menu, items):
         for item in items:
@@ -414,23 +444,23 @@
                 AppendMenu(menu, help=help, id=id, kind=kind, text=text)
                 # Link menu event to corresponding called functions
                 self.Bind(wx.EVT_MENU, callback, id=id)
-    
+
     # Add Block Pin Menu items to the given menu
     def AddBlockPinMenuItems(self, menu, connector):
-        [ID_NO_MODIFIER, ID_NEGATED, ID_RISING_EDGE, 
+        [ID_NO_MODIFIER, ID_NEGATED, ID_RISING_EDGE,
          ID_FALLING_EDGE] = [wx.NewId() for i in xrange(4)]
-        
+
         # Create menu items
         self.AddMenuItems(menu, [
             (ID_NO_MODIFIER, wx.ITEM_RADIO, _(u'No Modifier'), '', self.OnNoModifierMenu),
             (ID_NEGATED, wx.ITEM_RADIO, _(u'Negated'), '', self.OnNegatedMenu),
             (ID_RISING_EDGE, wx.ITEM_RADIO, _(u'Rising Edge'), '', self.OnRisingEdgeMenu),
             (ID_FALLING_EDGE, wx.ITEM_RADIO, _(u'Falling Edge'), '', self.OnFallingEdgeMenu)])
-        
+
         type = self.Controler.GetEditedElementType(self.TagName, self.Debug)
         menu.Enable(ID_RISING_EDGE, type != "function")
         menu.Enable(ID_FALLING_EDGE, type != "function")
-        
+
         if connector.IsNegated():
             menu.Check(ID_NEGATED, True)
         elif connector.GetEdge() == "rising":
@@ -439,80 +469,80 @@
             menu.Check(ID_FALLING_EDGE, True)
         else:
             menu.Check(ID_NO_MODIFIER, True)
-        
+
     # Add Alignment Menu items to the given menu
     def AddAlignmentMenuItems(self, menu):
         [ID_ALIGN_LEFT, ID_ALIGN_CENTER, ID_ALIGN_RIGHT,
          ID_ALIGN_TOP, ID_ALIGN_MIDDLE, ID_ALIGN_BOTTOM,
         ] = [wx.NewId() for i in xrange(6)]
-        
+
         # Create menu items
         self.AddMenuItems(menu, [
             (ID_ALIGN_LEFT, wx.ITEM_NORMAL, _(u'Left'), '', self.OnAlignLeftMenu),
-            (ID_ALIGN_CENTER, wx.ITEM_NORMAL, _(u'Center'), '', self.OnAlignCenterMenu), 
+            (ID_ALIGN_CENTER, wx.ITEM_NORMAL, _(u'Center'), '', self.OnAlignCenterMenu),
             (ID_ALIGN_RIGHT, wx.ITEM_NORMAL, _(u'Right'), '', self.OnAlignRightMenu),
             None,
-            (ID_ALIGN_TOP, wx.ITEM_NORMAL, _(u'Top'), '', self.OnAlignTopMenu), 
+            (ID_ALIGN_TOP, wx.ITEM_NORMAL, _(u'Top'), '', self.OnAlignTopMenu),
             (ID_ALIGN_MIDDLE, wx.ITEM_NORMAL, _(u'Middle'), '', self.OnAlignMiddleMenu),
             (ID_ALIGN_BOTTOM, wx.ITEM_NORMAL, _(u'Bottom'), '', self.OnAlignBottomMenu)])
-    
+
     # Add Wire Menu items to the given menu
     def AddWireMenuItems(self, menu, delete=False, replace=False):
         [ID_ADD_SEGMENT, ID_DELETE_SEGMENT, ID_REPLACE_WIRE,
          ] = [wx.NewId() for i in xrange(3)]
-        
+
         # Create menu items
         self.AddMenuItems(menu, [
             (ID_ADD_SEGMENT, wx.ITEM_NORMAL, _(u'Add Wire Segment'), '', self.OnAddSegmentMenu),
             (ID_DELETE_SEGMENT, wx.ITEM_NORMAL, _(u'Delete Wire Segment'), '', self.OnDeleteSegmentMenu),
             (ID_REPLACE_WIRE, wx.ITEM_NORMAL, _(u'Replace Wire by connections'), '', self.OnReplaceWireMenu)])
-        
+
         menu.Enable(ID_DELETE_SEGMENT, delete)
         menu.Enable(ID_REPLACE_WIRE, replace)
-    
+
     # Add Divergence Menu items to the given menu
     def AddDivergenceMenuItems(self, menu, delete=False):
         [ID_ADD_BRANCH, ID_DELETE_BRANCH] = [wx.NewId() for i in xrange(2)]
-        
+
         # Create menu items
         self.AddMenuItems(menu, [
             (ID_ADD_BRANCH, wx.ITEM_NORMAL, _(u'Add Divergence Branch'), '', self.OnAddBranchMenu),
             (ID_DELETE_BRANCH, wx.ITEM_NORMAL, _(u'Delete Divergence Branch'), '', self.OnDeleteBranchMenu)])
-        
+
         menu.Enable(ID_DELETE_BRANCH, delete)
-    
+
     # Add Add Menu items to the given menu
     def AddAddMenuItems(self, menu):
         [ID_ADD_BLOCK, ID_ADD_VARIABLE, ID_ADD_CONNECTION,
          ID_ADD_COMMENT] = [wx.NewId() for i in xrange(4)]
-        
+
         # Create menu items
         self.AddMenuItems(menu, [
             (ID_ADD_BLOCK, wx.ITEM_NORMAL, _(u'Block'), '', self.GetAddMenuCallBack(self.AddNewBlock)),
             (ID_ADD_VARIABLE, wx.ITEM_NORMAL, _(u'Variable'), '', self.GetAddMenuCallBack(self.AddNewVariable)),
             (ID_ADD_CONNECTION, wx.ITEM_NORMAL, _(u'Connection'), '', self.GetAddMenuCallBack(self.AddNewConnection)),
             None])
-        
+
         if self.CurrentLanguage != "FBD":
             [ID_ADD_POWER_RAIL, ID_ADD_CONTACT, ID_ADD_COIL,
             ] = [wx.NewId() for i in xrange(3)]
-            
+
             # Create menu items
             self.AddMenuItems(menu, [
                 (ID_ADD_POWER_RAIL, wx.ITEM_NORMAL, _(u'Power Rail'), '', self.GetAddMenuCallBack(self.AddNewPowerRail)),
                 (ID_ADD_CONTACT, wx.ITEM_NORMAL, _(u'Contact'), '', self.GetAddMenuCallBack(self.AddNewContact))])
-                
+
             if self.CurrentLanguage != "SFC":
                 self.AddMenuItems(menu, [
                      (ID_ADD_COIL, wx.ITEM_NORMAL, _(u'Coil'), '', self.GetAddMenuCallBack(self.AddNewCoil))])
-            
+
             menu.AppendSeparator()
-        
+
         if self.CurrentLanguage == "SFC":
-            [ID_ADD_INITIAL_STEP, ID_ADD_STEP, ID_ADD_TRANSITION, 
+            [ID_ADD_INITIAL_STEP, ID_ADD_STEP, ID_ADD_TRANSITION,
              ID_ADD_ACTION_BLOCK, ID_ADD_DIVERGENCE, ID_ADD_JUMP,
             ] = [wx.NewId() for i in xrange(6)]
-            
+
             # Create menu items
             self.AddMenuItems(menu, [
                 (ID_ADD_INITIAL_STEP, wx.ITEM_NORMAL, _(u'Initial Step'), '', self.GetAddMenuCallBack(self.AddNewStep, True)),
@@ -522,64 +552,64 @@
                 (ID_ADD_DIVERGENCE, wx.ITEM_NORMAL, _(u'Divergence'), '', self.GetAddMenuCallBack(self.AddNewDivergence)),
                 (ID_ADD_JUMP, wx.ITEM_NORMAL, _(u'Jump'), '', self.GetAddMenuCallBack(self.AddNewJump)),
                 None])
-        
+
         self.AddMenuItems(menu, [
              (ID_ADD_COMMENT, wx.ITEM_NORMAL, _(u'Comment'), '', self.GetAddMenuCallBack(self.AddNewComment))])
-        
+
     # Add Default Menu items to the given menu
     def AddDefaultMenuItems(self, menu, edit=False, block=False):
         if block:
             [ID_EDIT_BLOCK, ID_DELETE, ID_ADJUST_BLOCK_SIZE] = [wx.NewId() for i in xrange(3)]
-        
+
             # Create menu items
             self.AddMenuItems(menu, [
                  (ID_EDIT_BLOCK, wx.ITEM_NORMAL, _(u'Edit Block'), '', self.OnEditBlockMenu),
                  (ID_ADJUST_BLOCK_SIZE, wx.ITEM_NORMAL, _(u'Adjust Block Size'), '', self.OnAdjustBlockSizeMenu),
                  (ID_DELETE, wx.ITEM_NORMAL, _(u'Delete'), '', self.OnDeleteMenu)])
-        
+
             menu.Enable(ID_EDIT_BLOCK, edit)
-        
+
         else:
             [ID_CLEAR_EXEC_ORDER, ID_RESET_EXEC_ORDER] = [wx.NewId() for i in xrange(2)]
-        
+
             # Create menu items
             self.AddMenuItems(menu, [
                  (ID_CLEAR_EXEC_ORDER, wx.ITEM_NORMAL, _(u'Clear Execution Order'), '', self.OnClearExecutionOrderMenu),
                  (ID_RESET_EXEC_ORDER, wx.ITEM_NORMAL, _(u'Reset Execution Order'), '', self.OnResetExecutionOrderMenu)])
-            
+
             menu.AppendSeparator()
-            
+
             add_menu = wx.Menu(title='')
             self.AddAddMenuItems(add_menu)
             menu.AppendMenu(-1, _(u'Add'), add_menu)
-        
+
         menu.AppendSeparator()
-        
+
         [ID_CUT, ID_COPY, ID_PASTE] = [wx.NewId() for i in xrange(3)]
-        
+
         # Create menu items
         self.AddMenuItems(menu, [
              (ID_CUT, wx.ITEM_NORMAL, _(u'Cut'), '', self.GetClipboardCallBack(self.Cut)),
              (ID_COPY, wx.ITEM_NORMAL, _(u'Copy'), '', self.GetClipboardCallBack(self.Copy)),
              (ID_PASTE, wx.ITEM_NORMAL, _(u'Paste'), '', self.GetAddMenuCallBack(self.Paste))])
-        
+
         menu.Enable(ID_CUT, block)
         menu.Enable(ID_COPY, block)
         menu.Enable(ID_PASTE, self.ParentWindow.GetCopyBuffer() is not None)
-        
+
     def _init_Editor(self, prnt):
-        self.Editor = wx.ScrolledWindow(prnt, name="Viewer", 
-            pos=wx.Point(0, 0), size=wx.Size(0, 0), 
+        self.Editor = wx.ScrolledWindow(prnt, name="Viewer",
+            pos=wx.Point(0, 0), size=wx.Size(0, 0),
             style=wx.HSCROLL | wx.VSCROLL | wx.ALWAYS_SHOW_SB)
         self.Editor.ParentWindow = self
-    
+
     # Create a new Viewer
     def __init__(self, parent, tagname, window, controler, debug = False, instancepath = ""):
         self.VARIABLE_PANEL_TYPE = controler.GetPouType(tagname.split("::")[1])
-        
+
         EditorPanel.__init__(self, parent, tagname, window, controler, debug)
         DebugViewer.__init__(self, controler, debug)
-        
+
         # Adding a rubberband to Viewer
         self.rubberBand = RubberBand(viewer=self)
         self.Editor.SetBackgroundColour(wx.Colour(255,255,255))
@@ -601,32 +631,32 @@
         self.InstancePath = instancepath
         self.StartMousePos = None
         self.StartScreenPos = None
-        
+
         # Prevent search for highlighted element to be called too often
         self.LastHighlightCheckTime = gettime()
         # Prevent search for element producing tooltip to be called too often
         self.LastToolTipCheckTime = gettime()
-        
+
         self.Buffering = False
-        
+
         # Initialize Cursors
         ResetCursors()
         self.CurrentCursor = 0
-        
+
         # Initialize Block, Wire and Comment numbers
         self.wire_id = 0
-        
+
         # Initialize Viewer mode to Selection mode
         self.Mode = MODE_SELECTION
         self.SavedMode = False
         self.CurrentLanguage = "FBD"
-        
+
         if not self.Debug:
             self.Editor.SetDropTarget(ViewerDropTarget(self))
-        
+
         self.ElementRefreshList = []
         self.ElementRefreshList_lock = Lock()
-        
+
         dc = wx.ClientDC(self.Editor)
         font = wx.Font(faces["size"], wx.SWISS, wx.NORMAL, wx.NORMAL, faceName = faces["mono"])
         dc.SetFont(font)
@@ -639,15 +669,15 @@
         self.SetFont(font)
         self.MiniTextDC = wx.MemoryDC()
         self.MiniTextDC.SetFont(wx.Font(faces["size"] * 0.75, wx.SWISS, wx.NORMAL, wx.NORMAL, faceName = faces["helv"]))
-        
+
         self.CurrentScale = None
         self.SetScale(ZOOM_FACTORS.index(1.0), False)
-        
+
         self.RefreshHighlightsTimer = wx.Timer(self, -1)
         self.Bind(wx.EVT_TIMER, self.OnRefreshHighlightsTimer, self.RefreshHighlightsTimer)
-        
+
         self.ResetView()
-        
+
         # Link Viewer event to corresponding methods
         self.Editor.Bind(wx.EVT_PAINT, self.OnPaint)
         self.Editor.Bind(wx.EVT_LEFT_DOWN, self.OnViewerLeftDown)
@@ -665,55 +695,55 @@
         self.Editor.Bind(wx.EVT_MOUSEWHEEL, self.OnMouseWheelWindow)
         self.Editor.Bind(wx.EVT_SIZE, self.OnMoveWindow)
         self.Editor.Bind(wx.EVT_MOUSE_EVENTS, self.OnViewerMouseEvent)
-    
+
     # Destructor
     def __del__(self):
         DebugViewer.__del__(self)
         self.Flush()
         self.ResetView()
         self.RefreshHighlightsTimer.Stop()
-    
+
     def SetCurrentCursor(self, cursor):
         if self.Mode != MODE_MOTION:
             global CURSORS
             if self.CurrentCursor != cursor:
                 self.CurrentCursor = cursor
                 self.Editor.SetCursor(CURSORS[cursor])
-    
+
     def GetScrolledRect(self, rect):
-        rect.x, rect.y = self.Editor.CalcScrolledPosition(int(rect.x * self.ViewScale[0]), 
+        rect.x, rect.y = self.Editor.CalcScrolledPosition(int(rect.x * self.ViewScale[0]),
                                                    int(rect.y * self.ViewScale[1]))
         rect.width = int(rect.width * self.ViewScale[0]) + 2
         rect.height = int(rect.height * self.ViewScale[1]) + 2
         return rect
-    
+
     def GetTitle(self):
         if self.Debug:
             if len(self.InstancePath) > 15:
                 return "..." + self.InstancePath[-12:]
             return self.InstancePath
         return EditorPanel.GetTitle(self)
-    
+
     def GetScaling(self):
         return self.Scaling
-    
+
     def GetInstancePath(self, variable_base=False):
         if variable_base:
             words = self.TagName.split("::")
             if words[0] in ["A", "T"]:
                 return ".".join(self.InstancePath.split(".")[:-1])
         return self.InstancePath
-    
+
     def IsViewing(self, tagname):
         if self.Debug:
             return self.InstancePath == tagname
         return EditorPanel.IsViewing(self, tagname)
-    
+
     # Returns a new id
     def GetNewId(self):
         self.current_id += 1
         return self.current_id
-        
+
     def SetScale(self, scale_number, refresh=True, mouse_event=None):
         new_scale = max(0, min(scale_number, len(ZOOM_FACTORS) - 1))
         if self.CurrentScale != new_scale:
@@ -744,7 +774,7 @@
                     self.RefreshScrollBars()
                 self.RefreshScaling(refresh)
                 self.Editor.Thaw()
-    
+
     def GetScale(self):
         return self.CurrentScale
 
@@ -764,10 +794,10 @@
             self.Editor.PrepareDC(dc)
         dc.SetUserScale(self.ViewScale[0], self.ViewScale[1])
         return dc
-    
+
     def RefreshRect(self, rect, eraseBackground=True):
         self.Editor.RefreshRect(rect, eraseBackground)
-    
+
     def Scroll(self, x, y):
         if self.Debug and wx.Platform == '__WXMSW__':
             self.Editor.Freeze()
@@ -777,45 +807,45 @@
                 self.Editor.Thaw()
             else:
                 self.Editor.Refresh()
-    
+
     def GetScrollPos(self, orientation):
         return self.Editor.GetScrollPos(orientation)
-    
+
     def GetScrollRange(self, orientation):
         return self.Editor.GetScrollRange(orientation)
-    
+
     def GetScrollThumb(self, orientation):
         return self.Editor.GetScrollThumb(orientation)
-    
+
     def CalcUnscrolledPosition(self, x, y):
         return self.Editor.CalcUnscrolledPosition(x, y)
-    
+
     def GetViewStart(self):
         return self.Editor.GetViewStart()
-    
+
     def GetTextExtent(self, text):
         return self.Editor.GetTextExtent(text)
-    
+
     def GetFont(self):
         return self.Editor.GetFont()
-    
+
     def GetMiniTextExtent(self, text):
         return self.MiniTextDC.GetTextExtent(text)
-    
+
     def GetMiniFont(self):
         return self.MiniTextDC.GetFont()
-    
+
 #-------------------------------------------------------------------------------
 #                         Element management functions
 #-------------------------------------------------------------------------------
 
     def AddBlock(self, block):
         self.Blocks[block.GetId()] = block
-        
+
     def AddWire(self, wire):
         self.wire_id += 1
         self.Wires[wire] = self.wire_id
-        
+
     def AddComment(self, comment):
         self.Comments[comment.GetId()] = comment
 
@@ -823,10 +853,10 @@
         if block is not None:
             return self.Blocks.get(block.GetId(), False)
         return False
-        
+
     def IsWire(self, wire):
         return self.Wires.get(wire, False)
-        
+
     def IsComment(self, comment):
         if comment is not None:
             return self.Comments.get(comment.GetId(), False)
@@ -834,10 +864,10 @@
 
     def RemoveBlock(self, block):
         self.Blocks.pop(block.GetId())
-        
+
     def RemoveWire(self, wire):
         self.Wires.pop(wire)
-        
+
     def RemoveComment(self, comment):
         self.Comments.pop(comment.GetId())
 
@@ -860,7 +890,7 @@
                block.GetName() == name:
                 return block
         return None
-    
+
     def RefreshVisibleElements(self, xp = None, yp = None):
         x, y = self.Editor.CalcUnscrolledPosition(0, 0)
         if xp is not None:
@@ -876,7 +906,7 @@
             wire.TestVisible(screen)
         for block in self.Blocks.itervalues():
             block.TestVisible(screen)
-    
+
     def GetElementIECPath(self, element):
         iec_path = None
         instance_path = self.GetInstancePath(True)
@@ -912,7 +942,7 @@
             next_steps = self.GetNextSteps(connectors["outputs"])
             iec_path = "%s.%s->%s"%(instance_path, ",".join(previous_steps), ",".join(next_steps))
         return iec_path
-    
+
     def GetWireModifier(self, wire):
         connector = wire.EndConnected
         block = connector.GetParentBlock()
@@ -928,7 +958,7 @@
             else:
                 return connector.GetEdge()
         return "none"
-        
+
 #-------------------------------------------------------------------------------
 #                              Reset functions
 #-------------------------------------------------------------------------------
@@ -942,21 +972,21 @@
         self.SelectedElement = None
         self.HighlightedElement = None
         self.ToolTipElement = None
-    
+
     def Flush(self):
         self.UnsubscribeAllDataConsumers(tick=False)
         for block in self.Blocks.itervalues():
             block.Flush()
-        
+
     # Remove all elements
     def CleanView(self):
         for block in self.Blocks.itervalues():
             block.Clean()
         self.ResetView()
-    
+
     # Changes Viewer mode
     def SetMode(self, mode):
-        if self.Mode != mode or mode == MODE_SELECTION:    
+        if self.Mode != mode or mode == MODE_SELECTION:
             if self.Mode == MODE_MOTION:
                 wx.CallAfter(self.Editor.SetCursor, wx.NullCursor)
             self.Mode = mode
@@ -970,11 +1000,11 @@
         if self.Mode == MODE_MOTION:
             wx.CallAfter(self.Editor.SetCursor, wx.StockCursor(wx.CURSOR_HAND))
             self.SavedMode = True
-        
+
     # Return current drawing mode
     def GetDrawingMode(self):
         return self.ParentWindow.GetDrawingMode()
-    
+
     # Buffer the last model state
     def RefreshBuffer(self):
         self.Controler.BufferProject()
@@ -982,7 +1012,7 @@
             self.ParentWindow.RefreshTitle()
             self.ParentWindow.RefreshFileMenu()
             self.ParentWindow.RefreshEditMenu()
-    
+
     def StartBuffering(self):
         if not self.Buffering:
             self.Buffering = True
@@ -991,32 +1021,32 @@
                 self.ParentWindow.RefreshTitle()
                 self.ParentWindow.RefreshFileMenu()
                 self.ParentWindow.RefreshEditMenu()
-    
+
     def ResetBuffer(self):
         if self.Buffering:
             self.Controler.EndBuffering()
             self.Buffering = False
-    
+
     def GetBufferState(self):
         if not self.Debug:
             return self.Controler.GetBufferState()
         return False, False
-    
+
     def Undo(self):
         if not self.Debug:
             self.Controler.LoadPrevious()
             self.ParentWindow.CloseTabsWithoutModel()
-            
+
     def Redo(self):
         if not self.Debug:
             self.Controler.LoadNext()
             self.ParentWindow.CloseTabsWithoutModel()
-        
+
     def HasNoModel(self):
         if not self.Debug:
             return self.Controler.GetEditedElement(self.TagName) is None
         return False
-    
+
     # Refresh the current scaling
     def RefreshScaling(self, refresh=True):
         properties = self.Controler.GetProjectProperties(self.Debug)
@@ -1048,27 +1078,27 @@
         if refresh:
             self.RefreshVisibleElements()
             self.Editor.Refresh(False)
-        
-        
+
+
 #-------------------------------------------------------------------------------
 #                          Refresh functions
 #-------------------------------------------------------------------------------
-    
+
     VALUE_TRANSLATION = {True: _("Active"), False: _("Inactive")}
 
     def SetValue(self, value):
         if self.Value != value:
             self.Value = value
-            
+
             xstart, ystart = self.GetViewStart()
             window_size = self.Editor.GetClientSize()
             refresh_rect = self.GetRedrawRect()
-            if (xstart * SCROLLBAR_UNIT <= refresh_rect.x + refresh_rect.width and 
+            if (xstart * SCROLLBAR_UNIT <= refresh_rect.x + refresh_rect.width and
                 xstart * SCROLLBAR_UNIT + window_size[0] >= refresh_rect.x and
-                ystart * SCROLLBAR_UNIT <= refresh_rect.y + refresh_rect.height and 
+                ystart * SCROLLBAR_UNIT <= refresh_rect.y + refresh_rect.height and
                 ystart * SCROLLBAR_UNIT + window_size[1] >= refresh_rect.y):
                 self.ElementNeedRefresh(self)
-    
+
     def GetRedrawRect(self):
         dc = self.GetLogicalDC()
         ipw, iph = dc.GetTextExtent(_("Debug: %s") % self.InstancePath)
@@ -1078,12 +1108,12 @@
             vw = max(vw, w)
             vh = max(vh, h)
         return wx.Rect(ipw + 4, 2, vw, vh)
-    
+
     def ElementNeedRefresh(self, element):
         self.ElementRefreshList_lock.acquire()
         self.ElementRefreshList.append(element)
         self.ElementRefreshList_lock.release()
-        
+
     def NewDataAvailable(self, ticks, *args, **kwargs):
         if self.IsShown():
             refresh_rect = None
@@ -1095,25 +1125,25 @@
                     refresh_rect.Union(element.GetRedrawRect())
             self.ElementRefreshList = []
             self.ElementRefreshList_lock.release()
-            
+
             if refresh_rect is not None:
                 self.RefreshRect(self.GetScrolledRect(refresh_rect), False)
-        
+
     def SubscribeAllDataConsumers(self):
         self.RefreshView()
         DebugViewer.SubscribeAllDataConsumers(self)
-        
+
     # Refresh Viewer elements
     def RefreshView(self, variablepanel=True, selection=None):
         EditorPanel.RefreshView(self, variablepanel)
-        
+
         if self.TagName.split("::")[0] == "A" and self.Debug:
             self.AddDataConsumer("%s.Q" % self.InstancePath.upper(), self)
-        
+
         if self.ToolTipElement is not None:
             self.ToolTipElement.DestroyToolTip()
             self.ToolTipElement = None
-        
+
         self.Inhibit(True)
         self.current_id = 0
         # Start by reseting Viewer
@@ -1126,14 +1156,14 @@
         # Load Blocks until they are all loaded
         while len(instances) > 0:
             self.loadInstance(instances.popitem(0)[1], instances, selection)
-        
-        if (selection is not None and 
+
+        if (selection is not None and
             isinstance(self.SelectedElement, Graphic_Group)):
             self.SelectedElement.RefreshWireExclusion()
             self.SelectedElement.RefreshBoundingBox()
-        
+
         self.RefreshScrollBars()
-        
+
         for wire in self.Wires:
             if not wire.IsConnectedCompatible():
                 wire.SetValid(False)
@@ -1166,7 +1196,7 @@
         self.RefreshVisibleElements()
         self.ShowHighlights()
         self.Editor.Refresh(False)
-    
+
     def GetPreviousSteps(self, connectors):
         steps = []
         for connector in connectors:
@@ -1178,7 +1208,7 @@
                     connectors = previous.GetConnectors()
                     steps.extend(self.GetPreviousSteps(connectors["inputs"]))
         return steps
-    
+
     def GetNextSteps(self, connectors):
         steps = []
         for connector in connectors:
@@ -1192,7 +1222,7 @@
                     connectors = next.GetConnectors()
                     steps.extend(self.GetNextSteps(connectors["outputs"]))
         return steps
-    
+
     def GetMaxSize(self):
         maxx = maxy = 0
         for element in self.GetElements():
@@ -1200,7 +1230,7 @@
             maxx = max(maxx, bbox.x + bbox.width)
             maxy = max(maxy, bbox.y + bbox.height)
         return maxx, maxy
-    
+
     def RefreshScrollBars(self, width_incr=0, height_incr=0):
         xstart, ystart = self.GetViewStart()
         window_size = self.Editor.GetClientSize()
@@ -1213,22 +1243,22 @@
             maxy = max(maxy, extent.y + extent.height)
         maxx = int(maxx * self.ViewScale[0])
         maxy = int(maxy * self.ViewScale[1])
-        self.Editor.SetScrollbars(SCROLLBAR_UNIT, SCROLLBAR_UNIT, 
-            round(maxx / SCROLLBAR_UNIT) + width_incr, round(maxy / SCROLLBAR_UNIT) + height_incr, 
+        self.Editor.SetScrollbars(SCROLLBAR_UNIT, SCROLLBAR_UNIT,
+            round(maxx / SCROLLBAR_UNIT) + width_incr, round(maxy / SCROLLBAR_UNIT) + height_incr,
             xstart, ystart, True)
-    
+
     def EnsureVisible(self, block):
         xstart, ystart = self.GetViewStart()
         window_size = self.Editor.GetClientSize()
         block_bbx = block.GetBoundingBox()
-        
+
         screen_minx, screen_miny = xstart * SCROLLBAR_UNIT, ystart * SCROLLBAR_UNIT
         screen_maxx, screen_maxy = screen_minx + window_size[0], screen_miny + window_size[1]
-        block_minx = int(block_bbx.x * self.ViewScale[0]) 
+        block_minx = int(block_bbx.x * self.ViewScale[0])
         block_miny = int(block_bbx.y * self.ViewScale[1])
         block_maxx = int(round((block_bbx.x + block_bbx.width) * self.ViewScale[0]))
         block_maxy = int(round((block_bbx.y + block_bbx.height) * self.ViewScale[1]))
-        
+
         xpos, ypos = xstart, ystart
         if block_minx < screen_minx and block_maxx < screen_maxx:
             xpos -= (screen_minx - block_minx) / SCROLLBAR_UNIT + 1
@@ -1239,7 +1269,7 @@
         elif block_maxy > screen_maxy and block_miny > screen_miny:
             ypos += (block_maxy - screen_maxy) / SCROLLBAR_UNIT + 1
         self.Scroll(xpos, ypos)
-    
+
     def SelectInGroup(self, element):
         element.SetSelected(True)
         if self.SelectedElement is None:
@@ -1251,7 +1281,7 @@
             group.AddElement(self.SelectedElement)
             group.AddElement(element)
             self.SelectedElement = group
-        
+
     # Load instance from given informations
     def loadInstance(self, instance, remaining_instances, selection):
         self.current_id = max(self.current_id, instance.id)
@@ -1295,9 +1325,9 @@
                 connectors["outputs"].pop(0)
                 executionControl = True
             block_name = specific_values.name if specific_values.name is not None else ""
-            element = FBD_Block(self, instance.type, block_name, 
-                      instance.id, len(connectors["inputs"]), 
-                      connectors=connectors, executionControl=executionControl, 
+            element = FBD_Block(self, instance.type, block_name,
+                      instance.id, len(connectors["inputs"]),
+                      connectors=connectors, executionControl=executionControl,
                       executionOrder=specific_values.execution_order)
         if isinstance(element, Comment):
             self.AddComment(element)
@@ -1351,20 +1381,20 @@
             if refLocalId is None:
                 links_connected = False
                 continue
-            
+
             new_instance = remaining_instances.pop(refLocalId, None)
             if new_instance is not None:
                 self.loadInstance(new_instance, remaining_instances, selection)
-            
+
             connected = self.FindElementById(refLocalId)
             if connected is None:
                 links_connected = False
                 continue
-            
+
             points = link.points
             end_connector = connected.GetConnector(
                 wx.Point(points[-1].x, points[-1].y)
-                if len(points) > 0 else wx.Point(0, 0), 
+                if len(points) > 0 else wx.Point(0, 0),
                 link.formalParameter)
             if end_connector is not None:
                 if len(points) > 0:
@@ -1372,7 +1402,7 @@
                     wire.SetPoints(points)
                 else:
                     wire = Wire(self,
-                        [wx.Point(*start_connector.GetPosition()), 
+                        [wx.Point(*start_connector.GetPosition()),
                          start_connector.GetDirection()],
                         [wx.Point(*end_connector.GetPosition()),
                          end_connector.GetDirection()])
@@ -1388,12 +1418,12 @@
                     self.SelectInGroup(wire)
             else:
                 links_connected = False
-        
+
         return links_connected
-                        
+
     def IsOfType(self, type, reference):
         return self.Controler.IsOfType(type, reference, self.Debug)
-    
+
     def IsEndType(self, type):
         return self.Controler.IsEndType(type)
 
@@ -1411,7 +1441,7 @@
             if block.HitTest(pos) or block.TestHandle(event) != (0, 0):
                 return block
         return None
-    
+
     def FindWire(self, event):
         dc = self.GetLogicalDC()
         pos = event.GetLogicalPosition(dc)
@@ -1419,7 +1449,7 @@
             if wire.HitTest(pos) or wire.TestHandle(event) != (0, 0):
                 return wire
         return None
-    
+
     def FindElement(self, event, exclude_group = False, connectors = True):
         dc = self.GetLogicalDC()
         pos = event.GetLogicalPosition(dc)
@@ -1430,14 +1460,14 @@
             if element.HitTest(pos, connectors) or element.TestHandle(event) != (0, 0):
                 return element
         return None
-    
+
     def FindBlockConnector(self, pos, direction = None, exclude = None):
         for block in self.Blocks.itervalues():
             result = block.TestConnector(pos, direction, exclude)
             if result:
                 return result
         return None
-    
+
     def FindElementById(self, id):
         block = self.Blocks.get(id, None)
         if block is not None:
@@ -1446,7 +1476,7 @@
         if comment is not None:
             return comment
         return None
-    
+
     def SearchElements(self, bbox):
         elements = []
         for element in self.GetElements():
@@ -1460,7 +1490,7 @@
         self.SelectedElement = Graphic_Group(self)
         self.SelectedElement.SetElements(self.GetElements())
         self.SelectedElement.SetSelected(True)
-    
+
 #-------------------------------------------------------------------------------
 #                           Popup menu functions
 #-------------------------------------------------------------------------------
@@ -1516,7 +1546,7 @@
             self.AddDefaultMenuItems(menu, block=True, edit=edit)
         self.Editor.PopupMenu(menu)
         menu.Destroy()
-    
+
     def PopupVariableMenu(self):
         menu = wx.Menu(title='')
         variable_type = self.SelectedElement.GetType()
@@ -1532,7 +1562,7 @@
         self.AddDefaultMenuItems(menu, block=True)
         self.Editor.PopupMenu(menu)
         menu.Destroy()
-    
+
     def PopupConnectionMenu(self):
         menu = wx.Menu(title='')
         connection_type = self.SelectedElement.GetType()
@@ -1547,26 +1577,26 @@
         self.AddDefaultMenuItems(menu, block=True)
         self.Editor.PopupMenu(menu)
         menu.Destroy()
-    
+
     def PopupWireMenu(self, delete=True):
         menu = wx.Menu(title='')
-        
+
         # If Check that wire can be replace by connections or abort
         connected = self.SelectedElement.GetConnected()
         start_connector = (
             self.SelectedElement.GetEndConnected()
             if self.SelectedElement.GetStartConnected() in connected
             else self.SelectedElement.GetStartConnected())
-        
+
         self.AddWireMenuItems(menu, delete,
-            start_connector.GetDirection() == EAST and 
+            start_connector.GetDirection() == EAST and
             not isinstance(start_connector.GetParentBlock(), SFC_Step))
-        
+
         menu.AppendSeparator()
         self.AddDefaultMenuItems(menu, block=True)
         self.Editor.PopupMenu(menu)
         menu.Destroy()
-        
+
     def PopupDivergenceMenu(self, connector):
         menu = wx.Menu(title='')
         self.AddDivergenceMenuItems(menu, connector)
@@ -1574,7 +1604,7 @@
         self.AddDefaultMenuItems(menu, block=True)
         self.Editor.PopupMenu(menu)
         menu.Destroy()
-    
+
     def PopupGroupMenu(self):
         menu = wx.Menu(title='')
         align_menu = wx.Menu(title='')
@@ -1584,7 +1614,7 @@
         self.AddDefaultMenuItems(menu, block=True)
         self.Editor.PopupMenu(menu)
         menu.Destroy()
-        
+
     def PopupDefaultMenu(self, block=True):
         menu = wx.Menu(title='')
         self.AddDefaultMenuItems(menu, block=block)
@@ -1600,43 +1630,43 @@
             self.SelectedElement.AlignElements(ALIGN_LEFT, None)
             self.RefreshBuffer()
             self.Editor.Refresh(False)
-    
+
     def OnAlignCenterMenu(self, event):
         if self.SelectedElement is not None and isinstance(self.SelectedElement, Graphic_Group):
             self.SelectedElement.AlignElements(ALIGN_CENTER, None)
             self.RefreshBuffer()
             self.Editor.Refresh(False)
-    
+
     def OnAlignRightMenu(self, event):
         if self.SelectedElement is not None and isinstance(self.SelectedElement, Graphic_Group):
             self.SelectedElement.AlignElements(ALIGN_RIGHT, None)
             self.RefreshBuffer()
             self.Editor.Refresh(False)
-    
+
     def OnAlignTopMenu(self, event):
         if self.SelectedElement is not None and isinstance(self.SelectedElement, Graphic_Group):
             self.SelectedElement.AlignElements(None, ALIGN_TOP)
             self.RefreshBuffer()
             self.Editor.Refresh(False)
-    
+
     def OnAlignMiddleMenu(self, event):
         if self.SelectedElement is not None and isinstance(self.SelectedElement, Graphic_Group):
             self.SelectedElement.AlignElements(None, ALIGN_MIDDLE)
             self.RefreshBuffer()
             self.Editor.Refresh(False)
-    
+
     def OnAlignBottomMenu(self, event):
         if self.SelectedElement is not None and isinstance(self.SelectedElement, Graphic_Group):
             self.SelectedElement.AlignElements(None, ALIGN_BOTTOM)
             self.RefreshBuffer()
             self.Editor.Refresh(False)
-        
+
     def OnNoModifierMenu(self, event):
         if self.SelectedElement is not None and self.IsBlock(self.SelectedElement):
             self.SelectedElement.SetConnectorNegated(False)
             self.SelectedElement.Refresh()
             self.RefreshBuffer()
-    
+
     def OnNegatedMenu(self, event):
         if self.SelectedElement is not None and self.IsBlock(self.SelectedElement):
             self.SelectedElement.SetConnectorNegated(True)
@@ -1664,16 +1694,16 @@
         if self.SelectedElement is not None and self.IsWire(self.SelectedElement):
             self.SelectedElement.DeleteSegment()
             self.SelectedElement.Refresh()
-    
+
     def OnReplaceWireMenu(self, event):
         # Check that selected element is a wire before applying replace
-        if (self.SelectedElement is not None and 
+        if (self.SelectedElement is not None and
             self.IsWire(self.SelectedElement)):
-            
+
             # Get wire redraw bbox to erase it from screen
             wire = self.SelectedElement
             redraw_rect = wire.GetRedrawRect()
-            
+
             # Get connector at both ends of wire
             connected = wire.GetConnected()
             if wire.GetStartConnected() in connected:
@@ -1686,25 +1716,25 @@
                 end_connector = wire.GetEndConnected()
                 wire.UnConnectEndPoint()
                 point_to_connect = -1
-            
+
             # Get a new default connection name
             connection_name = self.Controler.GenerateNewName(
                     self.TagName, None, "Connection%d", 0)
-            
+
             # Create a connector to connect to wire
             id = self.GetNewId()
             connection = FBD_Connector(self, CONNECTOR, connection_name, id)
             connection.SetSize(*self.GetScaledSize(*connection.GetMinSize()))
-            
-            # Calculate position of connector at the right of start connector 
+
+            # Calculate position of connector at the right of start connector
             connector = connection.GetConnectors()["inputs"][0]
             rel_pos = connector.GetRelPosition()
             direction = connector.GetDirection()
             start_point = start_connector.GetPosition(False)
             end_point = (start_point[0] + LD_WIRE_SIZE, start_point[1])
-            connection.SetPosition(end_point[0] - rel_pos[0], 
+            connection.SetPosition(end_point[0] - rel_pos[0],
                                    end_point[1] - rel_pos[1])
-            
+
             # Connect connector to wire
             connector.Connect((wire, point_to_connect))
             if point_to_connect == 0:
@@ -1714,33 +1744,33 @@
             # Update redraw bbox with new wire trace so that it will be redraw
             # on screen
             redraw_rect.Union(wire.GetRedrawRect())
-            
+
             # Add connector to Viewer and model
             self.AddBlock(connection)
-            self.Controler.AddEditedElementConnection(self.TagName, id, 
+            self.Controler.AddEditedElementConnection(self.TagName, id,
                                                       CONNECTOR)
             connection.RefreshModel()
             # Update redraw bbox with new connector bbox so that it will be
             # drawn on screen
             redraw_rect.Union(connection.GetRedrawRect())
-            
+
             # Add new continuation
             id = self.GetNewId()
             connection = FBD_Connector(self, CONTINUATION, connection_name, id)
             connection.SetSize(*self.GetScaledSize(*connection.GetMinSize()))
-            
+
             # Calculate position of connection at the left of end connector
             connector = connection.GetConnectors()["outputs"][0]
             rel_pos = connector.GetRelPosition()
             direction = connector.GetDirection()
             end_point = end_connector.GetPosition(False)
             start_point = (end_point[0] - LD_WIRE_SIZE, end_point[1])
-            connection.SetPosition(start_point[0] - rel_pos[0], 
+            connection.SetPosition(start_point[0] - rel_pos[0],
                                    start_point[1] - rel_pos[1])
-            
+
             # Add Wire to Viewer and connect it to blocks
-            new_wire = Wire(self, 
-                [wx.Point(*start_point), connector.GetDirection()], 
+            new_wire = Wire(self,
+                [wx.Point(*start_point), connector.GetDirection()],
                 [wx.Point(*end_point), end_connector.GetDirection()])
             self.AddWire(new_wire)
             connector.Connect((new_wire, 0), False)
@@ -1750,25 +1780,25 @@
             # Update redraw bbox with new wire bbox so that it will be drawn on
             # screen
             redraw_rect.Union(new_wire.GetRedrawRect())
-            
+
             # Add connection to Viewer and model
             self.AddBlock(connection)
-            self.Controler.AddEditedElementConnection(self.TagName, id, 
+            self.Controler.AddEditedElementConnection(self.TagName, id,
                                                       CONTINUATION)
             connection.RefreshModel()
             # Update redraw bbox with new connection bbox so that it will be
             # drawn on screen
             redraw_rect.Union(connection.GetRedrawRect())
-            
+
             # Refresh model for new wire
             end_connector.RefreshParentBlock()
-            
-            # Redraw 
+
+            # Redraw
             self.RefreshBuffer()
             self.RefreshScrollBars()
             self.RefreshVisibleElements()
             self.RefreshRect(self.GetScrolledRect(redraw_rect), False)
-            
+
     def OnAddBranchMenu(self, event):
         if self.SelectedElement is not None and self.IsBlock(self.SelectedElement):
             self.AddDivergenceBranch(self.SelectedElement)
@@ -1799,7 +1829,7 @@
         self.Controler.ClearEditedElementExecutionOrder(self.TagName)
         self.RefreshBuffer()
         self.RefreshView()
-        
+
     def OnResetExecutionOrderMenu(self, event):
         self.Controler.ResetEditedElementExecutionOrder(self.TagName)
         self.RefreshBuffer()
@@ -1848,7 +1878,7 @@
                 tooltip_pos.y += 10
                 self.ToolTipElement.DisplayToolTip(tooltip_pos)
         event.Skip()
-    
+
     def OnViewerLeftDown(self, event):
         self.Editor.CaptureMouse()
         self.StartMousePos = event.GetPosition()
@@ -1911,7 +1941,7 @@
                         NORTH: [NORTH, SOUTH],
                         SOUTH: [SOUTH, NORTH]}[connector.GetDirection()]
                     wire = Wire(self, *map(list, zip(
-                                           [wx.Point(pos.x, pos.y), 
+                                           [wx.Point(pos.x, pos.y),
                                             wx.Point(scaled_pos.x, scaled_pos.y)],
                                            directions)))
                     wire.oldPos = scaled_pos
@@ -1942,8 +1972,8 @@
                     else:
                         self.rubberBand.Reset()
                         self.rubberBand.OnLeftDown(event, dc, self.Scaling)
-        elif self.Mode in [MODE_BLOCK, MODE_VARIABLE, MODE_CONNECTION, MODE_COMMENT, 
-                           MODE_CONTACT, MODE_COIL, MODE_POWERRAIL, MODE_INITIALSTEP, 
+        elif self.Mode in [MODE_BLOCK, MODE_VARIABLE, MODE_CONNECTION, MODE_COMMENT,
+                           MODE_CONTACT, MODE_COIL, MODE_POWERRAIL, MODE_INITIALSTEP,
                            MODE_STEP, MODE_TRANSITION, MODE_DIVERGENCE, MODE_JUMP, MODE_ACTION]:
             self.rubberBand.Reset()
             self.rubberBand.OnLeftDown(event, self.GetLogicalDC(), self.Scaling)
@@ -1974,7 +2004,7 @@
                     self.SelectedElement.SetSelected(True)
             else:
                 bbox = self.rubberBand.GetCurrentExtent()
-                self.rubberBand.OnLeftUp(event, self.GetLogicalDC(), self.Scaling)                
+                self.rubberBand.OnLeftUp(event, self.GetLogicalDC(), self.Scaling)
                 if self.Mode == MODE_BLOCK:
                     wx.CallAfter(self.AddNewBlock, bbox)
                 elif self.Mode == MODE_VARIABLE:
@@ -2020,9 +2050,9 @@
                 elif connector is None or self.SelectedElement.GetDragging():
                     start_connector = self.SelectedElement.GetStartConnected()
                     start_direction = start_connector.GetDirection()
-                    
+
                     items = []
-                    
+
                     if self.CurrentLanguage == "SFC" and start_direction == SOUTH:
                         items.extend([
                             (_(u'Initial Step'), self.GetAddToWireMenuCallBack(self.AddNewStep, True)),
@@ -2031,9 +2061,9 @@
                             (_(u'Divergence'), self.GetAddToWireMenuCallBack(self.AddNewDivergence)),
                             (_(u'Jump'), self.GetAddToWireMenuCallBack(self.AddNewJump)),
                         ])
-                    
+
                     elif start_direction == EAST:
-                        
+
                         if isinstance(start_connector.GetParentBlock(), SFC_Step):
                             items.append(
                                 (_(u'Action Block'), self.GetAddToWireMenuCallBack(self.AddNewActionBlock))
@@ -2044,7 +2074,7 @@
                                 (_(u'Variable'), self.GetAddToWireMenuCallBack(self.AddNewVariable, True)),
                                 (_(u'Connection'), self.GetAddToWireMenuCallBack(self.AddNewConnection)),
                             ])
-                            
+
                             if self.CurrentLanguage != "FBD":
                                 items.append(
                                     (_(u'Contact'), self.GetAddToWireMenuCallBack(self.AddNewContact))
@@ -2058,18 +2088,18 @@
                                 items.append(
                                     (_(u'Transition'), self.GetAddToWireMenuCallBack(self.AddNewTransition, True))
                                 )
-                                
+
                     if len(items) > 0:
                         if self.Editor.HasCapture():
                             self.Editor.ReleaseMouse()
-                        
+
                         # Popup contextual menu
                         menu = wx.Menu()
-                        self.AddMenuItems(menu, 
+                        self.AddMenuItems(menu,
                             [(wx.NewId(), wx.ITEM_NORMAL, text, '', callback)
                              for text, callback in items])
                         self.PopupMenu(menu)
-                    
+
                     self.SelectedElement.StartConnected.HighlightParentBlock(False)
                     if self.DrawingWire:
                         self.DrawingWire = False
@@ -2097,20 +2127,20 @@
         if self.Editor.HasCapture():
             self.Editor.ReleaseMouse()
         event.Skip()
-    
+
     def OnViewerMiddleDown(self, event):
         self.Editor.CaptureMouse()
         self.StartMousePos = event.GetPosition()
         self.StartScreenPos = self.GetScrollPos(wx.HORIZONTAL), self.GetScrollPos(wx.VERTICAL)
         event.Skip()
-        
+
     def OnViewerMiddleUp(self, event):
         self.StartMousePos = None
         self.StartScreenPos = None
         if self.Editor.HasCapture():
             self.Editor.ReleaseMouse()
         event.Skip()
-    
+
     def OnViewerRightDown(self, event):
         self.Editor.CaptureMouse()
         if self.Mode == MODE_SELECTION:
@@ -2126,7 +2156,7 @@
                     self.SelectedElement.OnRightDown(event, self.GetLogicalDC(), self.Scaling)
                 self.SelectedElement.Refresh()
         event.Skip()
-    
+
     def OnViewerRightUp(self, event):
         dc = self.GetLogicalDC()
         self.rubberBand.Reset()
@@ -2143,7 +2173,7 @@
         if self.Editor.HasCapture():
             self.Editor.ReleaseMouse()
         event.Skip()
-    
+
     def OnViewerLeftDClick(self, event):
         element = self.FindElement(event)
         if self.Mode == MODE_SELECTION and element is not None:
@@ -2151,11 +2181,11 @@
                 self.SelectedElement.SetSelected(False)
             if self.HighlightedElement is not None and self.HighlightedElement != element:
                 self.HighlightedElement.SetHighlighted(False)
-                    
+
             self.SelectedElement = element
             self.HighlightedElement = element
             self.SelectedElement.SetHighlighted(True)
-            
+
             if self.Debug:
                 if isinstance(self.SelectedElement, FBD_Block):
                     dc = self.GetLogicalDC()
@@ -2173,7 +2203,7 @@
                             "functionBlock": ITEM_FUNCTIONBLOCK,
                         }.get(self.Controler.GetPouType(instance_type))
                         if pou_type is not None and instance_type in self.Controler.GetProjectPouNames(self.Debug):
-                            self.ParentWindow.OpenDebugViewer(pou_type, 
+                            self.ParentWindow.OpenDebugViewer(pou_type,
                                 "%s.%s"%(self.GetInstancePath(True), self.SelectedElement.GetName()),
                                 self.Controler.ComputePouName(instance_type))
                 else:
@@ -2181,7 +2211,7 @@
                     if iec_path is not None:
                         if isinstance(self.SelectedElement, Wire):
                             if self.SelectedElement.EndConnected is not None:
-                                self.ParentWindow.OpenDebugViewer(ITEM_VAR_LOCAL, iec_path, 
+                                self.ParentWindow.OpenDebugViewer(ITEM_VAR_LOCAL, iec_path,
                                         self.SelectedElement.EndConnected.GetType())
                         else:
                             self.ParentWindow.OpenDebugViewer(ITEM_VAR_LOCAL, iec_path, "BOOL")
@@ -2192,7 +2222,7 @@
                     else:
                         instance_type = None
                     if instance_type in self.Controler.GetProjectPouNames(self.Debug):
-                        self.ParentWindow.EditProjectElement(ITEM_POU, 
+                        self.ParentWindow.EditProjectElement(ITEM_POU,
                                 self.Controler.ComputePouName(instance_type))
                     else:
                         self.SelectedElement.OnLeftDClick(event, self.GetLogicalDC(), self.Scaling)
@@ -2204,7 +2234,7 @@
             else:
                 self.SelectedElement.OnLeftDClick(event, self.GetLogicalDC(), self.Scaling)
         event.Skip()
-    
+
     def OnViewerMotion(self, event):
         if self.Editor.HasCapture() and not event.Dragging():
             return
@@ -2229,7 +2259,7 @@
             if (not event.Dragging() and
                 gettime() - self.LastHighlightCheckTime > REFRESH_PERIOD):
                 self.LastHighlightCheckTime = gettime()
-                highlighted = self.FindElement(event, connectors=False) 
+                highlighted = self.FindElement(event, connectors=False)
                 if self.HighlightedElement is not None and self.HighlightedElement != highlighted:
                     self.HighlightedElement.SetHighlighted(False)
                     self.HighlightedElement = None
@@ -2263,7 +2293,7 @@
                     if isinstance(self.SelectedElement, FBD_Block):
                         dc = self.GetLogicalDC()
                         connector = self.SelectedElement.TestConnector(
-                            wx.Point(dc.DeviceToLogicalX(self.StartMousePos.x), 
+                            wx.Point(dc.DeviceToLogicalX(self.StartMousePos.x),
                                      dc.DeviceToLogicalY(self.StartMousePos.y)))
                         if connector is not None:
                             element = connector
@@ -2354,7 +2384,7 @@
                 movex, movey = move
                 if not event.AltDown() or event.ShiftDown():
                     movex *= scaling[0]
-                    movey *= scaling[1] 
+                    movey *= scaling[1]
                     if event.ShiftDown() and not event.AltDown():
                         movex *= 10
                         movey *= 10
@@ -2420,7 +2450,7 @@
             width = round(float(width) / float(self.Scaling[0]) + 0.4) * self.Scaling[0]
             height = round(float(height) / float(self.Scaling[1]) + 0.4) * self.Scaling[1]
         return width, height
-    
+
     def AddNewElement(self, element, bbox, wire=None, connector=None):
         min_width, min_height = (element.GetMinSize(True)
                                  if isinstance(element, (LD_PowerRail,
@@ -2449,7 +2479,7 @@
         self.RefreshScrollBars()
         self.RefreshVisibleElements()
         element.Refresh()
-    
+
     def AddNewBlock(self, bbox, wire=None):
         dialog = FBDBlockDialog(self.ParentWindow, self.Controler, self.TagName)
         dialog.SetPreviewFont(self.GetFont())
@@ -2458,8 +2488,8 @@
             id = self.GetNewId()
             values = dialog.GetValues()
             values.setdefault("name", "")
-            block = FBD_Block(self, values["type"], values["name"], id, 
-                    values["extension"], values["inputs"], 
+            block = FBD_Block(self, values["type"], values["name"], id,
+                    values["extension"], values["inputs"],
                     executionControl = values["executionControl"],
                     executionOrder = values["executionOrder"])
             self.Controler.AddEditedElementBlock(self.TagName, id, values["type"], values.get("name", None))
@@ -2472,7 +2502,7 @@
                         break
             self.AddNewElement(block, bbox, wire, connector)
         dialog.Destroy()
-    
+
     def AddNewVariable(self, bbox, exclude_input=False, wire=None):
         dialog = FBDVariableDialog(self.ParentWindow, self.Controler, self.TagName, exclude_input)
         dialog.SetPreviewFont(self.GetFont())
@@ -2505,11 +2535,11 @@
             connection = FBD_Connector(self, values["type"], values["name"], id)
             self.Controler.AddEditedElementConnection(self.TagName, id, values["type"])
             self.AddNewElement(connection, bbox, wire)
-    
+
     def AddNewComment(self, bbox):
-        dialog = wx.TextEntryDialog(self.ParentWindow, 
-                                    _("Edit comment"), 
-                                    _("Please enter comment text"), 
+        dialog = wx.TextEntryDialog(self.ParentWindow,
+                                    _("Edit comment"),
+                                    _("Please enter comment text"),
                                     "", wx.OK|wx.CANCEL|wx.TE_MULTILINE)
         dialog.SetClientSize(wx.Size(400, 200))
         if dialog.ShowModal() == wx.ID_OK:
@@ -2592,11 +2622,11 @@
             step = SFC_Step(self, values["name"], initial, id)
             self.Controler.AddEditedElementStep(self.TagName, id)
             for connector in ["input", "output", "action"]:
-                getattr(step, ("Add" 
-                               if values[connector] 
+                getattr(step, ("Add"
+                               if values[connector]
                                else "Remove") + connector.capitalize())()
             self.AddNewElement(step, bbox, wire)
-    
+
     def AddNewTransition(self, bbox, connection=False, wire=None):
         if wire is not None and connection:
             values = {
@@ -2620,7 +2650,7 @@
             else:
                 connector = transition.GetConnectors()["inputs"][0]
             self.AddNewElement(transition, bbox, wire, connector)
-    
+
     def AddNewDivergence(self, bbox, wire=None):
         dialog = SFCDivergenceDialog(self.ParentWindow, self.Controler, self.TagName)
         dialog.SetPreviewFont(self.GetFont())
@@ -2638,8 +2668,8 @@
         for block in self.Blocks.itervalues():
             if isinstance(block, SFC_Step):
                 choices.append(block.GetName())
-        dialog = wx.SingleChoiceDialog(self.ParentWindow, 
-              _("Add a new jump"), _("Please choose a target"), 
+        dialog = wx.SingleChoiceDialog(self.ParentWindow,
+              _("Add a new jump"), _("Please choose a target"),
               choices, wx.DEFAULT_DIALOG_STYLE|wx.OK|wx.CANCEL)
         if dialog.ShowModal() == wx.ID_OK:
             id = self.GetNewId()
@@ -2668,11 +2698,11 @@
         dialog = FBDBlockDialog(self.ParentWindow, self.Controler, self.TagName)
         dialog.SetPreviewFont(self.GetFont())
         dialog.SetMinElementSize(block.GetSize())
-        old_values = {"name" : block.GetName(), 
-                      "type" : block.GetType(), 
-                      "extension" : block.GetExtension(), 
-                      "inputs" : block.GetInputTypes(), 
-                      "executionControl" : block.GetExecutionControl(), 
+        old_values = {"name" : block.GetName(),
+                      "type" : block.GetType(),
+                      "extension" : block.GetExtension(),
+                      "inputs" : block.GetInputTypes(),
+                      "executionControl" : block.GetExecutionControl(),
                       "executionOrder" : block.GetExecutionOrder()}
         dialog.SetValues(old_values)
         if dialog.ShowModal() == wx.ID_OK:
@@ -2702,7 +2732,7 @@
         dialog = FBDVariableDialog(self.ParentWindow, self.Controler, self.TagName)
         dialog.SetPreviewFont(self.GetFont())
         dialog.SetMinElementSize(variable.GetSize())
-        old_values = {"expression" : variable.GetName(), "class" : variable.GetType(), 
+        old_values = {"expression" : variable.GetName(), "class" : variable.GetType(),
                       "executionOrder" : variable.GetExecutionOrder()}
         dialog.SetValues(old_values)
         if dialog.ShowModal() == wx.ID_OK:
@@ -2758,12 +2788,12 @@
                 self.RefreshScrollBars()
                 self.RefreshVisibleElements()
                 connection.Refresh(rect)
-        
+
     def EditContactContent(self, contact):
         dialog = LDElementDialog(self.ParentWindow, self.Controler, self.TagName, "contact")
         dialog.SetPreviewFont(self.GetFont())
         dialog.SetMinElementSize(contact.GetSize())
-        dialog.SetValues({"variable" : contact.GetName(), 
+        dialog.SetValues({"variable" : contact.GetName(),
                           "modifier" : contact.GetType()})
         if dialog.ShowModal() == wx.ID_OK:
             values = dialog.GetValues()
@@ -2783,7 +2813,7 @@
         dialog = LDElementDialog(self.ParentWindow, self.Controler, self.TagName, "coil")
         dialog.SetPreviewFont(self.GetFont())
         dialog.SetMinElementSize(coil.GetSize())
-        dialog.SetValues({"variable" : coil.GetName(), 
+        dialog.SetValues({"variable" : coil.GetName(),
                           "modifier" : coil.GetType()})
         if dialog.ShowModal() == wx.ID_OK:
             values = dialog.GetValues()
@@ -2848,7 +2878,7 @@
             else:
                 step.RemoveOutput()
             if values["action"]:
-                step.AddAction()    
+                step.AddAction()
             else:
                 step.RemoveAction()
             step.UpdateSize(*self.GetScaledSize(values["width"], values["height"]))
@@ -2858,7 +2888,7 @@
             self.RefreshScrollBars()
             self.RefreshVisibleElements()
             step.Refresh(rect)
-        
+
     def EditTransitionContent(self, transition):
         dialog = SFCTransitionDialog(self.ParentWindow, self.Controler, self.TagName, self.GetDrawingMode() == FREEDRAWING_MODE)
         dialog.SetPreviewFont(self.GetFont())
@@ -2882,8 +2912,8 @@
         for block in self.Blocks.itervalues():
             if isinstance(block, SFC_Step):
                 choices.append(block.GetName())
-        dialog = wx.SingleChoiceDialog(self.ParentWindow, 
-              _("Edit jump target"), _("Please choose a target"), 
+        dialog = wx.SingleChoiceDialog(self.ParentWindow,
+              _("Edit jump target"), _("Please choose a target"),
               choices, wx.DEFAULT_DIALOG_STYLE|wx.OK|wx.CANCEL)
         dialog.SetSelection(choices.index(jump.GetTarget()))
         if dialog.ShowModal() == wx.ID_OK:
@@ -2918,10 +2948,10 @@
         dialog.Destroy()
 
     def EditCommentContent(self, comment):
-        dialog = wx.TextEntryDialog(self.ParentWindow, 
-                                    _("Edit comment"), 
-                                    _("Please enter comment text"), 
-                                    comment.GetContent(), 
+        dialog = wx.TextEntryDialog(self.ParentWindow,
+                                    _("Edit comment"),
+                                    _("Please enter comment text"),
+                                    comment.GetContent(),
                                     wx.OK|wx.CANCEL|wx.TE_MULTILINE)
         dialog.SetClientSize(wx.Size(400, 200))
         if dialog.ShowModal() == wx.ID_OK:
@@ -2952,7 +2982,7 @@
         infos["width"], infos["height"] = block.GetSize()
         infos["connectors"] = block.GetConnectors()
         self.Controler.SetEditedElementBlockInfos(self.TagName, blockid, infos)
-    
+
     def ChangeVariableType(self, variable, new_type):
         old_type = variable.GetType()
         rect = variable.GetRedrawRect(1, 1)
@@ -2966,7 +2996,7 @@
             self.RefreshVisibleElements()
             self.RefreshScrollBars()
             variable.Refresh(rect.Union(variable.GetRedrawRect()))
-    
+
     def RefreshVariableModel(self, variable):
         variableid = variable.GetId()
         infos = {}
@@ -3105,7 +3135,7 @@
             element.RefreshModel()
         wx.CallAfter(self.RefreshVariablePanel)
         wx.CallAfter(self.ParentWindow.RefreshPouInstanceVariablesPanel)
-        
+
     def DeleteVariable(self, variable):
         connectors = variable.GetConnectors()
         if len(connectors["outputs"]) > 0:
@@ -3190,7 +3220,7 @@
         self.Controler.RemoveEditedElementInstance(self.TagName, step.GetId())
         for element in elements:
             element.RefreshModel()
-            
+
     def DeleteTransition(self, transition):
         elements = []
         connectors = transition.GetConnectors()
@@ -3215,12 +3245,12 @@
         self.Controler.RemoveEditedElementInstance(self.TagName, divergence.GetId())
         for element in elements:
             element.RefreshModel()
-    
+
     def DeleteJump(self, jump):
         jump.Clean()
         self.RemoveBlock(jump)
         self.Controler.RemoveEditedElementInstance(self.TagName, jump.GetId())
-    
+
     def DeleteActionBlock(self, actionblock):
         actionblock.Clean()
         self.RemoveBlock(actionblock)
@@ -3230,7 +3260,7 @@
 #-------------------------------------------------------------------------------
 #                            Editing functions
 #-------------------------------------------------------------------------------
-    
+
     def Cut(self):
         if not self.Debug and (self.IsBlock(self.SelectedElement) or self.IsComment(self.SelectedElement) or isinstance(self.SelectedElement, Graphic_Group)):
             blocks, wires = self.SelectedElement.GetDefinition()
@@ -3244,13 +3274,13 @@
             self.RefreshVariablePanel()
             self.ParentWindow.RefreshPouInstanceVariablesPanel()
             self.RefreshRect(self.GetScrolledRect(rect), False)
-        
+
     def Copy(self):
         if not self.Debug and (self.IsBlock(self.SelectedElement) or self.IsComment(self.SelectedElement) or isinstance(self.SelectedElement, Graphic_Group)):
             blocks, wires = self.SelectedElement.GetDefinition()
             text = self.Controler.GetEditedElementInstancesCopy(self.TagName, blocks, wires, self.Debug)
             self.ParentWindow.SetCopyBuffer(text)
-            
+
     def Paste(self, bbx=None):
         if not self.Debug:
             element = self.ParentWindow.GetCopyBuffer()
@@ -3296,10 +3326,10 @@
             if blocktype is None:
                 blocktype = "Block"
             format = "%s%%d" % blocktype
-        return self.Controler.GenerateNewName(self.TagName, 
-                                              None, 
-                                              format, 
-                                              exclude=exclude, 
+        return self.Controler.GenerateNewName(self.TagName,
+                                              None,
+                                              format,
+                                              exclude=exclude,
                                               debug=self.Debug)
 
     def IsNamedElement(self, element):
@@ -3318,7 +3348,7 @@
                 block = element.Clone(self, new_id, pos=pos)
             self.AddBlockInModel(block)
         return block
-    
+
     def AddBlockInModel(self, block):
         if isinstance(block, Comment):
             self.AddComment(block)
@@ -3346,16 +3376,16 @@
                 self.RefreshPowerRailModel(block)
             elif isinstance(block, SFC_Step):
                 self.Controler.AddEditedElementStep(self.TagName, block.GetId())
-                self.RefreshStepModel(block)    
+                self.RefreshStepModel(block)
             elif isinstance(block, SFC_Transition):
                 self.Controler.AddEditedElementTransition(self.TagName, block.GetId())
-                self.RefreshTransitionModel(block)       
+                self.RefreshTransitionModel(block)
             elif isinstance(block, SFC_Divergence):
                 self.Controler.AddEditedElementDivergence(self.TagName, block.GetId(), block.GetType())
                 self.RefreshDivergenceModel(block)
             elif isinstance(block, SFC_Jump):
                 self.Controler.AddEditedElementJump(self.TagName, block.GetId())
-                self.RefreshJumpModel(block)       
+                self.RefreshJumpModel(block)
             elif isinstance(block, SFC_ActionBlock):
                 self.Controler.AddEditedElementActionBlock(self.TagName, block.GetId())
                 self.RefreshActionBlockModel(block)
@@ -3367,15 +3397,15 @@
     def Find(self, direction, search_params):
         if self.SearchParams != search_params:
             self.ClearHighlights(SEARCH_RESULT_HIGHLIGHT)
-            
+
             self.SearchParams = search_params
             criteria = {
-                "raw_pattern": search_params["find_pattern"], 
+                "raw_pattern": search_params["find_pattern"],
                 "pattern": re.compile(search_params["find_pattern"]),
                 "case_sensitive": search_params["case_sensitive"],
                 "regular_expression": search_params["regular_expression"],
                 "filter": "all"}
-            
+
             self.SearchResults = []
             blocks = []
             for infos, start, end, text in self.Controler.SearchInPou(self.TagName, criteria, self.Debug):
@@ -3388,7 +3418,7 @@
             blocks.sort(sort_blocks)
             self.SearchResults.extend([infos for block, infos in blocks])
             self.CurrentFindHighlight = None
-        
+
         if len(self.SearchResults) > 0:
             if self.CurrentFindHighlight is not None:
                 old_idx = self.SearchResults.index(self.CurrentFindHighlight)
@@ -3403,12 +3433,12 @@
             else:
                 self.CurrentFindHighlight = self.SearchResults[0]
                 self.AddHighlight(*self.CurrentFindHighlight)
-            
+
         else:
             if self.CurrentFindHighlight is not None:
                 self.RemoveHighlight(*self.CurrentFindHighlight)
             self.CurrentFindHighlight = None
-        
+
 #-------------------------------------------------------------------------------
 #                        Highlights showing functions
 #-------------------------------------------------------------------------------
@@ -3419,7 +3449,7 @@
 
     def ClearHighlights(self, highlight_type=None):
         EditorPanel.ClearHighlights(self, highlight_type)
-        
+
         if highlight_type is None:
             self.Highlights = []
         else:
@@ -3428,28 +3458,28 @@
 
     def AddHighlight(self, infos, start, end, highlight_type):
         EditorPanel.AddHighlight(self, infos, start, end, highlight_type)
-        
+
         self.Highlights.append((infos, start, end, highlight_type))
         if infos[0] not in ["var_local", "var_input", "var_output", "var_inout"]:
             block = self.Blocks.get(infos[1])
             if block is not None:
                 self.EnsureVisible(block)
             self.RefreshHighlightsTimer.Start(int(REFRESH_HIGHLIGHT_PERIOD * 1000), oneShot=True)
-    
+
     def RemoveHighlight(self, infos, start, end, highlight_type):
         EditorPanel.RemoveHighlight(self, infos, start, end, highlight_type)
-        
+
         if (infos, start, end, highlight_type) in self.Highlights:
             self.Highlights.remove((infos, start, end, highlight_type))
             self.RefreshHighlightsTimer.Start(int(REFRESH_HIGHLIGHT_PERIOD * 1000), oneShot=True)
-    
+
     def ShowHighlights(self):
         for infos, start, end, highlight_type in self.Highlights:
             if infos[0] in ["comment", "io_variable", "block", "connector", "coil", "contact", "step", "transition", "jump", "action_block"]:
                 block = self.FindElementById(infos[1])
                 if block is not None:
                     block.AddHighlight(infos[2:], start, end, highlight_type)
-        
+
 #-------------------------------------------------------------------------------
 #                            Drawing functions
 #-------------------------------------------------------------------------------
@@ -3465,7 +3495,7 @@
             self.RefreshVisibleElements(xp = event.GetPosition())
         else:
             self.RefreshVisibleElements(yp = event.GetPosition())
-        
+
         # Handle scroll in debug to fully redraw area and ensuring
         # instance path is fully draw without flickering
         if self.Debug and wx.Platform != '__WXMSW__':
@@ -3498,7 +3528,7 @@
                 yp = max(0, min(y - rotation * 3, self.Editor.GetVirtualSize()[1] / self.Editor.GetScrollPixelsPerUnit()[1]))
                 self.RefreshVisibleElements(yp = yp)
                 self.Scroll(x, yp)
-            
+
     def OnMoveWindow(self, event):
         client_size = self.GetClientSize()
         if self.LastClientSize != client_size:
@@ -3532,12 +3562,12 @@
             xstart, ystart = self.GetViewStart()
             window_size = self.Editor.GetClientSize()
             for x in xrange(self.PageSize[0] - (xstart * SCROLLBAR_UNIT) % self.PageSize[0], int(window_size[0] / self.ViewScale[0]), self.PageSize[0]):
-                dc.DrawLine(xstart * SCROLLBAR_UNIT + x + 1, int(ystart * SCROLLBAR_UNIT / self.ViewScale[0]), 
+                dc.DrawLine(xstart * SCROLLBAR_UNIT + x + 1, int(ystart * SCROLLBAR_UNIT / self.ViewScale[0]),
                             xstart * SCROLLBAR_UNIT + x + 1, int((ystart * SCROLLBAR_UNIT + window_size[1]) / self.ViewScale[0]))
             for y in xrange(self.PageSize[1] - (ystart * SCROLLBAR_UNIT) % self.PageSize[1], int(window_size[1] / self.ViewScale[1]), self.PageSize[1]):
-                dc.DrawLine(int(xstart * SCROLLBAR_UNIT / self.ViewScale[0]), ystart * SCROLLBAR_UNIT + y + 1, 
+                dc.DrawLine(int(xstart * SCROLLBAR_UNIT / self.ViewScale[0]), ystart * SCROLLBAR_UNIT + y + 1,
                             int((xstart * SCROLLBAR_UNIT + window_size[0]) / self.ViewScale[1]), ystart * SCROLLBAR_UNIT + y + 1)
-        
+
         # Draw all elements
         for comment in self.Comments.itervalues():
             if comment != self.SelectedElement and (comment.IsVisible() or printing):
@@ -3553,15 +3583,15 @@
         for block in self.Blocks.itervalues():
             if block != self.SelectedElement and (block.IsVisible() or printing):
                 block.Draw(dc)
-        
+
         if self.SelectedElement is not None and (self.SelectedElement.IsVisible() or printing):
             self.SelectedElement.Draw(dc)
-        
+
         if not printing:
             if self.Debug:
                 scalex, scaley = dc.GetUserScale()
                 dc.SetUserScale(1, 1)
-                
+
                 is_action = self.TagName.split("::")[0] == "A"
                 text = _("Debug: %s") % self.InstancePath
                 if is_action and self.Value is not None:
@@ -3578,9 +3608,9 @@
                         dc.SetTextForeground(wx.BLACK)
                     vw, vh = dc.GetTextExtent(value_text)
                     dc.DrawText(")", text_offset_x + tw + vw + 2, text_offset_y)
-                
+
                 dc.SetUserScale(scalex, scaley)
-                
+
             if self.rubberBand.IsShown():
                 self.rubberBand.Draw(dc)
             dc.EndDrawing()
--- a/tests/python/plc.xml	Fri Jun 06 18:30:49 2014 +0100
+++ b/tests/python/plc.xml	Tue Jul 08 18:01:33 2014 +0100
@@ -1,7 +1,7 @@
 <?xml version='1.0' encoding='utf-8'?>
 <project xmlns="http://www.plcopen.org/xml/tc6_0201" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xhtml="http://www.w3.org/1999/xhtml" xsi:schemaLocation="http://www.plcopen.org/xml/tc6_0201">
   <fileHeader companyName="" productName="Beremiz" productVersion="0.0" creationDateTime="2008-12-14T16:21:19"/>
-  <contentHeader name="Beremiz Python Support Tests" modificationDateTime="2014-03-27T09:15:55">
+  <contentHeader name="Beremiz Python Support Tests" modificationDateTime="2014-06-12T17:48:28">
     <coordinateInfo>
       <pageSize x="1024" y="1024"/>
       <fbd>
@@ -44,6 +44,11 @@
           </enum>
         </baseType>
       </dataType>
+      <dataType name="datatype0">
+        <baseType>
+          <BOOL/>
+        </baseType>
+      </dataType>
     </dataTypes>
     <pous>
       <pou name="main_pytest" pouType="program">
@@ -54,6 +59,11 @@
                 <string/>
               </type>
             </variable>
+            <variable name="fefvsd">
+              <type>
+                <derived name="datatype0"/>
+              </type>
+            </variable>
             <variable name="pytest_var2">
               <type>
                 <BOOL/>
@@ -895,6 +905,10 @@
                 <variable formalParameter="IN1" negated="true">
                   <connectionPointIn>
                     <relPosition x="0" y="35"/>
+                    <connection refLocalId="50">
+                      <position x="365" y="1100"/>
+                      <position x="305" y="1100"/>
+                    </connection>
                   </connectionPointIn>
                 </variable>
                 <variable formalParameter="IN2">
@@ -927,6 +941,10 @@
               <position x="510" y="1085"/>
               <connectionPointIn>
                 <relPosition x="0" y="15"/>
+                <connection refLocalId="51" formalParameter="OUT">
+                  <position x="510" y="1100"/>
+                  <position x="435" y="1100"/>
+                </connection>
               </connectionPointIn>
               <expression>Global_RS.S</expression>
             </outVariable>
@@ -934,6 +952,10 @@
               <position x="510" y="1200"/>
               <connectionPointIn>
                 <relPosition x="0" y="15"/>
+                <connection refLocalId="41" formalParameter="OUT">
+                  <position x="510" y="1215"/>
+                  <position x="435" y="1215"/>
+                </connection>
               </connectionPointIn>
               <expression>Global_RS.R1</expression>
             </outVariable>
@@ -950,6 +972,10 @@
                 <variable formalParameter="IN1">
                   <connectionPointIn>
                     <relPosition x="0" y="35"/>
+                    <connection refLocalId="24">
+                      <position x="365" y="1215"/>
+                      <position x="305" y="1215"/>
+                    </connection>
                   </connectionPointIn>
                 </variable>
                 <variable formalParameter="IN2">
@@ -1094,12 +1120,46 @@
               </connectionPointOut>
               <expression>23</expression>
             </inVariable>
-            <comment localId="60" height="40" width="500">
-              <position x="120" y="1020"/>
-              <content>
-                <xhtml:p><![CDATA[Test for access to Gobal FB variables is disabled, as broken in matiec]]></xhtml:p>
-              </content>
-            </comment>
+            <block localId="61" typeName="function0" executionOrderId="0" height="45" width="110">
+              <position x="1680" y="255"/>
+              <inputVariables>
+                <variable formalParameter="LocalVar0">
+                  <connectionPointIn>
+                    <relPosition x="0" y="30"/>
+                    <connection refLocalId="62">
+                      <position x="1680" y="285"/>
+                      <position x="1640" y="285"/>
+                    </connection>
+                  </connectionPointIn>
+                </variable>
+              </inputVariables>
+              <inOutVariables/>
+              <outputVariables>
+                <variable formalParameter="OUT">
+                  <connectionPointOut>
+                    <relPosition x="110" y="30"/>
+                  </connectionPointOut>
+                </variable>
+              </outputVariables>
+            </block>
+            <inVariable localId="62" executionOrderId="0" height="30" width="55" negated="false">
+              <position x="1585" y="270"/>
+              <connectionPointOut>
+                <relPosition x="55" y="15"/>
+              </connectionPointOut>
+              <expression>fefvsd</expression>
+            </inVariable>
+            <outVariable localId="63" executionOrderId="0" height="30" width="55" negated="false">
+              <position x="1825" y="270"/>
+              <connectionPointIn>
+                <relPosition x="0" y="15"/>
+                <connection refLocalId="61" formalParameter="OUT">
+                  <position x="1825" y="285"/>
+                  <position x="1790" y="285"/>
+                </connection>
+              </connectionPointIn>
+              <expression>fefvsd</expression>
+            </outVariable>
           </FBD>
         </body>
       </pou>
@@ -1213,6 +1273,26 @@
           </ST>
         </body>
       </pou>
+      <pou name="function0" pouType="function">
+        <interface>
+          <returnType>
+            <derived name="datatype0"/>
+          </returnType>
+          <inputVars>
+            <variable name="LocalVar0">
+              <type>
+                <derived name="datatype0"/>
+              </type>
+            </variable>
+          </inputVars>
+        </interface>
+        <body>
+          <ST>
+            <xhtml:p><![CDATA[function0 := LocalVar0;
+]]></xhtml:p>
+          </ST>
+        </body>
+      </pou>
     </pous>
   </types>
   <instances>
--- a/util/ProcessLogger.py	Fri Jun 06 18:30:49 2014 +0100
+++ b/util/ProcessLogger.py	Tue Jul 08 18:01:33 2014 +0100
@@ -71,7 +71,8 @@
     def __init__(self, logger, Command, finish_callback = None,
                  no_stdout = False, no_stderr = False, no_gui = True,
                  timeout = None, outlimit = None, errlimit = None,
-                 endlog = None, keyword = None, kill_it = False, cwd = None):
+                 endlog = None, keyword = None, kill_it = False, cwd = None,
+                 encoding = None):
         self.logger = logger
         if not isinstance(Command, list):
             self.Command_str = Command
@@ -87,8 +88,12 @@
             self.Command = Command
             self.Command_str = subprocess.list2cmdline(self.Command)
 
-        self.Command = map(lambda x: x.encode(sys.getfilesystemencoding()),
-                           self.Command)
+        fsencoding = sys.getfilesystemencoding()
+
+        if encoding is None:
+            encoding = fsencoding
+        self.Command = [self.Command[0].encode(fsencoding)]+map(
+            lambda x: x.encode(encoding), self.Command[1:])
 
         self.finish_callback = finish_callback
         self.no_stdout = no_stdout