Fixed pou variables information loading stylesheet
authorLaurent Bessard
Wed, 09 Oct 2013 10:57:20 +0200
changeset 1347 533741e5075c
parent 1346 92efd8fe3120
child 1348 aee0a7eb833a
Fixed pou variables information loading stylesheet
PLCControler.py
controls/VariablePanel.py
dialogs/ActionBlockDialog.py
dialogs/BlockPreviewDialog.py
dialogs/SFCStepNameDialog.py
editors/LDViewer.py
editors/SFCViewer.py
editors/TextViewer.py
editors/Viewer.py
plcopen/variables_infos.xslt
plcopen/variables_infos.ysl2
util/MiniTextControler.py
--- a/PLCControler.py	Fri Oct 04 12:17:03 2013 +0200
+++ b/PLCControler.py	Wed Oct 09 10:57:20 2013 +0200
@@ -101,77 +101,89 @@
  RESOURCES, PROPERTIES] = UNEDITABLE_NAMES
 
 #-------------------------------------------------------------------------------
+#                 Helper object for loading library in xslt stylesheets
+#-------------------------------------------------------------------------------
+
+class LibraryResolver(etree.Resolver):
+
+    def __init__(self, controller, debug=False):
+        self.Controller = controller
+        self.Debug = debug
+
+    def resolve(self, url, pubid, context):
+        lib_name = os.path.basename(url)
+        if lib_name in ["project", "stdlib", "extensions"]:
+            lib_el = etree.Element(lib_name)
+            if lib_name == "project":
+                lib_el.append(deepcopy(self.Controller.GetProject(self.Debug)))
+            elif lib_name == "stdlib":
+                for lib in [StdBlockLibrary, AddnlBlockLibrary]:
+                    lib_el.append(deepcopy(lib))
+            else:
+                for ctn in self.Controller.ConfNodeTypes:
+                    lib_el.append(deepcopy(ctn["types"]))
+            return self.resolve_string(etree.tostring(lib_el), context)
+
+#-------------------------------------------------------------------------------
+#           Helpers functions for translating list of arguments
+#                       from xslt to valid arguments
+#-------------------------------------------------------------------------------
+
+_BoolValue = lambda x: x in ["true", "0"]
+
+def _translate_args(translations, args):
+    return [translate(arg[0]) if len(arg) > 0 else None 
+            for translate, arg in
+            zip(translations, args)]
+
+#-------------------------------------------------------------------------------
 #                 Helpers object for generating pou var list
 #-------------------------------------------------------------------------------
 
-def compute_dimensions(el):
-    return [
-        (dimension.get("lower"), dimension.get("upper"))
-        for dimension in el.findall("dimension")]
-
-def extract_param(el):
-    if el.tag == "Type" and el.text is None:
-        array = el.find("array")
-        return ('array', array.text, compute_dimensions(array))
-    elif el.tag == "Tree":
-        return generate_var_tree(el)
-    elif el.tag == "Edit":
-        return el.text == "True"
-    elif el.text is None:
-        return ''
-    return el.text
-
-def generate_var_tree(tree):
-    return ([
-        (var.get("name"), var.text, generate_var_tree(var))
-         for var in tree.findall("var")],
-        compute_dimensions(tree))
-
-class AddVariable(etree.XSLTExtension):
+class _VariableInfos(object):
+    __slots__ = ["Name", "Class", "Option", "Location", "InitialValue", 
+                 "Edit", "Documentation", "Type", "Tree", "Number"]
+    def __init__(self, *args):
+        for attr, value in zip(self.__slots__, args):
+            setattr(self, attr, value if value is not None else "")
+    def copy(self):
+        return _VariableInfos(*[getattr(self, attr) for attr in self.__slots__])
+
+class VariablesInfosFactory:
     
     def __init__(self, variables):
-        etree.XSLTExtension.__init__(self)
         self.Variables = variables
-    
-    def execute(self, context, self_node, input_node, output_parent):
-        infos = etree.Element('var_infos')
-        self.process_children(context, infos)
-        self.Variables.append(
-            {el.tag.replace("_", " "): extract_param(el) for el in infos})
-
-class VarTree(etree.XSLTExtension):
-    
-    def __init__(self, controller, debug):
-        etree.XSLTExtension.__init__(self)
-        self.Controller = controller
-        self.Debug = debug
-    
-    def execute(self, context, self_node, input_node, output_parent):
-        typename = input_node.get("name")
-        pou_infos = self.Controller.GetPou(typename, self.Debug)
-        if pou_infos is not None:
-            self.apply_templates(context, pou_infos, output_parent)
-            return
-        
-        datatype_infos = self.Controller.GetDataType(typename, self.Debug)
-        if datatype_infos is not None:
-            self.apply_templates(context, datatype_infos, output_parent)
-            return
-
-class VarIsEdited(etree.XSLTExtension):
-    
-    def __init__(self, controller, debug):
-        etree.XSLTExtension.__init__(self)
-        self.Controller = controller
-        self.Debug = debug
-    
-    def execute(self, context, self_node, input_node, output_parent):
-        typename = input_node.get("name")
-        output_parent.text = str(
-            self.Controller.GetPou(typename, self.Debug) is None)
-
-variables_infos_xslt = etree.parse(
-    os.path.join(ScriptDirectory, "plcopen", "variables_infos.xslt"))
+        self.TreeStack = []
+        self.Type = None
+        self.Dimensions = None
+    
+    def SetType(self, context, *args):
+        self.Type = args[0][0]
+        
+    def GetType(self):
+        if len(self.Dimensions) > 0:
+            return ("array", self.Type, self.Dimensions)
+        return self.Type
+    
+    def GetTree(self):
+        return (self.TreeStack.pop(-1), self.Dimensions)
+    
+    def AddDimension(self, context, *args):
+        self.Dimensions.append(tuple(
+            _translate_args([str] * 2, args)))
+    
+    def AddTree(self, context, *args):
+        self.TreeStack.append([])
+        self.Dimensions = []
+    
+    def AddVarToTree(self, context, *args):
+        var = (args[0][0], self.Type, self.GetTree())
+        self.TreeStack[-1].append(var)
+    
+    def AddVariable(self, context, *args):
+        self.Variables.append(_VariableInfos(*(_translate_args(
+            [str] * 5 + [_BoolValue] + [str], args) + 
+            [self.GetType(), self.GetTree()])))
 
 #-------------------------------------------------------------------------------
 #            Helpers object for generating pou variable instance list
@@ -349,8 +361,6 @@
 #           Helpers object for generating pou block instances list
 #-------------------------------------------------------------------------------
 
