Adding help menu for inserting complex variable in graphical viewer
authorlbessard
Fri, 09 Jan 2009 17:09:59 +0100
changeset 297 e837b67cb184
parent 296 919f72861bfb
child 298 1b1a3ee785da
Adding help menu for inserting complex variable in graphical viewer
PLCControler.py
TextViewer.py
Viewer.py
--- a/PLCControler.py	Fri Dec 19 15:08:54 2008 +0100
+++ b/PLCControler.py	Fri Jan 09 17:09:59 2009 +0100
@@ -957,43 +957,33 @@
                         vars.append(tempvar)
         return vars
     
-    # Return the interface of the pou given by its name
-    def GetPouInterfaceVarsByName(self, name, debug = False):
-        project = self.GetProject(debug)
-        if project is not None:
-            # Found the pou correponding to name and return the interface vars
-            pou = project.getpou(name)
-            if pou is not None:
-                return self.GetPouInterfaceVars(pou, debug)
-        return None
-    
     # Recursively generate element name tree for a structured variable
     def GenerateVarTree(self, typename, debug = False):
         project = self.GetProject(debug)
         if project is not None:
             blocktype = self.GetBlockType(typename, debug = debug)
             if blocktype is not None:
-                tree = {}
+                tree = []
                 for var_name, var_type, var_modifier in blocktype["inputs"] + blocktype["outputs"]:
-                    tree[var_name] = self.GenerateVarTree(var_type, debug)
+                    tree.append((var_name, var_type, self.GenerateVarTree(var_type, debug)))
                 return tree
             datatype = project.getdataType(typename)
             if datatype is not None:
-                tree = {}
+                tree = []
                 basetype_content = datatype.baseType.getcontent()
                 if basetype_content["name"] == "derived":
                     tree = self.GenerateVarTree(basetype_content["value"].getname())
                 elif basetype_content["name"] == "array":
                     base_type = basetype_content["value"].baseType.getcontent()
                     if base_type["name"] == "derived":
-                        tree = self.GenerateVarTree(base_type["value"].getname())
+                        tree = [self.GenerateVarTree(base_type["value"].getname())]
                 elif basetype_content["name"] == "struct":
                     for element in basetype_content["value"].getvariable():
                         element_type = element.type.getcontent()
                         if element_type["name"] == "derived":
-                            tree[element.getname()] = self.GenerateVarTree(element_type["value"].getname())
+                            tree.append((element.getname(), element_type["value"].getname(), self.GenerateVarTree(element_type["value"].getname())))
                         else:
-                            tree[element.getname()] = {}
+                            tree.append((element.getname(), element_type["name"], []))
                 return tree
         return {}
     
@@ -1005,7 +995,7 @@
             # Extract variables from every varLists
             for type, varlist in pou.getvars():
                 for var in varlist.getvariable():
-                    tempvar = {"Name" : var.getname(), "Class" : type, "Tree" : {}}
+                    tempvar = {"Name" : var.getname(), "Class" : type, "Tree" : []}
                     vartype_content = var.gettype().getcontent()
                     if vartype_content["name"] == "derived":
                         tempvar["Type"] = vartype_content["value"].getname()
--- a/TextViewer.py	Fri Dec 19 15:08:54 2008 +0100
+++ b/TextViewer.py	Fri Jan 09 17:09:59 2009 +0100
@@ -274,7 +274,7 @@
         
         words = self.TagName.split("::")
         
-        self.Variables = dict([(variable["Name"], 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, self.Debug)])
         if self.Controler.GetEditedElementType(self.TagName, self.Debug)[1] == "function" or words[0] == "T" and self.TextSyntax == "IL":
             self.Variables[words[-1]] = {}
         
@@ -289,7 +289,15 @@
             self.EnumeratedValues.append(value.upper())
         
         self.Colourise(0, -1)
-        
+    
+    def GenerateVariableTree(self, list):
+        tree = {}
+        if len(list) == 1 and isinstance(list, ListType):
+            list = list[0]
+        for var_name, var_type, var_tree in list:
+            tree[var_name] = self.GenerateVariableTree(var_tree)
+        return tree
+    
     def RefreshScaling(self, refresh=True):
         pass
     
--- a/Viewer.py	Fri Dec 19 15:08:54 2008 +0100
+++ b/Viewer.py	Fri Jan 09 17:09:59 2009 +0100
@@ -152,35 +152,72 @@
                         self.ParentWindow.ParentWindow.RefreshVariablePanel(self.ParentWindow.GetTagName())
                         self.ParentWindow.Refresh(False)
             elif values[1] != "location":
