controls/PouInstanceVariablesPanel.py
changeset 684 f10449b18dbe
child 686 3216bf5f711d
equal deleted inserted replaced
683:37882f34f9cb 684:f10449b18dbe
       
     1 #!/usr/bin/env python
       
     2 # -*- coding: utf-8 -*-
       
     3 
       
     4 #This file is part of PLCOpenEditor, a library implementing an IEC 61131-3 editor
       
     5 #based on the plcopen standard. 
       
     6 #
       
     7 #Copyright (C) 2012: Edouard TISSERANT and Laurent BESSARD
       
     8 #
       
     9 #See COPYING file for copyrights details.
       
    10 #
       
    11 #This library is free software; you can redistribute it and/or
       
    12 #modify it under the terms of the GNU General Public
       
    13 #License as published by the Free Software Foundation; either
       
    14 #version 2.1 of the License, or (at your option) any later version.
       
    15 #
       
    16 #This library is distributed in the hope that it will be useful,
       
    17 #but WITHOUT ANY WARRANTY; without even the implied warranty of
       
    18 #MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
       
    19 #General Public License for more details.
       
    20 #
       
    21 #You should have received a copy of the GNU General Public
       
    22 #License along with this library; if not, write to the Free Software
       
    23 #Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
       
    24 
       
    25 import wx
       
    26 import wx.lib.buttons
       
    27 import wx.lib.agw.customtreectrl as CT
       
    28 
       
    29 from PLCControler import ITEMS_VARIABLE, ITEM_CONFIGURATION, ITEM_RESOURCE, ITEM_POU
       
    30 
       
    31 class PouInstanceVariablesPanel(wx.Panel):
       
    32     
       
    33     def __init__(self, parent, window, controller, debug):
       
    34         wx.Panel.__init__(self, name='PouInstanceTreePanel', 
       
    35                 parent=parent, pos=wx.Point(0, 0), 
       
    36                 size=wx.Size(0, 0), style=wx.TAB_TRAVERSAL)
       
    37         
       
    38         self.ParentButton = wx.lib.buttons.GenBitmapButton(
       
    39               name='ParentButton', parent=self, 
       
    40               bitmap=window.GenerateBitmap("up"), 
       
    41               pos=wx.Point(0, 0), size=wx.Size(28, 28), 
       
    42               style=wx.NO_BORDER)
       
    43         self.Bind(wx.EVT_BUTTON, self.OnParentButtonClick, 
       
    44                 self.ParentButton)
       
    45         
       
    46         self.InstanceChoice = wx.ComboBox(name='InstanceChoice', 
       
    47               parent=self, pos=wx.Point(0, 0),
       
    48               size=wx.Size(0, 28), style=wx.CB_READONLY)
       
    49         self.Bind(wx.EVT_COMBOBOX, self.OnInstanceChoiceChanged,
       
    50                 self.InstanceChoice)
       
    51         
       
    52         self.DebugButton = wx.lib.buttons.GenBitmapButton(
       
    53               name='DebugButton', parent=self, 
       
    54               bitmap=window.GenerateBitmap("debug"), 
       
    55               pos=wx.Point(0, 0), size=wx.Size(28, 28), 
       
    56               style=wx.NO_BORDER)
       
    57         self.Bind(wx.EVT_BUTTON, self.OnDebugButtonClick, 
       
    58                 self.DebugButton)
       
    59     
       
    60         self.VariablesList = CT.CustomTreeCtrl(
       
    61               name='VariablesList', parent=self,
       
    62               pos=wx.Point(0, 0), size=wx.Size(0, 0), 
       
    63               style=wx.SUNKEN_BORDER,
       
    64               agwStyle=CT.TR_NO_BUTTONS|
       
    65                        CT.TR_SINGLE|
       
    66                        CT.TR_HAS_VARIABLE_ROW_HEIGHT|
       
    67                        CT.TR_HIDE_ROOT|
       
    68                        CT.TR_LINES_AT_ROOT|
       
    69                        CT.TR_NO_LINES)
       
    70         self.VariablesList.Bind(CT.EVT_TREE_ITEM_ACTIVATED,
       
    71                 self.OnVariablesListItemActivated)
       
    72         
       
    73         buttons_sizer = wx.FlexGridSizer(cols=3, hgap=0, rows=1, vgap=0)
       
    74         buttons_sizer.AddWindow(self.ParentButton, 0, border=0, flag=0)
       
    75         buttons_sizer.AddWindow(self.InstanceChoice, 0, border=0, flag=wx.GROW)
       
    76         buttons_sizer.AddWindow(self.DebugButton, 0, border=0, flag=0)
       
    77         buttons_sizer.AddGrowableCol(1)
       
    78         buttons_sizer.AddGrowableRow(0)
       
    79         
       
    80         main_sizer = wx.FlexGridSizer(cols=1, hgap=0, rows=2, vgap=0)
       
    81         main_sizer.AddSizer(buttons_sizer, 0, border=0, flag=wx.GROW)
       
    82         main_sizer.AddWindow(self.VariablesList, 0, border=0, flag=wx.GROW)
       
    83         main_sizer.AddGrowableCol(0)
       
    84         main_sizer.AddGrowableRow(1)
       
    85         
       
    86         self.SetSizer(main_sizer)
       
    87         
       
    88         self.ParentWindow = window
       
    89         self.Controller = controller
       
    90         self.Debug = debug
       
    91         if not self.Debug:
       
    92             self.DebugButton.Hide()
       
    93         
       
    94         self.PouTagName = None
       
    95         self.PouInfos = None
       
    96         self.PouInstance = None
       
    97         
       
    98     def __del__(self):
       
    99         self.Controller = None
       
   100     
       
   101     def SetTreeImageList(self, tree_image_list):
       
   102         self.VariablesList.SetImageList(tree_image_list)
       
   103     
       
   104     def SetController(self, controller):
       
   105         self.Controller = controller
       
   106      
       
   107     def SetPouType(self, tagname, pou_instance=None):
       
   108         self.PouTagName = tagname
       
   109         if pou_instance is not None:
       
   110             self.PouInstance = pou_instance
       
   111         
       
   112         self.RefreshView()
       
   113     
       
   114     def ResetView(self):
       
   115         self.PouTagName = None
       
   116         self.PouInfos = None
       
   117         self.PouInstance = None
       
   118         
       
   119         self.RefreshView()
       
   120     
       
   121     def RefreshView(self):
       
   122         self.VariablesList.DeleteAllItems()
       
   123         self.InstanceChoice.Clear()
       
   124         
       
   125         if self.PouTagName is not None:
       
   126             self.PouInfos = self.Controller.GetPouVariables(self.PouTagName, self.Debug)
       
   127         else:
       
   128             self.PouInfos = None
       
   129         if self.PouInfos is not None:
       
   130             root = self.VariablesList.AddRoot("")
       
   131             for var_infos in self.PouInfos["variables"]:
       
   132                 if var_infos.get("type", None) is not None:
       
   133                     text = "%(name)s (%(type)s)" % var_infos
       
   134                 else:
       
   135                     text = var_infos["name"]
       
   136                 
       
   137                 panel = wx.Panel(self.VariablesList)
       
   138                     
       
   139                 buttons = []
       
   140                 if var_infos["class"] in ITEMS_VARIABLE:
       
   141                     if (var_infos["debug"] and self.Debug and
       
   142                         (self.Controller.IsOfType(var_infos["type"], "ANY_NUM", True) or
       
   143                          self.Controller.IsOfType(var_infos["type"], "ANY_BIT", True))):
       
   144                         graph_button = wx.lib.buttons.GenBitmapButton(name="graph", 
       
   145                               parent=panel, bitmap=self.ParentWindow.GenerateBitmap("graph"), 
       
   146                               pos=wx.Point(0, 0), size=wx.Size(28, 28), style=wx.NO_BORDER)
       
   147                         self.Bind(wx.EVT_BUTTON, self.GenGraphButtonCallback(var_infos), graph_button)
       
   148                         buttons.append(graph_button)
       
   149                 elif var_infos["edit"]:
       
   150                     edit_button = wx.lib.buttons.GenBitmapButton(name="edit", 
       
   151                           parent=panel, bitmap=self.ParentWindow.GenerateBitmap("edit"), 
       
   152                           pos=wx.Point(0, 0), size=wx.Size(28, 28), style=wx.NO_BORDER)
       
   153                     self.Bind(wx.EVT_BUTTON, self.GenEditButtonCallback(var_infos), edit_button)
       
   154                     buttons.append(edit_button)
       
   155                 
       
   156                 if var_infos["debug"] and self.Debug:
       
   157                     debug_button = wx.lib.buttons.GenBitmapButton(name="debug", 
       
   158                           parent=panel, bitmap=self.ParentWindow.GenerateBitmap("debug"), 
       
   159                           pos=wx.Point(0, 0), size=wx.Size(28, 28), style=wx.NO_BORDER)
       
   160                     self.Bind(wx.EVT_BUTTON, self.GenDebugButtonCallback(var_infos), debug_button)
       
   161                     buttons.append(debug_button)
       
   162                 
       
   163                 button_num = len(buttons)
       
   164                 if button_num > 0:
       
   165                     panel.SetSize(wx.Size(button_num * 32, 28))
       
   166                     panel.SetBackgroundColour(self.VariablesList.GetBackgroundColour())
       
   167                     panel_sizer = wx.BoxSizer(wx.HORIZONTAL)
       
   168                     panel.SetSizer(panel_sizer)
       
   169                     
       
   170                     for button in buttons:
       
   171                         panel_sizer.AddWindow(button, 0, border=4, flag=wx.LEFT)
       
   172                 else:
       
   173                     panel.Destroy()
       
   174                     panel = None
       
   175                 
       
   176                 item = self.VariablesList.AppendItem(root, text, wnd=panel)
       
   177                 self.VariablesList.SetItemImage(item, self.ParentWindow.GetTreeImage(var_infos["class"]))
       
   178                 self.VariablesList.SetPyData(item, var_infos)
       
   179             
       
   180             instances = self.Controller.SearchPouInstances(self.PouTagName, self.Debug)
       
   181             for instance in instances:
       
   182                 self.InstanceChoice.Append(instance)
       
   183             if self.PouInfos["class"] in [ITEM_CONFIGURATION, ITEM_RESOURCE]:
       
   184                 self.PouInstance = None
       
   185                 self.InstanceChoice.SetSelection(0)
       
   186             elif self.PouInstance in instances:
       
   187                 self.InstanceChoice.SetStringSelection(self.PouInstance)
       
   188             else:
       
   189                 self.PouInstance = None
       
   190                 self.InstanceChoice.SetValue(_("Select an instance"))
       
   191         
       
   192         self.RefreshButtons()
       
   193         
       
   194     def RefreshButtons(self):
       
   195         enabled = self.InstanceChoice.GetSelection() != -1
       
   196         self.ParentButton.Enable(enabled and self.PouInfos["class"] != ITEM_CONFIGURATION)
       
   197         self.DebugButton.Enable(enabled and self.PouInfos["debug"] and self.Debug)
       
   198         
       
   199         root = self.VariablesList.GetRootItem()
       
   200         if root is not None and root.IsOk():
       
   201             item, item_cookie = self.VariablesList.GetFirstChild(root)
       
   202             while item is not None and item.IsOk():
       
   203                 panel = self.VariablesList.GetItemWindow(item)
       
   204                 if panel is not None:
       
   205                     for child in panel.GetChildren():
       
   206                         if child.GetName() != "edit":
       
   207                             child.Enable(enabled)
       
   208                 item, item_cookie = self.VariablesList.GetNextChild(root, item_cookie)
       
   209     
       
   210     def GenEditButtonCallback(self, infos):
       
   211         def EditButtonCallback(event):
       
   212             var_class = infos["class"]
       
   213             if var_class == ITEM_RESOURCE:
       
   214                 tagname = self.Controller.ComputeConfigurationResourceName(
       
   215                     self.InstanceChoice.GetStringSelection(), 
       
   216                     infos["name"])
       
   217             else:
       
   218                 var_class = ITEM_POU
       
   219                 tagname = self.Controller.ComputePouName(infos["type"])
       
   220             self.ParentWindow.EditProjectElement(var_class, tagname)
       
   221             event.Skip()
       
   222         return EditButtonCallback
       
   223     
       
   224     def GenDebugButtonCallback(self, infos):
       
   225         def DebugButtonCallback(event):
       
   226             if self.InstanceChoice.GetSelection() != -1:
       
   227                 var_class = infos["class"]
       
   228                 var_path = "%s.%s" % (self.InstanceChoice.GetStringSelection(), 
       
   229                                       infos["name"])
       
   230                 if var_class in ITEMS_VARIABLE:
       
   231                     self.ParentWindow.AddDebugVariable(var_path, force=True)
       
   232                 else:
       
   233                     self.ParentWindow.OpenDebugViewer(
       
   234                         infos["class"],
       
   235                         var_path,
       
   236                         self.Controller.ComputePouName(infos["type"]))
       
   237             event.Skip()
       
   238         return DebugButtonCallback
       
   239     
       
   240     def GenGraphButtonCallback(self, infos):
       
   241         def GraphButtonCallback(event):
       
   242             if self.InstanceChoice.GetSelection() != -1:
       
   243                 if infos["class"] in ITEMS_VARIABLE:
       
   244                     var_path = "%s.%s" % (self.InstanceChoice.GetStringSelection(), 
       
   245                                           infos["name"])
       
   246                     self.ParentWindow.OpenGraphicViewer(var_path)
       
   247             event.Skip()
       
   248         return GraphButtonCallback
       
   249     
       
   250     def OnParentButtonClick(self, event):
       
   251         if self.InstanceChoice.GetSelection() != -1:
       
   252             parent_path = self.InstanceChoice.GetStringSelection().rsplit(".", 1)[0]
       
   253             tagname = self.Controller.GetPouInstanceTagname(parent_path, self.Debug)
       
   254             if tagname is not None:
       
   255                 wx.CallAfter(self.SetPouType, tagname, parent_path)
       
   256                 wx.CallAfter(self.ParentWindow.SelectProjectTreeItem, tagname)
       
   257         event.Skip()
       
   258         
       
   259     def OnInstanceChoiceChanged(self, event):
       
   260         self.RefreshButtons()
       
   261         event.Skip()
       
   262         
       
   263     def OnDebugButtonClick(self, event):
       
   264         if self.InstanceChoice.GetSelection() != -1:
       
   265             self.ParentWindow.OpenDebugViewer(
       
   266                 self.PouInfos["class"],
       
   267                 self.InstanceChoice.GetStringSelection(),
       
   268                 self.PouTagName)
       
   269         event.Skip()
       
   270         
       
   271     def OnVariablesListItemActivated(self, event):
       
   272         if self.InstanceChoice.GetSelection() != -1:
       
   273             instance_path = self.InstanceChoice.GetStringSelection()
       
   274             selected_item = self.VariablesList.GetSelection()
       
   275             if selected_item is not None and selected_item.IsOk():
       
   276                 item_infos = self.VariablesList.GetPyData(selected_item)
       
   277                 if item_infos["class"] not in ITEMS_VARIABLE:
       
   278                     if item_infos["class"] == ITEM_RESOURCE:
       
   279                         tagname = self.Controller.ComputeConfigurationResourceName(
       
   280                                        instance_path, 
       
   281                                        item_infos["name"])
       
   282                     else:
       
   283                         tagname = self.Controller.ComputePouName(item_infos["type"])
       
   284                     item_path = "%s.%s" % (instance_path, item_infos["name"])
       
   285                     wx.CallAfter(self.SetPouType, tagname, item_path)
       
   286                     wx.CallAfter(self.ParentWindow.SelectProjectTreeItem, tagname)
       
   287         event.Skip()
       
   288     
       
   289