-_BoolValue = lambda x: x in ["true", "0"]
-
 _Point = namedtuple("Point", ["x", "y"])
 
 _BlockInstanceInfos = namedtuple("BlockInstanceInfos", 
@@ -427,11 +437,6 @@
     def copy(self):
         return _ActionInfos(*[getattr(self, attr) for attr in self.__slots__])
 
-def _translate_args(translations, args):
-    return [translate(arg[0]) if len(arg) > 0 else None 
-            for translate, arg in
-            zip(translations, args)]
-
 class BlockInstanceFactory:
     
     def __init__(self, block_instances):
@@ -677,7 +682,7 @@
         if project is not None:
             for pou in project.getpous():
                 if pou_name is None or pou_name == pou.getname():
-                    variables.extend([var["Name"] for var in self.GetPouInterfaceVars(pou, debug)])
+                    variables.extend([var.Name for var in self.GetPouInterfaceVars(pou, debug=debug)])
                     for transition in pou.gettransitionList():
                         variables.append(transition.getname())
                     for action in pou.getactionList():
@@ -1299,35 +1304,35 @@
         current_varlist = None
         current_type = None
         for var in vars:
-            next_type = (var["Class"], 
-                         var["Option"], 
-                         var["Location"] in ["", None] or 
+            next_type = (var.Class, 
+                         var.Option, 
+                         var.Location in ["", None] or 
                          # When declaring globals, located 
                          # and not located variables are 
                          # in the same declaration block
-                         var["Class"] == "Global")
+                         var.Class == "Global")
             if current_type != next_type:
                 current_type = next_type
-                infos = VAR_CLASS_INFOS.get(var["Class"], None)
+                infos = VAR_CLASS_INFOS.get(var.Class, None)
                 if infos is not None:
                     current_varlist = PLCOpenParser.CreateElement(infos[0], "interface")
                 else:
                     current_varlist = PLCOpenParser.CreateElement("varList")
-                varlist_list.append((var["Class"], current_varlist))
-                if var["Option"] == "Constant":
+                varlist_list.append((var.Class, current_varlist))
+                if var.Option == "Constant":
                     current_varlist.setconstant(True)
-                elif var["Option"] == "Retain":
+                elif var.Option == "Retain":
                     current_varlist.setretain(True)
-                elif var["Option"] == "Non-Retain":
+                elif var.Option == "Non-Retain":
                     current_varlist.setnonretain(True)
             # Create variable and change its properties
             tempvar = PLCOpenParser.CreateElement("variable", "varListPlain")
-            tempvar.setname(var["Name"])
+            tempvar.setname(var.Name)
             
             var_type = PLCOpenParser.CreateElement("type", "variable")
-            if isinstance(var["Type"], TupleType):
-                if var["Type"][0] == "array":
-                    array_type, base_type_name, dimensions = var["Type"]
+            if isinstance(var.Type, TupleType):
+                if var.Type[0] == "array":
+                    array_type, base_type_name, dimensions = var.Type
                     array = PLCOpenParser.CreateElement("array", "dataType")
                     baseType = PLCOpenParser.CreateElement("baseType", "array")
                     array.setbaseType(baseType)
@@ -1349,43 +1354,51 @@
                         derived_datatype.setname(base_type_name)
                         baseType.setcontent(derived_datatype)
                     var_type.setcontent(array)
-            elif var["Type"] in self.GetBaseTypes():
+            elif var.Type in self.GetBaseTypes():
                 var_type.setcontent(PLCOpenParser.CreateElement(
-                    var["Type"].lower()
-                    if var["Type"] in ["STRING", "WSTRING"]
-                    else var["Type"], "dataType"))
+                    var.Type.lower()
+                    if var.Type in ["STRING", "WSTRING"]
+                    else var.Type, "dataType"))
             else:
                 derived_type = PLCOpenParser.CreateElement("derived", "dataType")
-                derived_type.setname(var["Type"])
+                derived_type.setname(var.Type)
                 var_type.setcontent(derived_type)
             tempvar.settype(var_type)
 
-            if var["Initial Value"] != "":
+            if var.InitialValue != "":
                 value = PLCOpenParser.CreateElement("initialValue", "variable")
-                value.setvalue(var["Initial Value"])
+                value.setvalue(var.InitialValue)
                 tempvar.setinitialValue(value)
-            if var["Location"] != "":
-                tempvar.setaddress(var["Location"])
+            if var.Location != "":
+                tempvar.setaddress(var.Location)
             else:
                 tempvar.setaddress(None)
-            if var['Documentation'] != "":
+            if var.Documentation != "":
                 ft = PLCOpenParser.CreateElement("documentation", "variable")
-                ft.setanyText(var['Documentation'])
+                ft.setanyText(var.Documentation)
                 tempvar.setdocumentation(ft)
 
             # Add variable to varList
             current_varlist.appendvariable(tempvar)
         return varlist_list
     
-    def GetVariableDictionary(self, object_with_vars, debug=False):
+    def GetVariableDictionary(self, object_with_vars, tree=False, debug=False):
         variables = []
+        factory = VariablesInfosFactory(variables)
+        
+        parser = etree.XMLParser()
+        if tree:
+            parser.resolvers.add(LibraryResolver(self, debug))
         
         variables_infos_xslt_tree = etree.XSLT(
-            variables_infos_xslt, extensions = {
-                ("var_infos_ns", "add_variable"): AddVariable(variables),
-                ("var_infos_ns", "var_tree"): VarTree(self, debug),
-                ("var_infos_ns", "is_edited"): VarIsEdited(self, debug)})
-        variables_infos_xslt_tree(object_with_vars)
+            etree.parse(
+                os.path.join(ScriptDirectory, "plcopen", "variables_infos.xslt"),
+                parser), 
+            extensions = {("var_infos_ns", name): getattr(factory, name)
+                for name in ["SetType", "AddDimension", "AddTree",
+                             "AddVarToTree", "AddVariable"]})
+        variables_infos_xslt_tree(object_with_vars,
+            tree=etree.XSLT.strparam(str(tree)))
         
         return variables
             
@@ -1479,12 +1492,12 @@
         return variables
 
     # Return the interface for the given pou
-    def GetPouInterfaceVars(self, pou, debug = False):
+    def GetPouInterfaceVars(self, pou, tree=False, debug = False):
         interface = pou.interface
         # Verify that the pou has an interface
         if interface is not None:
             # Extract variables defined in interface
-            return self.GetVariableDictionary(interface, debug)
+            return self.GetVariableDictionary(interface, tree, debug)
         return []
 
     # Replace the Pou interface by the one given
@@ -1530,30 +1543,35 @@
         if pou is not None:
             pou.updateElementName(old_name, new_name)
     
-    # Return the return type of the pou given by its name
-    def GetPouInterfaceReturnTypeByName(self, name):
-        project = self.GetProject(debug)
-        if project is not None:
-            # Found the pou correponding to name and return the return type
-            pou = project.getpou(name)
-            if pou is not None:
-                return self.GetPouInterfaceReturnType(pou)
-        return False
-    
     # Return the return type of the given pou
-    def GetPouInterfaceReturnType(self, pou):
+    def GetPouInterfaceReturnType(self, pou, tree=False, debug=False):
         # Verify that the pou has an interface
         if pou.interface is not None:
             # Return the return type if there is one
             return_type = pou.interface.getreturnType()
             if return_type is not None:
+                factory = VariablesInfosFactory([])
+        
+                parser = etree.XMLParser()
+                if tree:
+                    parser.resolvers.add(LibraryResolver(self))
+                
                 return_type_infos_xslt_tree = etree.XSLT(
-                    variables_infos_xslt, extensions = {
-                          ("var_infos_ns", "var_tree"): VarTree(self)})
-                return [extract_param(el) 
-                       for el in return_type_infos_xslt_tree(return_type).getroot()]
-                
-        return [None, ([], [])] 
+                    etree.parse(
+                        os.path.join(ScriptDirectory, "plcopen", "variables_infos.xslt"),
+                        parser), 
+                    extensions = {("var_infos_ns", name): getattr(factory, name)
+                                  for name in ["SetType", "AddDimension", 
+                                               "AddTree", "AddVarToTree"]})
+                return_type_infos_xslt_tree(return_type,
+                    tree=etree.XSLT.strparam(str(tree)))
+                if tree:
+                    return [factory.GetType(), factory.GetTree()]
+                return factory.GetType()
+        
+        if tree:
+            return [None, ([], [])]
+        return None
 
     # Function that add a new confnode to the confnode list
     def AddConfNodeTypesList(self, typeslist):
@@ -2209,25 +2227,25 @@
         return None
 
     # Return the edited element variables
-    def GetEditedElementInterfaceVars(self, tagname, debug = False):
+    def GetEditedElementInterfaceVars(self, tagname, tree=False, debug = False):
         words = tagname.split("::")
         if words[0] in ["P","T","A"]:
             project = self.GetProject(debug)
             if project is not None:
                 pou = project.getpou(words[1])
                 if pou is not None:
-                    return self.GetPouInterfaceVars(pou, debug)
+                    return self.GetPouInterfaceVars(pou, tree, debug)
         return []
 
     # Return the edited element return type
-    def GetEditedElementInterfaceReturnType(self, tagname, debug = False):
+    def GetEditedElementInterfaceReturnType(self, tagname, tree=False, debug = False):
         words = tagname.split("::")
         if words[0] == "P":
             project = self.GetProject(debug)
             if project is not None:
                 pou = self.Project.getpou(words[1])
                 if pou is not None:
-                    return self.GetPouInterfaceReturnType(pou)
+                    return self.GetPouInterfaceReturnType(pou, tree, debug)
         elif words[0] == 'T':
             return "BOOL"
         return None
@@ -2328,8 +2346,8 @@
                     names[datatype.getname().upper()] = True
                 for pou in project.getpous():
                     names[pou.getname().upper()] = True
-                    for var in self.GetPouInterfaceVars(pou, debug):
-                        names[var["Name"].upper()] = True
+                    for var in self.GetPouInterfaceVars(pou, debug=debug):
+                        names[var.Name.upper()] = True
                     for transition in pou.gettransitionList():
                         names[transition.getname().upper()] = True
                     for action in pou.getactionList():