-                if values[3] == self.ParentWindow.GetTagName():
-                    id = self.ParentWindow.GetNewId()
+                tagname = self.ParentWindow.GetTagName()
+                if values[3] == tagname:
                     if values[1] == "Output":
-                        var_type = OUTPUT
+                        var_class = OUTPUT
                     elif values[1] == "InOut":
-                        var_type = INPUT
+                        var_class = INPUT
                     else:
-                        var_type = INPUT
-                    variable = FBD_Variable(self.ParentWindow, var_type, values[0], values[2], id)
-                    width, height = variable.GetMinSize()
-                    if scaling is not None:
-                        x = round(float(x) / float(scaling[0])) * scaling[0]
-                        y = round(float(y) / float(scaling[1])) * scaling[1]
-                        width = round(float(width) / float(scaling[0]) + 0.5) * scaling[0]
-                        height = round(float(height) / float(scaling[1]) + 0.5) * scaling[1]
-                    variable.SetPosition(x, y)
-                    variable.SetSize(width, height)
-                    self.ParentWindow.AddBlock(variable)
-                    self.ParentWindow.Controler.AddEditedElementVariable(self.ParentWindow.GetTagName(), id, var_type)
-                    self.ParentWindow.RefreshVariableModel(variable)
-                    self.ParentWindow.RefreshBuffer()
-                    self.ParentWindow.RefreshScrollBars()
-                    self.ParentWindow.RefreshVisibleElements()
-                    self.ParentWindow.Refresh(False)
+                        var_class = INPUT
+                    tree = dict([(var["Name"], var["Tree"]) for var in self.ParentWindow.Controler.GetEditedElementInterfaceVars(tagname, self.ParentWindow.Debug)]).get(values[0], None)
+                    if tree is not None:
+                        if len(tree) > 0:
+                            menu = wx.Menu(title='')
+                            self.GenerateTreeMenu(x, y, scaling, menu, "", var_class, [(values[0], values[2], tree)])
+                            self.ParentWindow.PopupMenuXY(menu)
+                        else:
+                            self.AddParentVariableBlock(x, y, scaling, var_class, values[0], values[2])
+                    else:
+                        message = "Unknown variable \"%s\" this POU!" % values[0]
                 else:
                     message = "Variable don't belong to this POU!"
         if message is not None:
             wx.CallAfter(self.ShowMessage, message)
 
+    def GenerateTreeMenu(self, x, y, scaling, menu, base_path, var_class, tree):
+        for child_name, child_type, child_tree in tree:
+            if base_path:
+                child_path = "%s.%s" % (base_path, child_name)
+            else:
+                child_path = child_name
+            if len(child_tree) == 1 and isinstance(child_tree[0], ListType):
+                child_path += "[0]"
+                child_name += "[]"
+                child_tree = child_tree[0]
+            new_id = wx.NewId()
+            AppendMenu(menu, help='', id=new_id, kind=wx.ITEM_NORMAL, text=child_name)
+            self.ParentWindow.Bind(wx.EVT_MENU, self.GetAddVariableBlockFunction(x, y, scaling, var_class, child_path, child_type), id=new_id)
+            if len(child_tree) > 0:
+                new_id = wx.NewId()
+                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.AddParentVariableBlock(x, y, scaling, var_class, var_name, var_type)
+        return AddVariableFunction
+    
+    def AddParentVariableBlock(self, x, y, scaling, var_class, var_name, var_type):
+        id = self.ParentWindow.GetNewId()
+        variable = FBD_Variable(self.ParentWindow, var_class, var_name, var_type, id)
+        width, height = variable.GetMinSize()
+        if scaling is not None:
+            x = round(float(x) / float(scaling[0])) * scaling[0]
+            y = round(float(y) / float(scaling[1])) * scaling[1]
+            width = round(float(width) / float(scaling[0]) + 0.5) * scaling[0]
+            height = round(float(height) / float(scaling[1]) + 0.5) * scaling[1]
+        variable.SetPosition(x, y)
+        variable.SetSize(width, height)
+        self.ParentWindow.AddBlock(variable)
+        self.ParentWindow.Controler.AddEditedElementVariable(self.ParentWindow.GetTagName(), id, var_class)
+        self.ParentWindow.RefreshVariableModel(variable)
+        self.ParentWindow.RefreshBuffer()
+        self.ParentWindow.RefreshScrollBars()
+        self.ParentWindow.RefreshVisibleElements()
+        self.ParentWindow.Refresh(False)
+    
     def ShowMessage(self, message):
         message = wx.MessageDialog(self.ParentWindow, message, "Error", wx.OK|wx.ICON_ERROR)
         message.ShowModal()