--- a/controls/VariablePanel.py	Fri Oct 04 12:17:03 2013 +0200
+++ b/controls/VariablePanel.py	Wed Oct 09 10:57:20 2013 +0200
@@ -37,6 +37,7 @@
 from CustomTable import CustomTable
 from LocationCellEditor import LocationCellEditor
 from util.BitmapLibrary import GetBitmap
+from PLCControler import _VariableInfos
 
 #-------------------------------------------------------------------------------
 #                                 Helpers
@@ -105,12 +106,22 @@
         CustomTable.__init__(self, parent, data, colnames)
         self.old_value = None
     
+    def GetValueByName(self, row, colname):
+        if row < self.GetNumberRows():
+            return getattr(self.data[row], colname)
+
+    def SetValueByName(self, row, colname, value):
+        if row < self.GetNumberRows():
+            setattr(self.data[row], colname, value)
+    
     def GetValue(self, row, col):
         if row < self.GetNumberRows():
             if col == 0:
-                return self.data[row]["Number"]
+                return self.data[row].Number
             colname = self.GetColLabelValue(col, False)
-            value = self.data[row].get(colname, "")
+            if colname == "Initial Value":
+                colname = "InitialValue"
+            value = getattr(self.data[row], colname, "")
             if colname == "Type" and isinstance(value, TupleType):
                 if value[0] == "array":
                     return "ARRAY [%s] OF %s" % (",".join(map(lambda x : "..".join(x), value[2])), value[1])
@@ -124,15 +135,17 @@
         if col < len(self.colnames):
             colname = self.GetColLabelValue(col, False)
             if colname == "Name":
-                self.old_value = self.data[row][colname]
+                self.old_value = getattr(self.data[row], colname)
             elif colname == "Class":
                 value = VARIABLE_CLASSES_DICT[value]
                 self.SetValueByName(row, "Option", CheckOptionForClass[value](self.GetValueByName(row, "Option")))
                 if value == "External":
-                    self.SetValueByName(row, "Initial Value", "")
+                    self.SetValueByName(row, "InitialValue", "")
             elif colname == "Option":
                 value = OPTIONS_DICT[value]
-            self.data[row][colname] = value
+            elif colname == "Initial Value":
+                colname = "InitialValue"
+            setattr(self.data[row], colname, value)
 
     def GetOldValue(self):
         return self.old_value
@@ -314,8 +327,8 @@
                         for name in self.ParentWindow.Controler.\
                             GetEditedElementVariables(tagname, self.ParentWindow.Debug)]:
                     var_infos = self.ParentWindow.DefaultValue.copy()
-                    var_infos["Name"] = var_name
-                    var_infos["Type"] = values[2]
+                    var_infos.Name = var_name
+                    var_infos.Type = values[2]
                     if values[1] == "location":
                         location = values[0]
                         if not location.startswith("%"):
@@ -346,16 +359,16 @@
                                     GetConfigurationVariableNames(configs[0])]:
                                 self.ParentWindow.Controler.AddConfigurationGlobalVar(
                                     configs[0], values[2], var_name, location, "")
-                            var_infos["Class"] = "External"
+                            var_infos.Class = "External"
                         else:
                             if element_type == "program":
-                                var_infos["Class"] = "Local"
+                                var_infos.Class = "Local"
                             else:
-                                var_infos["Class"] = "Global"
-                            var_infos["Location"] = location
+                                var_infos.Class = "Global"
+                            var_infos.Location = location
                     else:
-                        var_infos["Class"] = "External"
-                    var_infos["Number"] = len(self.ParentWindow.Values)
+                        var_infos.Class = "External"
+                    var_infos.Number = len(self.ParentWindow.Values)
                     self.ParentWindow.Values.append(var_infos)
                     self.ParentWindow.SaveValues()
                     self.ParentWindow.RefreshValues()
@@ -447,16 +460,7 @@
         self.FilterChoices = []
         self.FilterChoiceTransfer = GetFilterChoiceTransfer()
         
-        self.DefaultValue = {
-             "Name" : "", 
-             "Class" : "", 
-             "Type" : "INT", 
-             "Location" : "",
-             "Initial Value" : "", 
-             "Option" : "",
-             "Documentation" : "", 
-             "Edit" : True
-        }
+        self.DefaultValue = _VariableInfos("", "", "", "", "", True, "", "INT", ([], []), 0)
         
         if element_type in ["config", "resource"]:
             self.DefaultTypes = {"All" : "Global"}
@@ -527,32 +531,32 @@
             if new_row > 0:
                 row_content = self.Values[new_row - 1].copy()
                 
-                result = VARIABLE_NAME_SUFFIX_MODEL.search(row_content["Name"])
+                result = VARIABLE_NAME_SUFFIX_MODEL.search(row_content.Name)
                 if result is not None:
-                    name = row_content["Name"][:result.start(1)]
+                    name = row_content.Name[:result.start(1)]
                     suffix = result.group(1)
                     if suffix != "":
                         start_idx = int(suffix)
                     else:
                         start_idx = 0
                 else:
-                    name = row_content["Name"]
+                    name = row_content.Name
                     start_idx = 0
             else:
                 row_content = None
                 start_idx = 0
                 name = "LocalVar"
                 
-            if row_content is not None and row_content["Edit"]: 
+            if row_content is not None and row_content.Edit: 
                 row_content = self.Values[new_row - 1].copy()
             else:
                 row_content = self.DefaultValue.copy()
                 if self.Filter in self.DefaultTypes:
-                    row_content["Class"] = self.DefaultTypes[self.Filter]
+                    row_content.Class = self.DefaultTypes[self.Filter]
                 else:
-                    row_content["Class"] = self.Filter
+                    row_content.Class = self.Filter
             
-            row_content["Name"] = self.Controler.GenerateNewName(
+            row_content.Name = self.Controler.GenerateNewName(
                     self.TagName, None, name + "%d", start_idx)
             
             if self.Filter == "All" and len(self.Values) > 0:
@@ -637,9 +641,9 @@
                 self.ReturnType.Clear()
                 for data_type in self.Controler.GetDataTypes(self.TagName, debug=self.Debug):
                     self.ReturnType.Append(data_type)
-                returnType, (var_tree, dimensions) = self.Controler.GetEditedElementInterfaceReturnType(self.TagName, self.Debug)
+                returnType = self.Controler.GetEditedElementInterfaceReturnType(self.TagName, debug=self.Debug)
             description = self.Controler.GetPouDescription(words[1])
-            self.Values = self.Controler.GetEditedElementInterfaceVars(self.TagName, self.Debug)
+            self.Values = self.Controler.GetEditedElementInterfaceVars(self.TagName, debug=self.Debug)
         
         if returnType is not None:
             self.ReturnType.SetStringSelection(returnType)
@@ -712,7 +716,7 @@
                 message = _("\"%s\" is a keyword. It can't be used!") % value
             elif value.upper() in self.PouNames:
                 message = _("A POU named \"%s\" already exists!") % value
-            elif value.upper() in [var["Name"].upper() for var in self.Values if var != self.Table.data[row]]:
+            elif value.upper() in [var.Name.upper() for var in self.Values if var != self.Table.data[row]]:
                 message = _("A variable with \"%s\" as name already exists in this pou!") % value
             else:
                 self.SaveValues(False)
@@ -846,8 +850,8 @@
     def RefreshValues(self):
         data = []
         for num, variable in enumerate(self.Values):
-            if variable["Class"] in self.ClassList:
-                variable["Number"] = num + 1
+            if variable.Class in self.ClassList:
+                variable.Number = num + 1
                 data.append(variable)
         self.Table.SetData(data)
         self.Table.ResetView(self.VariablesGrid)
--- a/dialogs/ActionBlockDialog.py	Fri Oct 04 12:17:03 2013 +0200
+++ b/dialogs/ActionBlockDialog.py	Wed Oct 09 10:57:20 2013 +0200
@@ -198,7 +198,7 @@
         self.DurationList = list
 
     def SetVariableList(self, list):
-        self.VariableList = "," + ",".join([variable["Name"] for variable in list])
+        self.VariableList = "," + ",".join([variable.Name for variable in list])
         
     def SetActionList(self, list):
         self.ActionList = "," + ",".join(list)
--- a/dialogs/BlockPreviewDialog.py	Fri Oct 04 12:17:03 2013 +0200
+++ b/dialogs/BlockPreviewDialog.py	Wed Oct 09 10:57:20 2013 +0200
@@ -170,14 +170,14 @@
         """
         # Get list of variables defined in POU
         self.VariableList = {
-            var["Name"]: (var["Class"], var["Type"])
+            var.Name: (var.Class, var.Type)
             for var in self.Controller.GetEditedElementInterfaceVars(
                                                         self.TagName)
-            if var["Edit"]}
+            if var.Edit}
         
         # Add POU name to variable list if POU is a function 
         returntype = self.Controller.GetEditedElementInterfaceReturnType(
-                                                            self.TagName)[0]
+                                                            self.TagName)
         if returntype is not None:
             self.VariableList[
                 self.Controller.GetEditedElementName(self.TagName)] = \
--- a/dialogs/SFCStepNameDialog.py	Fri Oct 04 12:17:03 2013 +0200
+++ b/dialogs/SFCStepNameDialog.py	Wed Oct 09 10:57:20 2013 +0200
@@ -67,7 +67,7 @@
         self.PouNames = [pou_name.upper() for pou_name in pou_names]
 
     def SetVariables(self, variables):
-        self.Variables = [var["Name"].upper() for var in variables]
+        self.Variables = [var.Name.upper() for var in variables]
 
     def SetStepNames(self, step_names):
         self.StepNames = [step_name.upper() for step_name in step_names]
--- a/editors/LDViewer.py	Fri Oct 04 12:17:03 2013 +0200
+++ b/editors/LDViewer.py	Wed Oct 09 10:57:20 2013 +0200
@@ -482,12 +482,12 @@
         dialog = LDElementDialog(self.ParentWindow, self.Controler, "coil")
         dialog.SetPreviewFont(self.GetFont())
         varlist = []
-        vars = self.Controler.GetEditedElementInterfaceVars(self.TagName, self.Debug)
+        vars = self.Controler.GetEditedElementInterfaceVars(self.TagName, debug=self.Debug)
         if vars:
             for var in vars:
-                if var["Class"] != "Input" and var["Type"] == "BOOL":
-                    varlist.append(var["Name"])
-        returntype = self.Controler.GetEditedElementInterfaceReturnType(self.TagName, self.Debug)[0]
+                if var.Class != "Input" and var.Type == "BOOL":
+                    varlist.append(var.Name)
+        returntype = self.Controler.GetEditedElementInterfaceReturnType(self.TagName, debug=self.Debug)
         if returntype == "BOOL":
             varlist.append(self.Controler.GetEditedElementName(self.TagName))
         dialog.SetVariables(varlist)
@@ -582,11 +582,11 @@
             dialog = LDElementDialog(self.ParentWindow, self.Controler, "contact")
             dialog.SetPreviewFont(self.GetFont())
             varlist = []
-            vars = self.Controler.GetEditedElementInterfaceVars(self.TagName, self.Debug)
+            vars = self.Controler.GetEditedElementInterfaceVars(self.TagName, debug=self.Debug)
             if vars:
                 for var in vars:
-                    if var["Class"] != "Output" and var["Type"] == "BOOL":
-                        varlist.append(var["Name"])
+                    if var.Class != "Output" and var.Type == "BOOL":
+                        varlist.append(var.Name)
             dialog.SetVariables(varlist)
             dialog.SetValues({"name":"","type":CONTACT_NORMAL})
             if dialog.ShowModal() == wx.ID_OK:
@@ -796,12 +796,12 @@
                         dialog = LDElementDialog(self.ParentWindow, self.Controleur, "coil")
                         dialog.SetPreviewFont(self.GetFont())
                         varlist = []
-                        vars = self.Controler.GetEditedElementInterfaceVars(self.TagName, self.Debug)
+                        vars = self.Controler.GetEditedElementInterfaceVars(self.TagName, debug=self.Debug)
                         if vars:
                             for var in vars:
-                                if var["Class"] != "Input" and var["Type"] == "BOOL":
-                                    varlist.append(var["Name"])
-                        returntype = self.Controler.GetEditedElementInterfaceReturnType(self.TagName, self.Debug)[0]
+                                if var.Class != "Input" and var.Type == "BOOL":
+                                    varlist.append(var.Name)
+                        returntype = self.Controler.GetEditedElementInterfaceReturnType(self.TagName, debug=self.Debug)
                         if returntype == "BOOL":
                             varlist.append(self.Controler.GetEditedElementName(self.TagName))
                         dialog.SetVariables(varlist)
--- a/editors/SFCViewer.py	Fri Oct 04 12:17:03 2013 +0200
+++ b/editors/SFCViewer.py	Wed Oct 09 10:57:20 2013 +0200
@@ -358,7 +358,7 @@
     def AddInitialStep(self, pos):
         dialog = SFCStepNameDialog(self.ParentWindow, _("Please enter step name"), _("Add a new initial step"), "", wx.OK|wx.CANCEL)
         dialog.SetPouNames(self.Controler.GetProjectPouNames(self.Debug))
-        dialog.SetVariables(self.Controler.GetEditedElementInterfaceVars(self.TagName, self.Debug))
+        dialog.SetVariables(self.Controler.GetEditedElementInterfaceVars(self.TagName, debug=self.Debug))
         dialog.SetStepNames([block.GetName() for block in self.Blocks if isinstance(block, SFC_Step)])
         if dialog.ShowModal() == wx.ID_OK:
             id = self.GetNewId()
@@ -380,7 +380,7 @@
         if self.SelectedElement in self.Wires or isinstance(self.SelectedElement, SFC_Step):
             dialog = SFCStepNameDialog(self.ParentWindow, _("Add a new step"), _("Please enter step name"), "", wx.OK|wx.CANCEL)
             dialog.SetPouNames(self.Controler.GetProjectPouNames(self.Debug))
-            dialog.SetVariables(self.Controler.GetEditedElementInterfaceVars(self.TagName, self.Debug))
+            dialog.SetVariables(self.Controler.GetEditedElementInterfaceVars(self.TagName, debug=self.Debug))
             dialog.SetStepNames([block.GetName() for block in self.Blocks if isinstance(block, SFC_Step)])
             if dialog.ShowModal() == wx.ID_OK:
                 name = dialog.GetValue()
@@ -437,7 +437,7 @@
                 dialog = ActionBlockDialog(self.ParentWindow)
                 dialog.SetQualifierList(self.Controler.GetQualifierTypes())
                 dialog.SetActionList(self.Controler.GetEditedElementActions(self.TagName, self.Debug))
-                dialog.SetVariableList(self.Controler.GetEditedElementInterfaceVars(self.TagName, self.Debug))
+                dialog.SetVariableList(self.Controler.GetEditedElementInterfaceVars(self.TagName, debug=self.Debug))
                 if dialog.ShowModal() == wx.ID_OK:
                     actions = dialog.GetValues()
                     self.SelectedElement.AddAction()
@@ -724,7 +724,7 @@
         else:
             dialog = SFCStepNameDialog(self.ParentWindow, _("Edit step name"), _("Please enter step name"), step.GetName(), wx.OK|wx.CANCEL)
             dialog.SetPouNames(self.Controler.GetProjectPouNames(self.Debug))
-            dialog.SetVariables(self.Controler.GetEditedElementInterfaceVars(self.TagName, self.Debug))
+            dialog.SetVariables(self.Controler.GetEditedElementInterfaceVars(self.TagName, debug=self.Debug))
             dialog.SetStepNames([block.GetName() for block in self.Blocks if isinstance(block, SFC_Step) and block.GetName() != step.GetName()])
             if dialog.ShowModal() == wx.ID_OK:
                 value = dialog.GetValue()
--- a/editors/TextViewer.py	Fri Oct 04 12:17:03 2013 +0200
+++ b/editors/TextViewer.py	Wed Oct 09 10:57:20 2013 +0200
@@ -458,9 +458,12 @@
             
     def RefreshVariableTree(self):
         words = self.TagName.split("::")
-        self.Variables = self.GenerateVariableTree([(variable["Name"], variable["Type"], variable["Tree"]) for variable in self.Controler.GetEditedElementInterfaceVars(self.TagName, self.Debug)])
+        self.Variables = self.GenerateVariableTree(
+            [(variable.Name, variable.Type, variable.Tree) 
+             for variable in self.Controler.GetEditedElementInterfaceVars(
+                self.TagName, True, self.Debug)])
         if self.Controler.GetEditedElementType(self.TagName, self.Debug)[1] == "function" or words[0] == "T" and self.TextSyntax == "IL":
-            return_type, (var_tree, var_dimension) = self.Controler.GetEditedElementInterfaceReturnType(self.TagName, self.Debug)
+            return_type, (var_tree, var_dimension) = self.Controler.GetEditedElementInterfaceReturnType(self.TagName, True, self.Debug)
             if return_type is not None:
                 self.Variables[words[-1].upper()] = self.GenerateVariableTree(var_tree)
             else:
--- a/editors/Viewer.py	Fri Oct 04 12:17:03 2013 +0200
+++ b/editors/Viewer.py	Wed Oct 09 10:57:20 2013 +0200
@@ -332,7 +332,7 @@
                     var_class = INPUT
                 else:
                     var_class = INPUT
-                tree = dict([(var["Name"], var["Tree"]) for var in self.ParentWindow.Controler.GetEditedElementInterfaceVars(tagname, self.ParentWindow.Debug)]).get(values[0], None)
+                tree = dict([(var.Name, var.Tree) for var in self.ParentWindow.Controler.GetEditedElementInterfaceVars(tagname, True, self.ParentWindow.Debug)]).get(values[0], None)
                 if tree is not None:
                     if len(tree[0]) > 0:
                         menu = wx.Menu(title='')
@@ -2620,7 +2620,7 @@
         dialog = ActionBlockDialog(self.ParentWindow)
         dialog.SetQualifierList(self.Controler.GetQualifierTypes())
         dialog.SetActionList(self.Controler.GetEditedElementActions(self.TagName, self.Debug))
-        dialog.SetVariableList(self.Controler.GetEditedElementInterfaceVars(self.TagName, self.Debug))
+        dialog.SetVariableList(self.Controler.GetEditedElementInterfaceVars(self.TagName, debug=self.Debug))
         if dialog.ShowModal() == wx.ID_OK:
             id = self.GetNewId()
             actionblock = SFC_ActionBlock(self, dialog.GetValues(), id)
@@ -2870,7 +2870,7 @@
         dialog = ActionBlockDialog(self.ParentWindow)
         dialog.SetQualifierList(self.Controler.GetQualifierTypes())
         dialog.SetActionList(self.Controler.GetEditedElementActions(self.TagName, self.Debug))
-        dialog.SetVariableList(self.Controler.GetEditedElementInterfaceVars(self.TagName, self.Debug))
+        dialog.SetVariableList(self.Controler.GetEditedElementInterfaceVars(self.TagName, debug=self.Debug))
         dialog.SetValues(actionblock.GetActions())
         if dialog.ShowModal() == wx.ID_OK:
             actions = dialog.GetValues()
--- a/plcopen/variables_infos.xslt	Fri Oct 04 12:17:03 2013 +0200
+++ b/plcopen/variables_infos.xslt	Wed Oct 09 10:57:20 2013 +0200
@@ -1,213 +1,1 @@
-<xsl:stylesheet version="1.0"
-    xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
-    xmlns:ppx="http://www.plcopen.org/xml/tc6_0201"
-    xmlns:xhtml="http://www.w3.org/1999/xhtml"
-    xmlns:ns="var_infos_ns"
-    extension-element-prefixes="ns"
-    exclude-result-prefixes="ns">
-  <xsl:template match="ppx:returnType">
-    <ReturnType>
-      <Type><xsl:apply-templates/></Type>
-      <Tree><xsl:apply-templates mode="var_tree"/></Tree>
-    </ReturnType>
-  </xsl:template>
-  <xsl:template match="ppx:localVars">
-    <xsl:call-template name="variables_infos">
-      <xsl:with-param name="var_class" select="'Local'"/>
-    </xsl:call-template>
-  </xsl:template>
-  <xsl:template match="ppx:globalVars">
-    <xsl:call-template name="variables_infos">
-      <xsl:with-param name="var_class" select="'Global'"/>
-    </xsl:call-template>
-  </xsl:template>
-  <xsl:template match="ppx:externalVars">
-    <xsl:call-template name="variables_infos">
-      <xsl:with-param name="var_class" select="'External'"/>
-    </xsl:call-template>
-  </xsl:template>
-  <xsl:template match="ppx:tempVars">
-    <xsl:call-template name="variables_infos">
-      <xsl:with-param name="var_class" select="'Temp'"/>
-    </xsl:call-template>
-  </xsl:template>
-  <xsl:template match="ppx:inputVars">
-    <xsl:call-template name="variables_infos">
-      <xsl:with-param name="var_class" select="'Input'"/>
-    </xsl:call-template>
-  </xsl:template>
-  <xsl:template match="ppx:outputVars">
-    <xsl:call-template name="variables_infos">
-      <xsl:with-param name="var_class" select="'Output'"/>
-    </xsl:call-template>
-  </xsl:template>
-  <xsl:template match="ppx:inOutVars">
-    <xsl:call-template name="variables_infos">
-      <xsl:with-param name="var_class" select="'InOut'"/>
-    </xsl:call-template>
-  </xsl:template>
-  <xsl:template name="variables_infos">
-    <xsl:param name="var_class"/>
-    <xsl:variable name="var_option">
-      <xsl:choose>
-        <xsl:when test="@constant='true' or @constant='1'">
-          <xsl:text>Constant</xsl:text>
-        </xsl:when>
-        <xsl:when test="@retain='true' or @retain='1'">
-          <xsl:text>Retain</xsl:text>
-        </xsl:when>
-        <xsl:when test="@nonretain='true' or @nonretain='1'">
-          <xsl:text>Non-Retain</xsl:text>
-        </xsl:when>
-      </xsl:choose>
-    </xsl:variable>
-    <xsl:for-each select="ppx:variable">
-      <ns:add_variable>
-        <Name><xsl:value-of select="@name"/></Name>
-        <Class><xsl:value-of select="$var_class"/></Class>
-        <Type><xsl:apply-templates select="ppx:type"/></Type>
-        <Option><xsl:value-of select="$var_option"/></Option>
-        <Location><xsl:value-of select="@address"/></Location>
-        <Initial_Value><xsl:apply-templates select="ppx:initialValue"/></Initial_Value>
-        <Edit><xsl:apply-templates select="ppx:type" mode="var_edit"/></Edit>
-        <Tree><xsl:apply-templates select="ppx:type" mode="var_tree"/></Tree>
-        <Documentation>
-          <xsl:value-of select="ppx:documentation/xhtml:p/text()"/>
-        </Documentation>
-      </ns:add_variable>
-    </xsl:for-each>
-  </xsl:template>
-  <xsl:template match="*[self::ppx:type or self::ppx:baseType or self::ppx:returnType]/ppx:derived">
-    <xsl:value-of select="@name"/>
-  </xsl:template>
-  <xsl:template match="*[self::ppx:type or self::ppx:baseType or self::ppx:returnType]/ppx:array">
-    <array>
-      <xsl:apply-templates select="ppx:baseType"/>
-      <xsl:for-each select="ppx:dimension">
-        <dimension>
-          <xsl:attribute name="lower">
-            <xsl:value-of select="@lower"/>
-          </xsl:attribute>
-          <xsl:attribute name="upper">
-            <xsl:value-of select="@upper"/>
-          </xsl:attribute>
-        </dimension>
-      </xsl:for-each>
-    </array>
-  </xsl:template>
-  <xsl:template match="*[self::ppx:type or self::ppx:baseType or self::ppx:returnType]/ppx:string">
-    <xsl:text>STRING</xsl:text>
-  </xsl:template>
-  <xsl:template match="*[self::ppx:type or self::ppx:baseType or self::ppx:returnType]/ppx:wstring">
-    <xsl:text>WSTRING</xsl:text>
-  </xsl:template>
-  <xsl:template match="*[self::ppx:type or self::ppx:baseType or self::ppx:returnType]/*">
-    <xsl:value-of select="local-name()"/>
-  </xsl:template>
-  <xsl:template match="*[self::ppx:type or self::ppx:baseType or self::ppx:returnType]/ppx:derived" mode="var_edit">
-    <ns:is_edited/>
-  </xsl:template>
-  <xsl:template match="*[self::ppx:type or self::ppx:baseType or self::ppx:returnType]/*" mode="var_edit">
-    <xsl:text>True</xsl:text>
-  </xsl:template>
-  <xsl:template match="ppx:initialValue">
-    <xsl:apply-templates/>
-  </xsl:template>
-  <xsl:template match="ppx:value">
-    <xsl:choose>
-      <xsl:when test="@repetitionValue">
-        <xsl:value-of select="@repetitionValue"/>
-        <xsl:text>(</xsl:text>
-        <xsl:apply-templates/>
-        <xsl:text>)</xsl:text>
-      </xsl:when>
-      <xsl:when test="@member">
-        <xsl:value-of select="@member"/>
-        <xsl:text> := </xsl:text>
-        <xsl:apply-templates/>
-      </xsl:when>
-      <xsl:otherwise>
-        <xsl:apply-templates/>
-      </xsl:otherwise>
-    </xsl:choose>
-  </xsl:template>
-  <xsl:template match="ppx:simpleValue">
-    <xsl:value-of select="@value"/>
-  </xsl:template>
-  <xsl:template match="ppx:arrayValue">
-    <xsl:text>[</xsl:text>
-    <xsl:for-each select="ppx:value">
-      <xsl:apply-templates select="."/>
-      <xsl:choose>
-        <xsl:when test="position()!=last()">
-          <xsl:text>, </xsl:text>
-        </xsl:when>
-      </xsl:choose>
-    </xsl:for-each>
-    <xsl:text>]</xsl:text>
-  </xsl:template>
-  <xsl:template match="ppx:structValue">
-    <xsl:text>(</xsl:text>
-    <xsl:for-each select="ppx:value">
-      <xsl:apply-templates select="."/>
-      <xsl:choose>
-        <xsl:when test="position()!=last()">
-          <xsl:text>, </xsl:text>
-        </xsl:when>
-      </xsl:choose>
-    </xsl:for-each>
-    <xsl:text>)</xsl:text>
-  </xsl:template>
-  <xsl:template match="ppx:pou" mode="var_tree">
-    <xsl:apply-templates select="ppx:interface/*[self::ppx:inputVars or self::ppx:inOutVars or self::ppx:outputVars]/ppx:variable" mode="var_tree"/>
-  </xsl:template>
-  <xsl:template match="ppx:variable" mode="var_tree">
-    <var>
-      <xsl:attribute name="name">
-        <xsl:value-of select="@name"/>
-      </xsl:attribute>
-      <xsl:apply-templates select="ppx:type" mode="var_tree"/>
-    </var>
-  </xsl:template>
-  <xsl:template match="ppx:dataType">
-    <xsl:apply-templates select="ppx:baseType" mode="var_tree"/>
-  </xsl:template>
-  <xsl:template match="*[self::ppx:type or self::ppx:baseType or self::ppx:returnType]/ppx:struct" mode="var_tree">
-    <xsl:apply-templates select="ppx:variable" mode="var_tree"/>
-  </xsl:template>
-  <xsl:template match="*[self::ppx:type or self::ppx:baseType or self::ppx:returnType]/ppx:derived" mode="var_tree">
-    <ns:var_tree/>
-    <xsl:choose>
-      <xsl:when test="count(./*) > 0">
-        <xsl:apply-templates mode="var_tree"/>
-      </xsl:when>
-      <xsl:otherwise>
-        <xsl:value-of select="@name"/>
-      </xsl:otherwise>
-    </xsl:choose>
-  </xsl:template>
-  <xsl:template match="*[self::ppx:type or self::ppx:baseType or self::ppx:returnType]/ppx:array" mode="var_tree">
-    <xsl:apply-templates select="ppx:baseType" mode="var_tree"/>
-    <xsl:for-each select="ppx:dimension">
-      <dimension>
-        <xsl:attribute name="lower">
-          <xsl:value-of select="@lower"/>
-        </xsl:attribute>
-        <xsl:attribute name="upper">
-          <xsl:value-of select="@upper"/>
-        </xsl:attribute>
-      </dimension>
-    </xsl:for-each>
-  </xsl:template>
-  <xsl:template match="*[self::ppx:type or self::ppx:baseType or self::ppx:returnType]/ppx:string" mode="var_tree">
-    <xsl:text>STRING</xsl:text>
-  </xsl:template>
-  <xsl:template match="*[self::ppx:type or self::ppx:baseType or self::ppx:returnType]/ppx:wstring" mode="var_tree">
-    <xsl:text>WSTRING</xsl:text>
-  </xsl:template>
-  <xsl:template match="*[self::ppx:type or self::ppx:baseType or self::ppx:returnType]/*" mode="var_tree">
-    <xsl:value-of select="local-name()"/>
-  </xsl:template>
-  <xsl:template match="text()"/>
-  <xsl:template match="text()" mode="var_tree"/>
-</xsl:stylesheet>
\ No newline at end of file
+<xsl:stylesheet xmlns:func="http://exslt.org/functions" xmlns:dyn="http://exslt.org/dynamic" xmlns:str="http://exslt.org/strings" xmlns:math="http://exslt.org/math" xmlns:exsl="http://exslt.org/common" extension-element-prefixes="ns" xmlns:xhtml="http://www.w3.org/1999/xhtml" xmlns:yml="http://fdik.org/yml" xmlns:set="http://exslt.org/sets" version="1.0" xmlns:ppx="http://www.plcopen.org/xml/tc6_0201" xmlns:ns="var_infos_ns" exclude-result-prefixes="ns" xmlns:regexp="http://exslt.org/regular-expressions" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"><xsl:output method="xml"/><xsl:variable name="space" select="'                                                                                                                                                                                                        '"/><xsl:param name="autoindent" select="4"/><xsl:param name="tree"/><xsl:template match="text()"><xsl:param name="_indent" select="0"/></xsl:template><xsl:variable name="project"><xsl:choose><xsl:when test="$tree='True'"><xsl:copy-of select="document('project')/project/*"/></xsl:when></xsl:choose></xsl:variable><xsl:variable name="stdlib"><xsl:choose><xsl:when test="$tree='True'"><xsl:copy-of select="document('stdlib')/stdlib/*"/></xsl:when></xsl:choose></xsl:variable><xsl:variable name="extensions"><xsl:choose><xsl:when test="$tree='True'"><xsl:copy-of select="document('extensions')/extensions/*"/></xsl:when></xsl:choose></xsl:variable><xsl:template match="ppx:returnType"><xsl:param name="_indent" select="0"/><xsl:value-of select="ns:AddTree()"/><xsl:apply-templates><xsl:with-param name="_indent" select="$_indent + (1) * $autoindent"/></xsl:apply-templates></xsl:template><xsl:template name="variables_infos"><xsl:param name="_indent" select="0"/><xsl:param name="var_class"/><xsl:variable name="var_option"><xsl:choose><xsl:when test="@constant='true' or @constant='1'"><xsl:text>Constant</xsl:text></xsl:when><xsl:when test="@retain='true' or @retain='1'"><xsl:text>Retain</xsl:text></xsl:when><xsl:when test="@nonretain='true' or @nonretain='1'"><xsl:text>Non-Retain</xsl:text></xsl:when></xsl:choose></xsl:variable><xsl:for-each select="ppx:variable"><xsl:variable name="initial_value"><xsl:apply-templates select="ppx:initialValue"><xsl:with-param name="_indent" select="$_indent + (1) * $autoindent"/></xsl:apply-templates></xsl:variable><xsl:variable name="edit"><xsl:choose><xsl:when test="$var_class='Global' or $var_class='External'"><xsl:text>true</xsl:text></xsl:when><xsl:otherwise><xsl:apply-templates mode="var_edit" select="ppx:type"><xsl:with-param name="_indent" select="$_indent + (1) * $autoindent"/></xsl:apply-templates></xsl:otherwise></xsl:choose></xsl:variable><xsl:value-of select="ns:AddTree()"/><xsl:apply-templates select="ppx:type"><xsl:with-param name="_indent" select="$_indent + (1) * $autoindent"/></xsl:apply-templates><xsl:value-of select="ns:AddVariable(@name, $var_class, $var_option, @address, $initial_value, $edit, ppx:documentation/xhtml:p/text())"/></xsl:for-each></xsl:template><xsl:template match="ppx:localVars"><xsl:param name="_indent" select="0"/><xsl:call-template name="variables_infos"><xsl:with-param name="var_class"><xsl:text>Local</xsl:text></xsl:with-param></xsl:call-template></xsl:template><xsl:template match="ppx:globalVars"><xsl:param name="_indent" select="0"/><xsl:call-template name="variables_infos"><xsl:with-param name="var_class"><xsl:text>Global</xsl:text></xsl:with-param></xsl:call-template></xsl:template><xsl:template match="ppx:externalVars"><xsl:param name="_indent" select="0"/><xsl:call-template name="variables_infos"><xsl:with-param name="var_class"><xsl:text>External</xsl:text></xsl:with-param></xsl:call-template></xsl:template><xsl:template match="ppx:tempVars"><xsl:param name="_indent" select="0"/><xsl:call-template name="variables_infos"><xsl:with-param name="var_class"><xsl:text>Temp</xsl:text></xsl:with-param></xsl:call-template></xsl:template><xsl:template match="ppx:inputVars"><xsl:param name="_indent" select="0"/><xsl:call-template name="variables_infos"><xsl:with-param name="var_class"><xsl:text>Input</xsl:text></xsl:with-param></xsl:call-template></xsl:template><xsl:template match="ppx:outputVars"><xsl:param name="_indent" select="0"/><xsl:call-template name="variables_infos"><xsl:with-param name="var_class"><xsl:text>Output</xsl:text></xsl:with-param></xsl:call-template></xsl:template><xsl:template match="ppx:inOutVars"><xsl:param name="_indent" select="0"/><xsl:call-template name="variables_infos"><xsl:with-param name="var_class"><xsl:text>InOut</xsl:text></xsl:with-param></xsl:call-template></xsl:template><xsl:template match="ppx:pou"><xsl:param name="_indent" select="0"/><xsl:apply-templates select="ppx:interface/*[self::ppx:inputVars or self::ppx:inOutVars or self::ppx:outputVars]/ppx:variable"><xsl:with-param name="_indent" select="$_indent + (1) * $autoindent"/></xsl:apply-templates></xsl:template><xsl:template match="ppx:variable"><xsl:param name="_indent" select="0"/><xsl:variable name="name"><xsl:value-of select="@name"/></xsl:variable><xsl:value-of select="ns:AddTree($name)"/><xsl:apply-templates select="ppx:type"><xsl:with-param name="_indent" select="$_indent + (1) * $autoindent"/></xsl:apply-templates><xsl:value-of select="ns:AddVarToTree($name)"/></xsl:template><xsl:template match="ppx:dataType"><xsl:param name="_indent" select="0"/><xsl:apply-templates select="ppx:baseType"><xsl:with-param name="_indent" select="$_indent + (1) * $autoindent"/></xsl:apply-templates></xsl:template><xsl:template match="*[self::ppx:type or self::ppx:baseType or self::ppx:returnType]/ppx:struct"><xsl:param name="_indent" select="0"/><xsl:apply-templates select="ppx:variable"><xsl:with-param name="_indent" select="$_indent + (1) * $autoindent"/></xsl:apply-templates></xsl:template><xsl:template match="*[self::ppx:type or self::ppx:baseType or self::ppx:returnType]/ppx:derived"><xsl:param name="_indent" select="0"/><xsl:variable name="type_name"><xsl:value-of select="@name"/></xsl:variable><xsl:choose><xsl:when test="$tree='True'"><xsl:apply-templates select="exsl:node-set($project)/ppx:project/ppx:types/ppx:pous/ppx:pou[@name=$type_name] |&#10;                         exsl:node-set($project)/ppx:project/ppx:types/ppx:dataTypes/ppx:dataType[@name=$type_name] |&#10;                         exsl:node-set($stdlib)/ppx:project/ppx:types/ppx:pous/ppx:pou[@name=$type_name] |&#10;                         exsl:node-set($stdlib)/ppx:project/ppx:types/ppx:dataTypes/ppx:dataType[@name=$type_name] |&#10;                         exsl:node-set($extensions)/ppx:project/ppx:types/ppx:pous/ppx:pou[@name=$type_name] |&#10;                         exsl:node-set($extensions)/ppx:project/ppx:types/ppx:dataTypes/ppx:dataType[@name=$type_name]"><xsl:with-param name="_indent" select="$_indent + (1) * $autoindent"/></xsl:apply-templates></xsl:when></xsl:choose><xsl:value-of select="ns:SetType($type_name)"/></xsl:template><xsl:template match="*[self::ppx:type or self::ppx:baseType or self::ppx:returnType]/ppx:array"><xsl:param name="_indent" select="0"/><xsl:apply-templates select="ppx:baseType"><xsl:with-param name="_indent" select="$_indent + (1) * $autoindent"/></xsl:apply-templates><xsl:for-each select="ppx:dimension"><xsl:value-of select="ns:AddDimension(@lower, @upper)"/></xsl:for-each></xsl:template><xsl:template match="*[self::ppx:type or self::ppx:baseType or self::ppx:returnType]/ppx:string"><xsl:param name="_indent" select="0"/><xsl:variable name="name"><xsl:text>STRING</xsl:text></xsl:variable><xsl:value-of select="ns:SetType($name)"/></xsl:template><xsl:template match="*[self::ppx:type or self::ppx:baseType or self::ppx:returnType]/ppx:wstring"><xsl:param name="_indent" select="0"/><xsl:variable name="name"><xsl:text>WSTRING</xsl:text></xsl:variable><xsl:value-of select="ns:SetType($name)"/></xsl:template><xsl:template match="*[self::ppx:type or self::ppx:baseType or self::ppx:returnType]/*"><xsl:param name="_indent" select="0"/><xsl:variable name="name"><xsl:value-of select="local-name()"/></xsl:variable><xsl:value-of select="ns:SetType($name)"/></xsl:template><xsl:template mode="var_edit" match="*[self::ppx:type or self::ppx:baseType or self::ppx:returnType]/ppx:derived"><xsl:param name="_indent" select="0"/><xsl:variable name="type_name" select="@name"/><xsl:variable name="pou_infos"><xsl:copy-of select="exsl:node-set($project)/ppx:project/ppx:types/ppx:pous/ppx:pou[@name=$type_name] |&#10;                    exsl:node-set($stdlib)/ppx:project/ppx:types/ppx:pous/ppx:pou[@name=$type_name] |&#10;                    exsl:node-set($extensions)/ppx:project/ppx:types/ppx:pous/ppx:pou[@name=$type_name]"/></xsl:variable><xsl:choose><xsl:when test="$pou_infos != ''"><xsl:text>false</xsl:text></xsl:when><xsl:otherwise><xsl:text>true</xsl:text></xsl:otherwise></xsl:choose></xsl:template><xsl:template mode="var_edit" match="*[self::ppx:type or self::ppx:baseType or self::ppx:returnType]/*"><xsl:param name="_indent" select="0"/><xsl:text>true</xsl:text></xsl:template><xsl:template match="ppx:value"><xsl:param name="_indent" select="0"/><xsl:choose><xsl:when test="@repetitionValue"><xsl:value-of select="@repetitionValue"/><xsl:text>(</xsl:text><xsl:apply-templates><xsl:with-param name="_indent" select="$_indent + (1) * $autoindent"/></xsl:apply-templates><xsl:text>)</xsl:text></xsl:when><xsl:when test="@member"><xsl:value-of select="@member"/><xsl:text> := </xsl:text><xsl:apply-templates><xsl:with-param name="_indent" select="$_indent + (1) * $autoindent"/></xsl:apply-templates></xsl:when><xsl:otherwise><xsl:apply-templates><xsl:with-param name="_indent" select="$_indent + (1) * $autoindent"/></xsl:apply-templates></xsl:otherwise></xsl:choose></xsl:template><xsl:template match="ppx:simpleValue"><xsl:param name="_indent" select="0"/><xsl:value-of select="@value"/></xsl:template><xsl:template name="complex_type_value"><xsl:param name="_indent" select="0"/><xsl:param name="start_bracket"/><xsl:param name="end_bracket"/><xsl:value-of select="@start_bracket"/><xsl:for-each select="ppx:value"><xsl:apply-templates select="."><xsl:with-param name="_indent" select="$_indent + (1) * $autoindent"/></xsl:apply-templates><xsl:choose><xsl:when test="position()!=last()"><xsl:text>, </xsl:text></xsl:when></xsl:choose></xsl:for-each><xsl:value-of select="@end_bracket"/></xsl:template><xsl:template match="ppx:arrayValue"><xsl:param name="_indent" select="0"/><xsl:call-template name="complex_type_value"><xsl:with-param name="start_bracket"><xsl:text>[</xsl:text></xsl:with-param><xsl:with-param name="end_bracket"><xsl:text>]</xsl:text></xsl:with-param></xsl:call-template></xsl:template><xsl:template match="ppx:structValue"><xsl:param name="_indent" select="0"/><xsl:call-template name="complex_type_value"><xsl:with-param name="start_bracket"><xsl:text>(</xsl:text></xsl:with-param><xsl:with-param name="end_bracket"><xsl:text>)</xsl:text></xsl:with-param></xsl:call-template></xsl:template></xsl:stylesheet>
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/plcopen/variables_infos.ysl2	Wed Oct 09 10:57:20 2013 +0200
@@ -0,0 +1,233 @@
+include yslt.yml2
+estylesheet xmlns:ppx="http://www.plcopen.org/xml/tc6_0201"
+            xmlns:xhtml="http://www.w3.org/1999/xhtml"
+            xmlns:ns="var_infos_ns" 
+            extension-element-prefixes="ns" 
+            exclude-result-prefixes="ns" {
+    
+    param "tree";
+    
+    template "text()";
+    
+    variable "project" {
+        choose {
+            when "$tree='True'" {
+                copy "document('project')/project/*";
+            }
+        }
+    }
+    
+    variable "stdlib" {
+        choose {
+            when "$tree='True'" {
+                copy "document('stdlib')/stdlib/*";
+            }
+        }
+    }
+    variable "extensions" {
+        choose {
+            when "$tree='True'" {
+                copy "document('extensions')/extensions/*";
+            }
+        }
+    }
+    
+    template "ppx:returnType" {
+        value "ns:AddTree()";
+        apply;
+    }
+    
+    function "variables_infos" {
+        param "var_class";
+        variable "var_option" {
+            choose {
+                when "@constant='true' or @constant='1'" > Constant
+                when "@retain='true' or @retain='1'" > Retain
+                when "@nonretain='true' or @nonretain='1'" > Non-Retain
+            }
+        }
+        foreach "ppx:variable" {
+            variable "initial_value" {
+                apply "ppx:initialValue";
+            }
+            variable "edit" {
+                choose {
+                    when "$var_class='Global' or $var_class='External'" > true
+                    otherwise {
+                        apply "ppx:type", mode="var_edit";
+                    }
+                }
+            }
+            value "ns:AddTree()";
+            apply "ppx:type";
+            value "ns:AddVariable(@name, $var_class, $var_option, @address, $initial_value, $edit, ppx:documentation/xhtml:p/text())";
+        }
+    }
+    
+    template "ppx:localVars" {
+        call "variables_infos" {
+            with "var_class" > Local
+        }
+    }
+    
+    template "ppx:globalVars" {
+        call "variables_infos" {
+            with "var_class" > Global
+        }
+    }
+    
+    template "ppx:externalVars" {
+        call "variables_infos" {
+            with "var_class" > External
+        }
+    }
+    
+    template "ppx:tempVars" {
+        call "variables_infos" {
+            with "var_class" > Temp
+        }
+    }
+    
+    template "ppx:inputVars" {
+        call "variables_infos" {
+            with "var_class" > Input
+        }
+    }
+    
+    template "ppx:outputVars" {
+        call "variables_infos" {
+            with "var_class" > Output
+        }
+    }
+    
+    template "ppx:inOutVars" {
+        call "variables_infos" {
+            with "var_class" > InOut
+        }
+    }
+    
+    template "ppx:pou" {
+        apply "ppx:interface/*[self::ppx:inputVars or self::ppx:inOutVars or self::ppx:outputVars]/ppx:variable";
+    }
+    
+    template "ppx:variable" {
+        variable "name" > «@name»
+        value "ns:AddTree($name)";
+        apply "ppx:type";
+        value "ns:AddVarToTree($name)";
+    }
+    
+    template "ppx:dataType" {
+        apply "ppx:baseType";
+    }
+    
+    template "*[self::ppx:type or self::ppx:baseType or self::ppx:returnType]/ppx:struct" {
+        apply "ppx:variable";
+    }
+    
+    template "*[self::ppx:type or self::ppx:baseType or self::ppx:returnType]/ppx:derived" {
+        variable "type_name" > «@name»
+        choose {
+            when "$tree='True'" {
+                apply """exsl:node-set($project)/ppx:project/ppx:types/ppx:pous/ppx:pou[@name=$type_name] |
+                         exsl:node-set($project)/ppx:project/ppx:types/ppx:dataTypes/ppx:dataType[@name=$type_name] |
+                         exsl:node-set($stdlib)/ppx:project/ppx:types/ppx:pous/ppx:pou[@name=$type_name] |
+                         exsl:node-set($stdlib)/ppx:project/ppx:types/ppx:dataTypes/ppx:dataType[@name=$type_name] |
+                         exsl:node-set($extensions)/ppx:project/ppx:types/ppx:pous/ppx:pou[@name=$type_name] |
+                         exsl:node-set($extensions)/ppx:project/ppx:types/ppx:dataTypes/ppx:dataType[@name=$type_name]""";
+            }
+        }
+        value "ns:SetType($type_name)";
+    }
+     
+    template "*[self::ppx:type or self::ppx:baseType or self::ppx:returnType]/ppx:array" {
+        apply "ppx:baseType";
+        foreach "ppx:dimension" {
+            value "ns:AddDimension(@lower, @upper)";
+        }
+    }
+    
+    template "*[self::ppx:type or self::ppx:baseType or self::ppx:returnType]/ppx:string" {
+        variable "name" > STRING
+        value "ns:SetType($name)";
+    }
+    
+    template "*[self::ppx:type or self::ppx:baseType or self::ppx:returnType]/ppx:wstring" {
+        variable "name" > WSTRING
+        value "ns:SetType($name)";
+    }
+    
+    template "*[self::ppx:type or self::ppx:baseType or self::ppx:returnType]/*" {
+        variable "name" > «local-name()»
+        value "ns:SetType($name)";
+    }
+    
+    template "*[self::ppx:type or self::ppx:baseType or self::ppx:returnType]/ppx:derived", mode="var_edit" {
+        variable "type_name", "@name";
+        variable "pou_infos" {
+            copy """exsl:node-set($project)/ppx:project/ppx:types/ppx:pous/ppx:pou[@name=$type_name] |
+                    exsl:node-set($stdlib)/ppx:project/ppx:types/ppx:pous/ppx:pou[@name=$type_name] |
+                    exsl:node-set($extensions)/ppx:project/ppx:types/ppx:pous/ppx:pou[@name=$type_name]""";
+        }
+        choose {
+            when "$pou_infos != ''" > false
+            otherwise > true
+        }
+    }
+    
+    template "*[self::ppx:type or self::ppx:baseType or self::ppx:returnType]/*", mode="var_edit" {
+        > true
+    }
+    
+    template "ppx:value" {
+        choose {
+            when "@repetitionValue" {
+                > «@repetitionValue»(
+                apply;
+                > )
+            }
+            when "@member" {
+                 > «@member» := 
+                 apply;
+            }
+            otherwise {
+                apply;
+            }
+        }
+    }
+    
+    template "ppx:simpleValue" {
+        > «@value»
+    }
+    
+    function "complex_type_value" {
+        param "start_bracket";
+        param "end_bracket";
+        > «@start_bracket»
+        foreach "ppx:value" {
+            apply ".";
+            choose {
+                when "position()!=last()" > , 
+            }
+        }
+        > «@end_bracket»
+    }
+    
+    template "ppx:arrayValue" {
+        call "complex_type_value" {
+            with "start_bracket" > [
+            with "end_bracket" > ]
+        }
+    }
+    
+    template "ppx:structValue" {
+        call "complex_type_value" {
+            with "start_bracket" > (
+            with "end_bracket" > )
+        }
+    }
+
+}
+
+    
+    
\ No newline at end of file
--- a/util/MiniTextControler.py	Fri Oct 04 12:17:03 2013 +0200
+++ b/util/MiniTextControler.py	Wed Oct 09 10:57:20 2013 +0200
@@ -29,7 +29,7 @@
             return text
         return ""
     
-    def GetEditedElementInterfaceVars(self, tagname, debug = False):
+    def GetEditedElementInterfaceVars(self, tagname, tree=False, debug = False):
         return []
     
     def GetEditedElementType(self, tagname, debug = False):